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