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