PackageManagerShellCommand.java revision 51245c74f4efb62f12b9b16c8d05f7302c31c275
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm; 18 19import android.app.ActivityManager; 20import android.content.ComponentName; 21import android.content.IIntentReceiver; 22import android.content.IIntentSender; 23import android.content.Intent; 24import android.content.IntentSender; 25import android.content.pm.ApplicationInfo; 26import android.content.pm.FeatureInfo; 27import android.content.pm.IPackageManager; 28import android.content.pm.InstrumentationInfo; 29import android.content.pm.PackageInfo; 30import android.content.pm.PackageInstaller; 31import android.content.pm.PackageItemInfo; 32import android.content.pm.PackageManager; 33import android.content.pm.PackageParser; 34import android.content.pm.PackageParser.ApkLite; 35import android.content.pm.PackageParser.PackageLite; 36import android.content.pm.PackageParser.PackageParserException; 37import android.content.pm.ParceledListSlice; 38import android.content.pm.PermissionGroupInfo; 39import android.content.pm.PermissionInfo; 40import android.content.pm.PackageInstaller.SessionInfo; 41import android.content.pm.PackageInstaller.SessionParams; 42import android.content.pm.ResolveInfo; 43import android.content.res.AssetManager; 44import android.content.res.Resources; 45import android.net.Uri; 46import android.os.Binder; 47import android.os.Build; 48import android.os.Bundle; 49import android.os.RemoteException; 50import android.os.ShellCommand; 51import android.os.SystemProperties; 52import android.os.UserHandle; 53import android.text.TextUtils; 54import android.util.ArraySet; 55import android.util.PrintWriterPrinter; 56import com.android.internal.content.PackageHelper; 57import com.android.internal.util.SizedInputStream; 58import com.android.server.SystemConfig; 59 60import dalvik.system.DexFile; 61 62import libcore.io.IoUtils; 63 64import java.io.File; 65import java.io.FileInputStream; 66import java.io.IOException; 67import java.io.InputStream; 68import java.io.OutputStream; 69import java.io.PrintWriter; 70import java.net.URISyntaxException; 71import java.util.ArrayList; 72import java.util.Collections; 73import java.util.Comparator; 74import java.util.List; 75import java.util.WeakHashMap; 76import java.util.concurrent.SynchronousQueue; 77import java.util.concurrent.TimeUnit; 78 79class PackageManagerShellCommand extends ShellCommand { 80 /** Path for streaming APK content */ 81 private static final String STDIN_PATH = "-"; 82 /** Whether or not APK content must be streamed from stdin */ 83 private static final boolean FORCE_STREAM_INSTALL = true; 84 85 final IPackageManager mInterface; 86 final private WeakHashMap<String, Resources> mResourceCache = 87 new WeakHashMap<String, Resources>(); 88 int mTargetUser; 89 boolean mBrief; 90 boolean mComponents; 91 92 PackageManagerShellCommand(PackageManagerService service) { 93 mInterface = service; 94 } 95 96 @Override 97 public int onCommand(String cmd) { 98 if (cmd == null) { 99 return handleDefaultCommands(cmd); 100 } 101 102 final PrintWriter pw = getOutPrintWriter(); 103 try { 104 switch(cmd) { 105 case "install": 106 return runInstall(); 107 case "install-abandon": 108 case "install-destroy": 109 return runInstallAbandon(); 110 case "install-commit": 111 return runInstallCommit(); 112 case "install-create": 113 return runInstallCreate(); 114 case "install-remove": 115 return runInstallRemove(); 116 case "install-write": 117 return runInstallWrite(); 118 case "compile": 119 return runCompile(); 120 case "dump-profiles": 121 return runDumpProfiles(); 122 case "list": 123 return runList(); 124 case "uninstall": 125 return runUninstall(); 126 case "resolve-activity": 127 return runResolveActivity(); 128 case "query-activities": 129 return runQueryIntentActivities(); 130 case "query-services": 131 return runQueryIntentServices(); 132 case "query-receivers": 133 return runQueryIntentReceivers(); 134 case "suspend": 135 return runSuspend(true); 136 case "unsuspend": 137 return runSuspend(false); 138 case "set-home-activity": 139 return runSetHomeActivity(); 140 case "get-privapp-permissions": 141 return runGetPrivappPermissions(); 142 default: 143 return handleDefaultCommands(cmd); 144 } 145 } catch (RemoteException e) { 146 pw.println("Remote exception: " + e); 147 } 148 return -1; 149 } 150 151 private void setParamsSize(InstallParams params, String inPath) { 152 // If we're forced to stream the package, the params size 153 // must be set via command-line argument. There's nothing 154 // to do here. 155 if (FORCE_STREAM_INSTALL) { 156 return; 157 } 158 final PrintWriter pw = getOutPrintWriter(); 159 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) { 160 File file = new File(inPath); 161 if (file.isFile()) { 162 try { 163 ApkLite baseApk = PackageParser.parseApkLite(file, 0); 164 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null); 165 params.sessionParams.setSize(PackageHelper.calculateInstalledSize( 166 pkgLite, false, params.sessionParams.abiOverride)); 167 } catch (PackageParserException | IOException e) { 168 pw.println("Error: Failed to parse APK file: " + file); 169 throw new IllegalArgumentException( 170 "Error: Failed to parse APK file: " + file, e); 171 } 172 } else { 173 pw.println("Error: Can't open non-file: " + inPath); 174 throw new IllegalArgumentException("Error: Can't open non-file: " + inPath); 175 } 176 } 177 } 178 179 private int runInstall() throws RemoteException { 180 final PrintWriter pw = getOutPrintWriter(); 181 final InstallParams params = makeInstallParams(); 182 final String inPath = getNextArg(); 183 184 setParamsSize(params, inPath); 185 final int sessionId = doCreateSession(params.sessionParams, 186 params.installerPackageName, params.userId); 187 boolean abandonSession = true; 188 try { 189 if (inPath == null && params.sessionParams.sizeBytes == -1) { 190 pw.println("Error: must either specify a package size or an APK file"); 191 return 1; 192 } 193 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk", 194 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 195 return 1; 196 } 197 if (doCommitSession(sessionId, false /*logSuccess*/) 198 != PackageInstaller.STATUS_SUCCESS) { 199 return 1; 200 } 201 abandonSession = false; 202 pw.println("Success"); 203 return 0; 204 } finally { 205 if (abandonSession) { 206 try { 207 doAbandonSession(sessionId, false /*logSuccess*/); 208 } catch (Exception ignore) { 209 } 210 } 211 } 212 } 213 214 private int runSuspend(boolean suspendedState) { 215 final PrintWriter pw = getOutPrintWriter(); 216 int userId = UserHandle.USER_SYSTEM; 217 String opt; 218 while ((opt = getNextOption()) != null) { 219 switch (opt) { 220 case "--user": 221 userId = UserHandle.parseUserArg(getNextArgRequired()); 222 break; 223 default: 224 pw.println("Error: Unknown option: " + opt); 225 return 1; 226 } 227 } 228 229 String packageName = getNextArg(); 230 if (packageName == null) { 231 pw.println("Error: package name not specified"); 232 return 1; 233 } 234 235 try { 236 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState, 237 userId); 238 pw.println("Package " + packageName + " new suspended state: " 239 + mInterface.isPackageSuspendedForUser(packageName, userId)); 240 return 0; 241 } catch (RemoteException | IllegalArgumentException e) { 242 pw.println(e.toString()); 243 return 1; 244 } 245 } 246 247 private int runInstallAbandon() throws RemoteException { 248 final int sessionId = Integer.parseInt(getNextArg()); 249 return doAbandonSession(sessionId, true /*logSuccess*/); 250 } 251 252 private int runInstallCommit() throws RemoteException { 253 final int sessionId = Integer.parseInt(getNextArg()); 254 return doCommitSession(sessionId, true /*logSuccess*/); 255 } 256 257 private int runInstallCreate() throws RemoteException { 258 final PrintWriter pw = getOutPrintWriter(); 259 final InstallParams installParams = makeInstallParams(); 260 final int sessionId = doCreateSession(installParams.sessionParams, 261 installParams.installerPackageName, installParams.userId); 262 263 // NOTE: adb depends on parsing this string 264 pw.println("Success: created install session [" + sessionId + "]"); 265 return 0; 266 } 267 268 private int runInstallWrite() throws RemoteException { 269 long sizeBytes = -1; 270 271 String opt; 272 while ((opt = getNextOption()) != null) { 273 if (opt.equals("-S")) { 274 sizeBytes = Long.parseLong(getNextArg()); 275 } else { 276 throw new IllegalArgumentException("Unknown option: " + opt); 277 } 278 } 279 280 final int sessionId = Integer.parseInt(getNextArg()); 281 final String splitName = getNextArg(); 282 final String path = getNextArg(); 283 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); 284 } 285 286 private int runInstallRemove() throws RemoteException { 287 final PrintWriter pw = getOutPrintWriter(); 288 289 final int sessionId = Integer.parseInt(getNextArg()); 290 291 final String splitName = getNextArg(); 292 if (splitName == null) { 293 pw.println("Error: split name not specified"); 294 return 1; 295 } 296 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/); 297 } 298 299 private int runCompile() throws RemoteException { 300 final PrintWriter pw = getOutPrintWriter(); 301 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false); 302 boolean forceCompilation = false; 303 boolean allPackages = false; 304 boolean clearProfileData = false; 305 String compilerFilter = null; 306 String compilationReason = null; 307 String checkProfilesRaw = null; 308 309 String opt; 310 while ((opt = getNextOption()) != null) { 311 switch (opt) { 312 case "-a": 313 allPackages = true; 314 break; 315 case "-c": 316 clearProfileData = true; 317 break; 318 case "-f": 319 forceCompilation = true; 320 break; 321 case "-m": 322 compilerFilter = getNextArgRequired(); 323 break; 324 case "-r": 325 compilationReason = getNextArgRequired(); 326 break; 327 case "--check-prof": 328 checkProfilesRaw = getNextArgRequired(); 329 break; 330 case "--reset": 331 forceCompilation = true; 332 clearProfileData = true; 333 compilationReason = "install"; 334 break; 335 default: 336 pw.println("Error: Unknown option: " + opt); 337 return 1; 338 } 339 } 340 341 if (checkProfilesRaw != null) { 342 if ("true".equals(checkProfilesRaw)) { 343 checkProfiles = true; 344 } else if ("false".equals(checkProfilesRaw)) { 345 checkProfiles = false; 346 } else { 347 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\"."); 348 return 1; 349 } 350 } 351 352 if (compilerFilter != null && compilationReason != null) { 353 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " + 354 "at the same time"); 355 return 1; 356 } 357 if (compilerFilter == null && compilationReason == null) { 358 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " + 359 "reason (\"-r\") at the same time"); 360 return 1; 361 } 362 363 String targetCompilerFilter; 364 if (compilerFilter != null) { 365 if (!DexFile.isValidCompilerFilter(compilerFilter)) { 366 pw.println("Error: \"" + compilerFilter + 367 "\" is not a valid compilation filter."); 368 return 1; 369 } 370 targetCompilerFilter = compilerFilter; 371 } else { 372 int reason = -1; 373 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 374 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals( 375 compilationReason)) { 376 reason = i; 377 break; 378 } 379 } 380 if (reason == -1) { 381 pw.println("Error: Unknown compilation reason: " + compilationReason); 382 return 1; 383 } 384 targetCompilerFilter = 385 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason); 386 } 387 388 389 List<String> packageNames = null; 390 if (allPackages) { 391 packageNames = mInterface.getAllPackages(); 392 } else { 393 String packageName = getNextArg(); 394 if (packageName == null) { 395 pw.println("Error: package name not specified"); 396 return 1; 397 } 398 packageNames = Collections.singletonList(packageName); 399 } 400 401 List<String> failedPackages = new ArrayList<>(); 402 for (String packageName : packageNames) { 403 if (clearProfileData) { 404 mInterface.clearApplicationProfileData(packageName); 405 } 406 407 boolean result = mInterface.performDexOptMode(packageName, 408 checkProfiles, targetCompilerFilter, forceCompilation); 409 if (!result) { 410 failedPackages.add(packageName); 411 } 412 } 413 414 if (failedPackages.isEmpty()) { 415 pw.println("Success"); 416 return 0; 417 } else if (failedPackages.size() == 1) { 418 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled"); 419 return 1; 420 } else { 421 pw.print("Failure: the following packages could not be compiled: "); 422 boolean is_first = true; 423 for (String packageName : failedPackages) { 424 if (is_first) { 425 is_first = false; 426 } else { 427 pw.print(", "); 428 } 429 pw.print(packageName); 430 } 431 pw.println(); 432 return 1; 433 } 434 } 435 436 private int runDumpProfiles() throws RemoteException { 437 String packageName = getNextArg(); 438 mInterface.dumpProfiles(packageName); 439 return 0; 440 } 441 442 private int runList() throws RemoteException { 443 final PrintWriter pw = getOutPrintWriter(); 444 final String type = getNextArg(); 445 if (type == null) { 446 pw.println("Error: didn't specify type of data to list"); 447 return -1; 448 } 449 switch(type) { 450 case "features": 451 return runListFeatures(); 452 case "instrumentation": 453 return runListInstrumentation(); 454 case "libraries": 455 return runListLibraries(); 456 case "package": 457 case "packages": 458 return runListPackages(false /*showSourceDir*/); 459 case "permission-groups": 460 return runListPermissionGroups(); 461 case "permissions": 462 return runListPermissions(); 463 } 464 pw.println("Error: unknown list type '" + type + "'"); 465 return -1; 466 } 467 468 private int runListFeatures() throws RemoteException { 469 final PrintWriter pw = getOutPrintWriter(); 470 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList(); 471 472 // sort by name 473 Collections.sort(list, new Comparator<FeatureInfo>() { 474 public int compare(FeatureInfo o1, FeatureInfo o2) { 475 if (o1.name == o2.name) return 0; 476 if (o1.name == null) return -1; 477 if (o2.name == null) return 1; 478 return o1.name.compareTo(o2.name); 479 } 480 }); 481 482 final int count = (list != null) ? list.size() : 0; 483 for (int p = 0; p < count; p++) { 484 FeatureInfo fi = list.get(p); 485 pw.print("feature:"); 486 if (fi.name != null) { 487 pw.print(fi.name); 488 if (fi.version > 0) { 489 pw.print("="); 490 pw.print(fi.version); 491 } 492 pw.println(); 493 } else { 494 pw.println("reqGlEsVersion=0x" 495 + Integer.toHexString(fi.reqGlEsVersion)); 496 } 497 } 498 return 0; 499 } 500 501 private int runListInstrumentation() throws RemoteException { 502 final PrintWriter pw = getOutPrintWriter(); 503 boolean showSourceDir = false; 504 String targetPackage = null; 505 506 try { 507 String opt; 508 while ((opt = getNextArg()) != null) { 509 switch (opt) { 510 case "-f": 511 showSourceDir = true; 512 break; 513 default: 514 if (opt.charAt(0) != '-') { 515 targetPackage = opt; 516 } else { 517 pw.println("Error: Unknown option: " + opt); 518 return -1; 519 } 520 break; 521 } 522 } 523 } catch (RuntimeException ex) { 524 pw.println("Error: " + ex.toString()); 525 return -1; 526 } 527 528 final List<InstrumentationInfo> list = 529 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList(); 530 531 // sort by target package 532 Collections.sort(list, new Comparator<InstrumentationInfo>() { 533 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 534 return o1.targetPackage.compareTo(o2.targetPackage); 535 } 536 }); 537 538 final int count = (list != null) ? list.size() : 0; 539 for (int p = 0; p < count; p++) { 540 final InstrumentationInfo ii = list.get(p); 541 pw.print("instrumentation:"); 542 if (showSourceDir) { 543 pw.print(ii.sourceDir); 544 pw.print("="); 545 } 546 final ComponentName cn = new ComponentName(ii.packageName, ii.name); 547 pw.print(cn.flattenToShortString()); 548 pw.print(" (target="); 549 pw.print(ii.targetPackage); 550 pw.println(")"); 551 } 552 return 0; 553 } 554 555 private int runListLibraries() throws RemoteException { 556 final PrintWriter pw = getOutPrintWriter(); 557 final List<String> list = new ArrayList<String>(); 558 final String[] rawList = mInterface.getSystemSharedLibraryNames(); 559 for (int i = 0; i < rawList.length; i++) { 560 list.add(rawList[i]); 561 } 562 563 // sort by name 564 Collections.sort(list, new Comparator<String>() { 565 public int compare(String o1, String o2) { 566 if (o1 == o2) return 0; 567 if (o1 == null) return -1; 568 if (o2 == null) return 1; 569 return o1.compareTo(o2); 570 } 571 }); 572 573 final int count = (list != null) ? list.size() : 0; 574 for (int p = 0; p < count; p++) { 575 String lib = list.get(p); 576 pw.print("library:"); 577 pw.println(lib); 578 } 579 return 0; 580 } 581 582 private int runListPackages(boolean showSourceDir) throws RemoteException { 583 final PrintWriter pw = getOutPrintWriter(); 584 int getFlags = 0; 585 boolean listDisabled = false, listEnabled = false; 586 boolean listSystem = false, listThirdParty = false; 587 boolean listInstaller = false; 588 boolean showUid = false; 589 int uid = -1; 590 int userId = UserHandle.USER_SYSTEM; 591 try { 592 String opt; 593 while ((opt = getNextOption()) != null) { 594 switch (opt) { 595 case "-d": 596 listDisabled = true; 597 break; 598 case "-e": 599 listEnabled = true; 600 break; 601 case "-f": 602 showSourceDir = true; 603 break; 604 case "-i": 605 listInstaller = true; 606 break; 607 case "-l": 608 // old compat 609 break; 610 case "-s": 611 listSystem = true; 612 break; 613 case "-U": 614 showUid = true; 615 break; 616 case "-u": 617 getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; 618 break; 619 case "-3": 620 listThirdParty = true; 621 break; 622 case "--user": 623 userId = UserHandle.parseUserArg(getNextArgRequired()); 624 break; 625 case "--uid": 626 showUid = true; 627 uid = Integer.parseInt(getNextArgRequired()); 628 break; 629 default: 630 pw.println("Error: Unknown option: " + opt); 631 return -1; 632 } 633 } 634 } catch (RuntimeException ex) { 635 pw.println("Error: " + ex.toString()); 636 return -1; 637 } 638 639 final String filter = getNextArg(); 640 641 @SuppressWarnings("unchecked") 642 final ParceledListSlice<PackageInfo> slice = 643 mInterface.getInstalledPackages(getFlags, userId); 644 final List<PackageInfo> packages = slice.getList(); 645 646 final int count = packages.size(); 647 for (int p = 0; p < count; p++) { 648 final PackageInfo info = packages.get(p); 649 if (filter != null && !info.packageName.contains(filter)) { 650 continue; 651 } 652 if (uid != -1 && info.applicationInfo.uid != uid) { 653 continue; 654 } 655 final boolean isSystem = 656 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; 657 if ((!listDisabled || !info.applicationInfo.enabled) && 658 (!listEnabled || info.applicationInfo.enabled) && 659 (!listSystem || isSystem) && 660 (!listThirdParty || !isSystem)) { 661 pw.print("package:"); 662 if (showSourceDir) { 663 pw.print(info.applicationInfo.sourceDir); 664 pw.print("="); 665 } 666 pw.print(info.packageName); 667 if (listInstaller) { 668 pw.print(" installer="); 669 pw.print(mInterface.getInstallerPackageName(info.packageName)); 670 } 671 if (showUid) { 672 pw.print(" uid:"); 673 pw.print(info.applicationInfo.uid); 674 } 675 pw.println(); 676 } 677 } 678 return 0; 679 } 680 681 private int runListPermissionGroups() throws RemoteException { 682 final PrintWriter pw = getOutPrintWriter(); 683 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList(); 684 685 final int count = pgs.size(); 686 for (int p = 0; p < count ; p++) { 687 final PermissionGroupInfo pgi = pgs.get(p); 688 pw.print("permission group:"); 689 pw.println(pgi.name); 690 } 691 return 0; 692 } 693 694 private int runListPermissions() throws RemoteException { 695 final PrintWriter pw = getOutPrintWriter(); 696 boolean labels = false; 697 boolean groups = false; 698 boolean userOnly = false; 699 boolean summary = false; 700 boolean dangerousOnly = false; 701 String opt; 702 while ((opt = getNextOption()) != null) { 703 switch (opt) { 704 case "-d": 705 dangerousOnly = true; 706 break; 707 case "-f": 708 labels = true; 709 break; 710 case "-g": 711 groups = true; 712 break; 713 case "-s": 714 groups = true; 715 labels = true; 716 summary = true; 717 break; 718 case "-u": 719 userOnly = true; 720 break; 721 default: 722 pw.println("Error: Unknown option: " + opt); 723 return 1; 724 } 725 } 726 727 final ArrayList<String> groupList = new ArrayList<String>(); 728 if (groups) { 729 final List<PermissionGroupInfo> infos = 730 mInterface.getAllPermissionGroups(0 /*flags*/).getList(); 731 final int count = infos.size(); 732 for (int i = 0; i < count; i++) { 733 groupList.add(infos.get(i).name); 734 } 735 groupList.add(null); 736 } else { 737 final String grp = getNextArg(); 738 groupList.add(grp); 739 } 740 741 if (dangerousOnly) { 742 pw.println("Dangerous Permissions:"); 743 pw.println(""); 744 doListPermissions(groupList, groups, labels, summary, 745 PermissionInfo.PROTECTION_DANGEROUS, 746 PermissionInfo.PROTECTION_DANGEROUS); 747 if (userOnly) { 748 pw.println("Normal Permissions:"); 749 pw.println(""); 750 doListPermissions(groupList, groups, labels, summary, 751 PermissionInfo.PROTECTION_NORMAL, 752 PermissionInfo.PROTECTION_NORMAL); 753 } 754 } else if (userOnly) { 755 pw.println("Dangerous and Normal Permissions:"); 756 pw.println(""); 757 doListPermissions(groupList, groups, labels, summary, 758 PermissionInfo.PROTECTION_NORMAL, 759 PermissionInfo.PROTECTION_DANGEROUS); 760 } else { 761 pw.println("All Permissions:"); 762 pw.println(""); 763 doListPermissions(groupList, groups, labels, summary, 764 -10000, 10000); 765 } 766 return 0; 767 } 768 769 private int runUninstall() throws RemoteException { 770 final PrintWriter pw = getOutPrintWriter(); 771 int flags = 0; 772 int userId = UserHandle.USER_ALL; 773 774 String opt; 775 while ((opt = getNextOption()) != null) { 776 switch (opt) { 777 case "-k": 778 flags |= PackageManager.DELETE_KEEP_DATA; 779 break; 780 case "--user": 781 userId = UserHandle.parseUserArg(getNextArgRequired()); 782 break; 783 default: 784 pw.println("Error: Unknown option: " + opt); 785 return 1; 786 } 787 } 788 789 final String packageName = getNextArg(); 790 if (packageName == null) { 791 pw.println("Error: package name not specified"); 792 return 1; 793 } 794 795 // if a split is specified, just remove it and not the whole package 796 final String splitName = getNextArg(); 797 if (splitName != null) { 798 return runRemoveSplit(packageName, splitName); 799 } 800 801 userId = translateUserId(userId, "runUninstall"); 802 if (userId == UserHandle.USER_ALL) { 803 userId = UserHandle.USER_SYSTEM; 804 flags |= PackageManager.DELETE_ALL_USERS; 805 } else { 806 final PackageInfo info = mInterface.getPackageInfo(packageName, 0, userId); 807 if (info == null) { 808 pw.println("Failure [not installed for " + userId + "]"); 809 return 1; 810 } 811 final boolean isSystem = 812 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 813 // If we are being asked to delete a system app for just one 814 // user set flag so it disables rather than reverting to system 815 // version of the app. 816 if (isSystem) { 817 flags |= PackageManager.DELETE_SYSTEM_APP; 818 } 819 } 820 821 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 822 mInterface.getPackageInstaller().uninstall(packageName, null /*callerPackageName*/, flags, 823 receiver.getIntentSender(), userId); 824 825 final Intent result = receiver.getResult(); 826 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 827 PackageInstaller.STATUS_FAILURE); 828 if (status == PackageInstaller.STATUS_SUCCESS) { 829 pw.println("Success"); 830 return 0; 831 } else { 832 pw.println("Failure [" 833 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 834 return 1; 835 } 836 } 837 838 private int runRemoveSplit(String packageName, String splitName) throws RemoteException { 839 final PrintWriter pw = getOutPrintWriter(); 840 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 841 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 842 sessionParams.appPackageName = packageName; 843 final int sessionId = 844 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL); 845 boolean abandonSession = true; 846 try { 847 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/) 848 != PackageInstaller.STATUS_SUCCESS) { 849 return 1; 850 } 851 if (doCommitSession(sessionId, false /*logSuccess*/) 852 != PackageInstaller.STATUS_SUCCESS) { 853 return 1; 854 } 855 abandonSession = false; 856 pw.println("Success"); 857 return 0; 858 } finally { 859 if (abandonSession) { 860 try { 861 doAbandonSession(sessionId, false /*logSuccess*/); 862 } catch (Exception ignore) { 863 } 864 } 865 } 866 } 867 868 private Intent parseIntentAndUser() throws URISyntaxException { 869 mTargetUser = UserHandle.USER_CURRENT; 870 mBrief = false; 871 mComponents = false; 872 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 873 @Override 874 public boolean handleOption(String opt, ShellCommand cmd) { 875 if ("--user".equals(opt)) { 876 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired()); 877 return true; 878 } else if ("--brief".equals(opt)) { 879 mBrief = true; 880 return true; 881 } else if ("--components".equals(opt)) { 882 mComponents = true; 883 return true; 884 } 885 return false; 886 } 887 }); 888 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 889 Binder.getCallingUid(), mTargetUser, false, false, null, null); 890 return intent; 891 } 892 893 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri, 894 boolean brief, boolean components) { 895 if (brief || components) { 896 final ComponentName comp; 897 if (ri.activityInfo != null) { 898 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); 899 } else if (ri.serviceInfo != null) { 900 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name); 901 } else if (ri.providerInfo != null) { 902 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name); 903 } else { 904 comp = null; 905 } 906 if (comp != null) { 907 if (!components) { 908 pr.println(prefix + "priority=" + ri.priority 909 + " preferredOrder=" + ri.preferredOrder 910 + " match=0x" + Integer.toHexString(ri.match) 911 + " specificIndex=" + ri.specificIndex 912 + " isDefault=" + ri.isDefault); 913 } 914 pr.println(prefix + comp.flattenToShortString()); 915 return; 916 } 917 } 918 ri.dump(pr, prefix); 919 } 920 921 private int runResolveActivity() { 922 Intent intent; 923 try { 924 intent = parseIntentAndUser(); 925 } catch (URISyntaxException e) { 926 throw new RuntimeException(e.getMessage(), e); 927 } 928 try { 929 ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser); 930 PrintWriter pw = getOutPrintWriter(); 931 if (ri == null) { 932 pw.println("No activity found"); 933 } else { 934 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 935 printResolveInfo(pr, "", ri, mBrief, mComponents); 936 } 937 } catch (RemoteException e) { 938 throw new RuntimeException("Failed calling service", e); 939 } 940 return 0; 941 } 942 943 private int runQueryIntentActivities() { 944 Intent intent; 945 try { 946 intent = parseIntentAndUser(); 947 } catch (URISyntaxException e) { 948 throw new RuntimeException(e.getMessage(), e); 949 } 950 try { 951 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0, 952 mTargetUser).getList(); 953 PrintWriter pw = getOutPrintWriter(); 954 if (result == null || result.size() <= 0) { 955 pw.println("No activities found"); 956 } else { 957 if (!mComponents) { 958 pw.print(result.size()); pw.println(" activities found:"); 959 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 960 for (int i = 0; i < result.size(); i++) { 961 pw.print(" Activity #"); pw.print(i); pw.println(":"); 962 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 963 } 964 } else { 965 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 966 for (int i = 0; i < result.size(); i++) { 967 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 968 } 969 } 970 } 971 } catch (RemoteException e) { 972 throw new RuntimeException("Failed calling service", e); 973 } 974 return 0; 975 } 976 977 private int runQueryIntentServices() { 978 Intent intent; 979 try { 980 intent = parseIntentAndUser(); 981 } catch (URISyntaxException e) { 982 throw new RuntimeException(e.getMessage(), e); 983 } 984 try { 985 List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0, 986 mTargetUser).getList(); 987 PrintWriter pw = getOutPrintWriter(); 988 if (result == null || result.size() <= 0) { 989 pw.println("No services found"); 990 } else { 991 if (!mComponents) { 992 pw.print(result.size()); pw.println(" services found:"); 993 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 994 for (int i = 0; i < result.size(); i++) { 995 pw.print(" Service #"); pw.print(i); pw.println(":"); 996 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 997 } 998 } else { 999 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1000 for (int i = 0; i < result.size(); i++) { 1001 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 1002 } 1003 } 1004 } 1005 } catch (RemoteException e) { 1006 throw new RuntimeException("Failed calling service", e); 1007 } 1008 return 0; 1009 } 1010 1011 private int runQueryIntentReceivers() { 1012 Intent intent; 1013 try { 1014 intent = parseIntentAndUser(); 1015 } catch (URISyntaxException e) { 1016 throw new RuntimeException(e.getMessage(), e); 1017 } 1018 try { 1019 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0, 1020 mTargetUser).getList(); 1021 PrintWriter pw = getOutPrintWriter(); 1022 if (result == null || result.size() <= 0) { 1023 pw.println("No receivers found"); 1024 } else { 1025 if (!mComponents) { 1026 pw.print(result.size()); pw.println(" receivers found:"); 1027 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1028 for (int i = 0; i < result.size(); i++) { 1029 pw.print(" Receiver #"); pw.print(i); pw.println(":"); 1030 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 1031 } 1032 } else { 1033 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1034 for (int i = 0; i < result.size(); i++) { 1035 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 1036 } 1037 } 1038 } 1039 } catch (RemoteException e) { 1040 throw new RuntimeException("Failed calling service", e); 1041 } 1042 return 0; 1043 } 1044 1045 private static class InstallParams { 1046 SessionParams sessionParams; 1047 String installerPackageName; 1048 int userId = UserHandle.USER_ALL; 1049 } 1050 1051 private InstallParams makeInstallParams() { 1052 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1053 final InstallParams params = new InstallParams(); 1054 params.sessionParams = sessionParams; 1055 String opt; 1056 while ((opt = getNextOption()) != null) { 1057 switch (opt) { 1058 case "-l": 1059 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 1060 break; 1061 case "-r": 1062 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1063 break; 1064 case "-i": 1065 params.installerPackageName = getNextArg(); 1066 if (params.installerPackageName == null) { 1067 throw new IllegalArgumentException("Missing installer package"); 1068 } 1069 break; 1070 case "-t": 1071 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 1072 break; 1073 case "-s": 1074 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL; 1075 break; 1076 case "-f": 1077 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL; 1078 break; 1079 case "-d": 1080 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 1081 break; 1082 case "-g": 1083 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; 1084 break; 1085 case "--dont-kill": 1086 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP; 1087 break; 1088 case "--originating-uri": 1089 sessionParams.originatingUri = Uri.parse(getNextArg()); 1090 break; 1091 case "--referrer": 1092 sessionParams.referrerUri = Uri.parse(getNextArg()); 1093 break; 1094 case "-p": 1095 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING; 1096 sessionParams.appPackageName = getNextArg(); 1097 if (sessionParams.appPackageName == null) { 1098 throw new IllegalArgumentException("Missing inherit package name"); 1099 } 1100 break; 1101 case "-S": 1102 final long sizeBytes = Long.parseLong(getNextArg()); 1103 if (sizeBytes <= 0) { 1104 throw new IllegalArgumentException("Size must be positive"); 1105 } 1106 sessionParams.setSize(sizeBytes); 1107 break; 1108 case "--abi": 1109 sessionParams.abiOverride = checkAbiArgument(getNextArg()); 1110 break; 1111 case "--ephemeral": 1112 sessionParams.installFlags |= PackageManager.INSTALL_EPHEMERAL; 1113 break; 1114 case "--user": 1115 params.userId = UserHandle.parseUserArg(getNextArgRequired()); 1116 break; 1117 case "--install-location": 1118 sessionParams.installLocation = Integer.parseInt(getNextArg()); 1119 break; 1120 case "--force-uuid": 1121 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID; 1122 sessionParams.volumeUuid = getNextArg(); 1123 if ("internal".equals(sessionParams.volumeUuid)) { 1124 sessionParams.volumeUuid = null; 1125 } 1126 break; 1127 case "--force-sdk": 1128 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; 1129 break; 1130 default: 1131 throw new IllegalArgumentException("Unknown option " + opt); 1132 } 1133 } 1134 return params; 1135 } 1136 1137 private int runSetHomeActivity() { 1138 final PrintWriter pw = getOutPrintWriter(); 1139 int userId = UserHandle.USER_SYSTEM; 1140 String opt; 1141 while ((opt = getNextOption()) != null) { 1142 switch (opt) { 1143 case "--user": 1144 userId = UserHandle.parseUserArg(getNextArgRequired()); 1145 break; 1146 default: 1147 pw.println("Error: Unknown option: " + opt); 1148 return 1; 1149 } 1150 } 1151 1152 String component = getNextArg(); 1153 ComponentName componentName = 1154 component != null ? ComponentName.unflattenFromString(component) : null; 1155 1156 if (componentName == null) { 1157 pw.println("Error: component name not specified or invalid"); 1158 return 1; 1159 } 1160 1161 try { 1162 mInterface.setHomeActivity(componentName, userId); 1163 pw.println("Success"); 1164 return 0; 1165 } catch (Exception e) { 1166 pw.println(e.toString()); 1167 return 1; 1168 } 1169 } 1170 1171 private int runGetPrivappPermissions() { 1172 final String pkg = getNextArg(); 1173 if (pkg == null) { 1174 System.err.println("Error: no package specified."); 1175 return 1; 1176 } 1177 ArraySet<String> privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg); 1178 getOutPrintWriter().println(privAppPermissions == null 1179 ? "{}" : privAppPermissions.toString()); 1180 return 0; 1181 } 1182 1183 private static String checkAbiArgument(String abi) { 1184 if (TextUtils.isEmpty(abi)) { 1185 throw new IllegalArgumentException("Missing ABI argument"); 1186 } 1187 1188 if ("-".equals(abi)) { 1189 return abi; 1190 } 1191 1192 final String[] supportedAbis = Build.SUPPORTED_ABIS; 1193 for (String supportedAbi : supportedAbis) { 1194 if (supportedAbi.equals(abi)) { 1195 return abi; 1196 } 1197 } 1198 1199 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 1200 } 1201 1202 private int translateUserId(int userId, String logContext) { 1203 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1204 userId, true, true, logContext, "pm command"); 1205 } 1206 1207 private int doCreateSession(SessionParams params, String installerPackageName, int userId) 1208 throws RemoteException { 1209 userId = translateUserId(userId, "runInstallCreate"); 1210 if (userId == UserHandle.USER_ALL) { 1211 userId = UserHandle.USER_SYSTEM; 1212 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 1213 } 1214 1215 final int sessionId = mInterface.getPackageInstaller() 1216 .createSession(params, installerPackageName, userId); 1217 return sessionId; 1218 } 1219 1220 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, 1221 boolean logSuccess) throws RemoteException { 1222 final PrintWriter pw = getOutPrintWriter(); 1223 if (FORCE_STREAM_INSTALL && inPath != null && !STDIN_PATH.equals(inPath)) { 1224 pw.println("Error: APK content must be streamed"); 1225 return 1; 1226 } 1227 if (STDIN_PATH.equals(inPath)) { 1228 inPath = null; 1229 } else if (inPath != null) { 1230 final File file = new File(inPath); 1231 if (file.isFile()) { 1232 sizeBytes = file.length(); 1233 } 1234 } 1235 if (sizeBytes <= 0) { 1236 pw.println("Error: must specify a APK size"); 1237 return 1; 1238 } 1239 1240 final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId); 1241 1242 PackageInstaller.Session session = null; 1243 InputStream in = null; 1244 OutputStream out = null; 1245 try { 1246 session = new PackageInstaller.Session( 1247 mInterface.getPackageInstaller().openSession(sessionId)); 1248 1249 if (inPath != null) { 1250 in = new FileInputStream(inPath); 1251 } else { 1252 in = new SizedInputStream(getRawInputStream(), sizeBytes); 1253 } 1254 out = session.openWrite(splitName, 0, sizeBytes); 1255 1256 int total = 0; 1257 byte[] buffer = new byte[65536]; 1258 int c; 1259 while ((c = in.read(buffer)) != -1) { 1260 total += c; 1261 out.write(buffer, 0, c); 1262 1263 if (info.sizeBytes > 0) { 1264 final float fraction = ((float) c / (float) info.sizeBytes); 1265 session.addProgress(fraction); 1266 } 1267 } 1268 session.fsync(out); 1269 1270 if (logSuccess) { 1271 pw.println("Success: streamed " + total + " bytes"); 1272 } 1273 return 0; 1274 } catch (IOException e) { 1275 pw.println("Error: failed to write; " + e.getMessage()); 1276 return 1; 1277 } finally { 1278 IoUtils.closeQuietly(out); 1279 IoUtils.closeQuietly(in); 1280 IoUtils.closeQuietly(session); 1281 } 1282 } 1283 1284 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess) 1285 throws RemoteException { 1286 final PrintWriter pw = getOutPrintWriter(); 1287 PackageInstaller.Session session = null; 1288 try { 1289 session = new PackageInstaller.Session( 1290 mInterface.getPackageInstaller().openSession(sessionId)); 1291 session.removeSplit(splitName); 1292 1293 if (logSuccess) { 1294 pw.println("Success"); 1295 } 1296 return 0; 1297 } catch (IOException e) { 1298 pw.println("Error: failed to remove split; " + e.getMessage()); 1299 return 1; 1300 } finally { 1301 IoUtils.closeQuietly(session); 1302 } 1303 } 1304 1305 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException { 1306 final PrintWriter pw = getOutPrintWriter(); 1307 PackageInstaller.Session session = null; 1308 try { 1309 session = new PackageInstaller.Session( 1310 mInterface.getPackageInstaller().openSession(sessionId)); 1311 1312 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1313 session.commit(receiver.getIntentSender()); 1314 1315 final Intent result = receiver.getResult(); 1316 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1317 PackageInstaller.STATUS_FAILURE); 1318 if (status == PackageInstaller.STATUS_SUCCESS) { 1319 if (logSuccess) { 1320 pw.println("Success"); 1321 } 1322 } else { 1323 pw.println("Failure [" 1324 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1325 } 1326 return status; 1327 } finally { 1328 IoUtils.closeQuietly(session); 1329 } 1330 } 1331 1332 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException { 1333 final PrintWriter pw = getOutPrintWriter(); 1334 PackageInstaller.Session session = null; 1335 try { 1336 session = new PackageInstaller.Session( 1337 mInterface.getPackageInstaller().openSession(sessionId)); 1338 session.abandon(); 1339 if (logSuccess) { 1340 pw.println("Success"); 1341 } 1342 return 0; 1343 } finally { 1344 IoUtils.closeQuietly(session); 1345 } 1346 } 1347 1348 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels, 1349 boolean summary, int startProtectionLevel, int endProtectionLevel) 1350 throws RemoteException { 1351 final PrintWriter pw = getOutPrintWriter(); 1352 final int groupCount = groupList.size(); 1353 for (int i = 0; i < groupCount; i++) { 1354 String groupName = groupList.get(i); 1355 String prefix = ""; 1356 if (groups) { 1357 if (i > 0) { 1358 pw.println(""); 1359 } 1360 if (groupName != null) { 1361 PermissionGroupInfo pgi = 1362 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/); 1363 if (summary) { 1364 Resources res = getResources(pgi); 1365 if (res != null) { 1366 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": "); 1367 } else { 1368 pw.print(pgi.name + ": "); 1369 1370 } 1371 } else { 1372 pw.println((labels ? "+ " : "") + "group:" + pgi.name); 1373 if (labels) { 1374 pw.println(" package:" + pgi.packageName); 1375 Resources res = getResources(pgi); 1376 if (res != null) { 1377 pw.println(" label:" 1378 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel)); 1379 pw.println(" description:" 1380 + loadText(pgi, pgi.descriptionRes, 1381 pgi.nonLocalizedDescription)); 1382 } 1383 } 1384 } 1385 } else { 1386 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:"); 1387 } 1388 prefix = " "; 1389 } 1390 List<PermissionInfo> ps = 1391 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList(); 1392 final int count = ps.size(); 1393 boolean first = true; 1394 for (int p = 0 ; p < count ; p++) { 1395 PermissionInfo pi = ps.get(p); 1396 if (groups && groupName == null && pi.group != null) { 1397 continue; 1398 } 1399 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 1400 if (base < startProtectionLevel 1401 || base > endProtectionLevel) { 1402 continue; 1403 } 1404 if (summary) { 1405 if (first) { 1406 first = false; 1407 } else { 1408 pw.print(", "); 1409 } 1410 Resources res = getResources(pi); 1411 if (res != null) { 1412 pw.print(loadText(pi, pi.labelRes, 1413 pi.nonLocalizedLabel)); 1414 } else { 1415 pw.print(pi.name); 1416 } 1417 } else { 1418 pw.println(prefix + (labels ? "+ " : "") 1419 + "permission:" + pi.name); 1420 if (labels) { 1421 pw.println(prefix + " package:" + pi.packageName); 1422 Resources res = getResources(pi); 1423 if (res != null) { 1424 pw.println(prefix + " label:" 1425 + loadText(pi, pi.labelRes, 1426 pi.nonLocalizedLabel)); 1427 pw.println(prefix + " description:" 1428 + loadText(pi, pi.descriptionRes, 1429 pi.nonLocalizedDescription)); 1430 } 1431 pw.println(prefix + " protectionLevel:" 1432 + PermissionInfo.protectionToString(pi.protectionLevel)); 1433 } 1434 } 1435 } 1436 1437 if (summary) { 1438 pw.println(""); 1439 } 1440 } 1441 } 1442 1443 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) 1444 throws RemoteException { 1445 if (nonLocalized != null) { 1446 return nonLocalized.toString(); 1447 } 1448 if (res != 0) { 1449 Resources r = getResources(pii); 1450 if (r != null) { 1451 try { 1452 return r.getString(res); 1453 } catch (Resources.NotFoundException e) { 1454 } 1455 } 1456 } 1457 return null; 1458 } 1459 1460 private Resources getResources(PackageItemInfo pii) throws RemoteException { 1461 Resources res = mResourceCache.get(pii.packageName); 1462 if (res != null) return res; 1463 1464 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0); 1465 AssetManager am = new AssetManager(); 1466 am.addAssetPath(ai.publicSourceDir); 1467 res = new Resources(am, null, null); 1468 mResourceCache.put(pii.packageName, res); 1469 return res; 1470 } 1471 1472 @Override 1473 public void onHelp() { 1474 final PrintWriter pw = getOutPrintWriter(); 1475 pw.println("Package manager (package) commands:"); 1476 pw.println(" help"); 1477 pw.println(" Print this help text."); 1478 pw.println(""); 1479 pw.println(" compile [-m MODE | -r REASON] [-f] [-c]"); 1480 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)"); 1481 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\"."); 1482 pw.println(" Options:"); 1483 pw.println(" -a: compile all packages"); 1484 pw.println(" -c: clear profile data before compiling"); 1485 pw.println(" -f: force compilation even if not needed"); 1486 pw.println(" -m: select compilation mode"); 1487 pw.println(" MODE is one of the dex2oat compiler filters:"); 1488 pw.println(" verify-none"); 1489 pw.println(" verify-at-runtime"); 1490 pw.println(" verify-profile"); 1491 pw.println(" interpret-only"); 1492 pw.println(" space-profile"); 1493 pw.println(" space"); 1494 pw.println(" speed-profile"); 1495 pw.println(" speed"); 1496 pw.println(" everything"); 1497 pw.println(" -r: select compilation reason"); 1498 pw.println(" REASON is one of:"); 1499 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 1500 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]); 1501 } 1502 pw.println(" --reset: restore package to its post-install state"); 1503 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?"); 1504 pw.println(" list features"); 1505 pw.println(" Prints all features of the system."); 1506 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]"); 1507 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE"); 1508 pw.println(" Options:"); 1509 pw.println(" -f: dump the name of the .apk file containing the test package"); 1510 pw.println(" list libraries"); 1511 pw.println(" Prints all system libraries."); 1512 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] " 1513 + "[--uid UID] [--user USER_ID] [FILTER]"); 1514 pw.println(" Prints all packages; optionally only those whose name contains"); 1515 pw.println(" the text in FILTER."); 1516 pw.println(" Options:"); 1517 pw.println(" -f: see their associated file"); 1518 pw.println(" -d: filter to only show disabled packages"); 1519 pw.println(" -e: filter to only show enabled packages"); 1520 pw.println(" -s: filter to only show system packages"); 1521 pw.println(" -3: filter to only show third party packages"); 1522 pw.println(" -i: see the installer for the packages"); 1523 pw.println(" -l: ignored (used for compatibility with older releases)"); 1524 pw.println(" -U: also show the package UID"); 1525 pw.println(" -u: also include uninstalled packages"); 1526 pw.println(" --uid UID: filter to only show packages with the given UID"); 1527 pw.println(" --user USER_ID: only list packages belonging to the given user"); 1528 pw.println(" list permission-groups"); 1529 pw.println(" Prints all known permission groups."); 1530 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); 1531 pw.println(" Prints all known permissions; optionally only those in GROUP."); 1532 pw.println(" Options:"); 1533 pw.println(" -g: organize by group"); 1534 pw.println(" -f: print all information"); 1535 pw.println(" -s: short summary"); 1536 pw.println(" -d: only list dangerous permissions"); 1537 pw.println(" -u: list only the permissions users will see"); 1538 pw.println(" dump-profiles TARGET-PACKAGE"); 1539 pw.println(" Dumps method/class profile files to"); 1540 pw.println(" /data/misc/profman/TARGET-PACKAGE.txt"); 1541 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT"); 1542 pw.println(" Prints the activity that resolves to the given Intent."); 1543 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT"); 1544 pw.println(" Prints all activities that can handle the given Intent."); 1545 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT"); 1546 pw.println(" Prints all services that can handle the given Intent."); 1547 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT"); 1548 pw.println(" Prints all broadcast receivers that can handle the given Intent."); 1549 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE"); 1550 pw.println(" Suspends the specified package (as user)."); 1551 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE"); 1552 pw.println(" Unsuspends the specified package (as user)."); 1553 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT"); 1554 pw.println(" set the default home activity (aka launcher)."); 1555 pw.println(); 1556 Intent.printIntentArgsHelp(pw , ""); 1557 } 1558 1559 private static class LocalIntentReceiver { 1560 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 1561 1562 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 1563 @Override 1564 public void send(int code, Intent intent, String resolvedType, 1565 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 1566 try { 1567 mResult.offer(intent, 5, TimeUnit.SECONDS); 1568 } catch (InterruptedException e) { 1569 throw new RuntimeException(e); 1570 } 1571 } 1572 }; 1573 1574 public IntentSender getIntentSender() { 1575 return new IntentSender((IIntentSender) mLocalSender); 1576 } 1577 1578 public Intent getResult() { 1579 try { 1580 return mResult.take(); 1581 } catch (InterruptedException e) { 1582 throw new RuntimeException(e); 1583 } 1584 } 1585 } 1586} 1587