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 17 package com.android.server.pm; 18 19 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 20 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 21 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 22 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 23 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 24 25 import android.accounts.IAccountManager; 26 import android.app.ActivityManager; 27 import android.app.ActivityManagerInternal; 28 import android.app.role.IRoleManager; 29 import android.app.role.RoleManager; 30 import android.content.ComponentName; 31 import android.content.Context; 32 import android.content.IIntentReceiver; 33 import android.content.IIntentSender; 34 import android.content.Intent; 35 import android.content.IntentSender; 36 import android.content.pm.ApplicationInfo; 37 import android.content.pm.FeatureInfo; 38 import android.content.pm.IPackageDataObserver; 39 import android.content.pm.IPackageInstaller; 40 import android.content.pm.IPackageManager; 41 import android.content.pm.InstrumentationInfo; 42 import android.content.pm.ModuleInfo; 43 import android.content.pm.PackageInfo; 44 import android.content.pm.PackageInstaller; 45 import android.content.pm.PackageInstaller.SessionInfo; 46 import android.content.pm.PackageInstaller.SessionParams; 47 import android.content.pm.PackageItemInfo; 48 import android.content.pm.PackageManager; 49 import android.content.pm.PackageManager.NameNotFoundException; 50 import android.content.pm.PackageManagerInternal; 51 import android.content.pm.PackageParser; 52 import android.content.pm.PackageParser.ApkLite; 53 import android.content.pm.PackageParser.PackageLite; 54 import android.content.pm.PackageParser.PackageParserException; 55 import android.content.pm.ParceledListSlice; 56 import android.content.pm.PermissionGroupInfo; 57 import android.content.pm.PermissionInfo; 58 import android.content.pm.ResolveInfo; 59 import android.content.pm.SuspendDialogInfo; 60 import android.content.pm.UserInfo; 61 import android.content.pm.VersionedPackage; 62 import android.content.pm.dex.ArtManager; 63 import android.content.pm.dex.DexMetadataHelper; 64 import android.content.pm.dex.ISnapshotRuntimeProfileCallback; 65 import android.content.res.AssetManager; 66 import android.content.res.Resources; 67 import android.content.rollback.IRollbackManager; 68 import android.content.rollback.PackageRollbackInfo; 69 import android.content.rollback.RollbackInfo; 70 import android.content.rollback.RollbackManager; 71 import android.net.Uri; 72 import android.os.Binder; 73 import android.os.Build; 74 import android.os.Bundle; 75 import android.os.IBinder; 76 import android.os.IUserManager; 77 import android.os.ParcelFileDescriptor; 78 import android.os.ParcelFileDescriptor.AutoCloseInputStream; 79 import android.os.PersistableBundle; 80 import android.os.Process; 81 import android.os.RemoteCallback; 82 import android.os.RemoteException; 83 import android.os.ServiceManager; 84 import android.os.ShellCommand; 85 import android.os.SystemClock; 86 import android.os.SystemProperties; 87 import android.os.UserHandle; 88 import android.os.UserManager; 89 import android.os.storage.StorageManager; 90 import android.system.ErrnoException; 91 import android.system.Os; 92 import android.text.TextUtils; 93 import android.text.format.DateUtils; 94 import android.util.ArraySet; 95 import android.util.PrintWriterPrinter; 96 import android.util.SparseArray; 97 98 import com.android.internal.content.PackageHelper; 99 import com.android.internal.util.ArrayUtils; 100 import com.android.internal.util.IndentingPrintWriter; 101 import com.android.server.LocalServices; 102 import com.android.server.SystemConfig; 103 104 import dalvik.system.DexFile; 105 106 import libcore.io.IoUtils; 107 import libcore.io.Streams; 108 109 import java.io.File; 110 import java.io.FileOutputStream; 111 import java.io.IOException; 112 import java.io.InputStream; 113 import java.io.OutputStream; 114 import java.io.PrintWriter; 115 import java.net.URISyntaxException; 116 import java.util.ArrayList; 117 import java.util.Collections; 118 import java.util.Comparator; 119 import java.util.LinkedList; 120 import java.util.List; 121 import java.util.Map; 122 import java.util.Objects; 123 import java.util.WeakHashMap; 124 import java.util.concurrent.CompletableFuture; 125 import java.util.concurrent.CountDownLatch; 126 import java.util.concurrent.LinkedBlockingQueue; 127 import java.util.concurrent.TimeUnit; 128 129 class PackageManagerShellCommand extends ShellCommand { 130 /** Path for streaming APK content */ 131 private static final String STDIN_PATH = "-"; 132 /** Path where ART profiles snapshots are dumped for the shell user */ 133 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/"; 134 private static final int DEFAULT_WAIT_MS = 60 * 1000; 135 136 final IPackageManager mInterface; 137 final private WeakHashMap<String, Resources> mResourceCache = 138 new WeakHashMap<String, Resources>(); 139 int mTargetUser; 140 boolean mBrief; 141 boolean mComponents; 142 int mQueryFlags; 143 PackageManagerShellCommand(PackageManagerService service)144 PackageManagerShellCommand(PackageManagerService service) { 145 mInterface = service; 146 } 147 148 @Override onCommand(String cmd)149 public int onCommand(String cmd) { 150 if (cmd == null) { 151 return handleDefaultCommands(cmd); 152 } 153 154 final PrintWriter pw = getOutPrintWriter(); 155 try { 156 switch(cmd) { 157 case "path": 158 return runPath(); 159 case "dump": 160 return runDump(); 161 case "list": 162 return runList(); 163 case "resolve-activity": 164 return runResolveActivity(); 165 case "query-activities": 166 return runQueryIntentActivities(); 167 case "query-services": 168 return runQueryIntentServices(); 169 case "query-receivers": 170 return runQueryIntentReceivers(); 171 case "install": 172 return runInstall(); 173 case "install-abandon": 174 case "install-destroy": 175 return runInstallAbandon(); 176 case "install-commit": 177 return runInstallCommit(); 178 case "install-create": 179 return runInstallCreate(); 180 case "install-remove": 181 return runInstallRemove(); 182 case "install-write": 183 return runInstallWrite(); 184 case "install-existing": 185 return runInstallExisting(); 186 case "set-install-location": 187 return runSetInstallLocation(); 188 case "get-install-location": 189 return runGetInstallLocation(); 190 case "install-add-session": 191 return runInstallAddSession(); 192 case "move-package": 193 return runMovePackage(); 194 case "move-primary-storage": 195 return runMovePrimaryStorage(); 196 case "compile": 197 return runCompile(); 198 case "reconcile-secondary-dex-files": 199 return runreconcileSecondaryDexFiles(); 200 case "force-dex-opt": 201 return runForceDexOpt(); 202 case "bg-dexopt-job": 203 return runDexoptJob(); 204 case "dump-profiles": 205 return runDumpProfiles(); 206 case "snapshot-profile": 207 return runSnapshotProfile(); 208 case "uninstall": 209 return runUninstall(); 210 case "clear": 211 return runClear(); 212 case "enable": 213 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 214 case "disable": 215 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 216 case "disable-user": 217 return runSetEnabledSetting( 218 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER); 219 case "disable-until-used": 220 return runSetEnabledSetting( 221 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED); 222 case "default-state": 223 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); 224 case "hide": 225 return runSetHiddenSetting(true); 226 case "unhide": 227 return runSetHiddenSetting(false); 228 case "suspend": 229 return runSuspend(true); 230 case "unsuspend": 231 return runSuspend(false); 232 case "grant": 233 return runGrantRevokePermission(true); 234 case "revoke": 235 return runGrantRevokePermission(false); 236 case "reset-permissions": 237 return runResetPermissions(); 238 case "set-permission-enforced": 239 return runSetPermissionEnforced(); 240 case "get-privapp-permissions": 241 return runGetPrivappPermissions(); 242 case "get-privapp-deny-permissions": 243 return runGetPrivappDenyPermissions(); 244 case "get-oem-permissions": 245 return runGetOemPermissions(); 246 case "set-app-link": 247 return runSetAppLink(); 248 case "get-app-link": 249 return runGetAppLink(); 250 case "trim-caches": 251 return runTrimCaches(); 252 case "create-user": 253 return runCreateUser(); 254 case "remove-user": 255 return runRemoveUser(); 256 case "set-user-restriction": 257 return runSetUserRestriction(); 258 case "get-max-users": 259 return runGetMaxUsers(); 260 case "get-max-running-users": 261 return runGetMaxRunningUsers(); 262 case "set-home-activity": 263 return runSetHomeActivity(); 264 case "set-installer": 265 return runSetInstaller(); 266 case "get-instantapp-resolver": 267 return runGetInstantAppResolver(); 268 case "has-feature": 269 return runHasFeature(); 270 case "set-harmful-app-warning": 271 return runSetHarmfulAppWarning(); 272 case "get-harmful-app-warning": 273 return runGetHarmfulAppWarning(); 274 case "get-stagedsessions": 275 return runListStagedSessions(); 276 case "uninstall-system-updates": 277 return uninstallSystemUpdates(); 278 case "rollback-app": 279 return runRollbackApp(); 280 case "get-moduleinfo": 281 return runGetModuleInfo(); 282 default: { 283 String nextArg = getNextArg(); 284 if (nextArg == null) { 285 if (cmd.equalsIgnoreCase("-l")) { 286 return runListPackages(false); 287 } else if (cmd.equalsIgnoreCase("-lf")) { 288 return runListPackages(true); 289 } 290 } else if (getNextArg() == null) { 291 if (cmd.equalsIgnoreCase("-p")) { 292 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM); 293 } 294 } 295 return handleDefaultCommands(cmd); 296 } 297 } 298 } catch (RemoteException e) { 299 pw.println("Remote exception: " + e); 300 } 301 return -1; 302 } 303 304 /** 305 * Shows module info 306 * 307 * Usage: get-moduleinfo [--all | --installed] [module-name] 308 * Example: get-moduleinfo, get-moduleinfo --all, get-moduleinfo xyz 309 */ runGetModuleInfo()310 private int runGetModuleInfo() { 311 final PrintWriter pw = getOutPrintWriter(); 312 int flags = 0; 313 314 String opt; 315 while ((opt = getNextOption()) != null) { 316 switch (opt) { 317 case "--all": 318 flags |= PackageManager.MATCH_ALL; 319 break; 320 case "--installed": 321 break; 322 default: 323 pw.println("Error: Unknown option: " + opt); 324 return -1; 325 } 326 } 327 328 String moduleName = getNextArg(); 329 try { 330 if (moduleName != null) { 331 ModuleInfo m = mInterface.getModuleInfo(moduleName, flags); 332 pw.println(m.toString() + " packageName: " + m.getPackageName()); 333 334 } else { 335 List<ModuleInfo> modules = mInterface.getInstalledModules(flags); 336 for (ModuleInfo m: modules) { 337 pw.println(m.toString() + " packageName: " + m.getPackageName()); 338 } 339 } 340 } catch (RemoteException e) { 341 pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]"); 342 return -1; 343 } 344 return 1; 345 } 346 uninstallSystemUpdates()347 private int uninstallSystemUpdates() { 348 final PrintWriter pw = getOutPrintWriter(); 349 List<String> failedUninstalls = new LinkedList<>(); 350 try { 351 final ParceledListSlice<ApplicationInfo> packages = 352 mInterface.getInstalledApplications( 353 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); 354 final IPackageInstaller installer = mInterface.getPackageInstaller(); 355 List<ApplicationInfo> list = packages.getList(); 356 for (ApplicationInfo info : list) { 357 if (info.isUpdatedSystemApp()) { 358 pw.println("Uninstalling updates to " + info.packageName + "..."); 359 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 360 installer.uninstall(new VersionedPackage(info.packageName, 361 info.versionCode), null /*callerPackageName*/, 0 /* flags */, 362 receiver.getIntentSender(), 0); 363 364 final Intent result = receiver.getResult(); 365 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 366 PackageInstaller.STATUS_FAILURE); 367 if (status != PackageInstaller.STATUS_SUCCESS) { 368 failedUninstalls.add(info.packageName); 369 } 370 } 371 } 372 } catch (RemoteException e) { 373 pw.println("Failure [" 374 + e.getClass().getName() + " - " 375 + e.getMessage() + "]"); 376 return 0; 377 } 378 if (!failedUninstalls.isEmpty()) { 379 pw.println("Failure [Couldn't uninstall packages: " 380 + TextUtils.join(", ", failedUninstalls) 381 + "]"); 382 return 0; 383 } 384 pw.println("Success"); 385 return 1; 386 } 387 runRollbackApp()388 private int runRollbackApp() { 389 final PrintWriter pw = getOutPrintWriter(); 390 391 final String packageName = getNextArgRequired(); 392 if (packageName == null) { 393 pw.println("Error: package name not specified"); 394 return 1; 395 } 396 397 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 398 try { 399 IRollbackManager rm = IRollbackManager.Stub.asInterface( 400 ServiceManager.getService(Context.ROLLBACK_SERVICE)); 401 402 RollbackInfo rollback = null; 403 for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) { 404 for (PackageRollbackInfo info : r.getPackages()) { 405 if (packageName.equals(info.getPackageName())) { 406 rollback = r; 407 break; 408 } 409 } 410 } 411 412 if (rollback == null) { 413 pw.println("No available rollbacks for: " + packageName); 414 return 1; 415 } 416 417 rm.commitRollback(rollback.getRollbackId(), 418 ParceledListSlice.<VersionedPackage>emptyList(), 419 "com.android.shell", receiver.getIntentSender()); 420 } catch (RemoteException re) { 421 // Cannot happen. 422 } 423 424 final Intent result = receiver.getResult(); 425 final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS, 426 RollbackManager.STATUS_FAILURE); 427 if (status == RollbackManager.STATUS_SUCCESS) { 428 pw.println("Success"); 429 return 0; 430 } else { 431 pw.println("Failure [" 432 + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]"); 433 return 1; 434 } 435 } 436 setParamsSize(InstallParams params, String inPath)437 private void setParamsSize(InstallParams params, String inPath) { 438 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) { 439 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r"); 440 if (fd == null) { 441 getErrPrintWriter().println("Error: Can't open file: " + inPath); 442 throw new IllegalArgumentException("Error: Can't open file: " + inPath); 443 } 444 try { 445 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0); 446 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null, 447 null, null); 448 params.sessionParams.setSize(PackageHelper.calculateInstalledSize( 449 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor())); 450 } catch (PackageParserException | IOException e) { 451 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath); 452 throw new IllegalArgumentException( 453 "Error: Failed to parse APK file: " + inPath, e); 454 } finally { 455 try { 456 fd.close(); 457 } catch (IOException e) { 458 } 459 } 460 } 461 } 462 /** 463 * Displays the package file for a package. 464 * @param pckg 465 */ displayPackageFilePath(String pckg, int userId)466 private int displayPackageFilePath(String pckg, int userId) throws RemoteException { 467 PackageInfo info = mInterface.getPackageInfo(pckg, PackageManager.MATCH_APEX, userId); 468 if (info != null && info.applicationInfo != null) { 469 final PrintWriter pw = getOutPrintWriter(); 470 pw.print("package:"); 471 pw.println(info.applicationInfo.sourceDir); 472 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { 473 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { 474 pw.print("package:"); 475 pw.println(splitSourceDir); 476 } 477 } 478 return 0; 479 } 480 return 1; 481 } 482 runPath()483 private int runPath() throws RemoteException { 484 int userId = UserHandle.USER_SYSTEM; 485 String option = getNextOption(); 486 if (option != null && option.equals("--user")) { 487 userId = UserHandle.parseUserArg(getNextArgRequired()); 488 } 489 490 String pkg = getNextArgRequired(); 491 if (pkg == null) { 492 getErrPrintWriter().println("Error: no package specified"); 493 return 1; 494 } 495 return displayPackageFilePath(pkg, userId); 496 } 497 runList()498 private int runList() throws RemoteException { 499 final PrintWriter pw = getOutPrintWriter(); 500 final String type = getNextArg(); 501 if (type == null) { 502 pw.println("Error: didn't specify type of data to list"); 503 return -1; 504 } 505 switch(type) { 506 case "features": 507 return runListFeatures(); 508 case "instrumentation": 509 return runListInstrumentation(); 510 case "libraries": 511 return runListLibraries(); 512 case "package": 513 case "packages": 514 return runListPackages(false /*showSourceDir*/); 515 case "permission-groups": 516 return runListPermissionGroups(); 517 case "permissions": 518 return runListPermissions(); 519 case "staged-sessions": 520 return runListStagedSessions(); 521 case "users": 522 ServiceManager.getService("user").shellCommand( 523 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(), 524 new String[] { "list" }, getShellCallback(), adoptResultReceiver()); 525 return 0; 526 } 527 pw.println("Error: unknown list type '" + type + "'"); 528 return -1; 529 } 530 runListFeatures()531 private int runListFeatures() throws RemoteException { 532 final PrintWriter pw = getOutPrintWriter(); 533 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList(); 534 535 // sort by name 536 Collections.sort(list, new Comparator<FeatureInfo>() { 537 public int compare(FeatureInfo o1, FeatureInfo o2) { 538 if (o1.name == o2.name) return 0; 539 if (o1.name == null) return -1; 540 if (o2.name == null) return 1; 541 return o1.name.compareTo(o2.name); 542 } 543 }); 544 545 final int count = (list != null) ? list.size() : 0; 546 for (int p = 0; p < count; p++) { 547 FeatureInfo fi = list.get(p); 548 pw.print("feature:"); 549 if (fi.name != null) { 550 pw.print(fi.name); 551 if (fi.version > 0) { 552 pw.print("="); 553 pw.print(fi.version); 554 } 555 pw.println(); 556 } else { 557 pw.println("reqGlEsVersion=0x" 558 + Integer.toHexString(fi.reqGlEsVersion)); 559 } 560 } 561 return 0; 562 } 563 runListInstrumentation()564 private int runListInstrumentation() throws RemoteException { 565 final PrintWriter pw = getOutPrintWriter(); 566 boolean showSourceDir = false; 567 String targetPackage = null; 568 569 try { 570 String opt; 571 while ((opt = getNextArg()) != null) { 572 switch (opt) { 573 case "-f": 574 showSourceDir = true; 575 break; 576 default: 577 if (opt.charAt(0) != '-') { 578 targetPackage = opt; 579 } else { 580 pw.println("Error: Unknown option: " + opt); 581 return -1; 582 } 583 break; 584 } 585 } 586 } catch (RuntimeException ex) { 587 pw.println("Error: " + ex.toString()); 588 return -1; 589 } 590 591 final List<InstrumentationInfo> list = 592 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList(); 593 594 // sort by target package 595 Collections.sort(list, new Comparator<InstrumentationInfo>() { 596 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 597 return o1.targetPackage.compareTo(o2.targetPackage); 598 } 599 }); 600 601 final int count = (list != null) ? list.size() : 0; 602 for (int p = 0; p < count; p++) { 603 final InstrumentationInfo ii = list.get(p); 604 pw.print("instrumentation:"); 605 if (showSourceDir) { 606 pw.print(ii.sourceDir); 607 pw.print("="); 608 } 609 final ComponentName cn = new ComponentName(ii.packageName, ii.name); 610 pw.print(cn.flattenToShortString()); 611 pw.print(" (target="); 612 pw.print(ii.targetPackage); 613 pw.println(")"); 614 } 615 return 0; 616 } 617 runListLibraries()618 private int runListLibraries() throws RemoteException { 619 final PrintWriter pw = getOutPrintWriter(); 620 final List<String> list = new ArrayList<String>(); 621 final String[] rawList = mInterface.getSystemSharedLibraryNames(); 622 for (int i = 0; i < rawList.length; i++) { 623 list.add(rawList[i]); 624 } 625 626 // sort by name 627 Collections.sort(list, new Comparator<String>() { 628 public int compare(String o1, String o2) { 629 if (o1 == o2) return 0; 630 if (o1 == null) return -1; 631 if (o2 == null) return 1; 632 return o1.compareTo(o2); 633 } 634 }); 635 636 final int count = (list != null) ? list.size() : 0; 637 for (int p = 0; p < count; p++) { 638 String lib = list.get(p); 639 pw.print("library:"); 640 pw.println(lib); 641 } 642 return 0; 643 } 644 runListPackages(boolean showSourceDir)645 private int runListPackages(boolean showSourceDir) throws RemoteException { 646 final PrintWriter pw = getOutPrintWriter(); 647 int getFlags = 0; 648 boolean listDisabled = false, listEnabled = false; 649 boolean listSystem = false, listThirdParty = false; 650 boolean listInstaller = false; 651 boolean showUid = false; 652 boolean showVersionCode = false; 653 boolean listApexOnly = false; 654 int uid = -1; 655 int userId = UserHandle.USER_SYSTEM; 656 try { 657 String opt; 658 while ((opt = getNextOption()) != null) { 659 switch (opt) { 660 case "-d": 661 listDisabled = true; 662 break; 663 case "-e": 664 listEnabled = true; 665 break; 666 case "-a": 667 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES; 668 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS; 669 break; 670 case "-f": 671 showSourceDir = true; 672 break; 673 case "-i": 674 listInstaller = true; 675 break; 676 case "-l": 677 // old compat 678 break; 679 case "-s": 680 listSystem = true; 681 break; 682 case "-U": 683 showUid = true; 684 break; 685 case "-u": 686 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES; 687 break; 688 case "-3": 689 listThirdParty = true; 690 break; 691 case "--show-versioncode": 692 showVersionCode = true; 693 break; 694 case "--apex-only": 695 getFlags |= PackageManager.MATCH_APEX; 696 listApexOnly = true; 697 break; 698 case "--user": 699 userId = UserHandle.parseUserArg(getNextArgRequired()); 700 break; 701 case "--uid": 702 showUid = true; 703 uid = Integer.parseInt(getNextArgRequired()); 704 break; 705 default: 706 pw.println("Error: Unknown option: " + opt); 707 return -1; 708 } 709 } 710 } catch (RuntimeException ex) { 711 pw.println("Error: " + ex.toString()); 712 return -1; 713 } 714 715 final String filter = getNextArg(); 716 717 @SuppressWarnings("unchecked") 718 final ParceledListSlice<PackageInfo> slice = 719 mInterface.getInstalledPackages(getFlags, userId); 720 final List<PackageInfo> packages = slice.getList(); 721 722 final int count = packages.size(); 723 for (int p = 0; p < count; p++) { 724 final PackageInfo info = packages.get(p); 725 if (filter != null && !info.packageName.contains(filter)) { 726 continue; 727 } 728 final boolean isApex = info.isApex; 729 if (uid != -1 && !isApex && info.applicationInfo.uid != uid) { 730 continue; 731 } 732 733 final boolean isSystem = !isApex && 734 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; 735 final boolean isEnabled = !isApex && info.applicationInfo.enabled; 736 if ((!listDisabled || !isEnabled) && 737 (!listEnabled || isEnabled) && 738 (!listSystem || isSystem) && 739 (!listThirdParty || !isSystem) && 740 (!listApexOnly || isApex)) { 741 pw.print("package:"); 742 if (showSourceDir) { 743 pw.print(info.applicationInfo.sourceDir); 744 pw.print("="); 745 } 746 pw.print(info.packageName); 747 if (showVersionCode) { 748 pw.print(" versionCode:"); 749 if (info.applicationInfo != null) { 750 pw.print(info.applicationInfo.longVersionCode); 751 } else { 752 pw.print(info.getLongVersionCode()); 753 } 754 } 755 if (listInstaller) { 756 pw.print(" installer="); 757 pw.print(mInterface.getInstallerPackageName(info.packageName)); 758 } 759 if (showUid && !isApex) { 760 pw.print(" uid:"); 761 pw.print(info.applicationInfo.uid); 762 } 763 pw.println(); 764 } 765 } 766 return 0; 767 } 768 runListPermissionGroups()769 private int runListPermissionGroups() throws RemoteException { 770 final PrintWriter pw = getOutPrintWriter(); 771 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList(); 772 773 final int count = pgs.size(); 774 for (int p = 0; p < count ; p++) { 775 final PermissionGroupInfo pgi = pgs.get(p); 776 pw.print("permission group:"); 777 pw.println(pgi.name); 778 } 779 return 0; 780 } 781 runListPermissions()782 private int runListPermissions() throws RemoteException { 783 final PrintWriter pw = getOutPrintWriter(); 784 boolean labels = false; 785 boolean groups = false; 786 boolean userOnly = false; 787 boolean summary = false; 788 boolean dangerousOnly = false; 789 String opt; 790 while ((opt = getNextOption()) != null) { 791 switch (opt) { 792 case "-d": 793 dangerousOnly = true; 794 break; 795 case "-f": 796 labels = true; 797 break; 798 case "-g": 799 groups = true; 800 break; 801 case "-s": 802 groups = true; 803 labels = true; 804 summary = true; 805 break; 806 case "-u": 807 userOnly = true; 808 break; 809 default: 810 pw.println("Error: Unknown option: " + opt); 811 return 1; 812 } 813 } 814 815 final ArrayList<String> groupList = new ArrayList<String>(); 816 if (groups) { 817 final List<PermissionGroupInfo> infos = 818 mInterface.getAllPermissionGroups(0 /*flags*/).getList(); 819 final int count = infos.size(); 820 for (int i = 0; i < count; i++) { 821 groupList.add(infos.get(i).name); 822 } 823 groupList.add(null); 824 } else { 825 final String grp = getNextArg(); 826 groupList.add(grp); 827 } 828 829 if (dangerousOnly) { 830 pw.println("Dangerous Permissions:"); 831 pw.println(""); 832 doListPermissions(groupList, groups, labels, summary, 833 PermissionInfo.PROTECTION_DANGEROUS, 834 PermissionInfo.PROTECTION_DANGEROUS); 835 if (userOnly) { 836 pw.println("Normal Permissions:"); 837 pw.println(""); 838 doListPermissions(groupList, groups, labels, summary, 839 PermissionInfo.PROTECTION_NORMAL, 840 PermissionInfo.PROTECTION_NORMAL); 841 } 842 } else if (userOnly) { 843 pw.println("Dangerous and Normal Permissions:"); 844 pw.println(""); 845 doListPermissions(groupList, groups, labels, summary, 846 PermissionInfo.PROTECTION_NORMAL, 847 PermissionInfo.PROTECTION_DANGEROUS); 848 } else { 849 pw.println("All Permissions:"); 850 pw.println(""); 851 doListPermissions(groupList, groups, labels, summary, 852 -10000, 10000); 853 } 854 return 0; 855 } 856 857 private static class SessionDump { 858 boolean onlyParent; // Show parent sessions only 859 boolean onlyReady; // Show only staged sessions that are in ready state 860 boolean onlySessionId; // Show sessionId only 861 } 862 863 // Returns true if the provided flag is a session flag and given SessionDump was updated setSessionFlag(String flag, SessionDump sessionDump)864 private boolean setSessionFlag(String flag, SessionDump sessionDump) { 865 switch (flag) { 866 case "--only-parent": 867 sessionDump.onlyParent = true; 868 break; 869 case "--only-ready": 870 sessionDump.onlyReady = true; 871 break; 872 case "--only-sessionid": 873 sessionDump.onlySessionId = true; 874 break; 875 default: 876 return false; 877 } 878 return true; 879 } 880 runListStagedSessions()881 private int runListStagedSessions() { 882 final IndentingPrintWriter pw = new IndentingPrintWriter( 883 getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120); 884 885 SessionDump sessionDump = new SessionDump(); 886 String opt; 887 while ((opt = getNextOption()) != null) { 888 if (!setSessionFlag(opt, sessionDump)) { 889 pw.println("Error: Unknown option: " + opt); 890 return -1; 891 } 892 } 893 894 try { 895 List<SessionInfo> stagedSessions = 896 mInterface.getPackageInstaller().getStagedSessions().getList(); 897 printSessionList(pw, stagedSessions, sessionDump); 898 } catch (RemoteException e) { 899 pw.println("Failure [" 900 + e.getClass().getName() + " - " 901 + e.getMessage() + "]"); 902 return -1; 903 } 904 return 1; 905 } 906 printSessionList(IndentingPrintWriter pw, List<SessionInfo> stagedSessions, SessionDump sessionDump)907 private void printSessionList(IndentingPrintWriter pw, List<SessionInfo> stagedSessions, 908 SessionDump sessionDump) { 909 final SparseArray<SessionInfo> sessionById = new SparseArray<>(stagedSessions.size()); 910 for (SessionInfo session : stagedSessions) { 911 sessionById.put(session.getSessionId(), session); 912 } 913 for (SessionInfo session: stagedSessions) { 914 if (sessionDump.onlyReady && !session.isStagedSessionReady()) { 915 continue; 916 } 917 if (session.getParentSessionId() != SessionInfo.INVALID_ID) { 918 continue; 919 } 920 printSession(pw, session, sessionDump); 921 if (session.isMultiPackage() && !sessionDump.onlyParent) { 922 pw.increaseIndent(); 923 final int[] childIds = session.getChildSessionIds(); 924 for (int i = 0; i < childIds.length; i++) { 925 final SessionInfo childSession = sessionById.get(childIds[i]); 926 if (childSession == null) { 927 if (sessionDump.onlySessionId) { 928 pw.println(childIds[i]); 929 } else { 930 pw.println("sessionId = " + childIds[i] + "; not found"); 931 } 932 } else { 933 printSession(pw, childSession, sessionDump); 934 } 935 } 936 pw.decreaseIndent(); 937 } 938 } 939 } 940 printSession(PrintWriter pw, SessionInfo session, SessionDump sessionDump)941 private static void printSession(PrintWriter pw, SessionInfo session, SessionDump sessionDump) { 942 if (sessionDump.onlySessionId) { 943 pw.println(session.getSessionId()); 944 return; 945 } 946 pw.println("sessionId = " + session.getSessionId() 947 + "; appPackageName = " + session.getAppPackageName() 948 + "; isStaged = " + session.isStaged() 949 + "; isReady = " + session.isStagedSessionReady() 950 + "; isApplied = " + session.isStagedSessionApplied() 951 + "; isFailed = " + session.isStagedSessionFailed() + ";"); 952 } 953 parseIntentAndUser()954 private Intent parseIntentAndUser() throws URISyntaxException { 955 mTargetUser = UserHandle.USER_CURRENT; 956 mBrief = false; 957 mComponents = false; 958 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 959 @Override 960 public boolean handleOption(String opt, ShellCommand cmd) { 961 if ("--user".equals(opt)) { 962 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired()); 963 return true; 964 } else if ("--brief".equals(opt)) { 965 mBrief = true; 966 return true; 967 } else if ("--components".equals(opt)) { 968 mComponents = true; 969 return true; 970 } else if ("--query-flags".equals(opt)) { 971 mQueryFlags = Integer.decode(cmd.getNextArgRequired()); 972 return true; 973 } 974 return false; 975 } 976 }); 977 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 978 Binder.getCallingUid(), mTargetUser, false, false, null, null); 979 return intent; 980 } 981 printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri, boolean brief, boolean components)982 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri, 983 boolean brief, boolean components) { 984 if (brief || components) { 985 final ComponentName comp; 986 if (ri.activityInfo != null) { 987 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); 988 } else if (ri.serviceInfo != null) { 989 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name); 990 } else if (ri.providerInfo != null) { 991 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name); 992 } else { 993 comp = null; 994 } 995 if (comp != null) { 996 if (!components) { 997 pr.println(prefix + "priority=" + ri.priority 998 + " preferredOrder=" + ri.preferredOrder 999 + " match=0x" + Integer.toHexString(ri.match) 1000 + " specificIndex=" + ri.specificIndex 1001 + " isDefault=" + ri.isDefault); 1002 } 1003 pr.println(prefix + comp.flattenToShortString()); 1004 return; 1005 } 1006 } 1007 ri.dump(pr, prefix); 1008 } 1009 runResolveActivity()1010 private int runResolveActivity() { 1011 Intent intent; 1012 try { 1013 intent = parseIntentAndUser(); 1014 } catch (URISyntaxException e) { 1015 throw new RuntimeException(e.getMessage(), e); 1016 } 1017 try { 1018 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags, 1019 mTargetUser); 1020 PrintWriter pw = getOutPrintWriter(); 1021 if (ri == null) { 1022 pw.println("No activity found"); 1023 } else { 1024 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1025 printResolveInfo(pr, "", ri, mBrief, mComponents); 1026 } 1027 } catch (RemoteException e) { 1028 throw new RuntimeException("Failed calling service", e); 1029 } 1030 return 0; 1031 } 1032 runQueryIntentActivities()1033 private int runQueryIntentActivities() { 1034 Intent intent; 1035 try { 1036 intent = parseIntentAndUser(); 1037 } catch (URISyntaxException e) { 1038 throw new RuntimeException(e.getMessage(), e); 1039 } 1040 try { 1041 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 1042 mQueryFlags, mTargetUser).getList(); 1043 PrintWriter pw = getOutPrintWriter(); 1044 if (result == null || result.size() <= 0) { 1045 pw.println("No activities found"); 1046 } else { 1047 if (!mComponents) { 1048 pw.print(result.size()); pw.println(" activities found:"); 1049 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1050 for (int i = 0; i < result.size(); i++) { 1051 pw.print(" Activity #"); pw.print(i); pw.println(":"); 1052 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 1053 } 1054 } else { 1055 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1056 for (int i = 0; i < result.size(); i++) { 1057 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 1058 } 1059 } 1060 } 1061 } catch (RemoteException e) { 1062 throw new RuntimeException("Failed calling service", e); 1063 } 1064 return 0; 1065 } 1066 runQueryIntentServices()1067 private int runQueryIntentServices() { 1068 Intent intent; 1069 try { 1070 intent = parseIntentAndUser(); 1071 } catch (URISyntaxException e) { 1072 throw new RuntimeException(e.getMessage(), e); 1073 } 1074 try { 1075 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 1076 mQueryFlags, mTargetUser).getList(); 1077 PrintWriter pw = getOutPrintWriter(); 1078 if (result == null || result.size() <= 0) { 1079 pw.println("No services found"); 1080 } else { 1081 if (!mComponents) { 1082 pw.print(result.size()); pw.println(" services found:"); 1083 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1084 for (int i = 0; i < result.size(); i++) { 1085 pw.print(" Service #"); pw.print(i); pw.println(":"); 1086 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 1087 } 1088 } else { 1089 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1090 for (int i = 0; i < result.size(); i++) { 1091 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 1092 } 1093 } 1094 } 1095 } catch (RemoteException e) { 1096 throw new RuntimeException("Failed calling service", e); 1097 } 1098 return 0; 1099 } 1100 runQueryIntentReceivers()1101 private int runQueryIntentReceivers() { 1102 Intent intent; 1103 try { 1104 intent = parseIntentAndUser(); 1105 } catch (URISyntaxException e) { 1106 throw new RuntimeException(e.getMessage(), e); 1107 } 1108 try { 1109 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 1110 mQueryFlags, mTargetUser).getList(); 1111 PrintWriter pw = getOutPrintWriter(); 1112 if (result == null || result.size() <= 0) { 1113 pw.println("No receivers found"); 1114 } else { 1115 if (!mComponents) { 1116 pw.print(result.size()); pw.println(" receivers found:"); 1117 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1118 for (int i = 0; i < result.size(); i++) { 1119 pw.print(" Receiver #"); pw.print(i); pw.println(":"); 1120 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents); 1121 } 1122 } else { 1123 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 1124 for (int i = 0; i < result.size(); i++) { 1125 printResolveInfo(pr, "", result.get(i), mBrief, mComponents); 1126 } 1127 } 1128 } 1129 } catch (RemoteException e) { 1130 throw new RuntimeException("Failed calling service", e); 1131 } 1132 return 0; 1133 } 1134 runInstall()1135 private int runInstall() throws RemoteException { 1136 final PrintWriter pw = getOutPrintWriter(); 1137 final InstallParams params = makeInstallParams(); 1138 final String inPath = getNextArg(); 1139 1140 setParamsSize(params, inPath); 1141 final int sessionId = doCreateSession(params.sessionParams, 1142 params.installerPackageName, params.userId); 1143 boolean abandonSession = true; 1144 try { 1145 if (inPath == null && params.sessionParams.sizeBytes == -1) { 1146 pw.println("Error: must either specify a package size or an APK file"); 1147 return 1; 1148 } 1149 final boolean isApex = 1150 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0; 1151 String splitName = "base." + (isApex ? "apex" : "apk"); 1152 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName, 1153 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 1154 return 1; 1155 } 1156 if (doCommitSession(sessionId, false /*logSuccess*/) 1157 != PackageInstaller.STATUS_SUCCESS) { 1158 return 1; 1159 } 1160 abandonSession = false; 1161 1162 if (!params.sessionParams.isStaged || !params.mWaitForStagedSessionReady) { 1163 pw.println("Success"); 1164 return 0; 1165 } 1166 return doWaitForStagedSessionRead(sessionId, params.timeoutMs, pw); 1167 } finally { 1168 if (abandonSession) { 1169 try { 1170 doAbandonSession(sessionId, false /*logSuccess*/); 1171 } catch (Exception ignore) { 1172 } 1173 } 1174 } 1175 } 1176 doWaitForStagedSessionRead(int sessionId, long timeoutMs, PrintWriter pw)1177 private int doWaitForStagedSessionRead(int sessionId, long timeoutMs, PrintWriter pw) 1178 throws RemoteException { 1179 if (timeoutMs <= 0) { 1180 timeoutMs = DEFAULT_WAIT_MS; 1181 } 1182 PackageInstaller.SessionInfo si = mInterface.getPackageInstaller() 1183 .getSessionInfo(sessionId); 1184 if (si == null) { 1185 pw.println("Failure [Unknown session " + sessionId + "]"); 1186 return 1; 1187 } 1188 if (!si.isStaged()) { 1189 pw.println("Failure [Session " + sessionId + " is not a staged session]"); 1190 return 1; 1191 } 1192 long currentTime = System.currentTimeMillis(); 1193 long endTime = currentTime + timeoutMs; 1194 // Using a loop instead of BroadcastReceiver since we can receive session update 1195 // broadcast only if packageInstallerName is "android". We can't always force 1196 // "android" as packageIntallerName, e.g, rollback auto implies 1197 // "-i com.android.shell". 1198 while (currentTime < endTime) { 1199 if (si != null && (si.isStagedSessionReady() || si.isStagedSessionFailed())) { 1200 break; 1201 } 1202 SystemClock.sleep(Math.min(endTime - currentTime, 100)); 1203 currentTime = System.currentTimeMillis(); 1204 si = mInterface.getPackageInstaller().getSessionInfo(sessionId); 1205 } 1206 if (si == null) { 1207 pw.println("Failure [failed to retrieve SessionInfo]"); 1208 return 1; 1209 } 1210 if (!si.isStagedSessionReady() && !si.isStagedSessionFailed()) { 1211 pw.println("Failure [timed out after " + timeoutMs + " ms]"); 1212 return 1; 1213 } 1214 if (!si.isStagedSessionReady()) { 1215 pw.println("Error [" + si.getStagedSessionErrorCode() + "] [" 1216 + si.getStagedSessionErrorMessage() + "]"); 1217 return 1; 1218 } 1219 pw.println("Success. Reboot device to apply staged session"); 1220 return 0; 1221 } 1222 runInstallAbandon()1223 private int runInstallAbandon() throws RemoteException { 1224 final int sessionId = Integer.parseInt(getNextArg()); 1225 return doAbandonSession(sessionId, true /*logSuccess*/); 1226 } 1227 runInstallCommit()1228 private int runInstallCommit() throws RemoteException { 1229 final PrintWriter pw = getOutPrintWriter(); 1230 String opt; 1231 boolean waitForStagedSessionReady = true; 1232 long timeoutMs = -1; 1233 while ((opt = getNextOption()) != null) { 1234 switch (opt) { 1235 case "--wait": 1236 waitForStagedSessionReady = true; 1237 // If there is only one remaining argument, then it represents the sessionId, we 1238 // shouldn't try to parse it as timeoutMs. 1239 if (getRemainingArgsCount() > 1) { 1240 try { 1241 timeoutMs = Long.parseLong(peekNextArg()); 1242 getNextArg(); 1243 } catch (NumberFormatException ignore) { 1244 } 1245 } 1246 break; 1247 case "--no-wait": 1248 waitForStagedSessionReady = false; 1249 break; 1250 } 1251 } 1252 final int sessionId = Integer.parseInt(getNextArg()); 1253 if (doCommitSession(sessionId, false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 1254 return 1; 1255 } 1256 final PackageInstaller.SessionInfo si = mInterface.getPackageInstaller() 1257 .getSessionInfo(sessionId); 1258 if (si == null || !si.isStaged() || !waitForStagedSessionReady) { 1259 pw.println("Success"); 1260 return 0; 1261 } 1262 return doWaitForStagedSessionRead(sessionId, timeoutMs, pw); 1263 } 1264 runInstallCreate()1265 private int runInstallCreate() throws RemoteException { 1266 final PrintWriter pw = getOutPrintWriter(); 1267 final InstallParams installParams = makeInstallParams(); 1268 final int sessionId = doCreateSession(installParams.sessionParams, 1269 installParams.installerPackageName, installParams.userId); 1270 1271 // NOTE: adb depends on parsing this string 1272 pw.println("Success: created install session [" + sessionId + "]"); 1273 return 0; 1274 } 1275 runInstallWrite()1276 private int runInstallWrite() throws RemoteException { 1277 long sizeBytes = -1; 1278 1279 String opt; 1280 while ((opt = getNextOption()) != null) { 1281 if (opt.equals("-S")) { 1282 sizeBytes = Long.parseLong(getNextArg()); 1283 } else { 1284 throw new IllegalArgumentException("Unknown option: " + opt); 1285 } 1286 } 1287 1288 final int sessionId = Integer.parseInt(getNextArg()); 1289 final String splitName = getNextArg(); 1290 final String path = getNextArg(); 1291 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); 1292 } 1293 runInstallAddSession()1294 private int runInstallAddSession() throws RemoteException { 1295 final PrintWriter pw = getOutPrintWriter(); 1296 final int parentSessionId = Integer.parseInt(getNextArg()); 1297 1298 List<Integer> otherSessionIds = new ArrayList<>(); 1299 String opt; 1300 while ((opt = getNextArg()) != null) { 1301 otherSessionIds.add(Integer.parseInt(opt)); 1302 } 1303 if (otherSessionIds.size() == 0) { 1304 pw.println("Error: At least two sessions are required."); 1305 return 1; 1306 } 1307 return doInstallAddSession(parentSessionId, ArrayUtils.convertToIntArray(otherSessionIds), 1308 true /*logSuccess*/); 1309 } 1310 runInstallRemove()1311 private int runInstallRemove() throws RemoteException { 1312 final PrintWriter pw = getOutPrintWriter(); 1313 1314 final int sessionId = Integer.parseInt(getNextArg()); 1315 1316 final String splitName = getNextArg(); 1317 if (splitName == null) { 1318 pw.println("Error: split name not specified"); 1319 return 1; 1320 } 1321 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/); 1322 } 1323 runInstallExisting()1324 private int runInstallExisting() throws RemoteException { 1325 final PrintWriter pw = getOutPrintWriter(); 1326 int userId = UserHandle.USER_SYSTEM; 1327 int installFlags = PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS; 1328 String opt; 1329 boolean waitTillComplete = false; 1330 while ((opt = getNextOption()) != null) { 1331 switch (opt) { 1332 case "--user": 1333 userId = UserHandle.parseUserArg(getNextArgRequired()); 1334 break; 1335 case "--ephemeral": 1336 case "--instant": 1337 installFlags |= PackageManager.INSTALL_INSTANT_APP; 1338 installFlags &= ~PackageManager.INSTALL_FULL_APP; 1339 break; 1340 case "--full": 1341 installFlags &= ~PackageManager.INSTALL_INSTANT_APP; 1342 installFlags |= PackageManager.INSTALL_FULL_APP; 1343 break; 1344 case "--wait": 1345 waitTillComplete = true; 1346 break; 1347 case "--restrict-permissions": 1348 installFlags &= ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS; 1349 break; 1350 default: 1351 pw.println("Error: Unknown option: " + opt); 1352 return 1; 1353 } 1354 } 1355 1356 final String packageName = getNextArg(); 1357 if (packageName == null) { 1358 pw.println("Error: package name not specified"); 1359 return 1; 1360 } 1361 1362 int installReason = PackageManager.INSTALL_REASON_UNKNOWN; 1363 try { 1364 if (waitTillComplete) { 1365 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1366 final IPackageInstaller installer = mInterface.getPackageInstaller(); 1367 pw.println("Installing package " + packageName + " for user: " + userId); 1368 installer.installExistingPackage(packageName, installFlags, installReason, 1369 receiver.getIntentSender(), userId, null); 1370 final Intent result = receiver.getResult(); 1371 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1372 PackageInstaller.STATUS_FAILURE); 1373 pw.println("Received intent for package install"); 1374 return status == PackageInstaller.STATUS_SUCCESS ? 0 : 1; 1375 } 1376 1377 final int res = mInterface.installExistingPackageAsUser(packageName, userId, 1378 installFlags, installReason, null); 1379 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) { 1380 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1381 } 1382 pw.println("Package " + packageName + " installed for user: " + userId); 1383 return 0; 1384 } catch (RemoteException | NameNotFoundException e) { 1385 pw.println(e.toString()); 1386 return 1; 1387 } 1388 } 1389 runSetInstallLocation()1390 private int runSetInstallLocation() throws RemoteException { 1391 int loc; 1392 1393 String arg = getNextArg(); 1394 if (arg == null) { 1395 getErrPrintWriter().println("Error: no install location specified."); 1396 return 1; 1397 } 1398 try { 1399 loc = Integer.parseInt(arg); 1400 } catch (NumberFormatException e) { 1401 getErrPrintWriter().println("Error: install location has to be a number."); 1402 return 1; 1403 } 1404 if (!mInterface.setInstallLocation(loc)) { 1405 getErrPrintWriter().println("Error: install location has to be a number."); 1406 return 1; 1407 } 1408 return 0; 1409 } 1410 runGetInstallLocation()1411 private int runGetInstallLocation() throws RemoteException { 1412 int loc = mInterface.getInstallLocation(); 1413 String locStr = "invalid"; 1414 if (loc == PackageHelper.APP_INSTALL_AUTO) { 1415 locStr = "auto"; 1416 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) { 1417 locStr = "internal"; 1418 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) { 1419 locStr = "external"; 1420 } 1421 getOutPrintWriter().println(loc + "[" + locStr + "]"); 1422 return 0; 1423 } 1424 runMovePackage()1425 public int runMovePackage() throws RemoteException { 1426 final String packageName = getNextArg(); 1427 if (packageName == null) { 1428 getErrPrintWriter().println("Error: package name not specified"); 1429 return 1; 1430 } 1431 String volumeUuid = getNextArg(); 1432 if ("internal".equals(volumeUuid)) { 1433 volumeUuid = null; 1434 } 1435 1436 final int moveId = mInterface.movePackage(packageName, volumeUuid); 1437 1438 int status = mInterface.getMoveStatus(moveId); 1439 while (!PackageManager.isMoveStatusFinished(status)) { 1440 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1441 status = mInterface.getMoveStatus(moveId); 1442 } 1443 1444 if (status == PackageManager.MOVE_SUCCEEDED) { 1445 getOutPrintWriter().println("Success"); 1446 return 0; 1447 } else { 1448 getErrPrintWriter().println("Failure [" + status + "]"); 1449 return 1; 1450 } 1451 } 1452 runMovePrimaryStorage()1453 public int runMovePrimaryStorage() throws RemoteException { 1454 String volumeUuid = getNextArg(); 1455 if ("internal".equals(volumeUuid)) { 1456 volumeUuid = null; 1457 } 1458 1459 final int moveId = mInterface.movePrimaryStorage(volumeUuid); 1460 1461 int status = mInterface.getMoveStatus(moveId); 1462 while (!PackageManager.isMoveStatusFinished(status)) { 1463 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1464 status = mInterface.getMoveStatus(moveId); 1465 } 1466 1467 if (status == PackageManager.MOVE_SUCCEEDED) { 1468 getOutPrintWriter().println("Success"); 1469 return 0; 1470 } else { 1471 getErrPrintWriter().println("Failure [" + status + "]"); 1472 return 1; 1473 } 1474 } 1475 runCompile()1476 private int runCompile() throws RemoteException { 1477 final PrintWriter pw = getOutPrintWriter(); 1478 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false); 1479 boolean forceCompilation = false; 1480 boolean allPackages = false; 1481 boolean clearProfileData = false; 1482 String compilerFilter = null; 1483 String compilationReason = null; 1484 String checkProfilesRaw = null; 1485 boolean secondaryDex = false; 1486 String split = null; 1487 boolean compileLayouts = false; 1488 1489 String opt; 1490 while ((opt = getNextOption()) != null) { 1491 switch (opt) { 1492 case "-a": 1493 allPackages = true; 1494 break; 1495 case "-c": 1496 clearProfileData = true; 1497 break; 1498 case "-f": 1499 forceCompilation = true; 1500 break; 1501 case "-m": 1502 compilerFilter = getNextArgRequired(); 1503 break; 1504 case "-r": 1505 compilationReason = getNextArgRequired(); 1506 break; 1507 case "--compile-layouts": 1508 compileLayouts = true; 1509 break; 1510 case "--check-prof": 1511 checkProfilesRaw = getNextArgRequired(); 1512 break; 1513 case "--reset": 1514 forceCompilation = true; 1515 clearProfileData = true; 1516 compilationReason = "install"; 1517 break; 1518 case "--secondary-dex": 1519 secondaryDex = true; 1520 break; 1521 case "--split": 1522 split = getNextArgRequired(); 1523 break; 1524 default: 1525 pw.println("Error: Unknown option: " + opt); 1526 return 1; 1527 } 1528 } 1529 1530 if (checkProfilesRaw != null) { 1531 if ("true".equals(checkProfilesRaw)) { 1532 checkProfiles = true; 1533 } else if ("false".equals(checkProfilesRaw)) { 1534 checkProfiles = false; 1535 } else { 1536 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\"."); 1537 return 1; 1538 } 1539 } 1540 1541 final boolean compilerFilterGiven = compilerFilter != null; 1542 final boolean compilationReasonGiven = compilationReason != null; 1543 // Make sure exactly one of -m, -r, or --compile-layouts is given. 1544 if ((!compilerFilterGiven && !compilationReasonGiven && !compileLayouts) 1545 || (!compilerFilterGiven && compilationReasonGiven && compileLayouts) 1546 || (compilerFilterGiven && !compilationReasonGiven && compileLayouts) 1547 || (compilerFilterGiven && compilationReasonGiven && !compileLayouts) 1548 || (compilerFilterGiven && compilationReasonGiven && compileLayouts)) { 1549 pw.println("Must specify exactly one of compilation filter (\"-m\"), compilation " + 1550 "reason (\"-r\"), or compile layouts (\"--compile-layouts\")"); 1551 return 1; 1552 } 1553 1554 if (allPackages && split != null) { 1555 pw.println("-a cannot be specified together with --split"); 1556 return 1; 1557 } 1558 1559 if (secondaryDex && split != null) { 1560 pw.println("--secondary-dex cannot be specified together with --split"); 1561 return 1; 1562 } 1563 1564 String targetCompilerFilter = null; 1565 if (compilerFilterGiven) { 1566 if (!DexFile.isValidCompilerFilter(compilerFilter)) { 1567 pw.println("Error: \"" + compilerFilter + 1568 "\" is not a valid compilation filter."); 1569 return 1; 1570 } 1571 targetCompilerFilter = compilerFilter; 1572 } 1573 if (compilationReasonGiven) { 1574 int reason = -1; 1575 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 1576 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals( 1577 compilationReason)) { 1578 reason = i; 1579 break; 1580 } 1581 } 1582 if (reason == -1) { 1583 pw.println("Error: Unknown compilation reason: " + compilationReason); 1584 return 1; 1585 } 1586 targetCompilerFilter = 1587 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason); 1588 } 1589 1590 1591 List<String> packageNames = null; 1592 if (allPackages) { 1593 packageNames = mInterface.getAllPackages(); 1594 } else { 1595 String packageName = getNextArg(); 1596 if (packageName == null) { 1597 pw.println("Error: package name not specified"); 1598 return 1; 1599 } 1600 packageNames = Collections.singletonList(packageName); 1601 } 1602 1603 List<String> failedPackages = new ArrayList<>(); 1604 int index = 0; 1605 for (String packageName : packageNames) { 1606 if (clearProfileData) { 1607 mInterface.clearApplicationProfileData(packageName); 1608 } 1609 1610 if (allPackages) { 1611 pw.println(++index + "/" + packageNames.size() + ": " + packageName); 1612 pw.flush(); 1613 } 1614 1615 boolean result = true; 1616 if (compileLayouts) { 1617 PackageManagerInternal internal = LocalServices.getService( 1618 PackageManagerInternal.class); 1619 result = internal.compileLayouts(packageName); 1620 } else { 1621 result = secondaryDex 1622 ? mInterface.performDexOptSecondary(packageName, 1623 targetCompilerFilter, forceCompilation) 1624 : mInterface.performDexOptMode(packageName, 1625 checkProfiles, targetCompilerFilter, forceCompilation, 1626 true /* bootComplete */, split); 1627 } 1628 if (!result) { 1629 failedPackages.add(packageName); 1630 } 1631 } 1632 1633 if (failedPackages.isEmpty()) { 1634 pw.println("Success"); 1635 return 0; 1636 } else if (failedPackages.size() == 1) { 1637 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled"); 1638 return 1; 1639 } else { 1640 pw.print("Failure: the following packages could not be compiled: "); 1641 boolean is_first = true; 1642 for (String packageName : failedPackages) { 1643 if (is_first) { 1644 is_first = false; 1645 } else { 1646 pw.print(", "); 1647 } 1648 pw.print(packageName); 1649 } 1650 pw.println(); 1651 return 1; 1652 } 1653 } 1654 runreconcileSecondaryDexFiles()1655 private int runreconcileSecondaryDexFiles() throws RemoteException { 1656 String packageName = getNextArg(); 1657 mInterface.reconcileSecondaryDexFiles(packageName); 1658 return 0; 1659 } 1660 runForceDexOpt()1661 public int runForceDexOpt() throws RemoteException { 1662 mInterface.forceDexOpt(getNextArgRequired()); 1663 return 0; 1664 } 1665 runDexoptJob()1666 private int runDexoptJob() throws RemoteException { 1667 String arg; 1668 List<String> packageNames = new ArrayList<>(); 1669 while ((arg = getNextArg()) != null) { 1670 packageNames.add(arg); 1671 } 1672 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null : 1673 packageNames); 1674 getOutPrintWriter().println(result ? "Success" : "Failure"); 1675 return result ? 0 : -1; 1676 } 1677 runDumpProfiles()1678 private int runDumpProfiles() throws RemoteException { 1679 String packageName = getNextArg(); 1680 mInterface.dumpProfiles(packageName); 1681 return 0; 1682 } 1683 runSnapshotProfile()1684 private int runSnapshotProfile() throws RemoteException { 1685 PrintWriter pw = getOutPrintWriter(); 1686 1687 // Parse the arguments 1688 final String packageName = getNextArg(); 1689 final boolean isBootImage = "android".equals(packageName); 1690 1691 String codePath = null; 1692 String opt; 1693 while ((opt = getNextArg()) != null) { 1694 switch (opt) { 1695 case "--code-path": 1696 if (isBootImage) { 1697 pw.write("--code-path cannot be used for the boot image."); 1698 return -1; 1699 } 1700 codePath = getNextArg(); 1701 break; 1702 default: 1703 pw.write("Unknown arg: " + opt); 1704 return -1; 1705 } 1706 } 1707 1708 // If no code path was explicitly requested, select the base code path. 1709 String baseCodePath = null; 1710 if (!isBootImage) { 1711 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0, 1712 /* userId */0); 1713 if (packageInfo == null) { 1714 pw.write("Package not found " + packageName); 1715 return -1; 1716 } 1717 baseCodePath = packageInfo.applicationInfo.getBaseCodePath(); 1718 if (codePath == null) { 1719 codePath = baseCodePath; 1720 } 1721 } 1722 1723 // Create the profile snapshot. 1724 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback(); 1725 // The calling package is needed to debug permission access. 1726 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID) 1727 ? "root" : "com.android.shell"; 1728 final int profileType = isBootImage 1729 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS; 1730 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) { 1731 pw.println("Error: Runtime profiling is not enabled"); 1732 return -1; 1733 } 1734 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName, 1735 codePath, callback, callingPackage); 1736 if (!callback.waitTillDone()) { 1737 pw.println("Error: callback not called"); 1738 return callback.mErrCode; 1739 } 1740 1741 // Copy the snapshot profile to the output profile file. 1742 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) { 1743 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath) 1744 ? "" : ("-" + new File(codePath).getName()); 1745 final String outputProfilePath = 1746 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof"; 1747 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) { 1748 Streams.copy(inStream, outStream); 1749 } 1750 // Give read permissions to the other group. 1751 Os.chmod(outputProfilePath, /*mode*/ 0644 ); 1752 } catch (IOException | ErrnoException e) { 1753 pw.println("Error when reading the profile fd: " + e.getMessage()); 1754 e.printStackTrace(pw); 1755 return -1; 1756 } 1757 return 0; 1758 } 1759 1760 private static class SnapshotRuntimeProfileCallback 1761 extends ISnapshotRuntimeProfileCallback.Stub { 1762 private boolean mSuccess = false; 1763 private int mErrCode = -1; 1764 private ParcelFileDescriptor mProfileReadFd = null; 1765 private CountDownLatch mDoneSignal = new CountDownLatch(1); 1766 1767 @Override onSuccess(ParcelFileDescriptor profileReadFd)1768 public void onSuccess(ParcelFileDescriptor profileReadFd) { 1769 mSuccess = true; 1770 try { 1771 // We need to dup the descriptor. We are in the same process as system server 1772 // and we will be receiving the same object (which will be closed on the 1773 // server side). 1774 mProfileReadFd = profileReadFd.dup(); 1775 } catch (IOException e) { 1776 e.printStackTrace(); 1777 } 1778 mDoneSignal.countDown(); 1779 } 1780 1781 @Override onError(int errCode)1782 public void onError(int errCode) { 1783 mSuccess = false; 1784 mErrCode = errCode; 1785 mDoneSignal.countDown(); 1786 } 1787 waitTillDone()1788 boolean waitTillDone() { 1789 boolean done = false; 1790 try { 1791 // The time-out is an arbitrary large value. Since this is a local call the result 1792 // will come very fast. 1793 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS); 1794 } catch (InterruptedException ignored) { 1795 } 1796 return done && mSuccess; 1797 } 1798 } 1799 runUninstall()1800 private int runUninstall() throws RemoteException { 1801 final PrintWriter pw = getOutPrintWriter(); 1802 int flags = 0; 1803 int userId = UserHandle.USER_ALL; 1804 long versionCode = PackageManager.VERSION_CODE_HIGHEST; 1805 1806 String opt; 1807 while ((opt = getNextOption()) != null) { 1808 switch (opt) { 1809 case "-k": 1810 flags |= PackageManager.DELETE_KEEP_DATA; 1811 break; 1812 case "--user": 1813 userId = UserHandle.parseUserArg(getNextArgRequired()); 1814 break; 1815 case "--versionCode": 1816 versionCode = Long.parseLong(getNextArgRequired()); 1817 break; 1818 default: 1819 pw.println("Error: Unknown option: " + opt); 1820 return 1; 1821 } 1822 } 1823 1824 final String packageName = getNextArg(); 1825 if (packageName == null) { 1826 pw.println("Error: package name not specified"); 1827 return 1; 1828 } 1829 1830 // if a split is specified, just remove it and not the whole package 1831 final String splitName = getNextArg(); 1832 if (splitName != null) { 1833 return runRemoveSplit(packageName, splitName); 1834 } 1835 1836 userId = translateUserId(userId, true /*allowAll*/, "runUninstall"); 1837 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1838 PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class); 1839 1840 if (internal.isApexPackage(packageName)) { 1841 internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender()); 1842 } else { 1843 if (userId == UserHandle.USER_ALL) { 1844 userId = UserHandle.USER_SYSTEM; 1845 flags |= PackageManager.DELETE_ALL_USERS; 1846 } else { 1847 final PackageInfo info = mInterface.getPackageInfo(packageName, 1848 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId); 1849 if (info == null) { 1850 pw.println("Failure [not installed for " + userId + "]"); 1851 return 1; 1852 } 1853 final boolean isSystem = 1854 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 1855 // If we are being asked to delete a system app for just one 1856 // user set flag so it disables rather than reverting to system 1857 // version of the app. 1858 if (isSystem) { 1859 flags |= PackageManager.DELETE_SYSTEM_APP; 1860 } 1861 } 1862 1863 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName, 1864 versionCode), null /*callerPackageName*/, flags, 1865 receiver.getIntentSender(), userId); 1866 } 1867 1868 final Intent result = receiver.getResult(); 1869 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1870 PackageInstaller.STATUS_FAILURE); 1871 if (status == PackageInstaller.STATUS_SUCCESS) { 1872 pw.println("Success"); 1873 return 0; 1874 } else { 1875 pw.println("Failure [" 1876 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1877 return 1; 1878 } 1879 } 1880 runRemoveSplit(String packageName, String splitName)1881 private int runRemoveSplit(String packageName, String splitName) throws RemoteException { 1882 final PrintWriter pw = getOutPrintWriter(); 1883 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 1884 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1885 sessionParams.appPackageName = packageName; 1886 final int sessionId = 1887 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL); 1888 boolean abandonSession = true; 1889 try { 1890 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/) 1891 != PackageInstaller.STATUS_SUCCESS) { 1892 return 1; 1893 } 1894 if (doCommitSession(sessionId, false /*logSuccess*/) 1895 != PackageInstaller.STATUS_SUCCESS) { 1896 return 1; 1897 } 1898 abandonSession = false; 1899 pw.println("Success"); 1900 return 0; 1901 } finally { 1902 if (abandonSession) { 1903 try { 1904 doAbandonSession(sessionId, false /*logSuccess*/); 1905 } catch (Exception ignore) { 1906 } 1907 } 1908 } 1909 } 1910 1911 static class ClearDataObserver extends IPackageDataObserver.Stub { 1912 boolean finished; 1913 boolean result; 1914 1915 @Override onRemoveCompleted(String packageName, boolean succeeded)1916 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1917 synchronized (this) { 1918 finished = true; 1919 result = succeeded; 1920 notifyAll(); 1921 } 1922 } 1923 } 1924 runClear()1925 private int runClear() throws RemoteException { 1926 int userId = UserHandle.USER_SYSTEM; 1927 String option = getNextOption(); 1928 if (option != null && option.equals("--user")) { 1929 userId = UserHandle.parseUserArg(getNextArgRequired()); 1930 } 1931 1932 String pkg = getNextArg(); 1933 if (pkg == null) { 1934 getErrPrintWriter().println("Error: no package specified"); 1935 return 1; 1936 } 1937 1938 ClearDataObserver obs = new ClearDataObserver(); 1939 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId); 1940 synchronized (obs) { 1941 while (!obs.finished) { 1942 try { 1943 obs.wait(); 1944 } catch (InterruptedException e) { 1945 } 1946 } 1947 } 1948 1949 if (obs.result) { 1950 getOutPrintWriter().println("Success"); 1951 return 0; 1952 } else { 1953 getErrPrintWriter().println("Failed"); 1954 return 1; 1955 } 1956 } 1957 enabledSettingToString(int state)1958 private static String enabledSettingToString(int state) { 1959 switch (state) { 1960 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1961 return "default"; 1962 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1963 return "enabled"; 1964 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1965 return "disabled"; 1966 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1967 return "disabled-user"; 1968 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1969 return "disabled-until-used"; 1970 } 1971 return "unknown"; 1972 } 1973 runSetEnabledSetting(int state)1974 private int runSetEnabledSetting(int state) throws RemoteException { 1975 int userId = UserHandle.USER_SYSTEM; 1976 String option = getNextOption(); 1977 if (option != null && option.equals("--user")) { 1978 userId = UserHandle.parseUserArg(getNextArgRequired()); 1979 } 1980 1981 String pkg = getNextArg(); 1982 if (pkg == null) { 1983 getErrPrintWriter().println("Error: no package or component specified"); 1984 return 1; 1985 } 1986 ComponentName cn = ComponentName.unflattenFromString(pkg); 1987 if (cn == null) { 1988 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId, 1989 "shell:" + android.os.Process.myUid()); 1990 getOutPrintWriter().println("Package " + pkg + " new state: " 1991 + enabledSettingToString( 1992 mInterface.getApplicationEnabledSetting(pkg, userId))); 1993 return 0; 1994 } else { 1995 mInterface.setComponentEnabledSetting(cn, state, 0, userId); 1996 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: " 1997 + enabledSettingToString( 1998 mInterface.getComponentEnabledSetting(cn, userId))); 1999 return 0; 2000 } 2001 } 2002 runSetHiddenSetting(boolean state)2003 private int runSetHiddenSetting(boolean state) throws RemoteException { 2004 int userId = UserHandle.USER_SYSTEM; 2005 String option = getNextOption(); 2006 if (option != null && option.equals("--user")) { 2007 userId = UserHandle.parseUserArg(getNextArgRequired()); 2008 } 2009 2010 String pkg = getNextArg(); 2011 if (pkg == null) { 2012 getErrPrintWriter().println("Error: no package or component specified"); 2013 return 1; 2014 } 2015 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId); 2016 getOutPrintWriter().println("Package " + pkg + " new hidden state: " 2017 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId)); 2018 return 0; 2019 } 2020 runSuspend(boolean suspendedState)2021 private int runSuspend(boolean suspendedState) { 2022 final PrintWriter pw = getOutPrintWriter(); 2023 int userId = UserHandle.USER_SYSTEM; 2024 String dialogMessage = null; 2025 final PersistableBundle appExtras = new PersistableBundle(); 2026 final PersistableBundle launcherExtras = new PersistableBundle(); 2027 String opt; 2028 while ((opt = getNextOption()) != null) { 2029 switch (opt) { 2030 case "--user": 2031 userId = UserHandle.parseUserArg(getNextArgRequired()); 2032 break; 2033 case "--dialogMessage": 2034 dialogMessage = getNextArgRequired(); 2035 break; 2036 case "--ael": 2037 case "--aes": 2038 case "--aed": 2039 case "--lel": 2040 case "--les": 2041 case "--led": 2042 final String key = getNextArgRequired(); 2043 final String val = getNextArgRequired(); 2044 if (!suspendedState) { 2045 break; 2046 } 2047 final PersistableBundle bundleToInsert = 2048 opt.startsWith("--a") ? appExtras : launcherExtras; 2049 switch (opt.charAt(4)) { 2050 case 'l': 2051 bundleToInsert.putLong(key, Long.valueOf(val)); 2052 break; 2053 case 'd': 2054 bundleToInsert.putDouble(key, Double.valueOf(val)); 2055 break; 2056 case 's': 2057 bundleToInsert.putString(key, val); 2058 break; 2059 } 2060 break; 2061 default: 2062 pw.println("Error: Unknown option: " + opt); 2063 return 1; 2064 } 2065 } 2066 2067 final String packageName = getNextArg(); 2068 if (packageName == null) { 2069 pw.println("Error: package name not specified"); 2070 return 1; 2071 } 2072 final String callingPackage = 2073 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell"; 2074 2075 final SuspendDialogInfo info; 2076 if (!TextUtils.isEmpty(dialogMessage)) { 2077 info = new SuspendDialogInfo.Builder() 2078 .setMessage(dialogMessage) 2079 .build(); 2080 } else { 2081 info = null; 2082 } 2083 try { 2084 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState, 2085 appExtras, launcherExtras, info, callingPackage, userId); 2086 pw.println("Package " + packageName + " new suspended state: " 2087 + mInterface.isPackageSuspendedForUser(packageName, userId)); 2088 return 0; 2089 } catch (RemoteException | IllegalArgumentException e) { 2090 pw.println(e.toString()); 2091 return 1; 2092 } 2093 } 2094 runGrantRevokePermission(boolean grant)2095 private int runGrantRevokePermission(boolean grant) throws RemoteException { 2096 int userId = UserHandle.USER_SYSTEM; 2097 2098 String opt = null; 2099 while ((opt = getNextOption()) != null) { 2100 if (opt.equals("--user")) { 2101 userId = UserHandle.parseUserArg(getNextArgRequired()); 2102 } 2103 } 2104 2105 String pkg = getNextArg(); 2106 if (pkg == null) { 2107 getErrPrintWriter().println("Error: no package specified"); 2108 return 1; 2109 } 2110 String perm = getNextArg(); 2111 if (perm == null) { 2112 getErrPrintWriter().println("Error: no permission specified"); 2113 return 1; 2114 } 2115 2116 if (grant) { 2117 mInterface.grantRuntimePermission(pkg, perm, userId); 2118 } else { 2119 mInterface.revokeRuntimePermission(pkg, perm, userId); 2120 } 2121 return 0; 2122 } 2123 runResetPermissions()2124 private int runResetPermissions() throws RemoteException { 2125 mInterface.resetRuntimePermissions(); 2126 return 0; 2127 } 2128 runSetPermissionEnforced()2129 private int runSetPermissionEnforced() throws RemoteException { 2130 final String permission = getNextArg(); 2131 if (permission == null) { 2132 getErrPrintWriter().println("Error: no permission specified"); 2133 return 1; 2134 } 2135 final String enforcedRaw = getNextArg(); 2136 if (enforcedRaw == null) { 2137 getErrPrintWriter().println("Error: no enforcement specified"); 2138 return 1; 2139 } 2140 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw)); 2141 return 0; 2142 } 2143 isVendorApp(String pkg)2144 private boolean isVendorApp(String pkg) { 2145 try { 2146 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); 2147 return info != null && info.applicationInfo.isVendor(); 2148 } catch (RemoteException e) { 2149 return false; 2150 } 2151 } 2152 isProductApp(String pkg)2153 private boolean isProductApp(String pkg) { 2154 try { 2155 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); 2156 return info != null && info.applicationInfo.isProduct(); 2157 } catch (RemoteException e) { 2158 return false; 2159 } 2160 } 2161 isSystemExtApp(String pkg)2162 private boolean isSystemExtApp(String pkg) { 2163 try { 2164 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); 2165 return info != null && info.applicationInfo.isSystemExt(); 2166 } catch (RemoteException e) { 2167 return false; 2168 } 2169 } 2170 runGetPrivappPermissions()2171 private int runGetPrivappPermissions() { 2172 final String pkg = getNextArg(); 2173 if (pkg == null) { 2174 getErrPrintWriter().println("Error: no package specified."); 2175 return 1; 2176 } 2177 2178 ArraySet<String> privAppPermissions = null; 2179 if (isVendorApp(pkg)) { 2180 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg); 2181 } else if (isProductApp(pkg)) { 2182 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg); 2183 } else if (isSystemExtApp(pkg)) { 2184 privAppPermissions = SystemConfig.getInstance() 2185 .getSystemExtPrivAppPermissions(pkg); 2186 } else { 2187 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg); 2188 } 2189 2190 getOutPrintWriter().println(privAppPermissions == null 2191 ? "{}" : privAppPermissions.toString()); 2192 return 0; 2193 } 2194 runGetPrivappDenyPermissions()2195 private int runGetPrivappDenyPermissions() { 2196 final String pkg = getNextArg(); 2197 if (pkg == null) { 2198 getErrPrintWriter().println("Error: no package specified."); 2199 return 1; 2200 } 2201 2202 ArraySet<String> privAppPermissions = null; 2203 if (isVendorApp(pkg)) { 2204 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg); 2205 } else if (isProductApp(pkg)) { 2206 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg); 2207 } else if (isSystemExtApp(pkg)) { 2208 privAppPermissions = SystemConfig.getInstance() 2209 .getSystemExtPrivAppDenyPermissions(pkg); 2210 } else { 2211 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg); 2212 } 2213 2214 getOutPrintWriter().println(privAppPermissions == null 2215 ? "{}" : privAppPermissions.toString()); 2216 return 0; 2217 } 2218 runGetOemPermissions()2219 private int runGetOemPermissions() { 2220 final String pkg = getNextArg(); 2221 if (pkg == null) { 2222 getErrPrintWriter().println("Error: no package specified."); 2223 return 1; 2224 } 2225 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance() 2226 .getOemPermissions(pkg); 2227 if (oemPermissions == null || oemPermissions.isEmpty()) { 2228 getOutPrintWriter().println("{}"); 2229 } else { 2230 oemPermissions.forEach((permission, granted) -> 2231 getOutPrintWriter().println(permission + " granted:" + granted) 2232 ); 2233 } 2234 return 0; 2235 } 2236 linkStateToString(int state)2237 private String linkStateToString(int state) { 2238 switch (state) { 2239 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined"; 2240 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask"; 2241 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always"; 2242 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never"; 2243 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask"; 2244 } 2245 return "Unknown link state: " + state; 2246 } 2247 2248 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined} runSetAppLink()2249 private int runSetAppLink() throws RemoteException { 2250 int userId = UserHandle.USER_SYSTEM; 2251 2252 String opt; 2253 while ((opt = getNextOption()) != null) { 2254 if (opt.equals("--user")) { 2255 userId = UserHandle.parseUserArg(getNextArgRequired()); 2256 } else { 2257 getErrPrintWriter().println("Error: unknown option: " + opt); 2258 return 1; 2259 } 2260 } 2261 2262 // Package name to act on; required 2263 final String pkg = getNextArg(); 2264 if (pkg == null) { 2265 getErrPrintWriter().println("Error: no package specified."); 2266 return 1; 2267 } 2268 2269 // State to apply; {always|ask|never|undefined}, required 2270 final String modeString = getNextArg(); 2271 if (modeString == null) { 2272 getErrPrintWriter().println("Error: no app link state specified."); 2273 return 1; 2274 } 2275 2276 final int newMode; 2277 switch (modeString.toLowerCase()) { 2278 case "undefined": 2279 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 2280 break; 2281 2282 case "always": 2283 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 2284 break; 2285 2286 case "ask": 2287 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 2288 break; 2289 2290 case "always-ask": 2291 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 2292 break; 2293 2294 case "never": 2295 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 2296 break; 2297 2298 default: 2299 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'"); 2300 return 1; 2301 } 2302 2303 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); 2304 if (info == null) { 2305 getErrPrintWriter().println("Error: package " + pkg + " not found."); 2306 return 1; 2307 } 2308 2309 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 2310 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links."); 2311 return 1; 2312 } 2313 2314 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) { 2315 getErrPrintWriter().println("Error: unable to update app link status for " + pkg); 2316 return 1; 2317 } 2318 2319 return 0; 2320 } 2321 2322 // pm get-app-link [--user USER_ID] PACKAGE runGetAppLink()2323 private int runGetAppLink() throws RemoteException { 2324 int userId = UserHandle.USER_SYSTEM; 2325 2326 String opt; 2327 while ((opt = getNextOption()) != null) { 2328 if (opt.equals("--user")) { 2329 userId = UserHandle.parseUserArg(getNextArgRequired()); 2330 } else { 2331 getErrPrintWriter().println("Error: unknown option: " + opt); 2332 return 1; 2333 } 2334 } 2335 2336 // Package name to act on; required 2337 final String pkg = getNextArg(); 2338 if (pkg == null) { 2339 getErrPrintWriter().println("Error: no package specified."); 2340 return 1; 2341 } 2342 2343 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); 2344 if (info == null) { 2345 getErrPrintWriter().println("Error: package " + pkg + " not found."); 2346 return 1; 2347 } 2348 2349 if ((info.applicationInfo.privateFlags 2350 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 2351 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links."); 2352 return 1; 2353 } 2354 2355 getOutPrintWriter().println(linkStateToString( 2356 mInterface.getIntentVerificationStatus(pkg, userId))); 2357 2358 return 0; 2359 } 2360 runTrimCaches()2361 private int runTrimCaches() throws RemoteException { 2362 String size = getNextArg(); 2363 if (size == null) { 2364 getErrPrintWriter().println("Error: no size specified"); 2365 return 1; 2366 } 2367 long multiplier = 1; 2368 int len = size.length(); 2369 char c = size.charAt(len - 1); 2370 if (c < '0' || c > '9') { 2371 if (c == 'K' || c == 'k') { 2372 multiplier = 1024L; 2373 } else if (c == 'M' || c == 'm') { 2374 multiplier = 1024L*1024L; 2375 } else if (c == 'G' || c == 'g') { 2376 multiplier = 1024L*1024L*1024L; 2377 } else { 2378 getErrPrintWriter().println("Invalid suffix: " + c); 2379 return 1; 2380 } 2381 size = size.substring(0, len-1); 2382 } 2383 long sizeVal; 2384 try { 2385 sizeVal = Long.parseLong(size) * multiplier; 2386 } catch (NumberFormatException e) { 2387 getErrPrintWriter().println("Error: expected number at: " + size); 2388 return 1; 2389 } 2390 String volumeUuid = getNextArg(); 2391 if ("internal".equals(volumeUuid)) { 2392 volumeUuid = null; 2393 } 2394 ClearDataObserver obs = new ClearDataObserver(); 2395 mInterface.freeStorageAndNotify(volumeUuid, sizeVal, 2396 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs); 2397 synchronized (obs) { 2398 while (!obs.finished) { 2399 try { 2400 obs.wait(); 2401 } catch (InterruptedException e) { 2402 } 2403 } 2404 } 2405 return 0; 2406 } 2407 isNumber(String s)2408 private static boolean isNumber(String s) { 2409 try { 2410 Integer.parseInt(s); 2411 } catch (NumberFormatException nfe) { 2412 return false; 2413 } 2414 return true; 2415 } 2416 runCreateUser()2417 public int runCreateUser() throws RemoteException { 2418 String name; 2419 int userId = -1; 2420 int flags = 0; 2421 String opt; 2422 boolean preCreateOnly = false; 2423 while ((opt = getNextOption()) != null) { 2424 if ("--profileOf".equals(opt)) { 2425 userId = UserHandle.parseUserArg(getNextArgRequired()); 2426 } else if ("--managed".equals(opt)) { 2427 flags |= UserInfo.FLAG_MANAGED_PROFILE; 2428 } else if ("--restricted".equals(opt)) { 2429 flags |= UserInfo.FLAG_RESTRICTED; 2430 } else if ("--ephemeral".equals(opt)) { 2431 flags |= UserInfo.FLAG_EPHEMERAL; 2432 } else if ("--guest".equals(opt)) { 2433 flags |= UserInfo.FLAG_GUEST; 2434 } else if ("--demo".equals(opt)) { 2435 flags |= UserInfo.FLAG_DEMO; 2436 } else if ("--pre-create-only".equals(opt)) { 2437 preCreateOnly = true; 2438 } else { 2439 getErrPrintWriter().println("Error: unknown option " + opt); 2440 return 1; 2441 } 2442 } 2443 String arg = getNextArg(); 2444 if (arg == null && !preCreateOnly) { 2445 getErrPrintWriter().println("Error: no user name specified."); 2446 return 1; 2447 } 2448 if (arg != null && preCreateOnly) { 2449 getErrPrintWriter().println("Warning: name is ignored for pre-created users"); 2450 } 2451 2452 name = arg; 2453 UserInfo info; 2454 IUserManager um = IUserManager.Stub.asInterface( 2455 ServiceManager.getService(Context.USER_SERVICE)); 2456 IAccountManager accm = IAccountManager.Stub.asInterface( 2457 ServiceManager.getService(Context.ACCOUNT_SERVICE)); 2458 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) { 2459 // In non-split user mode, userId can only be SYSTEM 2460 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM; 2461 info = um.createRestrictedProfile(name, parentUserId); 2462 accm.addSharedAccountsFromParentUser(parentUserId, userId, 2463 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell"); 2464 } else if (userId < 0) { 2465 info = preCreateOnly ? um.preCreateUser(flags) : um.createUser(name, flags); 2466 } else { 2467 info = um.createProfileForUser(name, flags, userId, null); 2468 } 2469 2470 if (info != null) { 2471 getOutPrintWriter().println("Success: created user id " + info.id); 2472 return 0; 2473 } else { 2474 getErrPrintWriter().println("Error: couldn't create User."); 2475 return 1; 2476 } 2477 } 2478 runRemoveUser()2479 public int runRemoveUser() throws RemoteException { 2480 int userId; 2481 String arg = getNextArg(); 2482 if (arg == null) { 2483 getErrPrintWriter().println("Error: no user id specified."); 2484 return 1; 2485 } 2486 userId = UserHandle.parseUserArg(arg); 2487 IUserManager um = IUserManager.Stub.asInterface( 2488 ServiceManager.getService(Context.USER_SERVICE)); 2489 if (um.removeUser(userId)) { 2490 getOutPrintWriter().println("Success: removed user"); 2491 return 0; 2492 } else { 2493 getErrPrintWriter().println("Error: couldn't remove user id " + userId); 2494 return 1; 2495 } 2496 } 2497 runSetUserRestriction()2498 public int runSetUserRestriction() throws RemoteException { 2499 int userId = UserHandle.USER_SYSTEM; 2500 String opt = getNextOption(); 2501 if (opt != null && "--user".equals(opt)) { 2502 userId = UserHandle.parseUserArg(getNextArgRequired()); 2503 } 2504 2505 String restriction = getNextArg(); 2506 String arg = getNextArg(); 2507 boolean value; 2508 if ("1".equals(arg)) { 2509 value = true; 2510 } else if ("0".equals(arg)) { 2511 value = false; 2512 } else { 2513 getErrPrintWriter().println("Error: valid value not specified"); 2514 return 1; 2515 } 2516 IUserManager um = IUserManager.Stub.asInterface( 2517 ServiceManager.getService(Context.USER_SERVICE)); 2518 um.setUserRestriction(restriction, value, userId); 2519 return 0; 2520 } 2521 runGetMaxUsers()2522 public int runGetMaxUsers() { 2523 getOutPrintWriter().println("Maximum supported users: " 2524 + UserManager.getMaxSupportedUsers()); 2525 return 0; 2526 } 2527 runGetMaxRunningUsers()2528 public int runGetMaxRunningUsers() { 2529 ActivityManagerInternal activityManagerInternal = 2530 LocalServices.getService(ActivityManagerInternal.class); 2531 getOutPrintWriter().println("Maximum supported running users: " 2532 + activityManagerInternal.getMaxRunningUsers()); 2533 return 0; 2534 } 2535 2536 private static class InstallParams { 2537 SessionParams sessionParams; 2538 String installerPackageName; 2539 int userId = UserHandle.USER_ALL; 2540 boolean mWaitForStagedSessionReady = true; 2541 long timeoutMs = DEFAULT_WAIT_MS; 2542 } 2543 makeInstallParams()2544 private InstallParams makeInstallParams() { 2545 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2546 final InstallParams params = new InstallParams(); 2547 2548 params.sessionParams = sessionParams; 2549 // Whitelist all permissions by default 2550 sessionParams.installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS; 2551 2552 String opt; 2553 boolean replaceExisting = true; 2554 while ((opt = getNextOption()) != null) { 2555 switch (opt) { 2556 case "-r": // ignore 2557 break; 2558 case "-R": 2559 replaceExisting = false; 2560 break; 2561 case "-i": 2562 params.installerPackageName = getNextArg(); 2563 if (params.installerPackageName == null) { 2564 throw new IllegalArgumentException("Missing installer package"); 2565 } 2566 break; 2567 case "-t": 2568 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 2569 break; 2570 case "-f": 2571 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL; 2572 break; 2573 case "-d": 2574 sessionParams.installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE; 2575 break; 2576 case "-g": 2577 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; 2578 break; 2579 case "--restrict-permissions": 2580 sessionParams.installFlags &= 2581 ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS; 2582 break; 2583 case "--dont-kill": 2584 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP; 2585 break; 2586 case "--originating-uri": 2587 sessionParams.originatingUri = Uri.parse(getNextArg()); 2588 break; 2589 case "--referrer": 2590 sessionParams.referrerUri = Uri.parse(getNextArg()); 2591 break; 2592 case "-p": 2593 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING; 2594 sessionParams.appPackageName = getNextArg(); 2595 if (sessionParams.appPackageName == null) { 2596 throw new IllegalArgumentException("Missing inherit package name"); 2597 } 2598 break; 2599 case "--pkg": 2600 sessionParams.appPackageName = getNextArg(); 2601 if (sessionParams.appPackageName == null) { 2602 throw new IllegalArgumentException("Missing package name"); 2603 } 2604 break; 2605 case "-S": 2606 final long sizeBytes = Long.parseLong(getNextArg()); 2607 if (sizeBytes <= 0) { 2608 throw new IllegalArgumentException("Size must be positive"); 2609 } 2610 sessionParams.setSize(sizeBytes); 2611 break; 2612 case "--abi": 2613 sessionParams.abiOverride = checkAbiArgument(getNextArg()); 2614 break; 2615 case "--ephemeral": 2616 case "--instant": 2617 case "--instantapp": 2618 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/); 2619 break; 2620 case "--full": 2621 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/); 2622 break; 2623 case "--preload": 2624 sessionParams.setInstallAsVirtualPreload(); 2625 break; 2626 case "--user": 2627 params.userId = UserHandle.parseUserArg(getNextArgRequired()); 2628 break; 2629 case "--install-location": 2630 sessionParams.installLocation = Integer.parseInt(getNextArg()); 2631 break; 2632 case "--install-reason": 2633 sessionParams.installReason = Integer.parseInt(getNextArg()); 2634 break; 2635 case "--force-uuid": 2636 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID; 2637 sessionParams.volumeUuid = getNextArg(); 2638 if ("internal".equals(sessionParams.volumeUuid)) { 2639 sessionParams.volumeUuid = null; 2640 } 2641 break; 2642 case "--force-sdk": // ignore 2643 break; 2644 case "--apex": 2645 sessionParams.setInstallAsApex(); 2646 sessionParams.setStaged(); 2647 break; 2648 case "--multi-package": 2649 sessionParams.setMultiPackage(); 2650 break; 2651 case "--staged": 2652 sessionParams.setStaged(); 2653 break; 2654 case "--force-queryable": 2655 break; 2656 case "--enable-rollback": 2657 if (params.installerPackageName == null) { 2658 // com.android.shell has the TEST_MANAGE_ROLLBACKS 2659 // permission needed to enable rollback for non-module 2660 // packages, which is likely what the user wants when 2661 // enabling rollback through the shell command. Set 2662 // the installer to com.android.shell if no installer 2663 // has been provided so that the user doesn't have to 2664 // remember to set it themselves. 2665 params.installerPackageName = "com.android.shell"; 2666 } 2667 sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK; 2668 break; 2669 case "--wait": 2670 params.mWaitForStagedSessionReady = true; 2671 try { 2672 params.timeoutMs = Long.parseLong(peekNextArg()); 2673 getNextArg(); 2674 } catch (NumberFormatException ignore) { 2675 } 2676 break; 2677 case "--no-wait": 2678 params.mWaitForStagedSessionReady = false; 2679 break; 2680 default: 2681 throw new IllegalArgumentException("Unknown option " + opt); 2682 } 2683 } 2684 if (replaceExisting) { 2685 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 2686 } 2687 return params; 2688 } 2689 runSetHomeActivity()2690 private int runSetHomeActivity() { 2691 final PrintWriter pw = getOutPrintWriter(); 2692 int userId = UserHandle.USER_SYSTEM; 2693 String opt; 2694 while ((opt = getNextOption()) != null) { 2695 switch (opt) { 2696 case "--user": 2697 userId = UserHandle.parseUserArg(getNextArgRequired()); 2698 break; 2699 default: 2700 pw.println("Error: Unknown option: " + opt); 2701 return 1; 2702 } 2703 } 2704 2705 String pkgName; 2706 String component = getNextArg(); 2707 if (component.indexOf('/') < 0) { 2708 // No component specified, so assume it's just a package name. 2709 pkgName = component; 2710 } else { 2711 ComponentName componentName = 2712 component != null ? ComponentName.unflattenFromString(component) : null; 2713 if (componentName == null) { 2714 pw.println("Error: invalid component name"); 2715 return 1; 2716 } 2717 pkgName = componentName.getPackageName(); 2718 } 2719 2720 2721 final CompletableFuture<Boolean> future = new CompletableFuture<>(); 2722 final RemoteCallback callback = new RemoteCallback(res -> future.complete(res != null)); 2723 try { 2724 IRoleManager roleManager = android.app.role.IRoleManager.Stub.asInterface( 2725 ServiceManager.getServiceOrThrow(Context.ROLE_SERVICE)); 2726 roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, pkgName, 2727 0, userId, callback); 2728 boolean success = future.get(); 2729 if (success) { 2730 pw.println("Success"); 2731 return 0; 2732 } else { 2733 pw.println("Error: Failed to set default home."); 2734 return 1; 2735 } 2736 } catch (Exception e) { 2737 pw.println(e.toString()); 2738 return 1; 2739 } 2740 } 2741 runSetInstaller()2742 private int runSetInstaller() throws RemoteException { 2743 final String targetPackage = getNextArg(); 2744 final String installerPackageName = getNextArg(); 2745 2746 if (targetPackage == null || installerPackageName == null) { 2747 getErrPrintWriter().println("Must provide both target and installer package names"); 2748 return 1; 2749 } 2750 2751 mInterface.setInstallerPackageName(targetPackage, installerPackageName); 2752 getOutPrintWriter().println("Success"); 2753 return 0; 2754 } 2755 runGetInstantAppResolver()2756 private int runGetInstantAppResolver() { 2757 final PrintWriter pw = getOutPrintWriter(); 2758 try { 2759 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent(); 2760 if (instantAppsResolver == null) { 2761 return 1; 2762 } 2763 pw.println(instantAppsResolver.flattenToString()); 2764 return 0; 2765 } catch (Exception e) { 2766 pw.println(e.toString()); 2767 return 1; 2768 } 2769 } 2770 runHasFeature()2771 private int runHasFeature() { 2772 final PrintWriter err = getErrPrintWriter(); 2773 final String featureName = getNextArg(); 2774 if (featureName == null) { 2775 err.println("Error: expected FEATURE name"); 2776 return 1; 2777 } 2778 final String versionString = getNextArg(); 2779 try { 2780 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString); 2781 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version); 2782 getOutPrintWriter().println(hasFeature); 2783 return hasFeature ? 0 : 1; 2784 } catch (NumberFormatException e) { 2785 err.println("Error: illegal version number " + versionString); 2786 return 1; 2787 } catch (RemoteException e) { 2788 err.println(e.toString()); 2789 return 1; 2790 } 2791 } 2792 runDump()2793 private int runDump() { 2794 String pkg = getNextArg(); 2795 if (pkg == null) { 2796 getErrPrintWriter().println("Error: no package specified"); 2797 return 1; 2798 } 2799 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg); 2800 return 0; 2801 } 2802 runSetHarmfulAppWarning()2803 private int runSetHarmfulAppWarning() throws RemoteException { 2804 int userId = UserHandle.USER_CURRENT; 2805 2806 String opt; 2807 while ((opt = getNextOption()) != null) { 2808 if (opt.equals("--user")) { 2809 userId = UserHandle.parseUserArg(getNextArgRequired()); 2810 } else { 2811 getErrPrintWriter().println("Error: Unknown option: " + opt); 2812 return -1; 2813 } 2814 } 2815 2816 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning"); 2817 2818 final String packageName = getNextArgRequired(); 2819 final String warning = getNextArg(); 2820 2821 mInterface.setHarmfulAppWarning(packageName, warning, userId); 2822 2823 return 0; 2824 } 2825 runGetHarmfulAppWarning()2826 private int runGetHarmfulAppWarning() throws RemoteException { 2827 int userId = UserHandle.USER_CURRENT; 2828 2829 String opt; 2830 while ((opt = getNextOption()) != null) { 2831 if (opt.equals("--user")) { 2832 userId = UserHandle.parseUserArg(getNextArgRequired()); 2833 } else { 2834 getErrPrintWriter().println("Error: Unknown option: " + opt); 2835 return -1; 2836 } 2837 } 2838 2839 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning"); 2840 2841 final String packageName = getNextArgRequired(); 2842 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId); 2843 if (!TextUtils.isEmpty(warning)) { 2844 getOutPrintWriter().println(warning); 2845 return 0; 2846 } else { 2847 return 1; 2848 } 2849 } 2850 checkAbiArgument(String abi)2851 private static String checkAbiArgument(String abi) { 2852 if (TextUtils.isEmpty(abi)) { 2853 throw new IllegalArgumentException("Missing ABI argument"); 2854 } 2855 2856 if ("-".equals(abi)) { 2857 return abi; 2858 } 2859 2860 final String[] supportedAbis = Build.SUPPORTED_ABIS; 2861 for (String supportedAbi : supportedAbis) { 2862 if (supportedAbi.equals(abi)) { 2863 return abi; 2864 } 2865 } 2866 2867 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 2868 } 2869 translateUserId(int userId, boolean allowAll, String logContext)2870 private int translateUserId(int userId, boolean allowAll, String logContext) { 2871 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 2872 userId, allowAll, true, logContext, "pm command"); 2873 } 2874 doCreateSession(SessionParams params, String installerPackageName, int userId)2875 private int doCreateSession(SessionParams params, String installerPackageName, int userId) 2876 throws RemoteException { 2877 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate"); 2878 if (userId == UserHandle.USER_ALL) { 2879 userId = UserHandle.USER_SYSTEM; 2880 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 2881 } 2882 2883 final int sessionId = mInterface.getPackageInstaller() 2884 .createSession(params, installerPackageName, userId); 2885 return sessionId; 2886 } 2887 doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, boolean logSuccess)2888 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, 2889 boolean logSuccess) throws RemoteException { 2890 PackageInstaller.Session session = null; 2891 try { 2892 final PrintWriter pw = getOutPrintWriter(); 2893 final ParcelFileDescriptor fd; 2894 if (STDIN_PATH.equals(inPath)) { 2895 fd = ParcelFileDescriptor.dup(getInFileDescriptor()); 2896 } else if (inPath != null) { 2897 fd = openFileForSystem(inPath, "r"); 2898 if (fd == null) { 2899 return -1; 2900 } 2901 sizeBytes = fd.getStatSize(); 2902 if (sizeBytes < 0) { 2903 getErrPrintWriter().println("Unable to get size of: " + inPath); 2904 return -1; 2905 } 2906 } else { 2907 fd = ParcelFileDescriptor.dup(getInFileDescriptor()); 2908 } 2909 if (sizeBytes <= 0) { 2910 getErrPrintWriter().println("Error: must specify a APK size"); 2911 return 1; 2912 } 2913 2914 session = new PackageInstaller.Session( 2915 mInterface.getPackageInstaller().openSession(sessionId)); 2916 session.write(splitName, 0, sizeBytes, fd); 2917 2918 if (logSuccess) { 2919 pw.println("Success: streamed " + sizeBytes + " bytes"); 2920 } 2921 return 0; 2922 } catch (IOException e) { 2923 getErrPrintWriter().println("Error: failed to write; " + e.getMessage()); 2924 return 1; 2925 } finally { 2926 IoUtils.closeQuietly(session); 2927 } 2928 } 2929 doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess)2930 private int doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess) 2931 throws RemoteException { 2932 final PrintWriter pw = getOutPrintWriter(); 2933 PackageInstaller.Session session = null; 2934 try { 2935 session = new PackageInstaller.Session( 2936 mInterface.getPackageInstaller().openSession(parentId)); 2937 if (!session.isMultiPackage()) { 2938 getErrPrintWriter().println( 2939 "Error: parent session ID is not a multi-package session"); 2940 return 1; 2941 } 2942 for (int i = 0; i < sessionIds.length; i++) { 2943 session.addChildSessionId(sessionIds[i]); 2944 } 2945 if (logSuccess) { 2946 pw.println("Success"); 2947 } 2948 return 0; 2949 } finally { 2950 IoUtils.closeQuietly(session); 2951 } 2952 } 2953 doRemoveSplit(int sessionId, String splitName, boolean logSuccess)2954 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess) 2955 throws RemoteException { 2956 final PrintWriter pw = getOutPrintWriter(); 2957 PackageInstaller.Session session = null; 2958 try { 2959 session = new PackageInstaller.Session( 2960 mInterface.getPackageInstaller().openSession(sessionId)); 2961 session.removeSplit(splitName); 2962 2963 if (logSuccess) { 2964 pw.println("Success"); 2965 } 2966 return 0; 2967 } catch (IOException e) { 2968 pw.println("Error: failed to remove split; " + e.getMessage()); 2969 return 1; 2970 } finally { 2971 IoUtils.closeQuietly(session); 2972 } 2973 } 2974 doCommitSession(int sessionId, boolean logSuccess)2975 private int doCommitSession(int sessionId, boolean logSuccess) 2976 throws RemoteException { 2977 2978 final PrintWriter pw = getOutPrintWriter(); 2979 PackageInstaller.Session session = null; 2980 try { 2981 session = new PackageInstaller.Session( 2982 mInterface.getPackageInstaller().openSession(sessionId)); 2983 if (!session.isMultiPackage() && !session.isStaged()) { 2984 // Sanity check that all .dm files match an apk. 2985 // (The installer does not support standalone .dm files and will not process them.) 2986 try { 2987 DexMetadataHelper.validateDexPaths(session.getNames()); 2988 } catch (IllegalStateException | IOException e) { 2989 pw.println( 2990 "Warning [Could not validate the dex paths: " + e.getMessage() + "]"); 2991 } 2992 } 2993 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 2994 session.commit(receiver.getIntentSender()); 2995 final Intent result = receiver.getResult(); 2996 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 2997 PackageInstaller.STATUS_FAILURE); 2998 if (status == PackageInstaller.STATUS_SUCCESS) { 2999 if (logSuccess) { 3000 pw.println("Success"); 3001 } 3002 } else { 3003 pw.println("Failure [" 3004 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 3005 } 3006 return status; 3007 } finally { 3008 IoUtils.closeQuietly(session); 3009 } 3010 } 3011 doAbandonSession(int sessionId, boolean logSuccess)3012 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException { 3013 final PrintWriter pw = getOutPrintWriter(); 3014 PackageInstaller.Session session = null; 3015 try { 3016 session = new PackageInstaller.Session( 3017 mInterface.getPackageInstaller().openSession(sessionId)); 3018 session.abandon(); 3019 if (logSuccess) { 3020 pw.println("Success"); 3021 } 3022 return 0; 3023 } finally { 3024 IoUtils.closeQuietly(session); 3025 } 3026 } 3027 doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels, boolean summary, int startProtectionLevel, int endProtectionLevel)3028 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels, 3029 boolean summary, int startProtectionLevel, int endProtectionLevel) 3030 throws RemoteException { 3031 final PrintWriter pw = getOutPrintWriter(); 3032 final int groupCount = groupList.size(); 3033 for (int i = 0; i < groupCount; i++) { 3034 String groupName = groupList.get(i); 3035 String prefix = ""; 3036 if (groups) { 3037 if (i > 0) { 3038 pw.println(""); 3039 } 3040 if (groupName != null) { 3041 PermissionGroupInfo pgi = 3042 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/); 3043 if (summary) { 3044 Resources res = getResources(pgi); 3045 if (res != null) { 3046 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": "); 3047 } else { 3048 pw.print(pgi.name + ": "); 3049 3050 } 3051 } else { 3052 pw.println((labels ? "+ " : "") + "group:" + pgi.name); 3053 if (labels) { 3054 pw.println(" package:" + pgi.packageName); 3055 Resources res = getResources(pgi); 3056 if (res != null) { 3057 pw.println(" label:" 3058 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel)); 3059 pw.println(" description:" 3060 + loadText(pgi, pgi.descriptionRes, 3061 pgi.nonLocalizedDescription)); 3062 } 3063 } 3064 } 3065 } else { 3066 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:"); 3067 } 3068 prefix = " "; 3069 } 3070 List<PermissionInfo> ps = 3071 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList(); 3072 final int count = ps.size(); 3073 boolean first = true; 3074 for (int p = 0 ; p < count ; p++) { 3075 PermissionInfo pi = ps.get(p); 3076 if (groups && groupName == null && pi.group != null) { 3077 continue; 3078 } 3079 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 3080 if (base < startProtectionLevel 3081 || base > endProtectionLevel) { 3082 continue; 3083 } 3084 if (summary) { 3085 if (first) { 3086 first = false; 3087 } else { 3088 pw.print(", "); 3089 } 3090 Resources res = getResources(pi); 3091 if (res != null) { 3092 pw.print(loadText(pi, pi.labelRes, 3093 pi.nonLocalizedLabel)); 3094 } else { 3095 pw.print(pi.name); 3096 } 3097 } else { 3098 pw.println(prefix + (labels ? "+ " : "") 3099 + "permission:" + pi.name); 3100 if (labels) { 3101 pw.println(prefix + " package:" + pi.packageName); 3102 Resources res = getResources(pi); 3103 if (res != null) { 3104 pw.println(prefix + " label:" 3105 + loadText(pi, pi.labelRes, 3106 pi.nonLocalizedLabel)); 3107 pw.println(prefix + " description:" 3108 + loadText(pi, pi.descriptionRes, 3109 pi.nonLocalizedDescription)); 3110 } 3111 pw.println(prefix + " protectionLevel:" 3112 + PermissionInfo.protectionToString(pi.protectionLevel)); 3113 } 3114 } 3115 } 3116 3117 if (summary) { 3118 pw.println(""); 3119 } 3120 } 3121 } 3122 loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)3123 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) 3124 throws RemoteException { 3125 if (nonLocalized != null) { 3126 return nonLocalized.toString(); 3127 } 3128 if (res != 0) { 3129 Resources r = getResources(pii); 3130 if (r != null) { 3131 try { 3132 return r.getString(res); 3133 } catch (Resources.NotFoundException e) { 3134 } 3135 } 3136 } 3137 return null; 3138 } 3139 getResources(PackageItemInfo pii)3140 private Resources getResources(PackageItemInfo pii) throws RemoteException { 3141 Resources res = mResourceCache.get(pii.packageName); 3142 if (res != null) return res; 3143 3144 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0); 3145 AssetManager am = new AssetManager(); 3146 am.addAssetPath(ai.publicSourceDir); 3147 res = new Resources(am, null, null); 3148 mResourceCache.put(pii.packageName, res); 3149 return res; 3150 } 3151 3152 @Override onHelp()3153 public void onHelp() { 3154 final PrintWriter pw = getOutPrintWriter(); 3155 pw.println("Package manager (package) commands:"); 3156 pw.println(" help"); 3157 pw.println(" Print this help text."); 3158 pw.println(""); 3159 pw.println(" path [--user USER_ID] PACKAGE"); 3160 pw.println(" Print the path to the .apk of the given PACKAGE."); 3161 pw.println(""); 3162 pw.println(" dump PACKAGE"); 3163 pw.println(" Print various system state associated with the given PACKAGE."); 3164 pw.println(""); 3165 pw.println(" list features"); 3166 pw.println(" Prints all features of the system."); 3167 pw.println(""); 3168 pw.println(" has-feature FEATURE_NAME [version]"); 3169 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,"); 3170 pw.println(" otherwise prints false and returns exit status 1"); 3171 pw.println(""); 3172 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]"); 3173 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE"); 3174 pw.println(" Options:"); 3175 pw.println(" -f: dump the name of the .apk file containing the test package"); 3176 pw.println(""); 3177 pw.println(" list libraries"); 3178 pw.println(" Prints all system libraries."); 3179 pw.println(""); 3180 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] "); 3181 pw.println(" [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]"); 3182 pw.println(" Prints all packages; optionally only those whose name contains"); 3183 pw.println(" the text in FILTER. Options are:"); 3184 pw.println(" -f: see their associated file"); 3185 pw.println(" -a: all known packages (but excluding APEXes)"); 3186 pw.println(" -d: filter to only show disabled packages"); 3187 pw.println(" -e: filter to only show enabled packages"); 3188 pw.println(" -s: filter to only show system packages"); 3189 pw.println(" -3: filter to only show third party packages"); 3190 pw.println(" -i: see the installer for the packages"); 3191 pw.println(" -l: ignored (used for compatibility with older releases)"); 3192 pw.println(" -U: also show the package UID"); 3193 pw.println(" -u: also include uninstalled packages"); 3194 pw.println(" --show-versioncode: also show the version code"); 3195 pw.println(" --apex-only: only show APEX packages"); 3196 pw.println(" --uid UID: filter to only show packages with the given UID"); 3197 pw.println(" --user USER_ID: only list packages belonging to the given user"); 3198 pw.println(""); 3199 pw.println(" list permission-groups"); 3200 pw.println(" Prints all known permission groups."); 3201 pw.println(""); 3202 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); 3203 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:"); 3204 pw.println(" -g: organize by group"); 3205 pw.println(" -f: print all information"); 3206 pw.println(" -s: short summary"); 3207 pw.println(" -d: only list dangerous permissions"); 3208 pw.println(" -u: list only the permissions users will see"); 3209 pw.println(""); 3210 pw.println(" list staged-sessions [--only-ready] [--only-sessionid] [--only-parent]"); 3211 pw.println(" Displays list of all staged sessions on device."); 3212 pw.println(" --only-ready: show only staged sessions that are ready"); 3213 pw.println(" --only-sessionid: show only sessionId of each session"); 3214 pw.println(" --only-parent: hide all children sessions"); 3215 pw.println(""); 3216 pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]"); 3217 pw.println(" [--user USER_ID] INTENT"); 3218 pw.println(" Prints the activity that resolves to the given INTENT."); 3219 pw.println(""); 3220 pw.println(" query-activities [--brief] [--components] [--query-flags FLAGS]"); 3221 pw.println(" [--user USER_ID] INTENT"); 3222 pw.println(" Prints all activities that can handle the given INTENT."); 3223 pw.println(""); 3224 pw.println(" query-services [--brief] [--components] [--query-flags FLAGS]"); 3225 pw.println(" [--user USER_ID] INTENT"); 3226 pw.println(" Prints all services that can handle the given INTENT."); 3227 pw.println(""); 3228 pw.println(" query-receivers [--brief] [--components] [--query-flags FLAGS]"); 3229 pw.println(" [--user USER_ID] INTENT"); 3230 pw.println(" Prints all broadcast receivers that can handle the given INTENT."); 3231 pw.println(""); 3232 pw.println(" install [-lrtfdgw] [-i PACKAGE] [--user USER_ID|all|current]"); 3233 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); 3234 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]"); 3235 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]"); 3236 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); 3237 pw.println(" [--enable-rollback]"); 3238 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]"); 3239 pw.println(" [--apex] [--wait TIMEOUT]"); 3240 pw.println(" [PATH|-]"); 3241 pw.println(" Install an application. Must provide the apk data to install, either as a"); 3242 pw.println(" file path or '-' to read from stdin. Options are:"); 3243 pw.println(" -l: forward lock application"); 3244 pw.println(" -R: disallow replacement of existing application"); 3245 pw.println(" -t: allow test packages"); 3246 pw.println(" -i: specify package name of installer owning the app"); 3247 pw.println(" -f: install application on internal flash"); 3248 pw.println(" -d: allow version code downgrade (debuggable packages only)"); 3249 pw.println(" -p: partial application install (new split on top of existing pkg)"); 3250 pw.println(" -g: grant all runtime permissions"); 3251 pw.println(" -S: size in bytes of package, required for stdin"); 3252 pw.println(" --user: install under the given user."); 3253 pw.println(" --dont-kill: installing a new feature split, don't kill running app"); 3254 pw.println(" --restrict-permissions: don't whitelist restricted permissions at install"); 3255 pw.println(" --originating-uri: set URI where app was downloaded from"); 3256 pw.println(" --referrer: set URI that instigated the install of the app"); 3257 pw.println(" --pkg: specify expected package name of app being installed"); 3258 pw.println(" --abi: override the default ABI of the platform"); 3259 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app"); 3260 pw.println(" --full: cause the app to be installed as a non-ephemeral full app"); 3261 pw.println(" --install-location: force the install location:"); 3262 pw.println(" 0=auto, 1=internal only, 2=prefer external"); 3263 pw.println(" --install-reason: indicates why the app is being installed:"); 3264 pw.println(" 0=unknown, 1=admin policy, 2=device restore,"); 3265 pw.println(" 3=device setup, 4=user request"); 3266 pw.println(" --force-uuid: force install on to disk volume with given UUID"); 3267 pw.println(" --apex: install an .apex file, not an .apk"); 3268 pw.println(" --wait: when performing staged install, wait TIMEOUT milliseconds"); 3269 pw.println(" for pre-reboot verification to complete. If TIMEOUT is not"); 3270 pw.println(" specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds."); 3271 pw.println(""); 3272 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]"); 3273 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); 3274 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]"); 3275 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]"); 3276 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); 3277 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]"); 3278 pw.println(" [--multi-package] [--staged]"); 3279 pw.println(" Like \"install\", but starts an install session. Use \"install-write\""); 3280 pw.println(" to push data into the session, and \"install-commit\" to finish."); 3281 pw.println(""); 3282 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]"); 3283 pw.println(" Write an apk into the given install session. If the path is '-', data"); 3284 pw.println(" will be read from stdin. Options are:"); 3285 pw.println(" -S: size in bytes of package, required for stdin"); 3286 pw.println(""); 3287 pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs"); 3288 pw.println(" Add one or more session IDs to a multi-package session."); 3289 pw.println(""); 3290 pw.println(" install-commit SESSION_ID"); 3291 pw.println(" Commit the given active install session, installing the app."); 3292 pw.println(""); 3293 pw.println(" install-abandon SESSION_ID"); 3294 pw.println(" Delete the given active install session."); 3295 pw.println(""); 3296 pw.println(" set-install-location LOCATION"); 3297 pw.println(" Changes the default install location. NOTE this is only intended for debugging;"); 3298 pw.println(" using this can cause applications to break and other undersireable behavior."); 3299 pw.println(" LOCATION is one of:"); 3300 pw.println(" 0 [auto]: Let system decide the best location"); 3301 pw.println(" 1 [internal]: Install on internal device storage"); 3302 pw.println(" 2 [external]: Install on external media"); 3303 pw.println(""); 3304 pw.println(" get-install-location"); 3305 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location."); 3306 pw.println(""); 3307 pw.println(" move-package PACKAGE [internal|UUID]"); 3308 pw.println(""); 3309 pw.println(" move-primary-storage [internal|UUID]"); 3310 pw.println(""); 3311 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]"); 3312 pw.println(" Remove the given package name from the system. May remove an entire app"); 3313 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the"); 3314 pw.println(" given app. Options are:"); 3315 pw.println(" -k: keep the data and cache directories around after package removal."); 3316 pw.println(" --user: remove the app from the given user."); 3317 pw.println(" --versionCode: only uninstall if the app has the given version code."); 3318 pw.println(""); 3319 pw.println(" clear [--user USER_ID] PACKAGE"); 3320 pw.println(" Deletes all data associated with a package."); 3321 pw.println(""); 3322 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 3323 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 3324 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 3325 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 3326 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT"); 3327 pw.println(" These commands change the enabled state of a given package or"); 3328 pw.println(" component (written as \"package/class\")."); 3329 pw.println(""); 3330 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 3331 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 3332 pw.println(""); 3333 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE"); 3334 pw.println(" Suspends the specified package (as user)."); 3335 pw.println(""); 3336 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE"); 3337 pw.println(" Unsuspends the specified package (as user)."); 3338 pw.println(""); 3339 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION"); 3340 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION"); 3341 pw.println(" These commands either grant or revoke permissions to apps. The permissions"); 3342 pw.println(" must be declared as used in the app's manifest, be runtime permissions"); 3343 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1."); 3344 pw.println(""); 3345 pw.println(" reset-permissions"); 3346 pw.println(" Revert all runtime permissions to their default state."); 3347 pw.println(""); 3348 pw.println(" set-permission-enforced PERMISSION [true|false]"); 3349 pw.println(""); 3350 pw.println(" get-privapp-permissions TARGET-PACKAGE"); 3351 pw.println(" Prints all privileged permissions for a package."); 3352 pw.println(""); 3353 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE"); 3354 pw.println(" Prints all privileged permissions that are denied for a package."); 3355 pw.println(""); 3356 pw.println(" get-oem-permissions TARGET-PACKAGE"); 3357 pw.println(" Prints all OEM permissions for a package."); 3358 pw.println(""); 3359 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}"); 3360 pw.println(" get-app-link [--user USER_ID] PACKAGE"); 3361 pw.println(""); 3362 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]"); 3363 pw.println(" Trim cache files to reach the given free space."); 3364 pw.println(""); 3365 pw.println(" list users"); 3366 pw.println(" Lists the current users."); 3367 pw.println(""); 3368 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]"); 3369 pw.println(" [--guest] [--pre-create-only] USER_NAME"); 3370 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier"); 3371 pw.println(" of the user."); 3372 pw.println(""); 3373 pw.println(" remove-user USER_ID"); 3374 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data"); 3375 pw.println(" associated with that user"); 3376 pw.println(""); 3377 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE"); 3378 pw.println(""); 3379 pw.println(" get-max-users"); 3380 pw.println(""); 3381 pw.println(" get-max-running-users"); 3382 pw.println(""); 3383 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]"); 3384 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)"); 3385 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:"); 3386 pw.println(" -a: compile all packages"); 3387 pw.println(" -c: clear profile data before compiling"); 3388 pw.println(" -f: force compilation even if not needed"); 3389 pw.println(" -m: select compilation mode"); 3390 pw.println(" MODE is one of the dex2oat compiler filters:"); 3391 pw.println(" assume-verified"); 3392 pw.println(" extract"); 3393 pw.println(" verify"); 3394 pw.println(" quicken"); 3395 pw.println(" space-profile"); 3396 pw.println(" space"); 3397 pw.println(" speed-profile"); 3398 pw.println(" speed"); 3399 pw.println(" everything"); 3400 pw.println(" -r: select compilation reason"); 3401 pw.println(" REASON is one of:"); 3402 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) { 3403 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]); 3404 } 3405 pw.println(" --reset: restore package to its post-install state"); 3406 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?"); 3407 pw.println(" --secondary-dex: compile app secondary dex files"); 3408 pw.println(" --split SPLIT: compile only the given split name"); 3409 pw.println(" --compile-layouts: compile layout resources for faster inflation"); 3410 pw.println(""); 3411 pw.println(" force-dex-opt PACKAGE"); 3412 pw.println(" Force immediate execution of dex opt for the given PACKAGE."); 3413 pw.println(""); 3414 pw.println(" bg-dexopt-job"); 3415 pw.println(" Execute the background optimizations immediately."); 3416 pw.println(" Note that the command only runs the background optimizer logic. It may"); 3417 pw.println(" overlap with the actual job but the job scheduler will not be able to"); 3418 pw.println(" cancel it. It will also run even if the device is not in the idle"); 3419 pw.println(" maintenance mode."); 3420 pw.println(""); 3421 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE"); 3422 pw.println(" Reconciles the package secondary dex files with the generated oat files."); 3423 pw.println(""); 3424 pw.println(" dump-profiles TARGET-PACKAGE"); 3425 pw.println(" Dumps method/class profile files to"); 3426 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt"); 3427 pw.println(""); 3428 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]"); 3429 pw.println(" Take a snapshot of the package profiles to"); 3430 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION 3431 + "TARGET-PACKAGE[-code-path].prof"); 3432 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image"); 3433 pw.println(""); 3434 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT"); 3435 pw.println(" Set the default home activity (aka launcher)."); 3436 pw.println(" TARGET-COMPONENT can be a package name (com.package.my) or a full"); 3437 pw.println(" component (com.package.my/component.name). However, only the package name"); 3438 pw.println(" matters: the actual component used will be determined automatically from"); 3439 pw.println(" the package."); 3440 pw.println(""); 3441 pw.println(" set-installer PACKAGE INSTALLER"); 3442 pw.println(" Set installer package name"); 3443 pw.println(""); 3444 pw.println(" get-instantapp-resolver"); 3445 pw.println(" Return the name of the component that is the current instant app installer."); 3446 pw.println(""); 3447 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]"); 3448 pw.println(" Mark the app as harmful with the given warning message."); 3449 pw.println(""); 3450 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>"); 3451 pw.println(" Return the harmful app warning message for the given app, if present"); 3452 pw.println(); 3453 pw.println(" uninstall-system-updates"); 3454 pw.println(" Remove updates to all system applications and fall back to their /system " + 3455 "version."); 3456 pw.println(""); 3457 pw.println(" get-moduleinfo [--all | --installed] [module-name]"); 3458 pw.println(" Displays module info. If module-name is specified only that info is shown"); 3459 pw.println(" By default, without any argument only installed modules are shown."); 3460 pw.println(" --all: show all module info"); 3461 pw.println(" --installed: show only installed modules"); 3462 pw.println(""); 3463 Intent.printIntentArgsHelp(pw , ""); 3464 } 3465 3466 private static class LocalIntentReceiver { 3467 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>(); 3468 3469 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 3470 @Override 3471 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, 3472 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 3473 try { 3474 mResult.offer(intent, 5, TimeUnit.SECONDS); 3475 } catch (InterruptedException e) { 3476 throw new RuntimeException(e); 3477 } 3478 } 3479 }; 3480 getIntentSender()3481 public IntentSender getIntentSender() { 3482 return new IntentSender((IIntentSender) mLocalSender); 3483 } 3484 getResult()3485 public Intent getResult() { 3486 try { 3487 return mResult.take(); 3488 } catch (InterruptedException e) { 3489 throw new RuntimeException(e); 3490 } 3491 } 3492 } 3493 } 3494