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