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