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