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