PackageManagerShellCommand.java revision 09dd1ec4b2dedb862b6276763268380ec037a58e
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.res.AssetManager; 50import android.content.res.Resources; 51import android.net.Uri; 52import android.os.Binder; 53import android.os.Build; 54import android.os.Bundle; 55import android.os.IBinder; 56import android.os.IUserManager; 57import android.os.ParcelFileDescriptor; 58import android.os.Process; 59import android.os.RemoteException; 60import android.os.ServiceManager; 61import android.os.ShellCommand; 62import android.os.SystemClock; 63import android.os.SystemProperties; 64import android.os.UserHandle; 65import android.os.UserManager; 66import android.os.storage.StorageManager; 67import android.text.TextUtils; 68import android.text.format.DateUtils; 69import android.util.ArraySet; 70import android.util.PrintWriterPrinter; 71 72import com.android.internal.content.PackageHelper; 73import com.android.internal.util.ArrayUtils; 74import com.android.internal.util.SizedInputStream; 75import com.android.server.SystemConfig; 76 77import dalvik.system.DexFile; 78 79import libcore.io.IoUtils; 80 81import java.io.File; 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)); 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 for (String packageName : packageNames) { 1173 if (clearProfileData) { 1174 mInterface.clearApplicationProfileData(packageName); 1175 } 1176 1177 boolean result = secondaryDex 1178 ? mInterface.performDexOptSecondary(packageName, 1179 targetCompilerFilter, forceCompilation) 1180 : mInterface.performDexOptMode(packageName, 1181 checkProfiles, targetCompilerFilter, forceCompilation, 1182 true /* bootComplete */, split); 1183 if (!result) { 1184 failedPackages.add(packageName); 1185 } 1186 } 1187 1188 if (failedPackages.isEmpty()) { 1189 pw.println("Success"); 1190 return 0; 1191 } else if (failedPackages.size() == 1) { 1192 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled"); 1193 return 1; 1194 } else { 1195 pw.print("Failure: the following packages could not be compiled: "); 1196 boolean is_first = true; 1197 for (String packageName : failedPackages) { 1198 if (is_first) { 1199 is_first = false; 1200 } else { 1201 pw.print(", "); 1202 } 1203 pw.print(packageName); 1204 } 1205 pw.println(); 1206 return 1; 1207 } 1208 } 1209 1210 private int runreconcileSecondaryDexFiles() throws RemoteException { 1211 String packageName = getNextArg(); 1212 mInterface.reconcileSecondaryDexFiles(packageName); 1213 return 0; 1214 } 1215 1216 public int runForceDexOpt() throws RemoteException { 1217 mInterface.forceDexOpt(getNextArgRequired()); 1218 return 0; 1219 } 1220 1221 private int runDexoptJob() throws RemoteException { 1222 String arg; 1223 List<String> packageNames = new ArrayList<>(); 1224 while ((arg = getNextArg()) != null) { 1225 packageNames.add(arg); 1226 } 1227 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null : 1228 packageNames); 1229 return result ? 0 : -1; 1230 } 1231 1232 private int runDumpProfiles() throws RemoteException { 1233 String packageName = getNextArg(); 1234 mInterface.dumpProfiles(packageName); 1235 return 0; 1236 } 1237 1238 private int runUninstall() throws RemoteException { 1239 final PrintWriter pw = getOutPrintWriter(); 1240 int flags = 0; 1241 int userId = UserHandle.USER_ALL; 1242 int versionCode = PackageManager.VERSION_CODE_HIGHEST; 1243 1244 String opt; 1245 while ((opt = getNextOption()) != null) { 1246 switch (opt) { 1247 case "-k": 1248 flags |= PackageManager.DELETE_KEEP_DATA; 1249 break; 1250 case "--user": 1251 userId = UserHandle.parseUserArg(getNextArgRequired()); 1252 break; 1253 case "--versionCode": 1254 versionCode = Integer.parseInt(getNextArgRequired()); 1255 break; 1256 default: 1257 pw.println("Error: Unknown option: " + opt); 1258 return 1; 1259 } 1260 } 1261 1262 final String packageName = getNextArg(); 1263 if (packageName == null) { 1264 pw.println("Error: package name not specified"); 1265 return 1; 1266 } 1267 1268 // if a split is specified, just remove it and not the whole package 1269 final String splitName = getNextArg(); 1270 if (splitName != null) { 1271 return runRemoveSplit(packageName, splitName); 1272 } 1273 1274 userId = translateUserId(userId, "runUninstall"); 1275 if (userId == UserHandle.USER_ALL) { 1276 userId = UserHandle.USER_SYSTEM; 1277 flags |= PackageManager.DELETE_ALL_USERS; 1278 } else { 1279 final PackageInfo info = mInterface.getPackageInfo(packageName, 1280 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId); 1281 if (info == null) { 1282 pw.println("Failure [not installed for " + userId + "]"); 1283 return 1; 1284 } 1285 final boolean isSystem = 1286 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 1287 // If we are being asked to delete a system app for just one 1288 // user set flag so it disables rather than reverting to system 1289 // version of the app. 1290 if (isSystem) { 1291 flags |= PackageManager.DELETE_SYSTEM_APP; 1292 } 1293 } 1294 1295 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1296 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName, 1297 versionCode), null /*callerPackageName*/, flags, 1298 receiver.getIntentSender(), userId); 1299 1300 final Intent result = receiver.getResult(); 1301 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1302 PackageInstaller.STATUS_FAILURE); 1303 if (status == PackageInstaller.STATUS_SUCCESS) { 1304 pw.println("Success"); 1305 return 0; 1306 } else { 1307 pw.println("Failure [" 1308 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1309 return 1; 1310 } 1311 } 1312 1313 private int runRemoveSplit(String packageName, String splitName) throws RemoteException { 1314 final PrintWriter pw = getOutPrintWriter(); 1315 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 1316 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1317 sessionParams.appPackageName = packageName; 1318 final int sessionId = 1319 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL); 1320 boolean abandonSession = true; 1321 try { 1322 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/) 1323 != PackageInstaller.STATUS_SUCCESS) { 1324 return 1; 1325 } 1326 if (doCommitSession(sessionId, false /*logSuccess*/) 1327 != PackageInstaller.STATUS_SUCCESS) { 1328 return 1; 1329 } 1330 abandonSession = false; 1331 pw.println("Success"); 1332 return 0; 1333 } finally { 1334 if (abandonSession) { 1335 try { 1336 doAbandonSession(sessionId, false /*logSuccess*/); 1337 } catch (Exception ignore) { 1338 } 1339 } 1340 } 1341 } 1342 1343 static class ClearDataObserver extends IPackageDataObserver.Stub { 1344 boolean finished; 1345 boolean result; 1346 1347 @Override 1348 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1349 synchronized (this) { 1350 finished = true; 1351 result = succeeded; 1352 notifyAll(); 1353 } 1354 } 1355 } 1356 1357 private int runClear() throws RemoteException { 1358 int userId = UserHandle.USER_SYSTEM; 1359 String option = getNextOption(); 1360 if (option != null && option.equals("--user")) { 1361 userId = UserHandle.parseUserArg(getNextArgRequired()); 1362 } 1363 1364 String pkg = getNextArg(); 1365 if (pkg == null) { 1366 getErrPrintWriter().println("Error: no package specified"); 1367 return 1; 1368 } 1369 1370 ClearDataObserver obs = new ClearDataObserver(); 1371 ActivityManager.getService().clearApplicationUserData(pkg, obs, userId); 1372 synchronized (obs) { 1373 while (!obs.finished) { 1374 try { 1375 obs.wait(); 1376 } catch (InterruptedException e) { 1377 } 1378 } 1379 } 1380 1381 if (obs.result) { 1382 getOutPrintWriter().println("Success"); 1383 return 0; 1384 } else { 1385 getErrPrintWriter().println("Failed"); 1386 return 1; 1387 } 1388 } 1389 1390 private static String enabledSettingToString(int state) { 1391 switch (state) { 1392 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1393 return "default"; 1394 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1395 return "enabled"; 1396 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1397 return "disabled"; 1398 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1399 return "disabled-user"; 1400 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1401 return "disabled-until-used"; 1402 } 1403 return "unknown"; 1404 } 1405 1406 private int runSetEnabledSetting(int state) throws RemoteException { 1407 int userId = UserHandle.USER_SYSTEM; 1408 String option = getNextOption(); 1409 if (option != null && option.equals("--user")) { 1410 userId = UserHandle.parseUserArg(getNextArgRequired()); 1411 } 1412 1413 String pkg = getNextArg(); 1414 if (pkg == null) { 1415 getErrPrintWriter().println("Error: no package or component specified"); 1416 return 1; 1417 } 1418 ComponentName cn = ComponentName.unflattenFromString(pkg); 1419 if (cn == null) { 1420 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId, 1421 "shell:" + android.os.Process.myUid()); 1422 getOutPrintWriter().println("Package " + pkg + " new state: " 1423 + enabledSettingToString( 1424 mInterface.getApplicationEnabledSetting(pkg, userId))); 1425 return 0; 1426 } else { 1427 mInterface.setComponentEnabledSetting(cn, state, 0, userId); 1428 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: " 1429 + enabledSettingToString( 1430 mInterface.getComponentEnabledSetting(cn, userId))); 1431 return 0; 1432 } 1433 } 1434 1435 private int runSetHiddenSetting(boolean state) throws RemoteException { 1436 int userId = UserHandle.USER_SYSTEM; 1437 String option = getNextOption(); 1438 if (option != null && option.equals("--user")) { 1439 userId = UserHandle.parseUserArg(getNextArgRequired()); 1440 } 1441 1442 String pkg = getNextArg(); 1443 if (pkg == null) { 1444 getErrPrintWriter().println("Error: no package or component specified"); 1445 return 1; 1446 } 1447 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId); 1448 getOutPrintWriter().println("Package " + pkg + " new hidden state: " 1449 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId)); 1450 return 0; 1451 } 1452 1453 private int runSuspend(boolean suspendedState) { 1454 final PrintWriter pw = getOutPrintWriter(); 1455 int userId = UserHandle.USER_SYSTEM; 1456 String opt; 1457 while ((opt = getNextOption()) != null) { 1458 switch (opt) { 1459 case "--user": 1460 userId = UserHandle.parseUserArg(getNextArgRequired()); 1461 break; 1462 default: 1463 pw.println("Error: Unknown option: " + opt); 1464 return 1; 1465 } 1466 } 1467 1468 String packageName = getNextArg(); 1469 if (packageName == null) { 1470 pw.println("Error: package name not specified"); 1471 return 1; 1472 } 1473 1474 try { 1475 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState, 1476 userId); 1477 pw.println("Package " + packageName + " new suspended state: " 1478 + mInterface.isPackageSuspendedForUser(packageName, userId)); 1479 return 0; 1480 } catch (RemoteException | IllegalArgumentException e) { 1481 pw.println(e.toString()); 1482 return 1; 1483 } 1484 } 1485 1486 private int runGrantRevokePermission(boolean grant) throws RemoteException { 1487 int userId = UserHandle.USER_SYSTEM; 1488 1489 String opt = null; 1490 while ((opt = getNextOption()) != null) { 1491 if (opt.equals("--user")) { 1492 userId = UserHandle.parseUserArg(getNextArgRequired()); 1493 } 1494 } 1495 1496 String pkg = getNextArg(); 1497 if (pkg == null) { 1498 getErrPrintWriter().println("Error: no package specified"); 1499 return 1; 1500 } 1501 String perm = getNextArg(); 1502 if (perm == null) { 1503 getErrPrintWriter().println("Error: no permission specified"); 1504 return 1; 1505 } 1506 1507 if (grant) { 1508 mInterface.grantRuntimePermission(pkg, perm, userId); 1509 } else { 1510 mInterface.revokeRuntimePermission(pkg, perm, userId); 1511 } 1512 return 0; 1513 } 1514 1515 private int runResetPermissions() throws RemoteException { 1516 mInterface.resetRuntimePermissions(); 1517 return 0; 1518 } 1519 1520 private int runSetPermissionEnforced() throws RemoteException { 1521 final String permission = getNextArg(); 1522 if (permission == null) { 1523 getErrPrintWriter().println("Error: no permission specified"); 1524 return 1; 1525 } 1526 final String enforcedRaw = getNextArg(); 1527 if (enforcedRaw == null) { 1528 getErrPrintWriter().println("Error: no enforcement specified"); 1529 return 1; 1530 } 1531 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw)); 1532 return 0; 1533 } 1534 1535 private int runGetPrivappPermissions() { 1536 final String pkg = getNextArg(); 1537 if (pkg == null) { 1538 getErrPrintWriter().println("Error: no package specified."); 1539 return 1; 1540 } 1541 ArraySet<String> privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg); 1542 getOutPrintWriter().println(privAppPermissions == null 1543 ? "{}" : privAppPermissions.toString()); 1544 return 0; 1545 } 1546 1547 private int runGetPrivappDenyPermissions() { 1548 final String pkg = getNextArg(); 1549 if (pkg == null) { 1550 getErrPrintWriter().println("Error: no package specified."); 1551 return 1; 1552 } 1553 ArraySet<String> privAppDenyPermissions = 1554 SystemConfig.getInstance().getPrivAppDenyPermissions(pkg); 1555 getOutPrintWriter().println(privAppDenyPermissions == null 1556 ? "{}" : privAppDenyPermissions.toString()); 1557 return 0; 1558 } 1559 1560 private int runGetOemPermissions() { 1561 final String pkg = getNextArg(); 1562 if (pkg == null) { 1563 getErrPrintWriter().println("Error: no package specified."); 1564 return 1; 1565 } 1566 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance() 1567 .getOemPermissions(pkg); 1568 if (oemPermissions == null || oemPermissions.isEmpty()) { 1569 getOutPrintWriter().println("{}"); 1570 } else { 1571 oemPermissions.forEach((permission, granted) -> 1572 getOutPrintWriter().println(permission + " granted:" + granted) 1573 ); 1574 } 1575 return 0; 1576 } 1577 1578 private String linkStateToString(int state) { 1579 switch (state) { 1580 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined"; 1581 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask"; 1582 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always"; 1583 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never"; 1584 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask"; 1585 } 1586 return "Unknown link state: " + state; 1587 } 1588 1589 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined} 1590 private int runSetAppLink() throws RemoteException { 1591 int userId = UserHandle.USER_SYSTEM; 1592 1593 String opt; 1594 while ((opt = getNextOption()) != null) { 1595 if (opt.equals("--user")) { 1596 userId = UserHandle.parseUserArg(getNextArgRequired()); 1597 } else { 1598 getErrPrintWriter().println("Error: unknown option: " + opt); 1599 return 1; 1600 } 1601 } 1602 1603 // Package name to act on; required 1604 final String pkg = getNextArg(); 1605 if (pkg == null) { 1606 getErrPrintWriter().println("Error: no package specified."); 1607 return 1; 1608 } 1609 1610 // State to apply; {always|ask|never|undefined}, required 1611 final String modeString = getNextArg(); 1612 if (modeString == null) { 1613 getErrPrintWriter().println("Error: no app link state specified."); 1614 return 1; 1615 } 1616 1617 final int newMode; 1618 switch (modeString.toLowerCase()) { 1619 case "undefined": 1620 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1621 break; 1622 1623 case "always": 1624 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1625 break; 1626 1627 case "ask": 1628 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 1629 break; 1630 1631 case "always-ask": 1632 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 1633 break; 1634 1635 case "never": 1636 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 1637 break; 1638 1639 default: 1640 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'"); 1641 return 1; 1642 } 1643 1644 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); 1645 if (info == null) { 1646 getErrPrintWriter().println("Error: package " + pkg + " not found."); 1647 return 1; 1648 } 1649 1650 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 1651 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links."); 1652 return 1; 1653 } 1654 1655 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) { 1656 getErrPrintWriter().println("Error: unable to update app link status for " + pkg); 1657 return 1; 1658 } 1659 1660 return 0; 1661 } 1662 1663 // pm get-app-link [--user USER_ID] PACKAGE 1664 private int runGetAppLink() throws RemoteException { 1665 int userId = UserHandle.USER_SYSTEM; 1666 1667 String opt; 1668 while ((opt = getNextOption()) != null) { 1669 if (opt.equals("--user")) { 1670 userId = UserHandle.parseUserArg(getNextArgRequired()); 1671 } else { 1672 getErrPrintWriter().println("Error: unknown option: " + opt); 1673 return 1; 1674 } 1675 } 1676 1677 // Package name to act on; required 1678 final String pkg = getNextArg(); 1679 if (pkg == null) { 1680 getErrPrintWriter().println("Error: no package specified."); 1681 return 1; 1682 } 1683 1684 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); 1685 if (info == null) { 1686 getErrPrintWriter().println("Error: package " + pkg + " not found."); 1687 return 1; 1688 } 1689 1690 if ((info.applicationInfo.privateFlags 1691 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 1692 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links."); 1693 return 1; 1694 } 1695 1696 getOutPrintWriter().println(linkStateToString( 1697 mInterface.getIntentVerificationStatus(pkg, userId))); 1698 1699 return 0; 1700 } 1701 1702 private int runTrimCaches() throws RemoteException { 1703 String size = getNextArg(); 1704 if (size == null) { 1705 getErrPrintWriter().println("Error: no size specified"); 1706 return 1; 1707 } 1708 long multiplier = 1; 1709 int len = size.length(); 1710 char c = size.charAt(len - 1); 1711 if (c < '0' || c > '9') { 1712 if (c == 'K' || c == 'k') { 1713 multiplier = 1024L; 1714 } else if (c == 'M' || c == 'm') { 1715 multiplier = 1024L*1024L; 1716 } else if (c == 'G' || c == 'g') { 1717 multiplier = 1024L*1024L*1024L; 1718 } else { 1719 getErrPrintWriter().println("Invalid suffix: " + c); 1720 return 1; 1721 } 1722 size = size.substring(0, len-1); 1723 } 1724 long sizeVal; 1725 try { 1726 sizeVal = Long.parseLong(size) * multiplier; 1727 } catch (NumberFormatException e) { 1728 getErrPrintWriter().println("Error: expected number at: " + size); 1729 return 1; 1730 } 1731 String volumeUuid = getNextArg(); 1732 if ("internal".equals(volumeUuid)) { 1733 volumeUuid = null; 1734 } 1735 ClearDataObserver obs = new ClearDataObserver(); 1736 mInterface.freeStorageAndNotify(volumeUuid, sizeVal, 1737 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs); 1738 synchronized (obs) { 1739 while (!obs.finished) { 1740 try { 1741 obs.wait(); 1742 } catch (InterruptedException e) { 1743 } 1744 } 1745 } 1746 return 0; 1747 } 1748 1749 private static boolean isNumber(String s) { 1750 try { 1751 Integer.parseInt(s); 1752 } catch (NumberFormatException nfe) { 1753 return false; 1754 } 1755 return true; 1756 } 1757 1758 public int runCreateUser() throws RemoteException { 1759 String name; 1760 int userId = -1; 1761 int flags = 0; 1762 String opt; 1763 while ((opt = getNextOption()) != null) { 1764 if ("--profileOf".equals(opt)) { 1765 userId = UserHandle.parseUserArg(getNextArgRequired()); 1766 } else if ("--managed".equals(opt)) { 1767 flags |= UserInfo.FLAG_MANAGED_PROFILE; 1768 } else if ("--restricted".equals(opt)) { 1769 flags |= UserInfo.FLAG_RESTRICTED; 1770 } else if ("--ephemeral".equals(opt)) { 1771 flags |= UserInfo.FLAG_EPHEMERAL; 1772 } else if ("--guest".equals(opt)) { 1773 flags |= UserInfo.FLAG_GUEST; 1774 } else if ("--demo".equals(opt)) { 1775 flags |= UserInfo.FLAG_DEMO; 1776 } else { 1777 getErrPrintWriter().println("Error: unknown option " + opt); 1778 return 1; 1779 } 1780 } 1781 String arg = getNextArg(); 1782 if (arg == null) { 1783 getErrPrintWriter().println("Error: no user name specified."); 1784 return 1; 1785 } 1786 name = arg; 1787 UserInfo info; 1788 IUserManager um = IUserManager.Stub.asInterface( 1789 ServiceManager.getService(Context.USER_SERVICE)); 1790 IAccountManager accm = IAccountManager.Stub.asInterface( 1791 ServiceManager.getService(Context.ACCOUNT_SERVICE)); 1792 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) { 1793 // In non-split user mode, userId can only be SYSTEM 1794 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM; 1795 info = um.createRestrictedProfile(name, parentUserId); 1796 accm.addSharedAccountsFromParentUser(parentUserId, userId, 1797 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell"); 1798 } else if (userId < 0) { 1799 info = um.createUser(name, flags); 1800 } else { 1801 info = um.createProfileForUser(name, flags, userId, null); 1802 } 1803 1804 if (info != null) { 1805 getOutPrintWriter().println("Success: created user id " + info.id); 1806 return 0; 1807 } else { 1808 getErrPrintWriter().println("Error: couldn't create User."); 1809 return 1; 1810 } 1811 } 1812 1813 public int runRemoveUser() throws RemoteException { 1814 int userId; 1815 String arg = getNextArg(); 1816 if (arg == null) { 1817 getErrPrintWriter().println("Error: no user id specified."); 1818 return 1; 1819 } 1820 userId = UserHandle.parseUserArg(arg); 1821 IUserManager um = IUserManager.Stub.asInterface( 1822 ServiceManager.getService(Context.USER_SERVICE)); 1823 if (um.removeUser(userId)) { 1824 getOutPrintWriter().println("Success: removed user"); 1825 return 0; 1826 } else { 1827 getErrPrintWriter().println("Error: couldn't remove user id " + userId); 1828 return 1; 1829 } 1830 } 1831 1832 public int runSetUserRestriction() throws RemoteException { 1833 int userId = UserHandle.USER_SYSTEM; 1834 String opt = getNextOption(); 1835 if (opt != null && "--user".equals(opt)) { 1836 userId = UserHandle.parseUserArg(getNextArgRequired()); 1837 } 1838 1839 String restriction = getNextArg(); 1840 String arg = getNextArg(); 1841 boolean value; 1842 if ("1".equals(arg)) { 1843 value = true; 1844 } else if ("0".equals(arg)) { 1845 value = false; 1846 } else { 1847 getErrPrintWriter().println("Error: valid value not specified"); 1848 return 1; 1849 } 1850 IUserManager um = IUserManager.Stub.asInterface( 1851 ServiceManager.getService(Context.USER_SERVICE)); 1852 um.setUserRestriction(restriction, value, userId); 1853 return 0; 1854 } 1855 1856 public int runGetMaxUsers() { 1857 getOutPrintWriter().println("Maximum supported users: " 1858 + UserManager.getMaxSupportedUsers()); 1859 return 0; 1860 } 1861 1862 private static class InstallParams { 1863 SessionParams sessionParams; 1864 String installerPackageName; 1865 int userId = UserHandle.USER_ALL; 1866 } 1867 1868 private InstallParams makeInstallParams() { 1869 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1870 final InstallParams params = new InstallParams(); 1871 params.sessionParams = sessionParams; 1872 String opt; 1873 while ((opt = getNextOption()) != null) { 1874 switch (opt) { 1875 case "-l": 1876 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 1877 break; 1878 case "-r": 1879 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1880 break; 1881 case "-i": 1882 params.installerPackageName = getNextArg(); 1883 if (params.installerPackageName == null) { 1884 throw new IllegalArgumentException("Missing installer package"); 1885 } 1886 break; 1887 case "-t": 1888 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 1889 break; 1890 case "-s": 1891 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL; 1892 break; 1893 case "-f": 1894 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL; 1895 break; 1896 case "-d": 1897 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 1898 break; 1899 case "-g": 1900 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; 1901 break; 1902 case "--dont-kill": 1903 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP; 1904 break; 1905 case "--originating-uri": 1906 sessionParams.originatingUri = Uri.parse(getNextArg()); 1907 break; 1908 case "--referrer": 1909 sessionParams.referrerUri = Uri.parse(getNextArg()); 1910 break; 1911 case "-p": 1912 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING; 1913 sessionParams.appPackageName = getNextArg(); 1914 if (sessionParams.appPackageName == null) { 1915 throw new IllegalArgumentException("Missing inherit package name"); 1916 } 1917 break; 1918 case "--pkg": 1919 sessionParams.appPackageName = getNextArg(); 1920 if (sessionParams.appPackageName == null) { 1921 throw new IllegalArgumentException("Missing package name"); 1922 } 1923 break; 1924 case "-S": 1925 final long sizeBytes = Long.parseLong(getNextArg()); 1926 if (sizeBytes <= 0) { 1927 throw new IllegalArgumentException("Size must be positive"); 1928 } 1929 sessionParams.setSize(sizeBytes); 1930 break; 1931 case "--abi": 1932 sessionParams.abiOverride = checkAbiArgument(getNextArg()); 1933 break; 1934 case "--ephemeral": 1935 case "--instant": 1936 case "--instantapp": 1937 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/); 1938 break; 1939 case "--full": 1940 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/); 1941 break; 1942 case "--preload": 1943 sessionParams.setInstallAsVirtualPreload(); 1944 break; 1945 case "--user": 1946 params.userId = UserHandle.parseUserArg(getNextArgRequired()); 1947 break; 1948 case "--install-location": 1949 sessionParams.installLocation = Integer.parseInt(getNextArg()); 1950 break; 1951 case "--force-uuid": 1952 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID; 1953 sessionParams.volumeUuid = getNextArg(); 1954 if ("internal".equals(sessionParams.volumeUuid)) { 1955 sessionParams.volumeUuid = null; 1956 } 1957 break; 1958 case "--force-sdk": 1959 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; 1960 break; 1961 default: 1962 throw new IllegalArgumentException("Unknown option " + opt); 1963 } 1964 } 1965 return params; 1966 } 1967 1968 private int runSetHomeActivity() { 1969 final PrintWriter pw = getOutPrintWriter(); 1970 int userId = UserHandle.USER_SYSTEM; 1971 String opt; 1972 while ((opt = getNextOption()) != null) { 1973 switch (opt) { 1974 case "--user": 1975 userId = UserHandle.parseUserArg(getNextArgRequired()); 1976 break; 1977 default: 1978 pw.println("Error: Unknown option: " + opt); 1979 return 1; 1980 } 1981 } 1982 1983 String component = getNextArg(); 1984 ComponentName componentName = 1985 component != null ? ComponentName.unflattenFromString(component) : null; 1986 1987 if (componentName == null) { 1988 pw.println("Error: component name not specified or invalid"); 1989 return 1; 1990 } 1991 1992 try { 1993 mInterface.setHomeActivity(componentName, userId); 1994 pw.println("Success"); 1995 return 0; 1996 } catch (Exception e) { 1997 pw.println(e.toString()); 1998 return 1; 1999 } 2000 } 2001 2002 private int runSetInstaller() throws RemoteException { 2003 final String targetPackage = getNextArg(); 2004 final String installerPackageName = getNextArg(); 2005 2006 if (targetPackage == null || installerPackageName == null) { 2007 getErrPrintWriter().println("Must provide both target and installer package names"); 2008 return 1; 2009 } 2010 2011 mInterface.setInstallerPackageName(targetPackage, installerPackageName); 2012 getOutPrintWriter().println("Success"); 2013 return 0; 2014 } 2015 2016 private int runGetInstantAppResolver() { 2017 final PrintWriter pw = getOutPrintWriter(); 2018 try { 2019 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent(); 2020 if (instantAppsResolver == null) { 2021 return 1; 2022 } 2023 pw.println(instantAppsResolver.flattenToString()); 2024 return 0; 2025 } catch (Exception e) { 2026 pw.println(e.toString()); 2027 return 1; 2028 } 2029 } 2030 2031 private int runHasFeature() { 2032 final PrintWriter err = getErrPrintWriter(); 2033 final String featureName = getNextArg(); 2034 if (featureName == null) { 2035 err.println("Error: expected FEATURE name"); 2036 return 1; 2037 } 2038 final String versionString = getNextArg(); 2039 try { 2040 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString); 2041 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version); 2042 getOutPrintWriter().println(hasFeature); 2043 return hasFeature ? 0 : 1; 2044 } catch (NumberFormatException e) { 2045 err.println("Error: illegal version number " + versionString); 2046 return 1; 2047 } catch (RemoteException e) { 2048 err.println(e.toString()); 2049 return 1; 2050 } 2051 } 2052 2053 private int runDump() { 2054 String pkg = getNextArg(); 2055 if (pkg == null) { 2056 getErrPrintWriter().println("Error: no package specified"); 2057 return 1; 2058 } 2059 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg); 2060 return 0; 2061 } 2062 2063 private static String checkAbiArgument(String abi) { 2064 if (TextUtils.isEmpty(abi)) { 2065 throw new IllegalArgumentException("Missing ABI argument"); 2066 } 2067 2068 if ("-".equals(abi)) { 2069 return abi; 2070 } 2071 2072 final String[] supportedAbis = Build.SUPPORTED_ABIS; 2073 for (String supportedAbi : supportedAbis) { 2074 if (supportedAbi.equals(abi)) { 2075 return abi; 2076 } 2077 } 2078 2079 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 2080 } 2081 2082 private int translateUserId(int userId, String logContext) { 2083 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 2084 userId, true, true, logContext, "pm command"); 2085 } 2086 2087 private int doCreateSession(SessionParams params, String installerPackageName, int userId) 2088 throws RemoteException { 2089 userId = translateUserId(userId, "runInstallCreate"); 2090 if (userId == UserHandle.USER_ALL) { 2091 userId = UserHandle.USER_SYSTEM; 2092 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 2093 } 2094 2095 final int sessionId = mInterface.getPackageInstaller() 2096 .createSession(params, installerPackageName, userId); 2097 return sessionId; 2098 } 2099 2100 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, 2101 boolean logSuccess) throws RemoteException { 2102 final PrintWriter pw = getOutPrintWriter(); 2103 final ParcelFileDescriptor fd; 2104 if (STDIN_PATH.equals(inPath)) { 2105 fd = null; 2106 } else if (inPath != null) { 2107 fd = openFileForSystem(inPath, "r"); 2108 if (fd == null) { 2109 return -1; 2110 } 2111 sizeBytes = fd.getStatSize(); 2112 if (sizeBytes < 0) { 2113 getErrPrintWriter().println("Unable to get size of: " + inPath); 2114 return -1; 2115 } 2116 } else { 2117 fd = null; 2118 } 2119 if (sizeBytes <= 0) { 2120 getErrPrintWriter().println("Error: must specify a APK size"); 2121 return 1; 2122 } 2123 2124 final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId); 2125 2126 PackageInstaller.Session session = null; 2127 InputStream in = null; 2128 OutputStream out = null; 2129 try { 2130 session = new PackageInstaller.Session( 2131 mInterface.getPackageInstaller().openSession(sessionId)); 2132 2133 if (fd != null) { 2134 in = new ParcelFileDescriptor.AutoCloseInputStream(fd); 2135 } else { 2136 in = new SizedInputStream(getRawInputStream(), sizeBytes); 2137 } 2138 out = session.openWrite(splitName, 0, sizeBytes); 2139 2140 int total = 0; 2141 byte[] buffer = new byte[1024 * 1024]; 2142 int c; 2143 while ((c = in.read(buffer)) != -1) { 2144 total += c; 2145 out.write(buffer, 0, c); 2146 2147 if (info.sizeBytes > 0) { 2148 final float fraction = ((float) c / (float) info.sizeBytes); 2149 session.addProgress(fraction); 2150 } 2151 } 2152 session.fsync(out); 2153 2154 if (logSuccess) { 2155 pw.println("Success: streamed " + total + " bytes"); 2156 } 2157 return 0; 2158 } catch (IOException e) { 2159 getErrPrintWriter().println("Error: failed to write; " + e.getMessage()); 2160 return 1; 2161 } finally { 2162 IoUtils.closeQuietly(out); 2163 IoUtils.closeQuietly(in); 2164 IoUtils.closeQuietly(session); 2165 } 2166 } 2167 2168 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess) 2169 throws RemoteException { 2170 final PrintWriter pw = getOutPrintWriter(); 2171 PackageInstaller.Session session = null; 2172 try { 2173 session = new PackageInstaller.Session( 2174 mInterface.getPackageInstaller().openSession(sessionId)); 2175 session.removeSplit(splitName); 2176 2177 if (logSuccess) { 2178 pw.println("Success"); 2179 } 2180 return 0; 2181 } catch (IOException e) { 2182 pw.println("Error: failed to remove split; " + e.getMessage()); 2183 return 1; 2184 } finally { 2185 IoUtils.closeQuietly(session); 2186 } 2187 } 2188 2189 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException { 2190 final PrintWriter pw = getOutPrintWriter(); 2191 PackageInstaller.Session session = null; 2192 try { 2193 session = new PackageInstaller.Session( 2194 mInterface.getPackageInstaller().openSession(sessionId)); 2195 2196 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 2197 session.commit(receiver.getIntentSender()); 2198 2199 final Intent result = receiver.getResult(); 2200 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 2201 PackageInstaller.STATUS_FAILURE); 2202 if (status == PackageInstaller.STATUS_SUCCESS) { 2203 if (logSuccess) { 2204 pw.println("Success"); 2205 } 2206 } else { 2207 pw.println("Failure [" 2208 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 2209 } 2210 return status; 2211 } finally { 2212 IoUtils.closeQuietly(session); 2213 } 2214 } 2215 2216 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException { 2217 final PrintWriter pw = getOutPrintWriter(); 2218 PackageInstaller.Session session = null; 2219 try { 2220 session = new PackageInstaller.Session( 2221 mInterface.getPackageInstaller().openSession(sessionId)); 2222 session.abandon(); 2223 if (logSuccess) { 2224 pw.println("Success"); 2225 } 2226 return 0; 2227 } finally { 2228 IoUtils.closeQuietly(session); 2229 } 2230 } 2231 2232 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels, 2233 boolean summary, int startProtectionLevel, int endProtectionLevel) 2234 throws RemoteException { 2235 final PrintWriter pw = getOutPrintWriter(); 2236 final int groupCount = groupList.size(); 2237 for (int i = 0; i < groupCount; i++) { 2238 String groupName = groupList.get(i); 2239 String prefix = ""; 2240 if (groups) { 2241 if (i > 0) { 2242 pw.println(""); 2243 } 2244 if (groupName != null) { 2245 PermissionGroupInfo pgi = 2246 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/); 2247 if (summary) { 2248 Resources res = getResources(pgi); 2249 if (res != null) { 2250 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": "); 2251 } else { 2252 pw.print(pgi.name + ": "); 2253 2254 } 2255 } else { 2256 pw.println((labels ? "+ " : "") + "group:" + pgi.name); 2257 if (labels) { 2258 pw.println(" package:" + pgi.packageName); 2259 Resources res = getResources(pgi); 2260 if (res != null) { 2261 pw.println(" label:" 2262 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel)); 2263 pw.println(" description:" 2264 + loadText(pgi, pgi.descriptionRes, 2265 pgi.nonLocalizedDescription)); 2266 } 2267 } 2268 } 2269 } else { 2270 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:"); 2271 } 2272 prefix = " "; 2273 } 2274 List<PermissionInfo> ps = 2275 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList(); 2276 final int count = ps.size(); 2277 boolean first = true; 2278 for (int p = 0 ; p < count ; p++) { 2279 PermissionInfo pi = ps.get(p); 2280 if (groups && groupName == null && pi.group != null) { 2281 continue; 2282 } 2283 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 2284 if (base < startProtectionLevel 2285 || base > endProtectionLevel) { 2286 continue; 2287 } 2288 if (summary) { 2289 if (first) { 2290 first = false; 2291 } else { 2292 pw.print(", "); 2293 } 2294 Resources res = getResources(pi); 2295 if (res != null) { 2296 pw.print(loadText(pi, pi.labelRes, 2297 pi.nonLocalizedLabel)); 2298 } else { 2299 pw.print(pi.name); 2300 } 2301 } else { 2302 pw.println(prefix + (labels ? "+ " : "") 2303 + "permission:" + pi.name); 2304 if (labels) { 2305 pw.println(prefix + " package:" + pi.packageName); 2306 Resources res = getResources(pi); 2307 if (res != null) { 2308 pw.println(prefix + " label:" 2309 + loadText(pi, pi.labelRes, 2310 pi.nonLocalizedLabel)); 2311 pw.println(prefix + " description:" 2312 + loadText(pi, pi.descriptionRes, 2313 pi.nonLocalizedDescription)); 2314 } 2315 pw.println(prefix + " protectionLevel:" 2316 + PermissionInfo.protectionToString(pi.protectionLevel)); 2317 } 2318 } 2319 } 2320 2321 if (summary) { 2322 pw.println(""); 2323 } 2324 } 2325 } 2326 2327 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) 2328 throws RemoteException { 2329 if (nonLocalized != null) { 2330 return nonLocalized.toString(); 2331 } 2332 if (res != 0) { 2333 Resources r = getResources(pii); 2334 if (r != null) { 2335 try { 2336 return r.getString(res); 2337 } catch (Resources.NotFoundException e) { 2338 } 2339 } 2340 } 2341 return null; 2342 } 2343 2344 private Resources getResources(PackageItemInfo pii) throws RemoteException { 2345 Resources res = mResourceCache.get(pii.packageName); 2346 if (res != null) return res; 2347 2348 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0); 2349 AssetManager am = new AssetManager(); 2350 am.addAssetPath(ai.publicSourceDir); 2351 res = new Resources(am, null, null); 2352 mResourceCache.put(pii.packageName, res); 2353 return res; 2354 } 2355 2356 @Override 2357 public void onHelp() { 2358 final PrintWriter pw = getOutPrintWriter(); 2359 pw.println("Package manager (package) commands:"); 2360 pw.println(" help"); 2361 pw.println(" Print this help text."); 2362 pw.println(""); 2363 pw.println(" path [--user USER_ID] PACKAGE"); 2364 pw.println(" Print the path to the .apk of the given PACKAGE."); 2365 pw.println(""); 2366 pw.println(" dump PACKAGE"); 2367 pw.println(" Print various system state associated with the given PACKAGE."); 2368 pw.println(""); 2369 pw.println(" list features"); 2370 pw.println(" Prints all features of the system."); 2371 pw.println(""); 2372 pw.println(" has-feature FEATURE_NAME [version]"); 2373 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,"); 2374 pw.println(" otherwise prints false and returns exit status 1"); 2375 pw.println(""); 2376 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]"); 2377 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE"); 2378 pw.println(" Options:"); 2379 pw.println(" -f: dump the name of the .apk file containing the test package"); 2380 pw.println(""); 2381 pw.println(" list libraries"); 2382 pw.println(" Prints all system libraries."); 2383 pw.println(""); 2384 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] "); 2385 pw.println(" [--uid UID] [--user USER_ID] [FILTER]"); 2386 pw.println(" Prints all packages; optionally only those whose name contains"); 2387 pw.println(" the text in FILTER. Options are:"); 2388 pw.println(" -f: see their associated file"); 2389 pw.println(" -d: filter to only show disabled packages"); 2390 pw.println(" -e: filter to only show enabled packages"); 2391 pw.println(" -s: filter to only show system packages"); 2392 pw.println(" -3: filter to only show third party packages"); 2393 pw.println(" -i: see the installer for the packages"); 2394 pw.println(" -l: ignored (used for compatibility with older releases)"); 2395 pw.println(" -U: also show the package UID"); 2396 pw.println(" -u: also include uninstalled packages"); 2397 pw.println(" --uid UID: filter to only show packages with the given UID"); 2398 pw.println(" --user USER_ID: only list packages belonging to the given user"); 2399 pw.println(""); 2400 pw.println(" list permission-groups"); 2401 pw.println(" Prints all known permission groups."); 2402 pw.println(""); 2403 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); 2404 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:"); 2405 pw.println(" -g: organize by group"); 2406 pw.println(" -f: print all information"); 2407 pw.println(" -s: short summary"); 2408 pw.println(" -d: only list dangerous permissions"); 2409 pw.println(" -u: list only the permissions users will see"); 2410 pw.println(""); 2411 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT"); 2412 pw.println(" Prints the activity that resolves to the given INTENT."); 2413 pw.println(""); 2414 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT"); 2415 pw.println(" Prints all activities that can handle the given INTENT."); 2416 pw.println(""); 2417 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT"); 2418 pw.println(" Prints all services that can handle the given INTENT."); 2419 pw.println(""); 2420 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT"); 2421 pw.println(" Prints all broadcast receivers that can handle the given INTENT."); 2422 pw.println(""); 2423 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]"); 2424 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); 2425 pw.println(" [--originating-uri URI] [---referrer URI]"); 2426 pw.println(" [--abi ABI_NAME] [--force-sdk]"); 2427 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); 2428 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]"); 2429 pw.println(" Install an application. Must provide the apk data to install, either as a"); 2430 pw.println(" file path or '-' to read from stdin. Options are:"); 2431 pw.println(" -l: forward lock application"); 2432 pw.println(" -r: allow replacement of existing application"); 2433 pw.println(" -t: allow test packages"); 2434 pw.println(" -i: specify package name of installer owning the app"); 2435 pw.println(" -s: install application on sdcard"); 2436 pw.println(" -f: install application on internal flash"); 2437 pw.println(" -d: allow version code downgrade (debuggable packages only)"); 2438 pw.println(" -p: partial application install (new split on top of existing pkg)"); 2439 pw.println(" -g: grant all runtime permissions"); 2440 pw.println(" -S: size in bytes of package, required for stdin"); 2441 pw.println(" --user: install under the given user."); 2442 pw.println(" --dont-kill: installing a new feature split, don't kill running app"); 2443 pw.println(" --originating-uri: set URI where app was downloaded from"); 2444 pw.println(" --referrer: set URI that instigated the install of the app"); 2445 pw.println(" --pkg: specify expected package name of app being installed"); 2446 pw.println(" --abi: override the default ABI of the platform"); 2447 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app"); 2448 pw.println(" --full: cause the app to be installed as a non-ephemeral full app"); 2449 pw.println(" --install-location: force the install location:"); 2450 pw.println(" 0=auto, 1=internal only, 2=prefer external"); 2451 pw.println(" --force-uuid: force install on to disk volume with given UUID"); 2452 pw.println(" --force-sdk: allow install even when existing app targets platform"); 2453 pw.println(" codename but new one targets a final API level"); 2454 pw.println(""); 2455 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]"); 2456 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); 2457 pw.println(" [--originating-uri URI] [---referrer URI]"); 2458 pw.println(" [--abi ABI_NAME] [--force-sdk]"); 2459 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); 2460 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]"); 2461 pw.println(" Like \"install\", but starts an install session. Use \"install-write\""); 2462 pw.println(" to push data into the session, and \"install-commit\" to finish."); 2463 pw.println(""); 2464 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]"); 2465 pw.println(" Write an apk into the given install session. If the path is '-', data"); 2466 pw.println(" will be read from stdin. Options are:"); 2467 pw.println(" -S: size in bytes of package, required for stdin"); 2468 pw.println(""); 2469 pw.println(" install-commit SESSION_ID"); 2470 pw.println(" Commit the given active install session, installing the app."); 2471 pw.println(""); 2472 pw.println(" install-abandon SESSION_ID"); 2473 pw.println(" Delete the given active install session."); 2474 pw.println(""); 2475 pw.println(" set-install-location LOCATION"); 2476 pw.println(" Changes the default install location. NOTE this is only intended for debugging;"); 2477 pw.println(" using this can cause applications to break and other undersireable behavior."); 2478 pw.println(" LOCATION is one of:"); 2479 pw.println(" 0 [auto]: Let system decide the best location"); 2480 pw.println(" 1 [internal]: Install on internal device storage"); 2481 pw.println(" 2 [external]: Install on external media"); 2482 pw.println(""); 2483 pw.println(" get-install-location"); 2484 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location."); 2485 pw.println(""); 2486 pw.println(" move-package PACKAGE [internal|UUID]"); 2487 pw.println(""); 2488 pw.println(" move-primary-storage [internal|UUID]"); 2489 pw.println(""); 2490 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]"); 2491 pw.println(" Remove the given package name from the system. May remove an entire app"); 2492 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the"); 2493 pw.println(" given app. Options are:"); 2494 pw.println(" -k: keep the data and cache directories around after package removal."); 2495 pw.println(" --user: remove the app from the given user."); 2496 pw.println(" --versionCode: only uninstall if the app has the given version code."); 2497 pw.println(""); 2498 pw.println(" clear [--user USER_ID] PACKAGE"); 2499 pw.println(" Deletes all data associated with a package."); 2500 pw.println(""); 2501 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 2502 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 2503 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 2504 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 2505 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT"); 2506 pw.println(" These commands change the enabled state of a given package or"); 2507 pw.println(" component (written as \"package/class\")."); 2508 pw.println(""); 2509 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 2510 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 2511 pw.println(""); 2512 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE"); 2513 pw.println(" Suspends the specified package (as user)."); 2514 pw.println(""); 2515 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE"); 2516 pw.println(" Unsuspends the specified package (as user)."); 2517 pw.println(""); 2518 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION"); 2519 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION"); 2520 pw.println(" These commands either grant or revoke permissions to apps. The permissions"); 2521 pw.println(" must be declared as used in the app's manifest, be runtime permissions"); 2522 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1."); 2523 pw.println(""); 2524 pw.println(" reset-permissions"); 2525 pw.println(" Revert all runtime permissions to their default state."); 2526 pw.println(""); 2527 pw.println(" set-permission-enforced PERMISSION [true|false]"); 2528 pw.println(""); 2529 pw.println(" get-privapp-permissions TARGET-PACKAGE"); 2530 pw.println(" Prints all privileged permissions for a package."); 2531 pw.println(""); 2532 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE"); 2533 pw.println(" Prints all privileged permissions that are denied for a package."); 2534 pw.println(""); 2535 pw.println(" get-oem-permissions TARGET-PACKAGE"); 2536 pw.println(" Prints all OEM permissions for a package."); 2537 pw.println(""); 2538 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}"); 2539 pw.println(" get-app-link [--user USER_ID] PACKAGE"); 2540 pw.println(""); 2541 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]"); 2542 pw.println(" Trim cache files to reach the given free space."); 2543 pw.println(""); 2544 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]"); 2545 pw.println(" [--guest] USER_NAME"); 2546 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier"); 2547 pw.println(" of the user."); 2548 pw.println(""); 2549 pw.println(" remove-user USER_ID"); 2550 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data"); 2551 pw.println(" associated with that user"); 2552 pw.println(""); 2553 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE"); 2554 pw.println(""); 2555 pw.println(" get-max-users"); 2556 pw.println(""); 2557 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]"); 2558 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)"); 2559 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:"); 2560 pw.println(" -a: compile all packages"); 2561 pw.println(" -c: clear profile data before compiling"); 2562 pw.println(" -f: force compilation even if not needed"); 2563 pw.println(" -m: select compilation mode"); 2564 pw.println(" MODE is one of the dex2oat compiler filters:"); 2565 pw.println(" assume-verified"); 2566 pw.println(" extract"); 2567 pw.println(" verify"); 2568 pw.println(" quicken"); 2569 pw.println(" space-profile"); 2570 pw.println(" space"); 2571 pw.println(" speed-profile"); 2572 pw.println(" speed"); 2573 pw.println(" everything"); 2574 pw.println(" -r: select compilation reason"); 2575 pw.println(" REASON is one of:"); 2576 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 2577 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]); 2578 } 2579 pw.println(" --reset: restore package to its post-install state"); 2580 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?"); 2581 pw.println(" --secondary-dex: compile app secondary dex files"); 2582 pw.println(" --split SPLIT: compile only the given split name"); 2583 pw.println(""); 2584 pw.println(" force-dex-opt PACKAGE"); 2585 pw.println(" Force immediate execution of dex opt for the given PACKAGE."); 2586 pw.println(""); 2587 pw.println(" bg-dexopt-job"); 2588 pw.println(" Execute the background optimizations immediately."); 2589 pw.println(" Note that the command only runs the background optimizer logic. It may"); 2590 pw.println(" overlap with the actual job but the job scheduler will not be able to"); 2591 pw.println(" cancel it. It will also run even if the device is not in the idle"); 2592 pw.println(" maintenance mode."); 2593 pw.println(""); 2594 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE"); 2595 pw.println(" Reconciles the package secondary dex files with the generated oat files."); 2596 pw.println(""); 2597 pw.println(" dump-profiles TARGET-PACKAGE"); 2598 pw.println(" Dumps method/class profile files to"); 2599 pw.println(" /data/misc/profman/TARGET-PACKAGE.txt"); 2600 pw.println(""); 2601 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT"); 2602 pw.println(" Set the default home activity (aka launcher)."); 2603 pw.println(""); 2604 pw.println(" set-installer PACKAGE INSTALLER"); 2605 pw.println(" Set installer package name"); 2606 pw.println(""); 2607 pw.println(" get-instantapp-resolver"); 2608 pw.println(" Return the name of the component that is the current instant app installer."); 2609 pw.println(); 2610 Intent.printIntentArgsHelp(pw , ""); 2611 } 2612 2613 private static class LocalIntentReceiver { 2614 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 2615 2616 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 2617 @Override 2618 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, 2619 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 2620 try { 2621 mResult.offer(intent, 5, TimeUnit.SECONDS); 2622 } catch (InterruptedException e) { 2623 throw new RuntimeException(e); 2624 } 2625 } 2626 }; 2627 2628 public IntentSender getIntentSender() { 2629 return new IntentSender((IIntentSender) mLocalSender); 2630 } 2631 2632 public Intent getResult() { 2633 try { 2634 return mResult.take(); 2635 } catch (InterruptedException e) { 2636 throw new RuntimeException(e); 2637 } 2638 } 2639 } 2640} 2641