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