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