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