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