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