PackageManagerShellCommand.java revision 3fc56c30000d9b88c2145d4297a97ec5061d60d1
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.accounts.IAccountManager; 20import android.app.ActivityManager; 21import android.content.ComponentName; 22import android.content.Context; 23import android.content.IIntentReceiver; 24import android.content.IIntentSender; 25import android.content.Intent; 26import android.content.IntentSender; 27import android.content.pm.ApplicationInfo; 28import android.content.pm.FeatureInfo; 29import android.content.pm.IPackageDataObserver; 30import android.content.pm.IPackageManager; 31import android.content.pm.InstrumentationInfo; 32import android.content.pm.PackageInfo; 33import android.content.pm.PackageInstaller; 34import android.content.pm.PackageItemInfo; 35import android.content.pm.PackageManager; 36import android.content.pm.PackageParser; 37import android.content.pm.PackageParser.ApkLite; 38import android.content.pm.PackageParser.PackageLite; 39import android.content.pm.PackageParser.PackageParserException; 40import android.content.pm.ParceledListSlice; 41import android.content.pm.PermissionGroupInfo; 42import android.content.pm.PermissionInfo; 43import android.content.pm.PackageInstaller.SessionInfo; 44import android.content.pm.PackageInstaller.SessionParams; 45import android.content.pm.PackageManager.NameNotFoundException; 46import android.content.pm.ResolveInfo; 47import android.content.pm.UserInfo; 48import android.content.pm.VersionedPackage; 49import android.content.pm.dex.DexMetadataHelper; 50import android.content.res.AssetManager; 51import android.content.res.Resources; 52import android.net.Uri; 53import android.os.Binder; 54import android.os.Build; 55import android.os.Bundle; 56import android.os.IBinder; 57import android.os.IUserManager; 58import android.os.ParcelFileDescriptor; 59import android.os.Process; 60import android.os.RemoteException; 61import android.os.ServiceManager; 62import android.os.ShellCommand; 63import android.os.SystemClock; 64import android.os.SystemProperties; 65import android.os.UserHandle; 66import android.os.UserManager; 67import android.os.storage.StorageManager; 68import android.text.TextUtils; 69import android.text.format.DateUtils; 70import android.util.ArraySet; 71import android.util.PrintWriterPrinter; 72 73import com.android.internal.content.PackageHelper; 74import com.android.internal.util.ArrayUtils; 75import com.android.internal.util.SizedInputStream; 76import com.android.server.SystemConfig; 77 78import dalvik.system.DexFile; 79 80import libcore.io.IoUtils; 81 82import java.io.IOException; 83import java.io.InputStream; 84import java.io.OutputStream; 85import java.io.PrintWriter; 86import java.net.URISyntaxException; 87import java.util.ArrayList; 88import java.util.Collections; 89import java.util.Comparator; 90import java.util.List; 91import java.util.Map; 92import java.util.WeakHashMap; 93import java.util.concurrent.SynchronousQueue; 94import java.util.concurrent.TimeUnit; 95 96import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 97import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 98import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 99import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 100import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 101 102class PackageManagerShellCommand extends ShellCommand { 103 /** Path for streaming APK content */ 104 private static final String STDIN_PATH = "-"; 105 106 final IPackageManager mInterface; 107 final private WeakHashMap<String, Resources> mResourceCache = 108 new WeakHashMap<String, Resources>(); 109 int mTargetUser; 110 boolean mBrief; 111 boolean mComponents; 112 113 PackageManagerShellCommand(PackageManagerService service) { 114 mInterface = service; 115 } 116 117 @Override 118 public int onCommand(String cmd) { 119 if (cmd == null) { 120 return handleDefaultCommands(cmd); 121 } 122 123 final PrintWriter pw = getOutPrintWriter(); 124 try { 125 switch(cmd) { 126 case "path": 127 return runPath(); 128 case "dump": 129 return runDump(); 130 case "list": 131 return runList(); 132 case "resolve-activity": 133 return runResolveActivity(); 134 case "query-activities": 135 return runQueryIntentActivities(); 136 case "query-services": 137 return runQueryIntentServices(); 138 case "query-receivers": 139 return runQueryIntentReceivers(); 140 case "install": 141 return runInstall(); 142 case "install-abandon": 143 case "install-destroy": 144 return runInstallAbandon(); 145 case "install-commit": 146 return runInstallCommit(); 147 case "install-create": 148 return runInstallCreate(); 149 case "install-remove": 150 return runInstallRemove(); 151 case "install-write": 152 return runInstallWrite(); 153 case "install-existing": 154 return runInstallExisting(); 155 case "set-install-location": 156 return runSetInstallLocation(); 157 case "get-install-location": 158 return runGetInstallLocation(); 159 case "move-package": 160 return runMovePackage(); 161 case "move-primary-storage": 162 return runMovePrimaryStorage(); 163 case "compile": 164 return runCompile(); 165 case "reconcile-secondary-dex-files": 166 return runreconcileSecondaryDexFiles(); 167 case "force-dex-opt": 168 return runForceDexOpt(); 169 case "bg-dexopt-job": 170 return runDexoptJob(); 171 case "dump-profiles": 172 return runDumpProfiles(); 173 case "uninstall": 174 return runUninstall(); 175 case "clear": 176 return runClear(); 177 case "enable": 178 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 179 case "disable": 180 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 181 case "disable-user": 182 return runSetEnabledSetting( 183 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER); 184 case "disable-until-used": 185 return runSetEnabledSetting( 186 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED); 187 case "default-state": 188 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); 189 case "hide": 190 return runSetHiddenSetting(true); 191 case "unhide": 192 return runSetHiddenSetting(false); 193 case "suspend": 194 return runSuspend(true); 195 case "unsuspend": 196 return runSuspend(false); 197 case "grant": 198 return runGrantRevokePermission(true); 199 case "revoke": 200 return runGrantRevokePermission(false); 201 case "reset-permissions": 202 return runResetPermissions(); 203 case "set-permission-enforced": 204 return runSetPermissionEnforced(); 205 case "get-privapp-permissions": 206 return runGetPrivappPermissions(); 207 case "get-privapp-deny-permissions": 208 return runGetPrivappDenyPermissions(); 209 case "get-oem-permissions": 210 return runGetOemPermissions(); 211 case "set-app-link": 212 return runSetAppLink(); 213 case "get-app-link": 214 return runGetAppLink(); 215 case "trim-caches": 216 return runTrimCaches(); 217 case "create-user": 218 return runCreateUser(); 219 case "remove-user": 220 return runRemoveUser(); 221 case "set-user-restriction": 222 return runSetUserRestriction(); 223 case "get-max-users": 224 return runGetMaxUsers(); 225 case "set-home-activity": 226 return runSetHomeActivity(); 227 case "set-installer": 228 return runSetInstaller(); 229 case "get-instantapp-resolver": 230 return runGetInstantAppResolver(); 231 case "has-feature": 232 return runHasFeature(); 233 default: { 234 String nextArg = getNextArg(); 235 if (nextArg == null) { 236 if (cmd.equalsIgnoreCase("-l")) { 237 return runListPackages(false); 238 } else if (cmd.equalsIgnoreCase("-lf")) { 239 return runListPackages(true); 240 } 241 } else if (getNextArg() == null) { 242 if (cmd.equalsIgnoreCase("-p")) { 243 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM); 244 } 245 } 246 return handleDefaultCommands(cmd); 247 } 248 } 249 } catch (RemoteException e) { 250 pw.println("Remote exception: " + e); 251 } 252 return -1; 253 } 254 255 private void setParamsSize(InstallParams params, String inPath) { 256 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) { 257 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r"); 258 if (fd == null) { 259 getErrPrintWriter().println("Error: Can't open file: " + inPath); 260 throw new IllegalArgumentException("Error: Can't open file: " + inPath); 261 } 262 try { 263 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0); 264 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null, 265 null, null); 266 params.sessionParams.setSize(PackageHelper.calculateInstalledSize( 267 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor())); 268 } catch (PackageParserException | IOException e) { 269 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath); 270 throw new IllegalArgumentException( 271 "Error: Failed to parse APK file: " + inPath, e); 272 } finally { 273 try { 274 fd.close(); 275 } catch (IOException e) { 276 } 277 } 278 } 279 } 280 /** 281 * Displays the package file for a package. 282 * @param pckg 283 */ 284 private int displayPackageFilePath(String pckg, int userId) throws RemoteException { 285 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId); 286 if (info != null && info.applicationInfo != null) { 287 final PrintWriter pw = getOutPrintWriter(); 288 pw.print("package:"); 289 pw.println(info.applicationInfo.sourceDir); 290 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { 291 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { 292 pw.print("package:"); 293 pw.println(splitSourceDir); 294 } 295 } 296 return 0; 297 } 298 return 1; 299 } 300 301 private int runPath() throws RemoteException { 302 int userId = UserHandle.USER_SYSTEM; 303 String option = getNextOption(); 304 if (option != null && option.equals("--user")) { 305 userId = UserHandle.parseUserArg(getNextArgRequired()); 306 } 307 308 String pkg = getNextArgRequired(); 309 if (pkg == null) { 310 getErrPrintWriter().println("Error: no package specified"); 311 return 1; 312 } 313 return displayPackageFilePath(pkg, userId); 314 } 315 316 private int runList() throws RemoteException { 317 final PrintWriter pw = getOutPrintWriter(); 318 final String type = getNextArg(); 319 if (type == null) { 320 pw.println("Error: didn't specify type of data to list"); 321 return -1; 322 } 323 switch(type) { 324 case "features": 325 return runListFeatures(); 326 case "instrumentation": 327 return runListInstrumentation(); 328 case "libraries": 329 return runListLibraries(); 330 case "package": 331 case "packages": 332 return runListPackages(false /*showSourceDir*/); 333 case "permission-groups": 334 return runListPermissionGroups(); 335 case "permissions": 336 return runListPermissions(); 337 case "users": 338 ServiceManager.getService("user").shellCommand( 339 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(), 340 new String[] { "list" }, getShellCallback(), adoptResultReceiver()); 341 return 0; 342 } 343 pw.println("Error: unknown list type '" + type + "'"); 344 return -1; 345 } 346 347 private int runListFeatures() throws RemoteException { 348 final PrintWriter pw = getOutPrintWriter(); 349 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList(); 350 351 // sort by name 352 Collections.sort(list, new Comparator<FeatureInfo>() { 353 public int compare(FeatureInfo o1, FeatureInfo o2) { 354 if (o1.name == o2.name) return 0; 355 if (o1.name == null) return -1; 356 if (o2.name == null) return 1; 357 return o1.name.compareTo(o2.name); 358 } 359 }); 360 361 final int count = (list != null) ? list.size() : 0; 362 for (int p = 0; p < count; p++) { 363 FeatureInfo fi = list.get(p); 364 pw.print("feature:"); 365 if (fi.name != null) { 366 pw.print(fi.name); 367 if (fi.version > 0) { 368 pw.print("="); 369 pw.print(fi.version); 370 } 371 pw.println(); 372 } else { 373 pw.println("reqGlEsVersion=0x" 374 + Integer.toHexString(fi.reqGlEsVersion)); 375 } 376 } 377 return 0; 378 } 379 380 private int runListInstrumentation() throws RemoteException { 381 final PrintWriter pw = getOutPrintWriter(); 382 boolean showSourceDir = false; 383 String targetPackage = null; 384 385 try { 386 String opt; 387 while ((opt = getNextArg()) != null) { 388 switch (opt) { 389 case "-f": 390 showSourceDir = true; 391 break; 392 default: 393 if (opt.charAt(0) != '-') { 394 targetPackage = opt; 395 } else { 396 pw.println("Error: Unknown option: " + opt); 397 return -1; 398 } 399 break; 400 } 401 } 402 } catch (RuntimeException ex) { 403 pw.println("Error: " + ex.toString()); 404 return -1; 405 } 406 407 final List<InstrumentationInfo> list = 408 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList(); 409 410 // sort by target package 411 Collections.sort(list, new Comparator<InstrumentationInfo>() { 412 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 413 return o1.targetPackage.compareTo(o2.targetPackage); 414 } 415 }); 416 417 final int count = (list != null) ? list.size() : 0; 418 for (int p = 0; p < count; p++) { 419 final InstrumentationInfo ii = list.get(p); 420 pw.print("instrumentation:"); 421 if (showSourceDir) { 422 pw.print(ii.sourceDir); 423 pw.print("="); 424 } 425 final ComponentName cn = new ComponentName(ii.packageName, ii.name); 426 pw.print(cn.flattenToShortString()); 427 pw.print(" (target="); 428 pw.print(ii.targetPackage); 429 pw.println(")"); 430 } 431 return 0; 432 } 433 434 private int runListLibraries() throws RemoteException { 435 final PrintWriter pw = getOutPrintWriter(); 436 final List<String> list = new ArrayList<String>(); 437 final String[] rawList = mInterface.getSystemSharedLibraryNames(); 438 for (int i = 0; i < rawList.length; i++) { 439 list.add(rawList[i]); 440 } 441 442 // sort by name 443 Collections.sort(list, new Comparator<String>() { 444 public int compare(String o1, String o2) { 445 if (o1 == o2) return 0; 446 if (o1 == null) return -1; 447 if (o2 == null) return 1; 448 return o1.compareTo(o2); 449 } 450 }); 451 452 final int count = (list != null) ? list.size() : 0; 453 for (int p = 0; p < count; p++) { 454 String lib = list.get(p); 455 pw.print("library:"); 456 pw.println(lib); 457 } 458 return 0; 459 } 460 461 private int runListPackages(boolean showSourceDir) throws RemoteException { 462 final PrintWriter pw = getOutPrintWriter(); 463 int getFlags = 0; 464 boolean listDisabled = false, listEnabled = false; 465 boolean listSystem = false, listThirdParty = false; 466 boolean listInstaller = false; 467 boolean showUid = false; 468 boolean showVersionCode = false; 469 int uid = -1; 470 int userId = UserHandle.USER_SYSTEM; 471 try { 472 String opt; 473 while ((opt = getNextOption()) != null) { 474 switch (opt) { 475 case "-d": 476 listDisabled = true; 477 break; 478 case "-e": 479 listEnabled = true; 480 break; 481 case "-f": 482 showSourceDir = true; 483 break; 484 case "-i": 485 listInstaller = true; 486 break; 487 case "-l": 488 // old compat 489 break; 490 case "-s": 491 listSystem = true; 492 break; 493 case "-U": 494 showUid = true; 495 break; 496 case "-u": 497 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES; 498 break; 499 case "-3": 500 listThirdParty = true; 501 break; 502 case "--show-versioncode": 503 showVersionCode = true; 504 break; 505 case "--user": 506 userId = UserHandle.parseUserArg(getNextArgRequired()); 507 break; 508 case "--uid": 509 showUid = true; 510 uid = Integer.parseInt(getNextArgRequired()); 511 break; 512 default: 513 pw.println("Error: Unknown option: " + opt); 514 return -1; 515 } 516 } 517 } catch (RuntimeException ex) { 518 pw.println("Error: " + ex.toString()); 519 return -1; 520 } 521 522 final String filter = getNextArg(); 523 524 @SuppressWarnings("unchecked") 525 final ParceledListSlice<PackageInfo> slice = 526 mInterface.getInstalledPackages(getFlags, userId); 527 final List<PackageInfo> packages = slice.getList(); 528 529 final int count = packages.size(); 530 for (int p = 0; p < count; p++) { 531 final PackageInfo info = packages.get(p); 532 if (filter != null && !info.packageName.contains(filter)) { 533 continue; 534 } 535 if (uid != -1 && info.applicationInfo.uid != uid) { 536 continue; 537 } 538 final boolean isSystem = 539 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; 540 if ((!listDisabled || !info.applicationInfo.enabled) && 541 (!listEnabled || info.applicationInfo.enabled) && 542 (!listSystem || isSystem) && 543 (!listThirdParty || !isSystem)) { 544 pw.print("package:"); 545 if (showSourceDir) { 546 pw.print(info.applicationInfo.sourceDir); 547 pw.print("="); 548 } 549 pw.print(info.packageName); 550 if (showVersionCode) { 551 pw.print(" versionCode:"); 552 pw.print(info.applicationInfo.versionCode); 553 } 554 if (listInstaller) { 555 pw.print(" installer="); 556 pw.print(mInterface.getInstallerPackageName(info.packageName)); 557 } 558 if (showUid) { 559 pw.print(" uid:"); 560 pw.print(info.applicationInfo.uid); 561 } 562 pw.println(); 563 } 564 } 565 return 0; 566 } 567 568 private int runListPermissionGroups() throws RemoteException { 569 final PrintWriter pw = getOutPrintWriter(); 570 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList(); 571 572 final int count = pgs.size(); 573 for (int p = 0; p < count ; p++) { 574 final PermissionGroupInfo pgi = pgs.get(p); 575 pw.print("permission group:"); 576 pw.println(pgi.name); 577 } 578 return 0; 579 } 580 581 private int runListPermissions() throws RemoteException { 582 final PrintWriter pw = getOutPrintWriter(); 583 boolean labels = false; 584 boolean groups = false; 585 boolean userOnly = false; 586 boolean summary = false; 587 boolean dangerousOnly = false; 588 String opt; 589 while ((opt = getNextOption()) != null) { 590 switch (opt) { 591 case "-d": 592 dangerousOnly = true; 593 break; 594 case "-f": 595 labels = true; 596 break; 597 case "-g": 598 groups = true; 599 break; 600 case "-s": 601 groups = true; 602 labels = true; 603 summary = true; 604 break; 605 case "-u": 606 userOnly = true; 607 break; 608 default: 609 pw.println("Error: Unknown option: " + opt); 610 return 1; 611 } 612 } 613 614 final ArrayList<String> groupList = new ArrayList<String>(); 615 if (groups) { 616 final List<PermissionGroupInfo> infos = 617 mInterface.getAllPermissionGroups(0 /*flags*/).getList(); 618 final int count = infos.size(); 619 for (int i = 0; i < count; i++) { 620 groupList.add(infos.get(i).name); 621 } 622 groupList.add(null); 623 } else { 624 final String grp = getNextArg(); 625 groupList.add(grp); 626 } 627 628 if (dangerousOnly) { 629 pw.println("Dangerous Permissions:"); 630 pw.println(""); 631 doListPermissions(groupList, groups, labels, summary, 632 PermissionInfo.PROTECTION_DANGEROUS, 633 PermissionInfo.PROTECTION_DANGEROUS); 634 if (userOnly) { 635 pw.println("Normal Permissions:"); 636 pw.println(""); 637 doListPermissions(groupList, groups, labels, summary, 638 PermissionInfo.PROTECTION_NORMAL, 639 PermissionInfo.PROTECTION_NORMAL); 640 } 641 } else if (userOnly) { 642 pw.println("Dangerous and Normal Permissions:"); 643 pw.println(""); 644 doListPermissions(groupList, groups, labels, summary, 645 PermissionInfo.PROTECTION_NORMAL, 646 PermissionInfo.PROTECTION_DANGEROUS); 647 } else { 648 pw.println("All Permissions:"); 649 pw.println(""); 650 doListPermissions(groupList, groups, labels, summary, 651 -10000, 10000); 652 } 653 return 0; 654 } 655 656 private Intent parseIntentAndUser() throws URISyntaxException { 657 mTargetUser = UserHandle.USER_CURRENT; 658 mBrief = false; 659 mComponents = false; 660 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 661 @Override 662 public boolean handleOption(String opt, ShellCommand cmd) { 663 if ("--user".equals(opt)) { 664 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired()); 665 return true; 666 } else if ("--brief".equals(opt)) { 667 mBrief = true; 668 return true; 669 } else if ("--components".equals(opt)) { 670 mComponents = true; 671 return true; 672 } 673 return false; 674 } 675 }); 676 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 677 Binder.getCallingUid(), mTargetUser, false, false, null, null); 678 return intent; 679 } 680 681 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri, 682 boolean brief, boolean components) { 683 if (brief || components) { 684 final ComponentName comp; 685 if (ri.activityInfo != null) { 686 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); 687 } else if (ri.serviceInfo != null) { 688 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name); 689 } else if (ri.providerInfo != null) { 690 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name); 691 } else { 692 comp = null; 693 } 694 if (comp != null) { 695 if (!components) { 696 pr.println(prefix + "priority=" + ri.priority 697 + " preferredOrder=" + ri.preferredOrder 698 + " match=0x" + Integer.toHexString(ri.match) 699 + " specificIndex=" + ri.specificIndex 700 + " isDefault=" + ri.isDefault); 701 } 702 pr.println(prefix + comp.flattenToShortString()); 703 return; 704 } 705 } 706 ri.dump(pr, prefix); 707 } 708 709 private int runResolveActivity() { 710 Intent intent; 711 try { 712 intent = parseIntentAndUser(); 713 } catch (URISyntaxException e) { 714 throw new RuntimeException(e.getMessage(), e); 715 } 716 try { 717 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser); 718 PrintWriter pw = getOutPrintWriter(); 719 if (ri == null) { 720 pw.println("No activity found"); 721 } else { 722 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 723 printResolveInfo(pr, "", ri, mBrief, mComponents); 724 } 725 } catch (RemoteException e) { 726 throw new RuntimeException("Failed calling service", e); 727 } 728 return 0; 729 } 730 731 private int runQueryIntentActivities() { 732 Intent intent; 733 try { 734 intent = parseIntentAndUser(); 735 } catch (URISyntaxException e) { 736 throw new RuntimeException(e.getMessage(), e); 737 } 738 try { 739 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0, 740 mTargetUser).getList(); 741 PrintWriter pw = getOutPrintWriter(); 742 if (result == null || result.size() <= 0) { 743 pw.println("No activities found"); 744 } else { 745 if (!mComponents) { 746 pw.print(result.size()); pw.println(" activities found:"); 747 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 748 for (int i = 0; i < result.size(); i++) { 749 pw.print(" Activity #"); pw.print(i); pw.println(":"); 750 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 751 } 752 } else { 753 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 754 for (int i = 0; i < result.size(); i++) { 755 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 756 } 757 } 758 } 759 } catch (RemoteException e) { 760 throw new RuntimeException("Failed calling service", e); 761 } 762 return 0; 763 } 764 765 private int runQueryIntentServices() { 766 Intent intent; 767 try { 768 intent = parseIntentAndUser(); 769 } catch (URISyntaxException e) { 770 throw new RuntimeException(e.getMessage(), e); 771 } 772 try { 773 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0, 774 mTargetUser).getList(); 775 PrintWriter pw = getOutPrintWriter(); 776 if (result == null || result.size() <= 0) { 777 pw.println("No services found"); 778 } else { 779 if (!mComponents) { 780 pw.print(result.size()); pw.println(" services found:"); 781 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 782 for (int i = 0; i < result.size(); i++) { 783 pw.print(" Service #"); pw.print(i); pw.println(":"); 784 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 785 } 786 } else { 787 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 788 for (int i = 0; i < result.size(); i++) { 789 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 790 } 791 } 792 } 793 } catch (RemoteException e) { 794 throw new RuntimeException("Failed calling service", e); 795 } 796 return 0; 797 } 798 799 private int runQueryIntentReceivers() { 800 Intent intent; 801 try { 802 intent = parseIntentAndUser(); 803 } catch (URISyntaxException e) { 804 throw new RuntimeException(e.getMessage(), e); 805 } 806 try { 807 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0, 808 mTargetUser).getList(); 809 PrintWriter pw = getOutPrintWriter(); 810 if (result == null || result.size() <= 0) { 811 pw.println("No receivers found"); 812 } else { 813 if (!mComponents) { 814 pw.print(result.size()); pw.println(" receivers found:"); 815 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 816 for (int i = 0; i < result.size(); i++) { 817 pw.print(" Receiver #"); pw.print(i); pw.println(":"); 818 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 819 } 820 } else { 821 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 822 for (int i = 0; i < result.size(); i++) { 823 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 824 } 825 } 826 } 827 } catch (RemoteException e) { 828 throw new RuntimeException("Failed calling service", e); 829 } 830 return 0; 831 } 832 833 private int runInstall() throws RemoteException { 834 final PrintWriter pw = getOutPrintWriter(); 835 final InstallParams params = makeInstallParams(); 836 final String inPath = getNextArg(); 837 838 setParamsSize(params, inPath); 839 final int sessionId = doCreateSession(params.sessionParams, 840 params.installerPackageName, params.userId); 841 boolean abandonSession = true; 842 try { 843 if (inPath == null && params.sessionParams.sizeBytes == -1) { 844 pw.println("Error: must either specify a package size or an APK file"); 845 return 1; 846 } 847 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk", 848 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 849 return 1; 850 } 851 if (doCommitSession(sessionId, false /*logSuccess*/) 852 != PackageInstaller.STATUS_SUCCESS) { 853 return 1; 854 } 855 abandonSession = false; 856 pw.println("Success"); 857 return 0; 858 } finally { 859 if (abandonSession) { 860 try { 861 doAbandonSession(sessionId, false /*logSuccess*/); 862 } catch (Exception ignore) { 863 } 864 } 865 } 866 } 867 868 private int runInstallAbandon() throws RemoteException { 869 final int sessionId = Integer.parseInt(getNextArg()); 870 return doAbandonSession(sessionId, true /*logSuccess*/); 871 } 872 873 private int runInstallCommit() throws RemoteException { 874 final int sessionId = Integer.parseInt(getNextArg()); 875 return doCommitSession(sessionId, true /*logSuccess*/); 876 } 877 878 private int runInstallCreate() throws RemoteException { 879 final PrintWriter pw = getOutPrintWriter(); 880 final InstallParams installParams = makeInstallParams(); 881 final int sessionId = doCreateSession(installParams.sessionParams, 882 installParams.installerPackageName, installParams.userId); 883 884 // NOTE: adb depends on parsing this string 885 pw.println("Success: created install session [" + sessionId + "]"); 886 return 0; 887 } 888 889 private int runInstallWrite() throws RemoteException { 890 long sizeBytes = -1; 891 892 String opt; 893 while ((opt = getNextOption()) != null) { 894 if (opt.equals("-S")) { 895 sizeBytes = Long.parseLong(getNextArg()); 896 } else { 897 throw new IllegalArgumentException("Unknown option: " + opt); 898 } 899 } 900 901 final int sessionId = Integer.parseInt(getNextArg()); 902 final String splitName = getNextArg(); 903 final String path = getNextArg(); 904 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); 905 } 906 907 private int runInstallRemove() throws RemoteException { 908 final PrintWriter pw = getOutPrintWriter(); 909 910 final int sessionId = Integer.parseInt(getNextArg()); 911 912 final String splitName = getNextArg(); 913 if (splitName == null) { 914 pw.println("Error: split name not specified"); 915 return 1; 916 } 917 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/); 918 } 919 920 private int runInstallExisting() throws RemoteException { 921 final PrintWriter pw = getOutPrintWriter(); 922 int userId = UserHandle.USER_SYSTEM; 923 int installFlags = 0; 924 String opt; 925 while ((opt = getNextOption()) != null) { 926 switch (opt) { 927 case "--user": 928 userId = UserHandle.parseUserArg(getNextArgRequired()); 929 break; 930 case "--ephemeral": 931 case "--instant": 932 installFlags |= PackageManager.INSTALL_INSTANT_APP; 933 installFlags &= ~PackageManager.INSTALL_FULL_APP; 934 break; 935 case "--full": 936 installFlags &= ~PackageManager.INSTALL_INSTANT_APP; 937 installFlags |= PackageManager.INSTALL_FULL_APP; 938 break; 939 default: 940 pw.println("Error: Unknown option: " + opt); 941 return 1; 942 } 943 } 944 945 final String packageName = getNextArg(); 946 if (packageName == null) { 947 pw.println("Error: package name not specified"); 948 return 1; 949 } 950 951 try { 952 final int res = mInterface.installExistingPackageAsUser(packageName, userId, 953 installFlags, PackageManager.INSTALL_REASON_UNKNOWN); 954 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) { 955 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 956 } 957 pw.println("Package " + packageName + " installed for user: " + userId); 958 return 0; 959 } catch (RemoteException | NameNotFoundException e) { 960 pw.println(e.toString()); 961 return 1; 962 } 963 } 964 965 private int runSetInstallLocation() throws RemoteException { 966 int loc; 967 968 String arg = getNextArg(); 969 if (arg == null) { 970 getErrPrintWriter().println("Error: no install location specified."); 971 return 1; 972 } 973 try { 974 loc = Integer.parseInt(arg); 975 } catch (NumberFormatException e) { 976 getErrPrintWriter().println("Error: install location has to be a number."); 977 return 1; 978 } 979 if (!mInterface.setInstallLocation(loc)) { 980 getErrPrintWriter().println("Error: install location has to be a number."); 981 return 1; 982 } 983 return 0; 984 } 985 986 private int runGetInstallLocation() throws RemoteException { 987 int loc = mInterface.getInstallLocation(); 988 String locStr = "invalid"; 989 if (loc == PackageHelper.APP_INSTALL_AUTO) { 990 locStr = "auto"; 991 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) { 992 locStr = "internal"; 993 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) { 994 locStr = "external"; 995 } 996 getOutPrintWriter().println(loc + "[" + locStr + "]"); 997 return 0; 998 } 999 1000 public int runMovePackage() throws RemoteException { 1001 final String packageName = getNextArg(); 1002 if (packageName == null) { 1003 getErrPrintWriter().println("Error: package name not specified"); 1004 return 1; 1005 } 1006 String volumeUuid = getNextArg(); 1007 if ("internal".equals(volumeUuid)) { 1008 volumeUuid = null; 1009 } 1010 1011 final int moveId = mInterface.movePackage(packageName, volumeUuid); 1012 1013 int status = mInterface.getMoveStatus(moveId); 1014 while (!PackageManager.isMoveStatusFinished(status)) { 1015 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1016 status = mInterface.getMoveStatus(moveId); 1017 } 1018 1019 if (status == PackageManager.MOVE_SUCCEEDED) { 1020 getOutPrintWriter().println("Success"); 1021 return 0; 1022 } else { 1023 getErrPrintWriter().println("Failure [" + status + "]"); 1024 return 1; 1025 } 1026 } 1027 1028 public int runMovePrimaryStorage() throws RemoteException { 1029 String volumeUuid = getNextArg(); 1030 if ("internal".equals(volumeUuid)) { 1031 volumeUuid = null; 1032 } 1033 1034 final int moveId = mInterface.movePrimaryStorage(volumeUuid); 1035 1036 int status = mInterface.getMoveStatus(moveId); 1037 while (!PackageManager.isMoveStatusFinished(status)) { 1038 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1039 status = mInterface.getMoveStatus(moveId); 1040 } 1041 1042 if (status == PackageManager.MOVE_SUCCEEDED) { 1043 getOutPrintWriter().println("Success"); 1044 return 0; 1045 } else { 1046 getErrPrintWriter().println("Failure [" + status + "]"); 1047 return 1; 1048 } 1049 } 1050 1051 private int runCompile() throws RemoteException { 1052 final PrintWriter pw = getOutPrintWriter(); 1053 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false); 1054 boolean forceCompilation = false; 1055 boolean allPackages = false; 1056 boolean clearProfileData = false; 1057 String compilerFilter = null; 1058 String compilationReason = null; 1059 String checkProfilesRaw = null; 1060 boolean secondaryDex = false; 1061 String split = null; 1062 1063 String opt; 1064 while ((opt = getNextOption()) != null) { 1065 switch (opt) { 1066 case "-a": 1067 allPackages = true; 1068 break; 1069 case "-c": 1070 clearProfileData = true; 1071 break; 1072 case "-f": 1073 forceCompilation = true; 1074 break; 1075 case "-m": 1076 compilerFilter = getNextArgRequired(); 1077 break; 1078 case "-r": 1079 compilationReason = getNextArgRequired(); 1080 break; 1081 case "--check-prof": 1082 checkProfilesRaw = getNextArgRequired(); 1083 break; 1084 case "--reset": 1085 forceCompilation = true; 1086 clearProfileData = true; 1087 compilationReason = "install"; 1088 break; 1089 case "--secondary-dex": 1090 secondaryDex = true; 1091 break; 1092 case "--split": 1093 split = getNextArgRequired(); 1094 break; 1095 default: 1096 pw.println("Error: Unknown option: " + opt); 1097 return 1; 1098 } 1099 } 1100 1101 if (checkProfilesRaw != null) { 1102 if ("true".equals(checkProfilesRaw)) { 1103 checkProfiles = true; 1104 } else if ("false".equals(checkProfilesRaw)) { 1105 checkProfiles = false; 1106 } else { 1107 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\"."); 1108 return 1; 1109 } 1110 } 1111 1112 if (compilerFilter != null && compilationReason != null) { 1113 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " + 1114 "at the same time"); 1115 return 1; 1116 } 1117 if (compilerFilter == null && compilationReason == null) { 1118 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " + 1119 "reason (\"-r\") at the same time"); 1120 return 1; 1121 } 1122 1123 if (allPackages && split != null) { 1124 pw.println("-a cannot be specified together with --split"); 1125 return 1; 1126 } 1127 1128 if (secondaryDex && split != null) { 1129 pw.println("--secondary-dex cannot be specified together with --split"); 1130 return 1; 1131 } 1132 1133 String targetCompilerFilter; 1134 if (compilerFilter != null) { 1135 if (!DexFile.isValidCompilerFilter(compilerFilter)) { 1136 pw.println("Error: \"" + compilerFilter + 1137 "\" is not a valid compilation filter."); 1138 return 1; 1139 } 1140 targetCompilerFilter = compilerFilter; 1141 } else { 1142 int reason = -1; 1143 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 1144 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals( 1145 compilationReason)) { 1146 reason = i; 1147 break; 1148 } 1149 } 1150 if (reason == -1) { 1151 pw.println("Error: Unknown compilation reason: " + compilationReason); 1152 return 1; 1153 } 1154 targetCompilerFilter = 1155 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason); 1156 } 1157 1158 1159 List<String> packageNames = null; 1160 if (allPackages) { 1161 packageNames = mInterface.getAllPackages(); 1162 } else { 1163 String packageName = getNextArg(); 1164 if (packageName == null) { 1165 pw.println("Error: package name not specified"); 1166 return 1; 1167 } 1168 packageNames = Collections.singletonList(packageName); 1169 } 1170 1171 List<String> failedPackages = new ArrayList<>(); 1172 int index = 0; 1173 for (String packageName : packageNames) { 1174 if (clearProfileData) { 1175 mInterface.clearApplicationProfileData(packageName); 1176 } 1177 1178 if (allPackages) { 1179 pw.println(++index + "/" + packageNames.size() + ": " + packageName); 1180 pw.flush(); 1181 } 1182 1183 boolean result = secondaryDex 1184 ? mInterface.performDexOptSecondary(packageName, 1185 targetCompilerFilter, forceCompilation) 1186 : mInterface.performDexOptMode(packageName, 1187 checkProfiles, targetCompilerFilter, forceCompilation, 1188 true /* bootComplete */, split); 1189 if (!result) { 1190 failedPackages.add(packageName); 1191 } 1192 } 1193 1194 if (failedPackages.isEmpty()) { 1195 pw.println("Success"); 1196 return 0; 1197 } else if (failedPackages.size() == 1) { 1198 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled"); 1199 return 1; 1200 } else { 1201 pw.print("Failure: the following packages could not be compiled: "); 1202 boolean is_first = true; 1203 for (String packageName : failedPackages) { 1204 if (is_first) { 1205 is_first = false; 1206 } else { 1207 pw.print(", "); 1208 } 1209 pw.print(packageName); 1210 } 1211 pw.println(); 1212 return 1; 1213 } 1214 } 1215 1216 private int runreconcileSecondaryDexFiles() throws RemoteException { 1217 String packageName = getNextArg(); 1218 mInterface.reconcileSecondaryDexFiles(packageName); 1219 return 0; 1220 } 1221 1222 public int runForceDexOpt() throws RemoteException { 1223 mInterface.forceDexOpt(getNextArgRequired()); 1224 return 0; 1225 } 1226 1227 private int runDexoptJob() throws RemoteException { 1228 String arg; 1229 List<String> packageNames = new ArrayList<>(); 1230 while ((arg = getNextArg()) != null) { 1231 packageNames.add(arg); 1232 } 1233 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null : 1234 packageNames); 1235 return result ? 0 : -1; 1236 } 1237 1238 private int runDumpProfiles() throws RemoteException { 1239 String packageName = getNextArg(); 1240 mInterface.dumpProfiles(packageName); 1241 return 0; 1242 } 1243 1244 private int runUninstall() throws RemoteException { 1245 final PrintWriter pw = getOutPrintWriter(); 1246 int flags = 0; 1247 int userId = UserHandle.USER_ALL; 1248 long versionCode = PackageManager.VERSION_CODE_HIGHEST; 1249 1250 String opt; 1251 while ((opt = getNextOption()) != null) { 1252 switch (opt) { 1253 case "-k": 1254 flags |= PackageManager.DELETE_KEEP_DATA; 1255 break; 1256 case "--user": 1257 userId = UserHandle.parseUserArg(getNextArgRequired()); 1258 break; 1259 case "--versionCode": 1260 versionCode = Long.parseLong(getNextArgRequired()); 1261 break; 1262 default: 1263 pw.println("Error: Unknown option: " + opt); 1264 return 1; 1265 } 1266 } 1267 1268 final String packageName = getNextArg(); 1269 if (packageName == null) { 1270 pw.println("Error: package name not specified"); 1271 return 1; 1272 } 1273 1274 // if a split is specified, just remove it and not the whole package 1275 final String splitName = getNextArg(); 1276 if (splitName != null) { 1277 return runRemoveSplit(packageName, splitName); 1278 } 1279 1280 userId = translateUserId(userId, "runUninstall"); 1281 if (userId == UserHandle.USER_ALL) { 1282 userId = UserHandle.USER_SYSTEM; 1283 flags |= PackageManager.DELETE_ALL_USERS; 1284 } else { 1285 final PackageInfo info = mInterface.getPackageInfo(packageName, 1286 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId); 1287 if (info == null) { 1288 pw.println("Failure [not installed for " + userId + "]"); 1289 return 1; 1290 } 1291 final boolean isSystem = 1292 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 1293 // If we are being asked to delete a system app for just one 1294 // user set flag so it disables rather than reverting to system 1295 // version of the app. 1296 if (isSystem) { 1297 flags |= PackageManager.DELETE_SYSTEM_APP; 1298 } 1299 } 1300 1301 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1302 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName, 1303 versionCode), null /*callerPackageName*/, flags, 1304 receiver.getIntentSender(), userId); 1305 1306 final Intent result = receiver.getResult(); 1307 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1308 PackageInstaller.STATUS_FAILURE); 1309 if (status == PackageInstaller.STATUS_SUCCESS) { 1310 pw.println("Success"); 1311 return 0; 1312 } else { 1313 pw.println("Failure [" 1314 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1315 return 1; 1316 } 1317 } 1318 1319 private int runRemoveSplit(String packageName, String splitName) throws RemoteException { 1320 final PrintWriter pw = getOutPrintWriter(); 1321 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 1322 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1323 sessionParams.appPackageName = packageName; 1324 final int sessionId = 1325 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL); 1326 boolean abandonSession = true; 1327 try { 1328 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/) 1329 != PackageInstaller.STATUS_SUCCESS) { 1330 return 1; 1331 } 1332 if (doCommitSession(sessionId, false /*logSuccess*/) 1333 != PackageInstaller.STATUS_SUCCESS) { 1334 return 1; 1335 } 1336 abandonSession = false; 1337 pw.println("Success"); 1338 return 0; 1339 } finally { 1340 if (abandonSession) { 1341 try { 1342 doAbandonSession(sessionId, false /*logSuccess*/); 1343 } catch (Exception ignore) { 1344 } 1345 } 1346 } 1347 } 1348 1349 static class ClearDataObserver extends IPackageDataObserver.Stub { 1350 boolean finished; 1351 boolean result; 1352 1353 @Override 1354 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1355 synchronized (this) { 1356 finished = true; 1357 result = succeeded; 1358 notifyAll(); 1359 } 1360 } 1361 } 1362 1363 private int runClear() throws RemoteException { 1364 int userId = UserHandle.USER_SYSTEM; 1365 String option = getNextOption(); 1366 if (option != null && option.equals("--user")) { 1367 userId = UserHandle.parseUserArg(getNextArgRequired()); 1368 } 1369 1370 String pkg = getNextArg(); 1371 if (pkg == null) { 1372 getErrPrintWriter().println("Error: no package specified"); 1373 return 1; 1374 } 1375 1376 ClearDataObserver obs = new ClearDataObserver(); 1377 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId); 1378 synchronized (obs) { 1379 while (!obs.finished) { 1380 try { 1381 obs.wait(); 1382 } catch (InterruptedException e) { 1383 } 1384 } 1385 } 1386 1387 if (obs.result) { 1388 getOutPrintWriter().println("Success"); 1389 return 0; 1390 } else { 1391 getErrPrintWriter().println("Failed"); 1392 return 1; 1393 } 1394 } 1395 1396 private static String enabledSettingToString(int state) { 1397 switch (state) { 1398 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1399 return "default"; 1400 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1401 return "enabled"; 1402 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1403 return "disabled"; 1404 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1405 return "disabled-user"; 1406 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1407 return "disabled-until-used"; 1408 } 1409 return "unknown"; 1410 } 1411 1412 private int runSetEnabledSetting(int state) throws RemoteException { 1413 int userId = UserHandle.USER_SYSTEM; 1414 String option = getNextOption(); 1415 if (option != null && option.equals("--user")) { 1416 userId = UserHandle.parseUserArg(getNextArgRequired()); 1417 } 1418 1419 String pkg = getNextArg(); 1420 if (pkg == null) { 1421 getErrPrintWriter().println("Error: no package or component specified"); 1422 return 1; 1423 } 1424 ComponentName cn = ComponentName.unflattenFromString(pkg); 1425 if (cn == null) { 1426 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId, 1427 "shell:" + android.os.Process.myUid()); 1428 getOutPrintWriter().println("Package " + pkg + " new state: " 1429 + enabledSettingToString( 1430 mInterface.getApplicationEnabledSetting(pkg, userId))); 1431 return 0; 1432 } else { 1433 mInterface.setComponentEnabledSetting(cn, state, 0, userId); 1434 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: " 1435 + enabledSettingToString( 1436 mInterface.getComponentEnabledSetting(cn, userId))); 1437 return 0; 1438 } 1439 } 1440 1441 private int runSetHiddenSetting(boolean state) throws RemoteException { 1442 int userId = UserHandle.USER_SYSTEM; 1443 String option = getNextOption(); 1444 if (option != null && option.equals("--user")) { 1445 userId = UserHandle.parseUserArg(getNextArgRequired()); 1446 } 1447 1448 String pkg = getNextArg(); 1449 if (pkg == null) { 1450 getErrPrintWriter().println("Error: no package or component specified"); 1451 return 1; 1452 } 1453 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId); 1454 getOutPrintWriter().println("Package " + pkg + " new hidden state: " 1455 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId)); 1456 return 0; 1457 } 1458 1459 private int runSuspend(boolean suspendedState) { 1460 final PrintWriter pw = getOutPrintWriter(); 1461 int userId = UserHandle.USER_SYSTEM; 1462 String opt; 1463 while ((opt = getNextOption()) != null) { 1464 switch (opt) { 1465 case "--user": 1466 userId = UserHandle.parseUserArg(getNextArgRequired()); 1467 break; 1468 default: 1469 pw.println("Error: Unknown option: " + opt); 1470 return 1; 1471 } 1472 } 1473 1474 String packageName = getNextArg(); 1475 if (packageName == null) { 1476 pw.println("Error: package name not specified"); 1477 return 1; 1478 } 1479 1480 try { 1481 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState, 1482 userId); 1483 pw.println("Package " + packageName + " new suspended state: " 1484 + mInterface.isPackageSuspendedForUser(packageName, userId)); 1485 return 0; 1486 } catch (RemoteException | IllegalArgumentException e) { 1487 pw.println(e.toString()); 1488 return 1; 1489 } 1490 } 1491 1492 private int runGrantRevokePermission(boolean grant) throws RemoteException { 1493 int userId = UserHandle.USER_SYSTEM; 1494 1495 String opt = null; 1496 while ((opt = getNextOption()) != null) { 1497 if (opt.equals("--user")) { 1498 userId = UserHandle.parseUserArg(getNextArgRequired()); 1499 } 1500 } 1501 1502 String pkg = getNextArg(); 1503 if (pkg == null) { 1504 getErrPrintWriter().println("Error: no package specified"); 1505 return 1; 1506 } 1507 String perm = getNextArg(); 1508 if (perm == null) { 1509 getErrPrintWriter().println("Error: no permission specified"); 1510 return 1; 1511 } 1512 1513 if (grant) { 1514 mInterface.grantRuntimePermission(pkg, perm, userId); 1515 } else { 1516 mInterface.revokeRuntimePermission(pkg, perm, userId); 1517 } 1518 return 0; 1519 } 1520 1521 private int runResetPermissions() throws RemoteException { 1522 mInterface.resetRuntimePermissions(); 1523 return 0; 1524 } 1525 1526 private int runSetPermissionEnforced() throws RemoteException { 1527 final String permission = getNextArg(); 1528 if (permission == null) { 1529 getErrPrintWriter().println("Error: no permission specified"); 1530 return 1; 1531 } 1532 final String enforcedRaw = getNextArg(); 1533 if (enforcedRaw == null) { 1534 getErrPrintWriter().println("Error: no enforcement specified"); 1535 return 1; 1536 } 1537 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw)); 1538 return 0; 1539 } 1540 1541 private boolean isVendorApp(String pkg) { 1542 try { 1543 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); 1544 return info != null && info.applicationInfo.isVendor(); 1545 } catch (RemoteException e) { 1546 return false; 1547 } 1548 } 1549 1550 private int runGetPrivappPermissions() { 1551 final String pkg = getNextArg(); 1552 if (pkg == null) { 1553 getErrPrintWriter().println("Error: no package specified."); 1554 return 1; 1555 } 1556 1557 ArraySet<String> privAppPermissions = isVendorApp(pkg) ? 1558 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg) 1559 : SystemConfig.getInstance().getPrivAppPermissions(pkg); 1560 1561 getOutPrintWriter().println(privAppPermissions == null 1562 ? "{}" : privAppPermissions.toString()); 1563 return 0; 1564 } 1565 1566 private int runGetPrivappDenyPermissions() { 1567 final String pkg = getNextArg(); 1568 if (pkg == null) { 1569 getErrPrintWriter().println("Error: no package specified."); 1570 return 1; 1571 } 1572 1573 ArraySet<String> privAppPermissions = isVendorApp(pkg) ? 1574 SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg) 1575 : SystemConfig.getInstance().getPrivAppDenyPermissions(pkg); 1576 1577 getOutPrintWriter().println(privAppPermissions == null 1578 ? "{}" : privAppPermissions.toString()); 1579 return 0; 1580 } 1581 1582 private int runGetOemPermissions() { 1583 final String pkg = getNextArg(); 1584 if (pkg == null) { 1585 getErrPrintWriter().println("Error: no package specified."); 1586 return 1; 1587 } 1588 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance() 1589 .getOemPermissions(pkg); 1590 if (oemPermissions == null || oemPermissions.isEmpty()) { 1591 getOutPrintWriter().println("{}"); 1592 } else { 1593 oemPermissions.forEach((permission, granted) -> 1594 getOutPrintWriter().println(permission + " granted:" + granted) 1595 ); 1596 } 1597 return 0; 1598 } 1599 1600 private String linkStateToString(int state) { 1601 switch (state) { 1602 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined"; 1603 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask"; 1604 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always"; 1605 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never"; 1606 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask"; 1607 } 1608 return "Unknown link state: " + state; 1609 } 1610 1611 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined} 1612 private int runSetAppLink() throws RemoteException { 1613 int userId = UserHandle.USER_SYSTEM; 1614 1615 String opt; 1616 while ((opt = getNextOption()) != null) { 1617 if (opt.equals("--user")) { 1618 userId = UserHandle.parseUserArg(getNextArgRequired()); 1619 } else { 1620 getErrPrintWriter().println("Error: unknown option: " + opt); 1621 return 1; 1622 } 1623 } 1624 1625 // Package name to act on; required 1626 final String pkg = getNextArg(); 1627 if (pkg == null) { 1628 getErrPrintWriter().println("Error: no package specified."); 1629 return 1; 1630 } 1631 1632 // State to apply; {always|ask|never|undefined}, required 1633 final String modeString = getNextArg(); 1634 if (modeString == null) { 1635 getErrPrintWriter().println("Error: no app link state specified."); 1636 return 1; 1637 } 1638 1639 final int newMode; 1640 switch (modeString.toLowerCase()) { 1641 case "undefined": 1642 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1643 break; 1644 1645 case "always": 1646 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1647 break; 1648 1649 case "ask": 1650 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 1651 break; 1652 1653 case "always-ask": 1654 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 1655 break; 1656 1657 case "never": 1658 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 1659 break; 1660 1661 default: 1662 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'"); 1663 return 1; 1664 } 1665 1666 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); 1667 if (info == null) { 1668 getErrPrintWriter().println("Error: package " + pkg + " not found."); 1669 return 1; 1670 } 1671 1672 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 1673 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links."); 1674 return 1; 1675 } 1676 1677 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) { 1678 getErrPrintWriter().println("Error: unable to update app link status for " + pkg); 1679 return 1; 1680 } 1681 1682 return 0; 1683 } 1684 1685 // pm get-app-link [--user USER_ID] PACKAGE 1686 private int runGetAppLink() throws RemoteException { 1687 int userId = UserHandle.USER_SYSTEM; 1688 1689 String opt; 1690 while ((opt = getNextOption()) != null) { 1691 if (opt.equals("--user")) { 1692 userId = UserHandle.parseUserArg(getNextArgRequired()); 1693 } else { 1694 getErrPrintWriter().println("Error: unknown option: " + opt); 1695 return 1; 1696 } 1697 } 1698 1699 // Package name to act on; required 1700 final String pkg = getNextArg(); 1701 if (pkg == null) { 1702 getErrPrintWriter().println("Error: no package specified."); 1703 return 1; 1704 } 1705 1706 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); 1707 if (info == null) { 1708 getErrPrintWriter().println("Error: package " + pkg + " not found."); 1709 return 1; 1710 } 1711 1712 if ((info.applicationInfo.privateFlags 1713 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 1714 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links."); 1715 return 1; 1716 } 1717 1718 getOutPrintWriter().println(linkStateToString( 1719 mInterface.getIntentVerificationStatus(pkg, userId))); 1720 1721 return 0; 1722 } 1723 1724 private int runTrimCaches() throws RemoteException { 1725 String size = getNextArg(); 1726 if (size == null) { 1727 getErrPrintWriter().println("Error: no size specified"); 1728 return 1; 1729 } 1730 long multiplier = 1; 1731 int len = size.length(); 1732 char c = size.charAt(len - 1); 1733 if (c < '0' || c > '9') { 1734 if (c == 'K' || c == 'k') { 1735 multiplier = 1024L; 1736 } else if (c == 'M' || c == 'm') { 1737 multiplier = 1024L*1024L; 1738 } else if (c == 'G' || c == 'g') { 1739 multiplier = 1024L*1024L*1024L; 1740 } else { 1741 getErrPrintWriter().println("Invalid suffix: " + c); 1742 return 1; 1743 } 1744 size = size.substring(0, len-1); 1745 } 1746 long sizeVal; 1747 try { 1748 sizeVal = Long.parseLong(size) * multiplier; 1749 } catch (NumberFormatException e) { 1750 getErrPrintWriter().println("Error: expected number at: " + size); 1751 return 1; 1752 } 1753 String volumeUuid = getNextArg(); 1754 if ("internal".equals(volumeUuid)) { 1755 volumeUuid = null; 1756 } 1757 ClearDataObserver obs = new ClearDataObserver(); 1758 mInterface.freeStorageAndNotify(volumeUuid, sizeVal, 1759 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs); 1760 synchronized (obs) { 1761 while (!obs.finished) { 1762 try { 1763 obs.wait(); 1764 } catch (InterruptedException e) { 1765 } 1766 } 1767 } 1768 return 0; 1769 } 1770 1771 private static boolean isNumber(String s) { 1772 try { 1773 Integer.parseInt(s); 1774 } catch (NumberFormatException nfe) { 1775 return false; 1776 } 1777 return true; 1778 } 1779 1780 public int runCreateUser() throws RemoteException { 1781 String name; 1782 int userId = -1; 1783 int flags = 0; 1784 String opt; 1785 while ((opt = getNextOption()) != null) { 1786 if ("--profileOf".equals(opt)) { 1787 userId = UserHandle.parseUserArg(getNextArgRequired()); 1788 } else if ("--managed".equals(opt)) { 1789 flags |= UserInfo.FLAG_MANAGED_PROFILE; 1790 } else if ("--restricted".equals(opt)) { 1791 flags |= UserInfo.FLAG_RESTRICTED; 1792 } else if ("--ephemeral".equals(opt)) { 1793 flags |= UserInfo.FLAG_EPHEMERAL; 1794 } else if ("--guest".equals(opt)) { 1795 flags |= UserInfo.FLAG_GUEST; 1796 } else if ("--demo".equals(opt)) { 1797 flags |= UserInfo.FLAG_DEMO; 1798 } else { 1799 getErrPrintWriter().println("Error: unknown option " + opt); 1800 return 1; 1801 } 1802 } 1803 String arg = getNextArg(); 1804 if (arg == null) { 1805 getErrPrintWriter().println("Error: no user name specified."); 1806 return 1; 1807 } 1808 name = arg; 1809 UserInfo info; 1810 IUserManager um = IUserManager.Stub.asInterface( 1811 ServiceManager.getService(Context.USER_SERVICE)); 1812 IAccountManager accm = IAccountManager.Stub.asInterface( 1813 ServiceManager.getService(Context.ACCOUNT_SERVICE)); 1814 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) { 1815 // In non-split user mode, userId can only be SYSTEM 1816 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM; 1817 info = um.createRestrictedProfile(name, parentUserId); 1818 accm.addSharedAccountsFromParentUser(parentUserId, userId, 1819 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell"); 1820 } else if (userId < 0) { 1821 info = um.createUser(name, flags); 1822 } else { 1823 info = um.createProfileForUser(name, flags, userId, null); 1824 } 1825 1826 if (info != null) { 1827 getOutPrintWriter().println("Success: created user id " + info.id); 1828 return 0; 1829 } else { 1830 getErrPrintWriter().println("Error: couldn't create User."); 1831 return 1; 1832 } 1833 } 1834 1835 public int runRemoveUser() throws RemoteException { 1836 int userId; 1837 String arg = getNextArg(); 1838 if (arg == null) { 1839 getErrPrintWriter().println("Error: no user id specified."); 1840 return 1; 1841 } 1842 userId = UserHandle.parseUserArg(arg); 1843 IUserManager um = IUserManager.Stub.asInterface( 1844 ServiceManager.getService(Context.USER_SERVICE)); 1845 if (um.removeUser(userId)) { 1846 getOutPrintWriter().println("Success: removed user"); 1847 return 0; 1848 } else { 1849 getErrPrintWriter().println("Error: couldn't remove user id " + userId); 1850 return 1; 1851 } 1852 } 1853 1854 public int runSetUserRestriction() throws RemoteException { 1855 int userId = UserHandle.USER_SYSTEM; 1856 String opt = getNextOption(); 1857 if (opt != null && "--user".equals(opt)) { 1858 userId = UserHandle.parseUserArg(getNextArgRequired()); 1859 } 1860 1861 String restriction = getNextArg(); 1862 String arg = getNextArg(); 1863 boolean value; 1864 if ("1".equals(arg)) { 1865 value = true; 1866 } else if ("0".equals(arg)) { 1867 value = false; 1868 } else { 1869 getErrPrintWriter().println("Error: valid value not specified"); 1870 return 1; 1871 } 1872 IUserManager um = IUserManager.Stub.asInterface( 1873 ServiceManager.getService(Context.USER_SERVICE)); 1874 um.setUserRestriction(restriction, value, userId); 1875 return 0; 1876 } 1877 1878 public int runGetMaxUsers() { 1879 getOutPrintWriter().println("Maximum supported users: " 1880 + UserManager.getMaxSupportedUsers()); 1881 return 0; 1882 } 1883 1884 private static class InstallParams { 1885 SessionParams sessionParams; 1886 String installerPackageName; 1887 int userId = UserHandle.USER_ALL; 1888 } 1889 1890 private InstallParams makeInstallParams() { 1891 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1892 final InstallParams params = new InstallParams(); 1893 params.sessionParams = sessionParams; 1894 String opt; 1895 boolean replaceExisting = true; 1896 while ((opt = getNextOption()) != null) { 1897 switch (opt) { 1898 case "-l": 1899 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 1900 break; 1901 case "-r": // ignore 1902 break; 1903 case "-R": 1904 replaceExisting = false; 1905 break; 1906 case "-i": 1907 params.installerPackageName = getNextArg(); 1908 if (params.installerPackageName == null) { 1909 throw new IllegalArgumentException("Missing installer package"); 1910 } 1911 break; 1912 case "-t": 1913 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 1914 break; 1915 case "-s": 1916 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL; 1917 break; 1918 case "-f": 1919 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL; 1920 break; 1921 case "-d": 1922 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 1923 break; 1924 case "-g": 1925 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; 1926 break; 1927 case "--dont-kill": 1928 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP; 1929 break; 1930 case "--originating-uri": 1931 sessionParams.originatingUri = Uri.parse(getNextArg()); 1932 break; 1933 case "--referrer": 1934 sessionParams.referrerUri = Uri.parse(getNextArg()); 1935 break; 1936 case "-p": 1937 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING; 1938 sessionParams.appPackageName = getNextArg(); 1939 if (sessionParams.appPackageName == null) { 1940 throw new IllegalArgumentException("Missing inherit package name"); 1941 } 1942 break; 1943 case "--pkg": 1944 sessionParams.appPackageName = getNextArg(); 1945 if (sessionParams.appPackageName == null) { 1946 throw new IllegalArgumentException("Missing package name"); 1947 } 1948 break; 1949 case "-S": 1950 final long sizeBytes = Long.parseLong(getNextArg()); 1951 if (sizeBytes <= 0) { 1952 throw new IllegalArgumentException("Size must be positive"); 1953 } 1954 sessionParams.setSize(sizeBytes); 1955 break; 1956 case "--abi": 1957 sessionParams.abiOverride = checkAbiArgument(getNextArg()); 1958 break; 1959 case "--ephemeral": 1960 case "--instant": 1961 case "--instantapp": 1962 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/); 1963 break; 1964 case "--full": 1965 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/); 1966 break; 1967 case "--preload": 1968 sessionParams.setInstallAsVirtualPreload(); 1969 break; 1970 case "--user": 1971 params.userId = UserHandle.parseUserArg(getNextArgRequired()); 1972 break; 1973 case "--install-location": 1974 sessionParams.installLocation = Integer.parseInt(getNextArg()); 1975 break; 1976 case "--force-uuid": 1977 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID; 1978 sessionParams.volumeUuid = getNextArg(); 1979 if ("internal".equals(sessionParams.volumeUuid)) { 1980 sessionParams.volumeUuid = null; 1981 } 1982 break; 1983 case "--force-sdk": 1984 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; 1985 break; 1986 default: 1987 throw new IllegalArgumentException("Unknown option " + opt); 1988 } 1989 if (replaceExisting) { 1990 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1991 } 1992 } 1993 return params; 1994 } 1995 1996 private int runSetHomeActivity() { 1997 final PrintWriter pw = getOutPrintWriter(); 1998 int userId = UserHandle.USER_SYSTEM; 1999 String opt; 2000 while ((opt = getNextOption()) != null) { 2001 switch (opt) { 2002 case "--user": 2003 userId = UserHandle.parseUserArg(getNextArgRequired()); 2004 break; 2005 default: 2006 pw.println("Error: Unknown option: " + opt); 2007 return 1; 2008 } 2009 } 2010 2011 String component = getNextArg(); 2012 ComponentName componentName = 2013 component != null ? ComponentName.unflattenFromString(component) : null; 2014 2015 if (componentName == null) { 2016 pw.println("Error: component name not specified or invalid"); 2017 return 1; 2018 } 2019 2020 try { 2021 mInterface.setHomeActivity(componentName, userId); 2022 pw.println("Success"); 2023 return 0; 2024 } catch (Exception e) { 2025 pw.println(e.toString()); 2026 return 1; 2027 } 2028 } 2029 2030 private int runSetInstaller() throws RemoteException { 2031 final String targetPackage = getNextArg(); 2032 final String installerPackageName = getNextArg(); 2033 2034 if (targetPackage == null || installerPackageName == null) { 2035 getErrPrintWriter().println("Must provide both target and installer package names"); 2036 return 1; 2037 } 2038 2039 mInterface.setInstallerPackageName(targetPackage, installerPackageName); 2040 getOutPrintWriter().println("Success"); 2041 return 0; 2042 } 2043 2044 private int runGetInstantAppResolver() { 2045 final PrintWriter pw = getOutPrintWriter(); 2046 try { 2047 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent(); 2048 if (instantAppsResolver == null) { 2049 return 1; 2050 } 2051 pw.println(instantAppsResolver.flattenToString()); 2052 return 0; 2053 } catch (Exception e) { 2054 pw.println(e.toString()); 2055 return 1; 2056 } 2057 } 2058 2059 private int runHasFeature() { 2060 final PrintWriter err = getErrPrintWriter(); 2061 final String featureName = getNextArg(); 2062 if (featureName == null) { 2063 err.println("Error: expected FEATURE name"); 2064 return 1; 2065 } 2066 final String versionString = getNextArg(); 2067 try { 2068 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString); 2069 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version); 2070 getOutPrintWriter().println(hasFeature); 2071 return hasFeature ? 0 : 1; 2072 } catch (NumberFormatException e) { 2073 err.println("Error: illegal version number " + versionString); 2074 return 1; 2075 } catch (RemoteException e) { 2076 err.println(e.toString()); 2077 return 1; 2078 } 2079 } 2080 2081 private int runDump() { 2082 String pkg = getNextArg(); 2083 if (pkg == null) { 2084 getErrPrintWriter().println("Error: no package specified"); 2085 return 1; 2086 } 2087 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg); 2088 return 0; 2089 } 2090 2091 private static String checkAbiArgument(String abi) { 2092 if (TextUtils.isEmpty(abi)) { 2093 throw new IllegalArgumentException("Missing ABI argument"); 2094 } 2095 2096 if ("-".equals(abi)) { 2097 return abi; 2098 } 2099 2100 final String[] supportedAbis = Build.SUPPORTED_ABIS; 2101 for (String supportedAbi : supportedAbis) { 2102 if (supportedAbi.equals(abi)) { 2103 return abi; 2104 } 2105 } 2106 2107 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 2108 } 2109 2110 private int translateUserId(int userId, String logContext) { 2111 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 2112 userId, true, true, logContext, "pm command"); 2113 } 2114 2115 private int doCreateSession(SessionParams params, String installerPackageName, int userId) 2116 throws RemoteException { 2117 userId = translateUserId(userId, "runInstallCreate"); 2118 if (userId == UserHandle.USER_ALL) { 2119 userId = UserHandle.USER_SYSTEM; 2120 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 2121 } 2122 2123 final int sessionId = mInterface.getPackageInstaller() 2124 .createSession(params, installerPackageName, userId); 2125 return sessionId; 2126 } 2127 2128 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, 2129 boolean logSuccess) throws RemoteException { 2130 final PrintWriter pw = getOutPrintWriter(); 2131 final ParcelFileDescriptor fd; 2132 if (STDIN_PATH.equals(inPath)) { 2133 fd = null; 2134 } else if (inPath != null) { 2135 fd = openFileForSystem(inPath, "r"); 2136 if (fd == null) { 2137 return -1; 2138 } 2139 sizeBytes = fd.getStatSize(); 2140 if (sizeBytes < 0) { 2141 getErrPrintWriter().println("Unable to get size of: " + inPath); 2142 return -1; 2143 } 2144 } else { 2145 fd = null; 2146 } 2147 if (sizeBytes <= 0) { 2148 getErrPrintWriter().println("Error: must specify a APK size"); 2149 return 1; 2150 } 2151 2152 final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId); 2153 2154 PackageInstaller.Session session = null; 2155 InputStream in = null; 2156 OutputStream out = null; 2157 try { 2158 session = new PackageInstaller.Session( 2159 mInterface.getPackageInstaller().openSession(sessionId)); 2160 2161 if (fd != null) { 2162 in = new ParcelFileDescriptor.AutoCloseInputStream(fd); 2163 } else { 2164 in = new SizedInputStream(getRawInputStream(), sizeBytes); 2165 } 2166 out = session.openWrite(splitName, 0, sizeBytes); 2167 2168 int total = 0; 2169 byte[] buffer = new byte[1024 * 1024]; 2170 int c; 2171 while ((c = in.read(buffer)) != -1) { 2172 total += c; 2173 out.write(buffer, 0, c); 2174 2175 if (info.sizeBytes > 0) { 2176 final float fraction = ((float) c / (float) info.sizeBytes); 2177 session.addProgress(fraction); 2178 } 2179 } 2180 session.fsync(out); 2181 2182 if (logSuccess) { 2183 pw.println("Success: streamed " + total + " bytes"); 2184 } 2185 return 0; 2186 } catch (IOException e) { 2187 getErrPrintWriter().println("Error: failed to write; " + e.getMessage()); 2188 return 1; 2189 } finally { 2190 IoUtils.closeQuietly(out); 2191 IoUtils.closeQuietly(in); 2192 IoUtils.closeQuietly(session); 2193 } 2194 } 2195 2196 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess) 2197 throws RemoteException { 2198 final PrintWriter pw = getOutPrintWriter(); 2199 PackageInstaller.Session session = null; 2200 try { 2201 session = new PackageInstaller.Session( 2202 mInterface.getPackageInstaller().openSession(sessionId)); 2203 session.removeSplit(splitName); 2204 2205 if (logSuccess) { 2206 pw.println("Success"); 2207 } 2208 return 0; 2209 } catch (IOException e) { 2210 pw.println("Error: failed to remove split; " + e.getMessage()); 2211 return 1; 2212 } finally { 2213 IoUtils.closeQuietly(session); 2214 } 2215 } 2216 2217 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException { 2218 final PrintWriter pw = getOutPrintWriter(); 2219 PackageInstaller.Session session = null; 2220 try { 2221 session = new PackageInstaller.Session( 2222 mInterface.getPackageInstaller().openSession(sessionId)); 2223 2224 // Sanity check that all .dm files match an apk. 2225 // (The installer does not support standalone .dm files and will not process them.) 2226 try { 2227 DexMetadataHelper.validateDexPaths(session.getNames()); 2228 } catch (IllegalStateException | IOException e) { 2229 pw.println("Warning [Could not validate the dex paths: " + e.getMessage() + "]"); 2230 } 2231 2232 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 2233 session.commit(receiver.getIntentSender()); 2234 2235 final Intent result = receiver.getResult(); 2236 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 2237 PackageInstaller.STATUS_FAILURE); 2238 if (status == PackageInstaller.STATUS_SUCCESS) { 2239 if (logSuccess) { 2240 pw.println("Success"); 2241 } 2242 } else { 2243 pw.println("Failure [" 2244 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 2245 } 2246 return status; 2247 } finally { 2248 IoUtils.closeQuietly(session); 2249 } 2250 } 2251 2252 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException { 2253 final PrintWriter pw = getOutPrintWriter(); 2254 PackageInstaller.Session session = null; 2255 try { 2256 session = new PackageInstaller.Session( 2257 mInterface.getPackageInstaller().openSession(sessionId)); 2258 session.abandon(); 2259 if (logSuccess) { 2260 pw.println("Success"); 2261 } 2262 return 0; 2263 } finally { 2264 IoUtils.closeQuietly(session); 2265 } 2266 } 2267 2268 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels, 2269 boolean summary, int startProtectionLevel, int endProtectionLevel) 2270 throws RemoteException { 2271 final PrintWriter pw = getOutPrintWriter(); 2272 final int groupCount = groupList.size(); 2273 for (int i = 0; i < groupCount; i++) { 2274 String groupName = groupList.get(i); 2275 String prefix = ""; 2276 if (groups) { 2277 if (i > 0) { 2278 pw.println(""); 2279 } 2280 if (groupName != null) { 2281 PermissionGroupInfo pgi = 2282 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/); 2283 if (summary) { 2284 Resources res = getResources(pgi); 2285 if (res != null) { 2286 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": "); 2287 } else { 2288 pw.print(pgi.name + ": "); 2289 2290 } 2291 } else { 2292 pw.println((labels ? "+ " : "") + "group:" + pgi.name); 2293 if (labels) { 2294 pw.println(" package:" + pgi.packageName); 2295 Resources res = getResources(pgi); 2296 if (res != null) { 2297 pw.println(" label:" 2298 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel)); 2299 pw.println(" description:" 2300 + loadText(pgi, pgi.descriptionRes, 2301 pgi.nonLocalizedDescription)); 2302 } 2303 } 2304 } 2305 } else { 2306 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:"); 2307 } 2308 prefix = " "; 2309 } 2310 List<PermissionInfo> ps = 2311 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList(); 2312 final int count = ps.size(); 2313 boolean first = true; 2314 for (int p = 0 ; p < count ; p++) { 2315 PermissionInfo pi = ps.get(p); 2316 if (groups && groupName == null && pi.group != null) { 2317 continue; 2318 } 2319 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 2320 if (base < startProtectionLevel 2321 || base > endProtectionLevel) { 2322 continue; 2323 } 2324 if (summary) { 2325 if (first) { 2326 first = false; 2327 } else { 2328 pw.print(", "); 2329 } 2330 Resources res = getResources(pi); 2331 if (res != null) { 2332 pw.print(loadText(pi, pi.labelRes, 2333 pi.nonLocalizedLabel)); 2334 } else { 2335 pw.print(pi.name); 2336 } 2337 } else { 2338 pw.println(prefix + (labels ? "+ " : "") 2339 + "permission:" + pi.name); 2340 if (labels) { 2341 pw.println(prefix + " package:" + pi.packageName); 2342 Resources res = getResources(pi); 2343 if (res != null) { 2344 pw.println(prefix + " label:" 2345 + loadText(pi, pi.labelRes, 2346 pi.nonLocalizedLabel)); 2347 pw.println(prefix + " description:" 2348 + loadText(pi, pi.descriptionRes, 2349 pi.nonLocalizedDescription)); 2350 } 2351 pw.println(prefix + " protectionLevel:" 2352 + PermissionInfo.protectionToString(pi.protectionLevel)); 2353 } 2354 } 2355 } 2356 2357 if (summary) { 2358 pw.println(""); 2359 } 2360 } 2361 } 2362 2363 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) 2364 throws RemoteException { 2365 if (nonLocalized != null) { 2366 return nonLocalized.toString(); 2367 } 2368 if (res != 0) { 2369 Resources r = getResources(pii); 2370 if (r != null) { 2371 try { 2372 return r.getString(res); 2373 } catch (Resources.NotFoundException e) { 2374 } 2375 } 2376 } 2377 return null; 2378 } 2379 2380 private Resources getResources(PackageItemInfo pii) throws RemoteException { 2381 Resources res = mResourceCache.get(pii.packageName); 2382 if (res != null) return res; 2383 2384 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0); 2385 AssetManager am = new AssetManager(); 2386 am.addAssetPath(ai.publicSourceDir); 2387 res = new Resources(am, null, null); 2388 mResourceCache.put(pii.packageName, res); 2389 return res; 2390 } 2391 2392 @Override 2393 public void onHelp() { 2394 final PrintWriter pw = getOutPrintWriter(); 2395 pw.println("Package manager (package) commands:"); 2396 pw.println(" help"); 2397 pw.println(" Print this help text."); 2398 pw.println(""); 2399 pw.println(" path [--user USER_ID] PACKAGE"); 2400 pw.println(" Print the path to the .apk of the given PACKAGE."); 2401 pw.println(""); 2402 pw.println(" dump PACKAGE"); 2403 pw.println(" Print various system state associated with the given PACKAGE."); 2404 pw.println(""); 2405 pw.println(" list features"); 2406 pw.println(" Prints all features of the system."); 2407 pw.println(""); 2408 pw.println(" has-feature FEATURE_NAME [version]"); 2409 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,"); 2410 pw.println(" otherwise prints false and returns exit status 1"); 2411 pw.println(""); 2412 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]"); 2413 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE"); 2414 pw.println(" Options:"); 2415 pw.println(" -f: dump the name of the .apk file containing the test package"); 2416 pw.println(""); 2417 pw.println(" list libraries"); 2418 pw.println(" Prints all system libraries."); 2419 pw.println(""); 2420 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] "); 2421 pw.println(" [--uid UID] [--user USER_ID] [FILTER]"); 2422 pw.println(" Prints all packages; optionally only those whose name contains"); 2423 pw.println(" the text in FILTER. Options are:"); 2424 pw.println(" -f: see their associated file"); 2425 pw.println(" -d: filter to only show disabled packages"); 2426 pw.println(" -e: filter to only show enabled packages"); 2427 pw.println(" -s: filter to only show system packages"); 2428 pw.println(" -3: filter to only show third party packages"); 2429 pw.println(" -i: see the installer for the packages"); 2430 pw.println(" -l: ignored (used for compatibility with older releases)"); 2431 pw.println(" -U: also show the package UID"); 2432 pw.println(" -u: also include uninstalled packages"); 2433 pw.println(" --uid UID: filter to only show packages with the given UID"); 2434 pw.println(" --user USER_ID: only list packages belonging to the given user"); 2435 pw.println(""); 2436 pw.println(" list permission-groups"); 2437 pw.println(" Prints all known permission groups."); 2438 pw.println(""); 2439 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); 2440 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:"); 2441 pw.println(" -g: organize by group"); 2442 pw.println(" -f: print all information"); 2443 pw.println(" -s: short summary"); 2444 pw.println(" -d: only list dangerous permissions"); 2445 pw.println(" -u: list only the permissions users will see"); 2446 pw.println(""); 2447 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT"); 2448 pw.println(" Prints the activity that resolves to the given INTENT."); 2449 pw.println(""); 2450 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT"); 2451 pw.println(" Prints all activities that can handle the given INTENT."); 2452 pw.println(""); 2453 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT"); 2454 pw.println(" Prints all services that can handle the given INTENT."); 2455 pw.println(""); 2456 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT"); 2457 pw.println(" Prints all broadcast receivers that can handle the given INTENT."); 2458 pw.println(""); 2459 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]"); 2460 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); 2461 pw.println(" [--originating-uri URI] [---referrer URI]"); 2462 pw.println(" [--abi ABI_NAME] [--force-sdk]"); 2463 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); 2464 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]"); 2465 pw.println(" Install an application. Must provide the apk data to install, either as a"); 2466 pw.println(" file path or '-' to read from stdin. Options are:"); 2467 pw.println(" -l: forward lock application"); 2468 pw.println(" -R: disallow replacement of existing application"); 2469 pw.println(" -t: allow test packages"); 2470 pw.println(" -i: specify package name of installer owning the app"); 2471 pw.println(" -s: install application on sdcard"); 2472 pw.println(" -f: install application on internal flash"); 2473 pw.println(" -d: allow version code downgrade (debuggable packages only)"); 2474 pw.println(" -p: partial application install (new split on top of existing pkg)"); 2475 pw.println(" -g: grant all runtime permissions"); 2476 pw.println(" -S: size in bytes of package, required for stdin"); 2477 pw.println(" --user: install under the given user."); 2478 pw.println(" --dont-kill: installing a new feature split, don't kill running app"); 2479 pw.println(" --originating-uri: set URI where app was downloaded from"); 2480 pw.println(" --referrer: set URI that instigated the install of the app"); 2481 pw.println(" --pkg: specify expected package name of app being installed"); 2482 pw.println(" --abi: override the default ABI of the platform"); 2483 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app"); 2484 pw.println(" --full: cause the app to be installed as a non-ephemeral full app"); 2485 pw.println(" --install-location: force the install location:"); 2486 pw.println(" 0=auto, 1=internal only, 2=prefer external"); 2487 pw.println(" --force-uuid: force install on to disk volume with given UUID"); 2488 pw.println(" --force-sdk: allow install even when existing app targets platform"); 2489 pw.println(" codename but new one targets a final API level"); 2490 pw.println(""); 2491 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]"); 2492 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); 2493 pw.println(" [--originating-uri URI] [---referrer URI]"); 2494 pw.println(" [--abi ABI_NAME] [--force-sdk]"); 2495 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); 2496 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]"); 2497 pw.println(" Like \"install\", but starts an install session. Use \"install-write\""); 2498 pw.println(" to push data into the session, and \"install-commit\" to finish."); 2499 pw.println(""); 2500 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]"); 2501 pw.println(" Write an apk into the given install session. If the path is '-', data"); 2502 pw.println(" will be read from stdin. Options are:"); 2503 pw.println(" -S: size in bytes of package, required for stdin"); 2504 pw.println(""); 2505 pw.println(" install-commit SESSION_ID"); 2506 pw.println(" Commit the given active install session, installing the app."); 2507 pw.println(""); 2508 pw.println(" install-abandon SESSION_ID"); 2509 pw.println(" Delete the given active install session."); 2510 pw.println(""); 2511 pw.println(" set-install-location LOCATION"); 2512 pw.println(" Changes the default install location. NOTE this is only intended for debugging;"); 2513 pw.println(" using this can cause applications to break and other undersireable behavior."); 2514 pw.println(" LOCATION is one of:"); 2515 pw.println(" 0 [auto]: Let system decide the best location"); 2516 pw.println(" 1 [internal]: Install on internal device storage"); 2517 pw.println(" 2 [external]: Install on external media"); 2518 pw.println(""); 2519 pw.println(" get-install-location"); 2520 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location."); 2521 pw.println(""); 2522 pw.println(" move-package PACKAGE [internal|UUID]"); 2523 pw.println(""); 2524 pw.println(" move-primary-storage [internal|UUID]"); 2525 pw.println(""); 2526 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]"); 2527 pw.println(" Remove the given package name from the system. May remove an entire app"); 2528 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the"); 2529 pw.println(" given app. Options are:"); 2530 pw.println(" -k: keep the data and cache directories around after package removal."); 2531 pw.println(" --user: remove the app from the given user."); 2532 pw.println(" --versionCode: only uninstall if the app has the given version code."); 2533 pw.println(""); 2534 pw.println(" clear [--user USER_ID] PACKAGE"); 2535 pw.println(" Deletes all data associated with a package."); 2536 pw.println(""); 2537 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 2538 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 2539 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 2540 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 2541 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT"); 2542 pw.println(" These commands change the enabled state of a given package or"); 2543 pw.println(" component (written as \"package/class\")."); 2544 pw.println(""); 2545 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 2546 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 2547 pw.println(""); 2548 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE"); 2549 pw.println(" Suspends the specified package (as user)."); 2550 pw.println(""); 2551 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE"); 2552 pw.println(" Unsuspends the specified package (as user)."); 2553 pw.println(""); 2554 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION"); 2555 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION"); 2556 pw.println(" These commands either grant or revoke permissions to apps. The permissions"); 2557 pw.println(" must be declared as used in the app's manifest, be runtime permissions"); 2558 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1."); 2559 pw.println(""); 2560 pw.println(" reset-permissions"); 2561 pw.println(" Revert all runtime permissions to their default state."); 2562 pw.println(""); 2563 pw.println(" set-permission-enforced PERMISSION [true|false]"); 2564 pw.println(""); 2565 pw.println(" get-privapp-permissions TARGET-PACKAGE"); 2566 pw.println(" Prints all privileged permissions for a package."); 2567 pw.println(""); 2568 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE"); 2569 pw.println(" Prints all privileged permissions that are denied for a package."); 2570 pw.println(""); 2571 pw.println(" get-oem-permissions TARGET-PACKAGE"); 2572 pw.println(" Prints all OEM permissions for a package."); 2573 pw.println(""); 2574 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}"); 2575 pw.println(" get-app-link [--user USER_ID] PACKAGE"); 2576 pw.println(""); 2577 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]"); 2578 pw.println(" Trim cache files to reach the given free space."); 2579 pw.println(""); 2580 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]"); 2581 pw.println(" [--guest] USER_NAME"); 2582 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier"); 2583 pw.println(" of the user."); 2584 pw.println(""); 2585 pw.println(" remove-user USER_ID"); 2586 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data"); 2587 pw.println(" associated with that user"); 2588 pw.println(""); 2589 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE"); 2590 pw.println(""); 2591 pw.println(" get-max-users"); 2592 pw.println(""); 2593 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]"); 2594 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)"); 2595 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:"); 2596 pw.println(" -a: compile all packages"); 2597 pw.println(" -c: clear profile data before compiling"); 2598 pw.println(" -f: force compilation even if not needed"); 2599 pw.println(" -m: select compilation mode"); 2600 pw.println(" MODE is one of the dex2oat compiler filters:"); 2601 pw.println(" assume-verified"); 2602 pw.println(" extract"); 2603 pw.println(" verify"); 2604 pw.println(" quicken"); 2605 pw.println(" space-profile"); 2606 pw.println(" space"); 2607 pw.println(" speed-profile"); 2608 pw.println(" speed"); 2609 pw.println(" everything"); 2610 pw.println(" -r: select compilation reason"); 2611 pw.println(" REASON is one of:"); 2612 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 2613 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]); 2614 } 2615 pw.println(" --reset: restore package to its post-install state"); 2616 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?"); 2617 pw.println(" --secondary-dex: compile app secondary dex files"); 2618 pw.println(" --split SPLIT: compile only the given split name"); 2619 pw.println(""); 2620 pw.println(" force-dex-opt PACKAGE"); 2621 pw.println(" Force immediate execution of dex opt for the given PACKAGE."); 2622 pw.println(""); 2623 pw.println(" bg-dexopt-job"); 2624 pw.println(" Execute the background optimizations immediately."); 2625 pw.println(" Note that the command only runs the background optimizer logic. It may"); 2626 pw.println(" overlap with the actual job but the job scheduler will not be able to"); 2627 pw.println(" cancel it. It will also run even if the device is not in the idle"); 2628 pw.println(" maintenance mode."); 2629 pw.println(""); 2630 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE"); 2631 pw.println(" Reconciles the package secondary dex files with the generated oat files."); 2632 pw.println(""); 2633 pw.println(" dump-profiles TARGET-PACKAGE"); 2634 pw.println(" Dumps method/class profile files to"); 2635 pw.println(" /data/misc/profman/TARGET-PACKAGE.txt"); 2636 pw.println(""); 2637 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT"); 2638 pw.println(" Set the default home activity (aka launcher)."); 2639 pw.println(""); 2640 pw.println(" set-installer PACKAGE INSTALLER"); 2641 pw.println(" Set installer package name"); 2642 pw.println(""); 2643 pw.println(" get-instantapp-resolver"); 2644 pw.println(" Return the name of the component that is the current instant app installer."); 2645 pw.println(); 2646 Intent.printIntentArgsHelp(pw , ""); 2647 } 2648 2649 private static class LocalIntentReceiver { 2650 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 2651 2652 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 2653 @Override 2654 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, 2655 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 2656 try { 2657 mResult.offer(intent, 5, TimeUnit.SECONDS); 2658 } catch (InterruptedException e) { 2659 throw new RuntimeException(e); 2660 } 2661 } 2662 }; 2663 2664 public IntentSender getIntentSender() { 2665 return new IntentSender((IIntentSender) mLocalSender); 2666 } 2667 2668 public Intent getResult() { 2669 try { 2670 return mResult.take(); 2671 } catch (InterruptedException e) { 2672 throw new RuntimeException(e); 2673 } 2674 } 2675 } 2676} 2677