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