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