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 17package com.android.commands.pm; 18 19import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 20import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 21import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 22import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 23import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 24 25import android.accounts.IAccountManager; 26import android.app.ActivityManager; 27import android.app.ActivityManagerNative; 28import android.app.PackageInstallObserver; 29import android.content.ComponentName; 30import android.content.Context; 31import android.content.IIntentReceiver; 32import android.content.IIntentSender; 33import android.content.Intent; 34import android.content.IntentSender; 35import android.content.pm.ApplicationInfo; 36import android.content.pm.IPackageDataObserver; 37import android.content.pm.IPackageInstaller; 38import android.content.pm.IPackageManager; 39import android.content.pm.PackageInfo; 40import android.content.pm.PackageInstaller; 41import android.content.pm.PackageInstaller.SessionInfo; 42import android.content.pm.PackageInstaller.SessionParams; 43import android.content.pm.PackageManager; 44import android.content.pm.UserInfo; 45import android.net.Uri; 46import android.os.Binder; 47import android.os.Build; 48import android.os.Bundle; 49import android.os.Handler; 50import android.os.HandlerThread; 51import android.os.IUserManager; 52import android.os.RemoteException; 53import android.os.ResultReceiver; 54import android.os.ServiceManager; 55import android.os.SystemClock; 56import android.os.UserHandle; 57import android.os.UserManager; 58import android.text.TextUtils; 59import android.text.format.DateUtils; 60import android.util.Log; 61 62import com.android.internal.content.PackageHelper; 63import com.android.internal.util.ArrayUtils; 64import com.android.internal.util.SizedInputStream; 65 66import libcore.io.IoUtils; 67 68import java.io.File; 69import java.io.FileDescriptor; 70import java.io.FileInputStream; 71import java.io.IOException; 72import java.io.InputStream; 73import java.io.OutputStream; 74import java.util.concurrent.SynchronousQueue; 75import java.util.concurrent.TimeUnit; 76 77public 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 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 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 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 318 public IntentSender getIntentSender() { 319 return new IntentSender((IIntentSender) mLocalSender); 320 } 321 322 public Intent getResult() { 323 try { 324 return mResult.take(); 325 } catch (InterruptedException e) { 326 throw new RuntimeException(e); 327 } 328 } 329 } 330 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 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 */ 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 392 private int runInstallAbandon() throws RemoteException { 393 final int sessionId = Integer.parseInt(nextArg()); 394 return doAbandonSession(sessionId, true /*logSuccess*/); 395 } 396 397 private int runInstallCommit() throws RemoteException { 398 final int sessionId = Integer.parseInt(nextArg()); 399 return doCommitSession(sessionId, true /*logSuccess*/); 400 } 401 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 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 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 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 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 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 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 */ 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 643 private int runUninstall() { 644 return runShellCommand("package", mArgs); 645 } 646 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 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 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} 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 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 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 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 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 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 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 { 926 System.err.println("Error: unknown option " + opt); 927 return showUsage(); 928 } 929 } 930 String arg = nextArg(); 931 if (arg == null) { 932 System.err.println("Error: no user name specified."); 933 return 1; 934 } 935 name = arg; 936 try { 937 UserInfo info; 938 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) { 939 // In non-split user mode, userId can only be SYSTEM 940 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM; 941 info = mUm.createRestrictedProfile(name, parentUserId); 942 mAm.addSharedAccountsFromParentUser(parentUserId, userId); 943 } else if (userId < 0) { 944 info = mUm.createUser(name, flags); 945 } else { 946 info = mUm.createProfileForUser(name, flags, userId); 947 } 948 949 if (info != null) { 950 System.out.println("Success: created user id " + info.id); 951 return 1; 952 } else { 953 System.err.println("Error: couldn't create User."); 954 return 1; 955 } 956 } catch (RemoteException e) { 957 System.err.println(e.toString()); 958 System.err.println(PM_NOT_RUNNING_ERR); 959 return 1; 960 } 961 } 962 963 public int runRemoveUser() { 964 int userId; 965 String arg = nextArg(); 966 if (arg == null) { 967 System.err.println("Error: no user id specified."); 968 return 1; 969 } 970 try { 971 userId = Integer.parseInt(arg); 972 } catch (NumberFormatException e) { 973 System.err.println("Error: user id '" + arg + "' is not a number."); 974 return 1; 975 } 976 try { 977 if (mUm.removeUser(userId)) { 978 System.out.println("Success: removed user"); 979 return 0; 980 } else { 981 System.err.println("Error: couldn't remove user id " + userId); 982 return 1; 983 } 984 } catch (RemoteException e) { 985 System.err.println(e.toString()); 986 System.err.println(PM_NOT_RUNNING_ERR); 987 return 1; 988 } 989 } 990 991 public int runGetMaxUsers() { 992 System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers()); 993 return 0; 994 } 995 996 public int runForceDexOpt() { 997 final String packageName = nextArg(); 998 try { 999 mPm.forceDexOpt(packageName); 1000 return 0; 1001 } catch (RemoteException e) { 1002 throw e.rethrowAsRuntimeException(); 1003 } 1004 } 1005 1006 public int runMovePackage() { 1007 final String packageName = nextArg(); 1008 String volumeUuid = nextArg(); 1009 if ("internal".equals(volumeUuid)) { 1010 volumeUuid = null; 1011 } 1012 1013 try { 1014 final int moveId = mPm.movePackage(packageName, volumeUuid); 1015 1016 int status = mPm.getMoveStatus(moveId); 1017 while (!PackageManager.isMoveStatusFinished(status)) { 1018 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1019 status = mPm.getMoveStatus(moveId); 1020 } 1021 1022 if (status == PackageManager.MOVE_SUCCEEDED) { 1023 System.out.println("Success"); 1024 return 0; 1025 } else { 1026 System.err.println("Failure [" + status + "]"); 1027 return 1; 1028 } 1029 } catch (RemoteException e) { 1030 throw e.rethrowAsRuntimeException(); 1031 } 1032 } 1033 1034 public int runMovePrimaryStorage() { 1035 String volumeUuid = nextArg(); 1036 if ("internal".equals(volumeUuid)) { 1037 volumeUuid = null; 1038 } 1039 1040 try { 1041 final int moveId = mPm.movePrimaryStorage(volumeUuid); 1042 1043 int status = mPm.getMoveStatus(moveId); 1044 while (!PackageManager.isMoveStatusFinished(status)) { 1045 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS); 1046 status = mPm.getMoveStatus(moveId); 1047 } 1048 1049 if (status == PackageManager.MOVE_SUCCEEDED) { 1050 System.out.println("Success"); 1051 return 0; 1052 } else { 1053 System.err.println("Failure [" + status + "]"); 1054 return 1; 1055 } 1056 } catch (RemoteException e) { 1057 throw e.rethrowAsRuntimeException(); 1058 } 1059 } 1060 1061 public int runSetUserRestriction() { 1062 int userId = UserHandle.USER_SYSTEM; 1063 String opt = nextOption(); 1064 if (opt != null && "--user".equals(opt)) { 1065 String arg = nextArg(); 1066 if (arg == null || !isNumber(arg)) { 1067 System.err.println("Error: valid userId not specified"); 1068 return 1; 1069 } 1070 userId = Integer.parseInt(arg); 1071 } 1072 1073 String restriction = nextArg(); 1074 String arg = nextArg(); 1075 boolean value; 1076 if ("1".equals(arg)) { 1077 value = true; 1078 } else if ("0".equals(arg)) { 1079 value = false; 1080 } else { 1081 System.err.println("Error: valid value not specified"); 1082 return 1; 1083 } 1084 try { 1085 mUm.setUserRestriction(restriction, value, userId); 1086 return 0; 1087 } catch (RemoteException e) { 1088 System.err.println(e.toString()); 1089 return 1; 1090 } 1091 } 1092 1093 static class ClearDataObserver extends IPackageDataObserver.Stub { 1094 boolean finished; 1095 boolean result; 1096 1097 @Override 1098 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1099 synchronized (this) { 1100 finished = true; 1101 result = succeeded; 1102 notifyAll(); 1103 } 1104 } 1105 } 1106 1107 private int runClear() { 1108 int userId = UserHandle.USER_SYSTEM; 1109 String option = nextOption(); 1110 if (option != null && option.equals("--user")) { 1111 String optionData = nextOptionData(); 1112 if (optionData == null || !isNumber(optionData)) { 1113 System.err.println("Error: no USER_ID specified"); 1114 return showUsage(); 1115 } else { 1116 userId = Integer.parseInt(optionData); 1117 } 1118 } 1119 1120 String pkg = nextArg(); 1121 if (pkg == null) { 1122 System.err.println("Error: no package specified"); 1123 return showUsage(); 1124 } 1125 1126 ClearDataObserver obs = new ClearDataObserver(); 1127 try { 1128 ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId); 1129 synchronized (obs) { 1130 while (!obs.finished) { 1131 try { 1132 obs.wait(); 1133 } catch (InterruptedException e) { 1134 } 1135 } 1136 } 1137 1138 if (obs.result) { 1139 System.out.println("Success"); 1140 return 0; 1141 } else { 1142 System.err.println("Failed"); 1143 return 1; 1144 } 1145 } catch (RemoteException e) { 1146 System.err.println(e.toString()); 1147 System.err.println(PM_NOT_RUNNING_ERR); 1148 return 1; 1149 } 1150 } 1151 1152 private static String enabledSettingToString(int state) { 1153 switch (state) { 1154 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1155 return "default"; 1156 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1157 return "enabled"; 1158 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1159 return "disabled"; 1160 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1161 return "disabled-user"; 1162 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1163 return "disabled-until-used"; 1164 } 1165 return "unknown"; 1166 } 1167 1168 private static boolean isNumber(String s) { 1169 try { 1170 Integer.parseInt(s); 1171 } catch (NumberFormatException nfe) { 1172 return false; 1173 } 1174 return true; 1175 } 1176 1177 private int runSetEnabledSetting(int state) { 1178 int userId = UserHandle.USER_SYSTEM; 1179 String option = nextOption(); 1180 if (option != null && option.equals("--user")) { 1181 String optionData = nextOptionData(); 1182 if (optionData == null || !isNumber(optionData)) { 1183 System.err.println("Error: no USER_ID specified"); 1184 return showUsage(); 1185 } else { 1186 userId = Integer.parseInt(optionData); 1187 } 1188 } 1189 1190 String pkg = nextArg(); 1191 if (pkg == null) { 1192 System.err.println("Error: no package or component specified"); 1193 return showUsage(); 1194 } 1195 ComponentName cn = ComponentName.unflattenFromString(pkg); 1196 if (cn == null) { 1197 try { 1198 mPm.setApplicationEnabledSetting(pkg, state, 0, userId, 1199 "shell:" + android.os.Process.myUid()); 1200 System.out.println("Package " + pkg + " new state: " 1201 + enabledSettingToString( 1202 mPm.getApplicationEnabledSetting(pkg, userId))); 1203 return 0; 1204 } catch (RemoteException e) { 1205 System.err.println(e.toString()); 1206 System.err.println(PM_NOT_RUNNING_ERR); 1207 return 1; 1208 } 1209 } else { 1210 try { 1211 mPm.setComponentEnabledSetting(cn, state, 0, userId); 1212 System.out.println("Component " + cn.toShortString() + " new state: " 1213 + enabledSettingToString( 1214 mPm.getComponentEnabledSetting(cn, userId))); 1215 return 0; 1216 } catch (RemoteException e) { 1217 System.err.println(e.toString()); 1218 System.err.println(PM_NOT_RUNNING_ERR); 1219 return 1; 1220 } 1221 } 1222 } 1223 1224 private int runSetHiddenSetting(boolean state) { 1225 int userId = UserHandle.USER_SYSTEM; 1226 String option = nextOption(); 1227 if (option != null && option.equals("--user")) { 1228 String optionData = nextOptionData(); 1229 if (optionData == null || !isNumber(optionData)) { 1230 System.err.println("Error: no USER_ID specified"); 1231 return showUsage(); 1232 } else { 1233 userId = Integer.parseInt(optionData); 1234 } 1235 } 1236 1237 String pkg = nextArg(); 1238 if (pkg == null) { 1239 System.err.println("Error: no package or component specified"); 1240 return showUsage(); 1241 } 1242 try { 1243 mPm.setApplicationHiddenSettingAsUser(pkg, state, userId); 1244 System.out.println("Package " + pkg + " new hidden state: " 1245 + mPm.getApplicationHiddenSettingAsUser(pkg, userId)); 1246 return 0; 1247 } catch (RemoteException e) { 1248 System.err.println(e.toString()); 1249 System.err.println(PM_NOT_RUNNING_ERR); 1250 return 1; 1251 } 1252 } 1253 1254 private int runGrantRevokePermission(boolean grant) { 1255 int userId = UserHandle.USER_SYSTEM; 1256 1257 String opt = null; 1258 while ((opt = nextOption()) != null) { 1259 if (opt.equals("--user")) { 1260 userId = Integer.parseInt(nextArg()); 1261 } 1262 } 1263 1264 String pkg = nextArg(); 1265 if (pkg == null) { 1266 System.err.println("Error: no package specified"); 1267 return showUsage(); 1268 } 1269 String perm = nextArg(); 1270 if (perm == null) { 1271 System.err.println("Error: no permission specified"); 1272 return showUsage(); 1273 } 1274 1275 try { 1276 if (grant) { 1277 mPm.grantRuntimePermission(pkg, perm, userId); 1278 } else { 1279 mPm.revokeRuntimePermission(pkg, perm, userId); 1280 } 1281 return 0; 1282 } catch (RemoteException e) { 1283 System.err.println(e.toString()); 1284 System.err.println(PM_NOT_RUNNING_ERR); 1285 return 1; 1286 } catch (IllegalArgumentException e) { 1287 System.err.println("Bad argument: " + e.toString()); 1288 return showUsage(); 1289 } catch (SecurityException e) { 1290 System.err.println("Operation not allowed: " + e.toString()); 1291 return 1; 1292 } 1293 } 1294 1295 private int runResetPermissions() { 1296 try { 1297 mPm.resetRuntimePermissions(); 1298 return 0; 1299 } catch (RemoteException e) { 1300 System.err.println(e.toString()); 1301 System.err.println(PM_NOT_RUNNING_ERR); 1302 return 1; 1303 } catch (IllegalArgumentException e) { 1304 System.err.println("Bad argument: " + e.toString()); 1305 return showUsage(); 1306 } catch (SecurityException e) { 1307 System.err.println("Operation not allowed: " + e.toString()); 1308 return 1; 1309 } 1310 } 1311 1312 private int runSetPermissionEnforced() { 1313 final String permission = nextArg(); 1314 if (permission == null) { 1315 System.err.println("Error: no permission specified"); 1316 return showUsage(); 1317 } 1318 final String enforcedRaw = nextArg(); 1319 if (enforcedRaw == null) { 1320 System.err.println("Error: no enforcement specified"); 1321 return showUsage(); 1322 } 1323 final boolean enforced = Boolean.parseBoolean(enforcedRaw); 1324 try { 1325 mPm.setPermissionEnforced(permission, enforced); 1326 return 0; 1327 } catch (RemoteException e) { 1328 System.err.println(e.toString()); 1329 System.err.println(PM_NOT_RUNNING_ERR); 1330 return 1; 1331 } catch (IllegalArgumentException e) { 1332 System.err.println("Bad argument: " + e.toString()); 1333 return showUsage(); 1334 } catch (SecurityException e) { 1335 System.err.println("Operation not allowed: " + e.toString()); 1336 return 1; 1337 } 1338 } 1339 1340 static class ClearCacheObserver extends IPackageDataObserver.Stub { 1341 boolean finished; 1342 boolean result; 1343 1344 @Override 1345 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1346 synchronized (this) { 1347 finished = true; 1348 result = succeeded; 1349 notifyAll(); 1350 } 1351 } 1352 1353 } 1354 1355 private int runTrimCaches() { 1356 String size = nextArg(); 1357 if (size == null) { 1358 System.err.println("Error: no size specified"); 1359 return showUsage(); 1360 } 1361 int len = size.length(); 1362 long multiplier = 1; 1363 if (len > 1) { 1364 char c = size.charAt(len-1); 1365 if (c == 'K' || c == 'k') { 1366 multiplier = 1024L; 1367 } else if (c == 'M' || c == 'm') { 1368 multiplier = 1024L*1024L; 1369 } else if (c == 'G' || c == 'g') { 1370 multiplier = 1024L*1024L*1024L; 1371 } else { 1372 System.err.println("Invalid suffix: " + c); 1373 return showUsage(); 1374 } 1375 size = size.substring(0, len-1); 1376 } 1377 long sizeVal; 1378 try { 1379 sizeVal = Long.parseLong(size) * multiplier; 1380 } catch (NumberFormatException e) { 1381 System.err.println("Error: expected number at: " + size); 1382 return showUsage(); 1383 } 1384 String volumeUuid = nextArg(); 1385 if ("internal".equals(volumeUuid)) { 1386 volumeUuid = null; 1387 } 1388 ClearDataObserver obs = new ClearDataObserver(); 1389 try { 1390 mPm.freeStorageAndNotify(volumeUuid, sizeVal, obs); 1391 synchronized (obs) { 1392 while (!obs.finished) { 1393 try { 1394 obs.wait(); 1395 } catch (InterruptedException e) { 1396 } 1397 } 1398 } 1399 return 0; 1400 } catch (RemoteException e) { 1401 System.err.println(e.toString()); 1402 System.err.println(PM_NOT_RUNNING_ERR); 1403 return 1; 1404 } catch (IllegalArgumentException e) { 1405 System.err.println("Bad argument: " + e.toString()); 1406 return showUsage(); 1407 } catch (SecurityException e) { 1408 System.err.println("Operation not allowed: " + e.toString()); 1409 return 1; 1410 } 1411 } 1412 1413 /** 1414 * Displays the package file for a package. 1415 * @param pckg 1416 */ 1417 private int displayPackageFilePath(String pckg, int userId) { 1418 try { 1419 PackageInfo info = mPm.getPackageInfo(pckg, 0, userId); 1420 if (info != null && info.applicationInfo != null) { 1421 System.out.print("package:"); 1422 System.out.println(info.applicationInfo.sourceDir); 1423 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { 1424 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { 1425 System.out.print("package:"); 1426 System.out.println(splitSourceDir); 1427 } 1428 } 1429 return 0; 1430 } 1431 } catch (RemoteException e) { 1432 System.err.println(e.toString()); 1433 System.err.println(PM_NOT_RUNNING_ERR); 1434 } 1435 return 1; 1436 } 1437 1438 private String nextOption() { 1439 if (mNextArg >= mArgs.length) { 1440 return null; 1441 } 1442 String arg = mArgs[mNextArg]; 1443 if (!arg.startsWith("-")) { 1444 return null; 1445 } 1446 mNextArg++; 1447 if (arg.equals("--")) { 1448 return null; 1449 } 1450 if (arg.length() > 1 && arg.charAt(1) != '-') { 1451 if (arg.length() > 2) { 1452 mCurArgData = arg.substring(2); 1453 return arg.substring(0, 2); 1454 } else { 1455 mCurArgData = null; 1456 return arg; 1457 } 1458 } 1459 mCurArgData = null; 1460 return arg; 1461 } 1462 1463 private String nextOptionData() { 1464 if (mCurArgData != null) { 1465 return mCurArgData; 1466 } 1467 if (mNextArg >= mArgs.length) { 1468 return null; 1469 } 1470 String data = mArgs[mNextArg]; 1471 mNextArg++; 1472 return data; 1473 } 1474 1475 private String nextArg() { 1476 if (mNextArg >= mArgs.length) { 1477 return null; 1478 } 1479 String arg = mArgs[mNextArg]; 1480 mNextArg++; 1481 return arg; 1482 } 1483 1484 private static int showUsage() { 1485 System.err.println("usage: pm path [--user USER_ID] PACKAGE"); 1486 System.err.println(" pm dump PACKAGE"); 1487 System.err.println(" pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]"); 1488 System.err.println(" pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]"); 1489 System.err.println(" [--install-location 0/1/2]"); 1490 System.err.println(" [--force-uuid internal|UUID]"); 1491 System.err.println(" pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]"); 1492 System.err.println(" pm install-commit SESSION_ID"); 1493 System.err.println(" pm install-abandon SESSION_ID"); 1494 System.err.println(" pm uninstall [-k] [--user USER_ID] PACKAGE"); 1495 System.err.println(" pm set-installer PACKAGE INSTALLER"); 1496 System.err.println(" pm move-package PACKAGE [internal|UUID]"); 1497 System.err.println(" pm move-primary-storage [internal|UUID]"); 1498 System.err.println(" pm clear [--user USER_ID] PACKAGE"); 1499 System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1500 System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1501 System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 1502 System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 1503 System.err.println(" pm default-state [--user USER_ID] PACKAGE_OR_COMPONENT"); 1504 System.err.println(" pm hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1505 System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1506 System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION"); 1507 System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION"); 1508 System.err.println(" pm reset-permissions"); 1509 System.err.println(" pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}"); 1510 System.err.println(" pm get-app-link [--user USER_ID] PACKAGE"); 1511 System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]"); 1512 System.err.println(" pm get-install-location"); 1513 System.err.println(" pm set-permission-enforced PERMISSION [true|false]"); 1514 System.err.println(" pm trim-caches DESIRED_FREE_SPACE [internal|UUID]"); 1515 System.err.println(" pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME"); 1516 System.err.println(" pm remove-user USER_ID"); 1517 System.err.println(" pm get-max-users"); 1518 System.err.println(""); 1519 System.err.println("NOTE: 'pm list' commands have moved! Run 'adb shell cmd package'"); 1520 System.err.println(" to display the new commands."); 1521 System.err.println(""); 1522 System.err.println("pm path: print the path to the .apk of the given PACKAGE."); 1523 System.err.println(""); 1524 System.err.println("pm dump: print system state associated with the given PACKAGE."); 1525 System.err.println(""); 1526 System.err.println("pm install: install a single legacy package"); 1527 System.err.println("pm install-create: create an install session"); 1528 System.err.println(" -l: forward lock application"); 1529 System.err.println(" -r: replace existing application"); 1530 System.err.println(" -t: allow test packages"); 1531 System.err.println(" -i: specify the installer package name"); 1532 System.err.println(" -s: install application on sdcard"); 1533 System.err.println(" -f: install application on internal flash"); 1534 System.err.println(" -d: allow version code downgrade (debuggable packages only)"); 1535 System.err.println(" -p: partial application install"); 1536 System.err.println(" -g: grant all runtime permissions"); 1537 System.err.println(" -S: size in bytes of entire session"); 1538 System.err.println(""); 1539 System.err.println("pm install-write: write a package into existing session; path may"); 1540 System.err.println(" be '-' to read from stdin"); 1541 System.err.println(" -S: size in bytes of package, required for stdin"); 1542 System.err.println(""); 1543 System.err.println("pm install-commit: perform install of fully staged session"); 1544 System.err.println("pm install-abandon: abandon session"); 1545 System.err.println(""); 1546 System.err.println("pm set-installer: set installer package name"); 1547 System.err.println(""); 1548 System.err.println("pm uninstall: removes a package from the system. Options:"); 1549 System.err.println(" -k: keep the data and cache directories around after package removal."); 1550 System.err.println(""); 1551 System.err.println("pm clear: deletes all data associated with a package."); 1552 System.err.println(""); 1553 System.err.println("pm enable, disable, disable-user, disable-until-used, default-state:"); 1554 System.err.println(" these commands change the enabled state of a given package or"); 1555 System.err.println(" component (written as \"package/class\")."); 1556 System.err.println(""); 1557 System.err.println("pm grant, revoke: these commands either grant or revoke permissions"); 1558 System.err.println(" to apps. The permissions must be declared as used in the app's"); 1559 System.err.println(" manifest, be runtime permissions (protection level dangerous),"); 1560 System.err.println(" and the app targeting SDK greater than Lollipop MR1."); 1561 System.err.println(""); 1562 System.err.println("pm reset-permissions: revert all runtime permissions to their default state."); 1563 System.err.println(""); 1564 System.err.println("pm get-install-location: returns the current install location."); 1565 System.err.println(" 0 [auto]: Let system decide the best location"); 1566 System.err.println(" 1 [internal]: Install on internal device storage"); 1567 System.err.println(" 2 [external]: Install on external media"); 1568 System.err.println(""); 1569 System.err.println("pm set-install-location: changes the default install location."); 1570 System.err.println(" NOTE: this is only intended for debugging; using this can cause"); 1571 System.err.println(" applications to break and other undersireable behavior."); 1572 System.err.println(" 0 [auto]: Let system decide the best location"); 1573 System.err.println(" 1 [internal]: Install on internal device storage"); 1574 System.err.println(" 2 [external]: Install on external media"); 1575 System.err.println(""); 1576 System.err.println("pm trim-caches: trim cache files to reach the given free space."); 1577 System.err.println(""); 1578 System.err.println("pm create-user: create a new user with the given USER_NAME,"); 1579 System.err.println(" printing the new user identifier of the user."); 1580 System.err.println(""); 1581 System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,"); 1582 System.err.println(" deleting all data associated with that user"); 1583 System.err.println(""); 1584 return 1; 1585 } 1586} 1587