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