1 /* 2 * Copyright (C) 2007 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.commands.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.ActivityManagerNative; 28 import android.app.PackageInstallObserver; 29 import android.content.ComponentName; 30 import android.content.Context; 31 import android.content.IIntentReceiver; 32 import android.content.IIntentSender; 33 import android.content.Intent; 34 import android.content.IntentSender; 35 import android.content.pm.ApplicationInfo; 36 import android.content.pm.IPackageDataObserver; 37 import android.content.pm.IPackageInstaller; 38 import android.content.pm.IPackageManager; 39 import android.content.pm.PackageInfo; 40 import android.content.pm.PackageInstaller; 41 import android.content.pm.PackageInstaller.SessionInfo; 42 import android.content.pm.PackageInstaller.SessionParams; 43 import android.content.pm.PackageManager; 44 import android.content.pm.UserInfo; 45 import android.net.Uri; 46 import android.os.Binder; 47 import android.os.Build; 48 import android.os.Bundle; 49 import android.os.Handler; 50 import android.os.HandlerThread; 51 import android.os.IUserManager; 52 import android.os.RemoteException; 53 import android.os.ResultReceiver; 54 import android.os.ServiceManager; 55 import android.os.SystemClock; 56 import android.os.UserHandle; 57 import android.os.UserManager; 58 import android.text.TextUtils; 59 import android.text.format.DateUtils; 60 import android.util.Log; 61 62 import com.android.internal.content.PackageHelper; 63 import com.android.internal.util.ArrayUtils; 64 import com.android.internal.util.SizedInputStream; 65 66 import libcore.io.IoUtils; 67 68 import java.io.File; 69 import java.io.FileDescriptor; 70 import java.io.FileInputStream; 71 import java.io.IOException; 72 import java.io.InputStream; 73 import java.io.OutputStream; 74 import java.util.concurrent.SynchronousQueue; 75 import java.util.concurrent.TimeUnit; 76 77 public final class Pm { 78 private static final String TAG = "Pm"; 79 80 IPackageManager mPm; 81 IPackageInstaller mInstaller; 82 IUserManager mUm; 83 IAccountManager mAm; 84 85 private String[] mArgs; 86 private int mNextArg; 87 private String mCurArgData; 88 89 private static final String PM_NOT_RUNNING_ERR = 90 "Error: Could not access the Package Manager. Is the system running?"; 91 main(String[] args)92 public static void main(String[] args) { 93 int exitCode = 1; 94 try { 95 exitCode = new Pm().run(args); 96 } catch (Exception e) { 97 Log.e(TAG, "Error", e); 98 System.err.println("Error: " + e); 99 if (e instanceof RemoteException) { 100 System.err.println(PM_NOT_RUNNING_ERR); 101 } 102 } 103 System.exit(exitCode); 104 } 105 run(String[] args)106 public int run(String[] args) throws RemoteException { 107 boolean validCommand = false; 108 if (args.length < 1) { 109 return showUsage(); 110 } 111 mAm = IAccountManager.Stub.asInterface(ServiceManager.getService(Context.ACCOUNT_SERVICE)); 112 mUm = IUserManager.Stub.asInterface(ServiceManager.getService(Context.USER_SERVICE)); 113 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 114 115 if (mPm == null) { 116 System.err.println(PM_NOT_RUNNING_ERR); 117 return 1; 118 } 119 mInstaller = mPm.getPackageInstaller(); 120 121 mArgs = args; 122 String op = args[0]; 123 mNextArg = 1; 124 125 if ("list".equals(op)) { 126 return runList(); 127 } 128 129 if ("path".equals(op)) { 130 return runPath(); 131 } 132 133 if ("dump".equals(op)) { 134 return runDump(); 135 } 136 137 if ("install".equals(op)) { 138 return runInstall(); 139 } 140 141 if ("install-create".equals(op)) { 142 return runInstallCreate(); 143 } 144 145 if ("install-write".equals(op)) { 146 return runInstallWrite(); 147 } 148 149 if ("install-commit".equals(op)) { 150 return runInstallCommit(); 151 } 152 153 if ("install-abandon".equals(op) || "install-destroy".equals(op)) { 154 return runInstallAbandon(); 155 } 156 157 if ("set-installer".equals(op)) { 158 return runSetInstaller(); 159 } 160 161 if ("uninstall".equals(op)) { 162 return runUninstall(); 163 } 164 165 if ("clear".equals(op)) { 166 return runClear(); 167 } 168 169 if ("enable".equals(op)) { 170 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 171 } 172 173 if ("disable".equals(op)) { 174 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 175 } 176 177 if ("disable-user".equals(op)) { 178 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER); 179 } 180 181 if ("disable-until-used".equals(op)) { 182 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED); 183 } 184 185 if ("default-state".equals(op)) { 186 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); 187 } 188 189 if ("hide".equals(op)) { 190 return runSetHiddenSetting(true); 191 } 192 193 if ("unhide".equals(op)) { 194 return runSetHiddenSetting(false); 195 } 196 197 if ("grant".equals(op)) { 198 return runGrantRevokePermission(true); 199 } 200 201 if ("revoke".equals(op)) { 202 return runGrantRevokePermission(false); 203 } 204 205 if ("reset-permissions".equals(op)) { 206 return runResetPermissions(); 207 } 208 209 if ("set-permission-enforced".equals(op)) { 210 return runSetPermissionEnforced(); 211 } 212 213 if ("set-app-link".equals(op)) { 214 return runSetAppLink(); 215 } 216 217 if ("get-app-link".equals(op)) { 218 return runGetAppLink(); 219 } 220 221 if ("set-install-location".equals(op)) { 222 return runSetInstallLocation(); 223 } 224 225 if ("get-install-location".equals(op)) { 226 return runGetInstallLocation(); 227 } 228 229 if ("trim-caches".equals(op)) { 230 return runTrimCaches(); 231 } 232 233 if ("create-user".equals(op)) { 234 return runCreateUser(); 235 } 236 237 if ("remove-user".equals(op)) { 238 return runRemoveUser(); 239 } 240 241 if ("get-max-users".equals(op)) { 242 return runGetMaxUsers(); 243 } 244 245 if ("force-dex-opt".equals(op)) { 246 return runForceDexOpt(); 247 } 248 249 if ("move-package".equals(op)) { 250 return runMovePackage(); 251 } 252 253 if ("move-primary-storage".equals(op)) { 254 return runMovePrimaryStorage(); 255 } 256 257 if ("set-user-restriction".equals(op)) { 258 return runSetUserRestriction(); 259 } 260 261 try { 262 if (args.length == 1) { 263 if (args[0].equalsIgnoreCase("-l")) { 264 validCommand = true; 265 return runShellCommand("package", new String[] { "list", "package" }); 266 } else if (args[0].equalsIgnoreCase("-lf")) { 267 validCommand = true; 268 return runShellCommand("package", new String[] { "list", "package", "-f" }); 269 } 270 } else if (args.length == 2) { 271 if (args[0].equalsIgnoreCase("-p")) { 272 validCommand = true; 273 return displayPackageFilePath(args[1], UserHandle.USER_SYSTEM); 274 } 275 } 276 return 1; 277 } finally { 278 if (validCommand == false) { 279 if (op != null) { 280 System.err.println("Error: unknown command '" + op + "'"); 281 } 282 showUsage(); 283 } 284 } 285 } 286 runShellCommand(String serviceName, String[] args)287 private int runShellCommand(String serviceName, String[] args) { 288 final HandlerThread handlerThread = new HandlerThread("results"); 289 handlerThread.start(); 290 try { 291 ServiceManager.getService(serviceName).shellCommand( 292 FileDescriptor.in, FileDescriptor.out, FileDescriptor.err, 293 args, new ResultReceiver(new Handler(handlerThread.getLooper()))); 294 return 0; 295 } catch (RemoteException e) { 296 e.printStackTrace(); 297 } finally { 298 handlerThread.quitSafely(); 299 } 300 return -1; 301 } 302 303 private static class LocalIntentReceiver { 304 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 305 306 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 307 @Override 308 public void send(int code, Intent intent, String resolvedType, 309 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 310 try { 311 mResult.offer(intent, 5, TimeUnit.SECONDS); 312 } catch (InterruptedException e) { 313 throw new RuntimeException(e); 314 } 315 } 316 }; 317 getIntentSender()318 public IntentSender getIntentSender() { 319 return new IntentSender((IIntentSender) mLocalSender); 320 } 321 getResult()322 public Intent getResult() { 323 try { 324 return mResult.take(); 325 } catch (InterruptedException e) { 326 throw new RuntimeException(e); 327 } 328 } 329 } 330 translateUserId(int userId, String logContext)331 private int translateUserId(int userId, String logContext) { 332 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 333 userId, true, true, logContext, "pm command"); 334 } 335 checkAbiArgument(String abi)336 private static String checkAbiArgument(String abi) { 337 if (TextUtils.isEmpty(abi)) { 338 throw new IllegalArgumentException("Missing ABI argument"); 339 } 340 if ("-".equals(abi)) { 341 return abi; 342 } 343 final String[] supportedAbis = Build.SUPPORTED_ABIS; 344 for (String supportedAbi : supportedAbis) { 345 if (supportedAbi.equals(abi)) { 346 return abi; 347 } 348 } 349 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 350 } 351 352 /* 353 * Keep this around to support existing users of the "pm install" command that may not be 354 * able to be updated [or, at least informed the API has changed] such as ddmlib. 355 * 356 * Moving the implementation of "pm install" to "cmd package install" changes the executing 357 * context. Instead of being a stand alone process, "cmd package install" runs in the 358 * system_server process. Due to SELinux rules, system_server cannot access many directories; 359 * one of which being the package install staging directory [/data/local/tmp]. 360 * 361 * The use of "adb install" or "cmd package install" over "pm install" is highly encouraged. 362 */ runInstall()363 private int runInstall() throws RemoteException { 364 final InstallParams params = makeInstallParams(); 365 final int sessionId = doCreateSession(params.sessionParams, 366 params.installerPackageName, params.userId); 367 368 try { 369 final String inPath = nextArg(); 370 if (inPath == null && params.sessionParams.sizeBytes == 0) { 371 System.err.println("Error: must either specify a package size or an APK file"); 372 return 1; 373 } 374 if (doWriteSession(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk", 375 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 376 return 1; 377 } 378 if (doCommitSession(sessionId, false /*logSuccess*/) 379 != PackageInstaller.STATUS_SUCCESS) { 380 return 1; 381 } 382 System.out.println("Success"); 383 return 0; 384 } finally { 385 try { 386 mInstaller.abandonSession(sessionId); 387 } catch (Exception ignore) { 388 } 389 } 390 } 391 runInstallAbandon()392 private int runInstallAbandon() throws RemoteException { 393 final int sessionId = Integer.parseInt(nextArg()); 394 return doAbandonSession(sessionId, true /*logSuccess*/); 395 } 396 runInstallCommit()397 private int runInstallCommit() throws RemoteException { 398 final int sessionId = Integer.parseInt(nextArg()); 399 return doCommitSession(sessionId, true /*logSuccess*/); 400 } 401 runInstallCreate()402 private int runInstallCreate() throws RemoteException { 403 final InstallParams installParams = makeInstallParams(); 404 final int sessionId = doCreateSession(installParams.sessionParams, 405 installParams.installerPackageName, installParams.userId); 406 407 // NOTE: adb depends on parsing this string 408 System.out.println("Success: created install session [" + sessionId + "]"); 409 return PackageInstaller.STATUS_SUCCESS; 410 } 411 runInstallWrite()412 private int runInstallWrite() throws RemoteException { 413 long sizeBytes = -1; 414 415 String opt; 416 while ((opt = nextOption()) != null) { 417 if (opt.equals("-S")) { 418 sizeBytes = Long.parseLong(nextArg()); 419 } else { 420 throw new IllegalArgumentException("Unknown option: " + opt); 421 } 422 } 423 424 final int sessionId = Integer.parseInt(nextArg()); 425 final String splitName = nextArg(); 426 final String path = nextArg(); 427 return doWriteSession(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); 428 } 429 430 private static class InstallParams { 431 SessionParams sessionParams; 432 String installerPackageName; 433 int userId = UserHandle.USER_ALL; 434 } 435 makeInstallParams()436 private InstallParams makeInstallParams() { 437 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); 438 final InstallParams params = new InstallParams(); 439 params.sessionParams = sessionParams; 440 String opt; 441 while ((opt = nextOption()) != null) { 442 switch (opt) { 443 case "-l": 444 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 445 break; 446 case "-r": 447 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 448 break; 449 case "-i": 450 params.installerPackageName = nextArg(); 451 if (params.installerPackageName == null) { 452 throw new IllegalArgumentException("Missing installer package"); 453 } 454 break; 455 case "-t": 456 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 457 break; 458 case "-s": 459 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL; 460 break; 461 case "-f": 462 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL; 463 break; 464 case "-d": 465 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 466 break; 467 case "-g": 468 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; 469 break; 470 case "--dont-kill": 471 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP; 472 break; 473 case "--originating-uri": 474 sessionParams.originatingUri = Uri.parse(nextOptionData()); 475 break; 476 case "--referrer": 477 sessionParams.referrerUri = Uri.parse(nextOptionData()); 478 break; 479 case "-p": 480 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING; 481 sessionParams.appPackageName = nextOptionData(); 482 if (sessionParams.appPackageName == null) { 483 throw new IllegalArgumentException("Missing inherit package name"); 484 } 485 break; 486 case "-S": 487 sessionParams.setSize(Long.parseLong(nextOptionData())); 488 break; 489 case "--abi": 490 sessionParams.abiOverride = checkAbiArgument(nextOptionData()); 491 break; 492 case "--ephemeral": 493 sessionParams.installFlags |= PackageManager.INSTALL_EPHEMERAL; 494 break; 495 case "--user": 496 params.userId = UserHandle.parseUserArg(nextOptionData()); 497 break; 498 case "--install-location": 499 sessionParams.installLocation = Integer.parseInt(nextOptionData()); 500 break; 501 case "--force-uuid": 502 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID; 503 sessionParams.volumeUuid = nextOptionData(); 504 if ("internal".equals(sessionParams.volumeUuid)) { 505 sessionParams.volumeUuid = null; 506 } 507 break; 508 case "--force-sdk": 509 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; 510 break; 511 default: 512 throw new IllegalArgumentException("Unknown option " + opt); 513 } 514 } 515 return params; 516 } 517 doCreateSession(SessionParams params, String installerPackageName, int userId)518 private int doCreateSession(SessionParams params, String installerPackageName, int userId) 519 throws RemoteException { 520 userId = translateUserId(userId, "runInstallCreate"); 521 if (userId == UserHandle.USER_ALL) { 522 userId = UserHandle.USER_SYSTEM; 523 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 524 } 525 526 final int sessionId = mInstaller.createSession(params, installerPackageName, userId); 527 return sessionId; 528 } 529 doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName, boolean logSuccess)530 private int doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName, 531 boolean logSuccess) throws RemoteException { 532 if ("-".equals(inPath)) { 533 inPath = null; 534 } else if (inPath != null) { 535 final File file = new File(inPath); 536 if (file.isFile()) { 537 sizeBytes = file.length(); 538 } 539 } 540 541 final SessionInfo info = mInstaller.getSessionInfo(sessionId); 542 543 PackageInstaller.Session session = null; 544 InputStream in = null; 545 OutputStream out = null; 546 try { 547 session = new PackageInstaller.Session( 548 mInstaller.openSession(sessionId)); 549 550 if (inPath != null) { 551 in = new FileInputStream(inPath); 552 } else { 553 in = new SizedInputStream(System.in, sizeBytes); 554 } 555 out = session.openWrite(splitName, 0, sizeBytes); 556 557 int total = 0; 558 byte[] buffer = new byte[65536]; 559 int c; 560 while ((c = in.read(buffer)) != -1) { 561 total += c; 562 out.write(buffer, 0, c); 563 564 if (info.sizeBytes > 0) { 565 final float fraction = ((float) c / (float) info.sizeBytes); 566 session.addProgress(fraction); 567 } 568 } 569 session.fsync(out); 570 571 if (logSuccess) { 572 System.out.println("Success: streamed " + total + " bytes"); 573 } 574 return PackageInstaller.STATUS_SUCCESS; 575 } catch (IOException e) { 576 System.err.println("Error: failed to write; " + e.getMessage()); 577 return PackageInstaller.STATUS_FAILURE; 578 } finally { 579 IoUtils.closeQuietly(out); 580 IoUtils.closeQuietly(in); 581 IoUtils.closeQuietly(session); 582 } 583 } 584 doCommitSession(int sessionId, boolean logSuccess)585 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException { 586 PackageInstaller.Session session = null; 587 try { 588 session = new PackageInstaller.Session( 589 mInstaller.openSession(sessionId)); 590 591 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 592 session.commit(receiver.getIntentSender()); 593 594 final Intent result = receiver.getResult(); 595 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 596 PackageInstaller.STATUS_FAILURE); 597 if (status == PackageInstaller.STATUS_SUCCESS) { 598 if (logSuccess) { 599 System.out.println("Success"); 600 } 601 } else { 602 System.err.println("Failure [" 603 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 604 } 605 return status; 606 } finally { 607 IoUtils.closeQuietly(session); 608 } 609 } 610 doAbandonSession(int sessionId, boolean logSuccess)611 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException { 612 PackageInstaller.Session session = null; 613 try { 614 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 615 session.abandon(); 616 if (logSuccess) { 617 System.out.println("Success"); 618 } 619 return PackageInstaller.STATUS_SUCCESS; 620 } finally { 621 IoUtils.closeQuietly(session); 622 } 623 } 624 625 /** 626 * Execute the list sub-command. 627 * 628 * pm list [package | packages] 629 * pm list permission-groups 630 * pm list permissions 631 * pm list features 632 * pm list libraries 633 * pm list instrumentation 634 */ runList()635 private int runList() { 636 final String type = nextArg(); 637 if ("users".equals(type)) { 638 return runShellCommand("user", new String[] { "list" }); 639 } 640 return runShellCommand("package", mArgs); 641 } 642 runUninstall()643 private int runUninstall() { 644 return runShellCommand("package", mArgs); 645 } 646 runPath()647 private int runPath() { 648 int userId = UserHandle.USER_SYSTEM; 649 String option = nextOption(); 650 if (option != null && option.equals("--user")) { 651 String optionData = nextOptionData(); 652 if (optionData == null || !isNumber(optionData)) { 653 System.err.println("Error: no USER_ID specified"); 654 return showUsage(); 655 } else { 656 userId = Integer.parseInt(optionData); 657 } 658 } 659 660 String pkg = nextArg(); 661 if (pkg == null) { 662 System.err.println("Error: no package specified"); 663 return 1; 664 } 665 return displayPackageFilePath(pkg, userId); 666 } 667 runDump()668 private int runDump() { 669 String pkg = nextArg(); 670 if (pkg == null) { 671 System.err.println("Error: no package specified"); 672 return 1; 673 } 674 ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg); 675 return 0; 676 } 677 678 class LocalPackageInstallObserver extends PackageInstallObserver { 679 boolean finished; 680 int result; 681 String extraPermission; 682 String extraPackage; 683 684 @Override onPackageInstalled(String name, int status, String msg, Bundle extras)685 public void onPackageInstalled(String name, int status, String msg, Bundle extras) { 686 synchronized (this) { 687 finished = true; 688 result = status; 689 if (status == PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION) { 690 extraPermission = extras.getString( 691 PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION); 692 extraPackage = extras.getString( 693 PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE); 694 } 695 notifyAll(); 696 } 697 } 698 } 699 700 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined} runSetAppLink()701 private int runSetAppLink() { 702 int userId = UserHandle.USER_SYSTEM; 703 704 String opt; 705 while ((opt = nextOption()) != null) { 706 if (opt.equals("--user")) { 707 userId = Integer.parseInt(nextOptionData()); 708 if (userId < 0) { 709 System.err.println("Error: user must be >= 0"); 710 return 1; 711 } 712 } else { 713 System.err.println("Error: unknown option: " + opt); 714 return showUsage(); 715 } 716 } 717 718 // Package name to act on; required 719 final String pkg = nextArg(); 720 if (pkg == null) { 721 System.err.println("Error: no package specified."); 722 return showUsage(); 723 } 724 725 // State to apply; {always|ask|never|undefined}, required 726 final String modeString = nextArg(); 727 if (modeString == null) { 728 System.err.println("Error: no app link state specified."); 729 return showUsage(); 730 } 731 732 final int newMode; 733 switch (modeString.toLowerCase()) { 734 case "undefined": 735 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 736 break; 737 738 case "always": 739 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 740 break; 741 742 case "ask": 743 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 744 break; 745 746 case "always-ask": 747 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 748 break; 749 750 case "never": 751 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 752 break; 753 754 default: 755 System.err.println("Error: unknown app link state '" + modeString + "'"); 756 return 1; 757 } 758 759 try { 760 final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId); 761 if (info == null) { 762 System.err.println("Error: package " + pkg + " not found."); 763 return 1; 764 } 765 766 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 767 System.err.println("Error: package " + pkg + " does not handle web links."); 768 return 1; 769 } 770 771 if (!mPm.updateIntentVerificationStatus(pkg, newMode, userId)) { 772 System.err.println("Error: unable to update app link status for " + pkg); 773 return 1; 774 } 775 } catch (Exception e) { 776 System.err.println(e.toString()); 777 System.err.println(PM_NOT_RUNNING_ERR); 778 return 1; 779 } 780 781 return 0; 782 } 783 784 // pm get-app-link [--user USER_ID] PACKAGE runGetAppLink()785 private int runGetAppLink() { 786 int userId = UserHandle.USER_SYSTEM; 787 788 String opt; 789 while ((opt = nextOption()) != null) { 790 if (opt.equals("--user")) { 791 userId = Integer.parseInt(nextOptionData()); 792 if (userId < 0) { 793 System.err.println("Error: user must be >= 0"); 794 return 1; 795 } 796 } else { 797 System.err.println("Error: unknown option: " + opt); 798 return showUsage(); 799 } 800 } 801 802 // Package name to act on; required 803 final String pkg = nextArg(); 804 if (pkg == null) { 805 System.err.println("Error: no package specified."); 806 return showUsage(); 807 } 808 809 try { 810 final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId); 811 if (info == null) { 812 System.err.println("Error: package " + pkg + " not found."); 813 return 1; 814 } 815 816 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { 817 System.err.println("Error: package " + pkg + " does not handle web links."); 818 return 1; 819 } 820 821 System.out.println(linkStateToString(mPm.getIntentVerificationStatus(pkg, userId))); 822 } catch (Exception e) { 823 System.err.println(e.toString()); 824 System.err.println(PM_NOT_RUNNING_ERR); 825 return 1; 826 } 827 828 return 0; 829 } 830 linkStateToString(int state)831 private String linkStateToString(int state) { 832 switch (state) { 833 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined"; 834 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask"; 835 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always"; 836 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never"; 837 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask"; 838 } 839 return "Unknown link state: " + state; 840 } 841 runSetInstallLocation()842 private int runSetInstallLocation() { 843 int loc; 844 845 String arg = nextArg(); 846 if (arg == null) { 847 System.err.println("Error: no install location specified."); 848 return 1; 849 } 850 try { 851 loc = Integer.parseInt(arg); 852 } catch (NumberFormatException e) { 853 System.err.println("Error: install location has to be a number."); 854 return 1; 855 } 856 try { 857 if (!mPm.setInstallLocation(loc)) { 858 System.err.println("Error: install location has to be a number."); 859 return 1; 860 } 861 return 0; 862 } catch (RemoteException e) { 863 System.err.println(e.toString()); 864 System.err.println(PM_NOT_RUNNING_ERR); 865 return 1; 866 } 867 } 868 runGetInstallLocation()869 private int runGetInstallLocation() { 870 try { 871 int loc = mPm.getInstallLocation(); 872 String locStr = "invalid"; 873 if (loc == PackageHelper.APP_INSTALL_AUTO) { 874 locStr = "auto"; 875 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) { 876 locStr = "internal"; 877 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) { 878 locStr = "external"; 879 } 880 System.out.println(loc + "[" + locStr + "]"); 881 return 0; 882 } catch (RemoteException e) { 883 System.err.println(e.toString()); 884 System.err.println(PM_NOT_RUNNING_ERR); 885 return 1; 886 } 887 } 888 runSetInstaller()889 private int runSetInstaller() throws RemoteException { 890 final String targetPackage = nextArg(); 891 final String installerPackageName = nextArg(); 892 893 if (targetPackage == null || installerPackageName == null) { 894 throw new IllegalArgumentException( 895 "must provide both target and installer package names"); 896 } 897 898 mPm.setInstallerPackageName(targetPackage, installerPackageName); 899 System.out.println("Success"); 900 return 0; 901 } 902 runCreateUser()903 public int runCreateUser() { 904 String name; 905 int userId = -1; 906 int flags = 0; 907 String opt; 908 while ((opt = nextOption()) != null) { 909 if ("--profileOf".equals(opt)) { 910 String optionData = nextOptionData(); 911 if (optionData == null || !isNumber(optionData)) { 912 System.err.println("Error: no USER_ID specified"); 913 return showUsage(); 914 } else { 915 userId = Integer.parseInt(optionData); 916 } 917 } else if ("--managed".equals(opt)) { 918 flags |= UserInfo.FLAG_MANAGED_PROFILE; 919 } else if ("--restricted".equals(opt)) { 920 flags |= UserInfo.FLAG_RESTRICTED; 921 } else if ("--ephemeral".equals(opt)) { 922 flags |= UserInfo.FLAG_EPHEMERAL; 923 } else if ("--guest".equals(opt)) { 924 flags |= UserInfo.FLAG_GUEST; 925 } else if ("--demo".equals(opt)) { 926 flags |= UserInfo.FLAG_DEMO; 927 } else { 928 System.err.println("Error: unknown option " + opt); 929 return showUsage(); 930 } 931 } 932 String arg = nextArg(); 933 if (arg == null) { 934 System.err.println("Error: no user name specified."); 935 return 1; 936 } 937 name = arg; 938 try { 939 UserInfo info; 940 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) { 941 // In non-split user mode, userId can only be SYSTEM 942 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM; 943 info = mUm.createRestrictedProfile(name, parentUserId); 944 mAm.addSharedAccountsFromParentUser(parentUserId, userId); 945 } else if (userId < 0) { 946 info = mUm.createUser(name, flags); 947 } else { 948 info = mUm.createProfileForUser(name, flags, userId); 949 } 950 951 if (info != null) { 952 System.out.println("Success: created user id " + info.id); 953 return 1; 954 } else { 955 System.err.println("Error: couldn't create User."); 956 return 1; 957 } 958 } catch (RemoteException e) { 959 System.err.println(e.toString()); 960 System.err.println(PM_NOT_RUNNING_ERR); 961 return 1; 962 } 963 } 964 runRemoveUser()965 public int runRemoveUser() { 966 int userId; 967 String arg = nextArg(); 968 if (arg == null) { 969 System.err.println("Error: no user id specified."); 970 return 1; 971 } 972 try { 973 userId = Integer.parseInt(arg); 974 } catch (NumberFormatException e) { 975 System.err.println("Error: user id '" + arg + "' is not a number."); 976 return 1; 977 } 978 try { 979 if (mUm.removeUser(userId)) { 980 System.out.println("Success: removed user"); 981 return 0; 982 } else { 983 System.err.println("Error: couldn't remove user id " + userId); 984 return 1; 985 } 986 } catch (RemoteException e) { 987 System.err.println(e.toString()); 988 System.err.println(PM_NOT_RUNNING_ERR); 989 return 1; 990 } 991 } 992 runGetMaxUsers()993 public int runGetMaxUsers() { 994 System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers()); 995 return 0; 996 } 997 runForceDexOpt()998 public int runForceDexOpt() { 999 final String packageName = nextArg(); 1000 try { 1001 mPm.forceDexOpt(packageName); 1002 return 0; 1003 } catch (RemoteException e) { 1004 throw e.rethrowAsRuntimeException(); 1005 } 1006 } 1007 runMovePackage()1008 public int runMovePackage() { 1009 final String packageName = nextArg(); 1010 String volumeUuid = nextArg(); 1011 if ("internal".equals(volumeUuid)) { 1012 volumeUuid = null; 1013 } 1014 1015 try { 1016 final int moveId = mPm.movePackage(packageName, volumeUuid); 1017 1018 int status = mPm.getMoveStatus(moveId); 1019 while (!PackageManager.isMoveStatusFinished(status)) { 1020 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1021 status = mPm.getMoveStatus(moveId); 1022 } 1023 1024 if (status == PackageManager.MOVE_SUCCEEDED) { 1025 System.out.println("Success"); 1026 return 0; 1027 } else { 1028 System.err.println("Failure [" + status + "]"); 1029 return 1; 1030 } 1031 } catch (RemoteException e) { 1032 throw e.rethrowAsRuntimeException(); 1033 } 1034 } 1035 runMovePrimaryStorage()1036 public int runMovePrimaryStorage() { 1037 String volumeUuid = nextArg(); 1038 if ("internal".equals(volumeUuid)) { 1039 volumeUuid = null; 1040 } 1041 1042 try { 1043 final int moveId = mPm.movePrimaryStorage(volumeUuid); 1044 1045 int status = mPm.getMoveStatus(moveId); 1046 while (!PackageManager.isMoveStatusFinished(status)) { 1047 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1048 status = mPm.getMoveStatus(moveId); 1049 } 1050 1051 if (status == PackageManager.MOVE_SUCCEEDED) { 1052 System.out.println("Success"); 1053 return 0; 1054 } else { 1055 System.err.println("Failure [" + status + "]"); 1056 return 1; 1057 } 1058 } catch (RemoteException e) { 1059 throw e.rethrowAsRuntimeException(); 1060 } 1061 } 1062 runSetUserRestriction()1063 public int runSetUserRestriction() { 1064 int userId = UserHandle.USER_SYSTEM; 1065 String opt = nextOption(); 1066 if (opt != null && "--user".equals(opt)) { 1067 String arg = nextArg(); 1068 if (arg == null || !isNumber(arg)) { 1069 System.err.println("Error: valid userId not specified"); 1070 return 1; 1071 } 1072 userId = Integer.parseInt(arg); 1073 } 1074 1075 String restriction = nextArg(); 1076 String arg = nextArg(); 1077 boolean value; 1078 if ("1".equals(arg)) { 1079 value = true; 1080 } else if ("0".equals(arg)) { 1081 value = false; 1082 } else { 1083 System.err.println("Error: valid value not specified"); 1084 return 1; 1085 } 1086 try { 1087 mUm.setUserRestriction(restriction, value, userId); 1088 return 0; 1089 } catch (RemoteException e) { 1090 System.err.println(e.toString()); 1091 return 1; 1092 } 1093 } 1094 1095 static class ClearDataObserver extends IPackageDataObserver.Stub { 1096 boolean finished; 1097 boolean result; 1098 1099 @Override onRemoveCompleted(String packageName, boolean succeeded)1100 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1101 synchronized (this) { 1102 finished = true; 1103 result = succeeded; 1104 notifyAll(); 1105 } 1106 } 1107 } 1108 runClear()1109 private int runClear() { 1110 int userId = UserHandle.USER_SYSTEM; 1111 String option = nextOption(); 1112 if (option != null && option.equals("--user")) { 1113 String optionData = nextOptionData(); 1114 if (optionData == null || !isNumber(optionData)) { 1115 System.err.println("Error: no USER_ID specified"); 1116 return showUsage(); 1117 } else { 1118 userId = Integer.parseInt(optionData); 1119 } 1120 } 1121 1122 String pkg = nextArg(); 1123 if (pkg == null) { 1124 System.err.println("Error: no package specified"); 1125 return showUsage(); 1126 } 1127 1128 ClearDataObserver obs = new ClearDataObserver(); 1129 try { 1130 ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId); 1131 synchronized (obs) { 1132 while (!obs.finished) { 1133 try { 1134 obs.wait(); 1135 } catch (InterruptedException e) { 1136 } 1137 } 1138 } 1139 1140 if (obs.result) { 1141 System.out.println("Success"); 1142 return 0; 1143 } else { 1144 System.err.println("Failed"); 1145 return 1; 1146 } 1147 } catch (RemoteException e) { 1148 System.err.println(e.toString()); 1149 System.err.println(PM_NOT_RUNNING_ERR); 1150 return 1; 1151 } 1152 } 1153 enabledSettingToString(int state)1154 private static String enabledSettingToString(int state) { 1155 switch (state) { 1156 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1157 return "default"; 1158 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1159 return "enabled"; 1160 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1161 return "disabled"; 1162 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1163 return "disabled-user"; 1164 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1165 return "disabled-until-used"; 1166 } 1167 return "unknown"; 1168 } 1169 isNumber(String s)1170 private static boolean isNumber(String s) { 1171 try { 1172 Integer.parseInt(s); 1173 } catch (NumberFormatException nfe) { 1174 return false; 1175 } 1176 return true; 1177 } 1178 runSetEnabledSetting(int state)1179 private int runSetEnabledSetting(int state) { 1180 int userId = UserHandle.USER_SYSTEM; 1181 String option = nextOption(); 1182 if (option != null && option.equals("--user")) { 1183 String optionData = nextOptionData(); 1184 if (optionData == null || !isNumber(optionData)) { 1185 System.err.println("Error: no USER_ID specified"); 1186 return showUsage(); 1187 } else { 1188 userId = Integer.parseInt(optionData); 1189 } 1190 } 1191 1192 String pkg = nextArg(); 1193 if (pkg == null) { 1194 System.err.println("Error: no package or component specified"); 1195 return showUsage(); 1196 } 1197 ComponentName cn = ComponentName.unflattenFromString(pkg); 1198 if (cn == null) { 1199 try { 1200 mPm.setApplicationEnabledSetting(pkg, state, 0, userId, 1201 "shell:" + android.os.Process.myUid()); 1202 System.out.println("Package " + pkg + " new state: " 1203 + enabledSettingToString( 1204 mPm.getApplicationEnabledSetting(pkg, userId))); 1205 return 0; 1206 } catch (RemoteException e) { 1207 System.err.println(e.toString()); 1208 System.err.println(PM_NOT_RUNNING_ERR); 1209 return 1; 1210 } 1211 } else { 1212 try { 1213 mPm.setComponentEnabledSetting(cn, state, 0, userId); 1214 System.out.println("Component " + cn.toShortString() + " new state: " 1215 + enabledSettingToString( 1216 mPm.getComponentEnabledSetting(cn, userId))); 1217 return 0; 1218 } catch (RemoteException e) { 1219 System.err.println(e.toString()); 1220 System.err.println(PM_NOT_RUNNING_ERR); 1221 return 1; 1222 } 1223 } 1224 } 1225 runSetHiddenSetting(boolean state)1226 private int runSetHiddenSetting(boolean state) { 1227 int userId = UserHandle.USER_SYSTEM; 1228 String option = nextOption(); 1229 if (option != null && option.equals("--user")) { 1230 String optionData = nextOptionData(); 1231 if (optionData == null || !isNumber(optionData)) { 1232 System.err.println("Error: no USER_ID specified"); 1233 return showUsage(); 1234 } else { 1235 userId = Integer.parseInt(optionData); 1236 } 1237 } 1238 1239 String pkg = nextArg(); 1240 if (pkg == null) { 1241 System.err.println("Error: no package or component specified"); 1242 return showUsage(); 1243 } 1244 try { 1245 mPm.setApplicationHiddenSettingAsUser(pkg, state, userId); 1246 System.out.println("Package " + pkg + " new hidden state: " 1247 + mPm.getApplicationHiddenSettingAsUser(pkg, userId)); 1248 return 0; 1249 } catch (RemoteException e) { 1250 System.err.println(e.toString()); 1251 System.err.println(PM_NOT_RUNNING_ERR); 1252 return 1; 1253 } 1254 } 1255 runGrantRevokePermission(boolean grant)1256 private int runGrantRevokePermission(boolean grant) { 1257 int userId = UserHandle.USER_SYSTEM; 1258 1259 String opt = null; 1260 while ((opt = nextOption()) != null) { 1261 if (opt.equals("--user")) { 1262 userId = Integer.parseInt(nextArg()); 1263 } 1264 } 1265 1266 String pkg = nextArg(); 1267 if (pkg == null) { 1268 System.err.println("Error: no package specified"); 1269 return showUsage(); 1270 } 1271 String perm = nextArg(); 1272 if (perm == null) { 1273 System.err.println("Error: no permission specified"); 1274 return showUsage(); 1275 } 1276 1277 try { 1278 if (grant) { 1279 mPm.grantRuntimePermission(pkg, perm, userId); 1280 } else { 1281 mPm.revokeRuntimePermission(pkg, perm, userId); 1282 } 1283 return 0; 1284 } catch (RemoteException e) { 1285 System.err.println(e.toString()); 1286 System.err.println(PM_NOT_RUNNING_ERR); 1287 return 1; 1288 } catch (IllegalArgumentException e) { 1289 System.err.println("Bad argument: " + e.toString()); 1290 return showUsage(); 1291 } catch (SecurityException e) { 1292 System.err.println("Operation not allowed: " + e.toString()); 1293 return 1; 1294 } 1295 } 1296 runResetPermissions()1297 private int runResetPermissions() { 1298 try { 1299 mPm.resetRuntimePermissions(); 1300 return 0; 1301 } catch (RemoteException e) { 1302 System.err.println(e.toString()); 1303 System.err.println(PM_NOT_RUNNING_ERR); 1304 return 1; 1305 } catch (IllegalArgumentException e) { 1306 System.err.println("Bad argument: " + e.toString()); 1307 return showUsage(); 1308 } catch (SecurityException e) { 1309 System.err.println("Operation not allowed: " + e.toString()); 1310 return 1; 1311 } 1312 } 1313 runSetPermissionEnforced()1314 private int runSetPermissionEnforced() { 1315 final String permission = nextArg(); 1316 if (permission == null) { 1317 System.err.println("Error: no permission specified"); 1318 return showUsage(); 1319 } 1320 final String enforcedRaw = nextArg(); 1321 if (enforcedRaw == null) { 1322 System.err.println("Error: no enforcement specified"); 1323 return showUsage(); 1324 } 1325 final boolean enforced = Boolean.parseBoolean(enforcedRaw); 1326 try { 1327 mPm.setPermissionEnforced(permission, enforced); 1328 return 0; 1329 } catch (RemoteException e) { 1330 System.err.println(e.toString()); 1331 System.err.println(PM_NOT_RUNNING_ERR); 1332 return 1; 1333 } catch (IllegalArgumentException e) { 1334 System.err.println("Bad argument: " + e.toString()); 1335 return showUsage(); 1336 } catch (SecurityException e) { 1337 System.err.println("Operation not allowed: " + e.toString()); 1338 return 1; 1339 } 1340 } 1341 1342 static class ClearCacheObserver extends IPackageDataObserver.Stub { 1343 boolean finished; 1344 boolean result; 1345 1346 @Override onRemoveCompleted(String packageName, boolean succeeded)1347 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1348 synchronized (this) { 1349 finished = true; 1350 result = succeeded; 1351 notifyAll(); 1352 } 1353 } 1354 1355 } 1356 runTrimCaches()1357 private int runTrimCaches() { 1358 String size = nextArg(); 1359 if (size == null) { 1360 System.err.println("Error: no size specified"); 1361 return showUsage(); 1362 } 1363 int len = size.length(); 1364 long multiplier = 1; 1365 if (len > 1) { 1366 char c = size.charAt(len-1); 1367 if (c == 'K' || c == 'k') { 1368 multiplier = 1024L; 1369 } else if (c == 'M' || c == 'm') { 1370 multiplier = 1024L*1024L; 1371 } else if (c == 'G' || c == 'g') { 1372 multiplier = 1024L*1024L*1024L; 1373 } else { 1374 System.err.println("Invalid suffix: " + c); 1375 return showUsage(); 1376 } 1377 size = size.substring(0, len-1); 1378 } 1379 long sizeVal; 1380 try { 1381 sizeVal = Long.parseLong(size) * multiplier; 1382 } catch (NumberFormatException e) { 1383 System.err.println("Error: expected number at: " + size); 1384 return showUsage(); 1385 } 1386 String volumeUuid = nextArg(); 1387 if ("internal".equals(volumeUuid)) { 1388 volumeUuid = null; 1389 } 1390 ClearDataObserver obs = new ClearDataObserver(); 1391 try { 1392 mPm.freeStorageAndNotify(volumeUuid, sizeVal, obs); 1393 synchronized (obs) { 1394 while (!obs.finished) { 1395 try { 1396 obs.wait(); 1397 } catch (InterruptedException e) { 1398 } 1399 } 1400 } 1401 return 0; 1402 } catch (RemoteException e) { 1403 System.err.println(e.toString()); 1404 System.err.println(PM_NOT_RUNNING_ERR); 1405 return 1; 1406 } catch (IllegalArgumentException e) { 1407 System.err.println("Bad argument: " + e.toString()); 1408 return showUsage(); 1409 } catch (SecurityException e) { 1410 System.err.println("Operation not allowed: " + e.toString()); 1411 return 1; 1412 } 1413 } 1414 1415 /** 1416 * Displays the package file for a package. 1417 * @param pckg 1418 */ displayPackageFilePath(String pckg, int userId)1419 private int displayPackageFilePath(String pckg, int userId) { 1420 try { 1421 PackageInfo info = mPm.getPackageInfo(pckg, 0, userId); 1422 if (info != null && info.applicationInfo != null) { 1423 System.out.print("package:"); 1424 System.out.println(info.applicationInfo.sourceDir); 1425 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { 1426 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { 1427 System.out.print("package:"); 1428 System.out.println(splitSourceDir); 1429 } 1430 } 1431 return 0; 1432 } 1433 } catch (RemoteException e) { 1434 System.err.println(e.toString()); 1435 System.err.println(PM_NOT_RUNNING_ERR); 1436 } 1437 return 1; 1438 } 1439 nextOption()1440 private String nextOption() { 1441 if (mNextArg >= mArgs.length) { 1442 return null; 1443 } 1444 String arg = mArgs[mNextArg]; 1445 if (!arg.startsWith("-")) { 1446 return null; 1447 } 1448 mNextArg++; 1449 if (arg.equals("--")) { 1450 return null; 1451 } 1452 if (arg.length() > 1 && arg.charAt(1) != '-') { 1453 if (arg.length() > 2) { 1454 mCurArgData = arg.substring(2); 1455 return arg.substring(0, 2); 1456 } else { 1457 mCurArgData = null; 1458 return arg; 1459 } 1460 } 1461 mCurArgData = null; 1462 return arg; 1463 } 1464 nextOptionData()1465 private String nextOptionData() { 1466 if (mCurArgData != null) { 1467 return mCurArgData; 1468 } 1469 if (mNextArg >= mArgs.length) { 1470 return null; 1471 } 1472 String data = mArgs[mNextArg]; 1473 mNextArg++; 1474 return data; 1475 } 1476 nextArg()1477 private String nextArg() { 1478 if (mNextArg >= mArgs.length) { 1479 return null; 1480 } 1481 String arg = mArgs[mNextArg]; 1482 mNextArg++; 1483 return arg; 1484 } 1485 showUsage()1486 private static int showUsage() { 1487 System.err.println("usage: pm path [--user USER_ID] PACKAGE"); 1488 System.err.println(" pm dump PACKAGE"); 1489 System.err.println(" pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]"); 1490 System.err.println(" pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]"); 1491 System.err.println(" [--install-location 0/1/2]"); 1492 System.err.println(" [--force-uuid internal|UUID]"); 1493 System.err.println(" pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]"); 1494 System.err.println(" pm install-commit SESSION_ID"); 1495 System.err.println(" pm install-abandon SESSION_ID"); 1496 System.err.println(" pm uninstall [-k] [--user USER_ID] PACKAGE"); 1497 System.err.println(" pm set-installer PACKAGE INSTALLER"); 1498 System.err.println(" pm move-package PACKAGE [internal|UUID]"); 1499 System.err.println(" pm move-primary-storage [internal|UUID]"); 1500 System.err.println(" pm clear [--user USER_ID] PACKAGE"); 1501 System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1502 System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1503 System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 1504 System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 1505 System.err.println(" pm default-state [--user USER_ID] PACKAGE_OR_COMPONENT"); 1506 System.err.println(" pm hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1507 System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1508 System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION"); 1509 System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION"); 1510 System.err.println(" pm reset-permissions"); 1511 System.err.println(" pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}"); 1512 System.err.println(" pm get-app-link [--user USER_ID] PACKAGE"); 1513 System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]"); 1514 System.err.println(" pm get-install-location"); 1515 System.err.println(" pm set-permission-enforced PERMISSION [true|false]"); 1516 System.err.println(" pm trim-caches DESIRED_FREE_SPACE [internal|UUID]"); 1517 System.err.println(" pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME"); 1518 System.err.println(" pm remove-user USER_ID"); 1519 System.err.println(" pm get-max-users"); 1520 System.err.println(""); 1521 System.err.println("NOTE: 'pm list' commands have moved! Run 'adb shell cmd package'"); 1522 System.err.println(" to display the new commands."); 1523 System.err.println(""); 1524 System.err.println("pm path: print the path to the .apk of the given PACKAGE."); 1525 System.err.println(""); 1526 System.err.println("pm dump: print system state associated with the given PACKAGE."); 1527 System.err.println(""); 1528 System.err.println("pm install: install a single legacy package"); 1529 System.err.println("pm install-create: create an install session"); 1530 System.err.println(" -l: forward lock application"); 1531 System.err.println(" -r: replace existing application"); 1532 System.err.println(" -t: allow test packages"); 1533 System.err.println(" -i: specify the installer package name"); 1534 System.err.println(" -s: install application on sdcard"); 1535 System.err.println(" -f: install application on internal flash"); 1536 System.err.println(" -d: allow version code downgrade (debuggable packages only)"); 1537 System.err.println(" -p: partial application install"); 1538 System.err.println(" -g: grant all runtime permissions"); 1539 System.err.println(" -S: size in bytes of entire session"); 1540 System.err.println(""); 1541 System.err.println("pm install-write: write a package into existing session; path may"); 1542 System.err.println(" be '-' to read from stdin"); 1543 System.err.println(" -S: size in bytes of package, required for stdin"); 1544 System.err.println(""); 1545 System.err.println("pm install-commit: perform install of fully staged session"); 1546 System.err.println("pm install-abandon: abandon session"); 1547 System.err.println(""); 1548 System.err.println("pm set-installer: set installer package name"); 1549 System.err.println(""); 1550 System.err.println("pm uninstall: removes a package from the system. Options:"); 1551 System.err.println(" -k: keep the data and cache directories around after package removal."); 1552 System.err.println(""); 1553 System.err.println("pm clear: deletes all data associated with a package."); 1554 System.err.println(""); 1555 System.err.println("pm enable, disable, disable-user, disable-until-used, default-state:"); 1556 System.err.println(" these commands change the enabled state of a given package or"); 1557 System.err.println(" component (written as \"package/class\")."); 1558 System.err.println(""); 1559 System.err.println("pm grant, revoke: these commands either grant or revoke permissions"); 1560 System.err.println(" to apps. The permissions must be declared as used in the app's"); 1561 System.err.println(" manifest, be runtime permissions (protection level dangerous),"); 1562 System.err.println(" and the app targeting SDK greater than Lollipop MR1."); 1563 System.err.println(""); 1564 System.err.println("pm reset-permissions: revert all runtime permissions to their default state."); 1565 System.err.println(""); 1566 System.err.println("pm get-install-location: returns the current install location."); 1567 System.err.println(" 0 [auto]: Let system decide the best location"); 1568 System.err.println(" 1 [internal]: Install on internal device storage"); 1569 System.err.println(" 2 [external]: Install on external media"); 1570 System.err.println(""); 1571 System.err.println("pm set-install-location: changes the default install location."); 1572 System.err.println(" NOTE: this is only intended for debugging; using this can cause"); 1573 System.err.println(" applications to break and other undersireable behavior."); 1574 System.err.println(" 0 [auto]: Let system decide the best location"); 1575 System.err.println(" 1 [internal]: Install on internal device storage"); 1576 System.err.println(" 2 [external]: Install on external media"); 1577 System.err.println(""); 1578 System.err.println("pm trim-caches: trim cache files to reach the given free space."); 1579 System.err.println(""); 1580 System.err.println("pm create-user: create a new user with the given USER_NAME,"); 1581 System.err.println(" printing the new user identifier of the user."); 1582 System.err.println(""); 1583 System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,"); 1584 System.err.println(" deleting all data associated with that user"); 1585 System.err.println(""); 1586 return 1; 1587 } 1588 } 1589