Pm.java revision cbfd23ee6f14445c3e17c5169abbc80c216fa137
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 android.app.ActivityManager; 20import android.app.ActivityManagerNative; 21import android.content.ComponentName; 22import android.content.pm.ApplicationInfo; 23import android.content.pm.ContainerEncryptionParams; 24import android.content.pm.FeatureInfo; 25import android.content.pm.IPackageDataObserver; 26import android.content.pm.IPackageDeleteObserver; 27import android.content.pm.IPackageInstallObserver; 28import android.content.pm.IPackageManager; 29import android.content.pm.InstrumentationInfo; 30import android.content.pm.PackageInfo; 31import android.content.pm.PackageItemInfo; 32import android.content.pm.PackageManager; 33import android.content.pm.ParceledListSlice; 34import android.content.pm.PermissionGroupInfo; 35import android.content.pm.PermissionInfo; 36import android.content.pm.UserInfo; 37import android.content.pm.VerificationParams; 38import android.content.res.AssetManager; 39import android.content.res.Resources; 40import android.net.Uri; 41import android.os.IUserManager; 42import android.os.RemoteException; 43import android.os.ServiceManager; 44import android.os.UserHandle; 45import android.os.UserManager; 46 47import java.io.File; 48import java.io.FileDescriptor; 49import java.lang.reflect.Field; 50import java.lang.reflect.Modifier; 51import java.security.InvalidAlgorithmParameterException; 52import java.util.ArrayList; 53import java.util.Collections; 54import java.util.Comparator; 55import java.util.List; 56import java.util.WeakHashMap; 57 58import javax.crypto.SecretKey; 59import javax.crypto.spec.IvParameterSpec; 60import javax.crypto.spec.SecretKeySpec; 61 62import com.android.internal.content.PackageHelper; 63 64public final class Pm { 65 IPackageManager mPm; 66 IUserManager mUm; 67 68 private WeakHashMap<String, Resources> mResourceCache 69 = new WeakHashMap<String, Resources>(); 70 71 private String[] mArgs; 72 private int mNextArg; 73 private String mCurArgData; 74 75 private static final String PM_NOT_RUNNING_ERR = 76 "Error: Could not access the Package Manager. Is the system running?"; 77 78 public static void main(String[] args) { 79 new Pm().run(args); 80 } 81 82 public void run(String[] args) { 83 boolean validCommand = false; 84 if (args.length < 1) { 85 showUsage(); 86 return; 87 } 88 89 mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user")); 90 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 91 if (mPm == null) { 92 System.err.println(PM_NOT_RUNNING_ERR); 93 return; 94 } 95 96 mArgs = args; 97 String op = args[0]; 98 mNextArg = 1; 99 100 if ("list".equals(op)) { 101 runList(); 102 return; 103 } 104 105 if ("path".equals(op)) { 106 runPath(); 107 return; 108 } 109 110 if ("dump".equals(op)) { 111 runDump(); 112 return; 113 } 114 115 if ("install".equals(op)) { 116 runInstall(); 117 return; 118 } 119 120 if ("uninstall".equals(op)) { 121 runUninstall(); 122 return; 123 } 124 125 if ("clear".equals(op)) { 126 runClear(); 127 return; 128 } 129 130 if ("enable".equals(op)) { 131 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 132 return; 133 } 134 135 if ("disable".equals(op)) { 136 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 137 return; 138 } 139 140 if ("disable-user".equals(op)) { 141 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER); 142 return; 143 } 144 145 if ("disable-until-used".equals(op)) { 146 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED); 147 return; 148 } 149 150 if ("grant".equals(op)) { 151 runGrantRevokePermission(true); 152 return; 153 } 154 155 if ("revoke".equals(op)) { 156 runGrantRevokePermission(false); 157 return; 158 } 159 160 if ("set-permission-enforced".equals(op)) { 161 runSetPermissionEnforced(); 162 return; 163 } 164 165 if ("set-install-location".equals(op)) { 166 runSetInstallLocation(); 167 return; 168 } 169 170 if ("get-install-location".equals(op)) { 171 runGetInstallLocation(); 172 return; 173 } 174 175 if ("trim-caches".equals(op)) { 176 runTrimCaches(); 177 return; 178 } 179 180 if ("create-user".equals(op)) { 181 runCreateUser(); 182 return; 183 } 184 185 if ("remove-user".equals(op)) { 186 runRemoveUser(); 187 return; 188 } 189 190 if ("get-max-users".equals(op)) { 191 runGetMaxUsers(); 192 return; 193 } 194 195 try { 196 if (args.length == 1) { 197 if (args[0].equalsIgnoreCase("-l")) { 198 validCommand = true; 199 runListPackages(false); 200 } else if (args[0].equalsIgnoreCase("-lf")){ 201 validCommand = true; 202 runListPackages(true); 203 } 204 } else if (args.length == 2) { 205 if (args[0].equalsIgnoreCase("-p")) { 206 validCommand = true; 207 displayPackageFilePath(args[1]); 208 } 209 } 210 } finally { 211 if (validCommand == false) { 212 if (op != null) { 213 System.err.println("Error: unknown command '" + op + "'"); 214 } 215 showUsage(); 216 } 217 } 218 } 219 220 /** 221 * Execute the list sub-command. 222 * 223 * pm list [package | packages] 224 * pm list permission-groups 225 * pm list permissions 226 * pm list features 227 * pm list libraries 228 * pm list instrumentation 229 */ 230 private void runList() { 231 String type = nextArg(); 232 if (type == null) { 233 System.err.println("Error: didn't specify type of data to list"); 234 return; 235 } 236 if ("package".equals(type) || "packages".equals(type)) { 237 runListPackages(false); 238 } else if ("permission-groups".equals(type)) { 239 runListPermissionGroups(); 240 } else if ("permissions".equals(type)) { 241 runListPermissions(); 242 } else if ("features".equals(type)) { 243 runListFeatures(); 244 } else if ("libraries".equals(type)) { 245 runListLibraries(); 246 } else if ("instrumentation".equals(type)) { 247 runListInstrumentation(); 248 } else if ("users".equals(type)) { 249 runListUsers(); 250 } else { 251 System.err.println("Error: unknown list type '" + type + "'"); 252 } 253 } 254 255 /** 256 * Lists all the installed packages. 257 */ 258 private void runListPackages(boolean showApplicationPackage) { 259 int getFlags = 0; 260 boolean listDisabled = false, listEnabled = false; 261 boolean listSystem = false, listThirdParty = false; 262 boolean listInstaller = false; 263 int userId = UserHandle.USER_OWNER; 264 try { 265 String opt; 266 while ((opt=nextOption()) != null) { 267 if (opt.equals("-l")) { 268 // old compat 269 } else if (opt.equals("-lf")) { 270 showApplicationPackage = true; 271 } else if (opt.equals("-f")) { 272 showApplicationPackage = true; 273 } else if (opt.equals("-d")) { 274 listDisabled = true; 275 } else if (opt.equals("-e")) { 276 listEnabled = true; 277 } else if (opt.equals("-s")) { 278 listSystem = true; 279 } else if (opt.equals("-3")) { 280 listThirdParty = true; 281 } else if (opt.equals("-i")) { 282 listInstaller = true; 283 } else if (opt.equals("--user")) { 284 userId = Integer.parseInt(nextArg()); 285 } else if (opt.equals("-u")) { 286 getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; 287 } else { 288 System.err.println("Error: Unknown option: " + opt); 289 return; 290 } 291 } 292 } catch (RuntimeException ex) { 293 System.err.println("Error: " + ex.toString()); 294 return; 295 } 296 297 String filter = nextArg(); 298 299 try { 300 final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags, userId); 301 302 int count = packages.size(); 303 for (int p = 0 ; p < count ; p++) { 304 PackageInfo info = packages.get(p); 305 if (filter != null && !info.packageName.contains(filter)) { 306 continue; 307 } 308 final boolean isSystem = 309 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; 310 if ((!listDisabled || !info.applicationInfo.enabled) && 311 (!listEnabled || info.applicationInfo.enabled) && 312 (!listSystem || isSystem) && 313 (!listThirdParty || !isSystem)) { 314 System.out.print("package:"); 315 if (showApplicationPackage) { 316 System.out.print(info.applicationInfo.sourceDir); 317 System.out.print("="); 318 } 319 System.out.print(info.packageName); 320 if (listInstaller) { 321 System.out.print(" installer="); 322 System.out.print(mPm.getInstallerPackageName(info.packageName)); 323 } 324 System.out.println(); 325 } 326 } 327 } catch (RemoteException e) { 328 System.err.println(e.toString()); 329 System.err.println(PM_NOT_RUNNING_ERR); 330 } 331 } 332 333 @SuppressWarnings("unchecked") 334 private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags, int userId) 335 throws RemoteException { 336 ParceledListSlice<PackageInfo> slice = pm.getInstalledPackages(flags, userId); 337 return slice.getList(); 338 } 339 340 /** 341 * Lists all of the features supported by the current device. 342 * 343 * pm list features 344 */ 345 private void runListFeatures() { 346 try { 347 List<FeatureInfo> list = new ArrayList<FeatureInfo>(); 348 FeatureInfo[] rawList = mPm.getSystemAvailableFeatures(); 349 for (int i=0; i<rawList.length; i++) { 350 list.add(rawList[i]); 351 } 352 353 354 // Sort by name 355 Collections.sort(list, new Comparator<FeatureInfo>() { 356 public int compare(FeatureInfo o1, FeatureInfo o2) { 357 if (o1.name == o2.name) return 0; 358 if (o1.name == null) return -1; 359 if (o2.name == null) return 1; 360 return o1.name.compareTo(o2.name); 361 } 362 }); 363 364 int count = (list != null) ? list.size() : 0; 365 for (int p = 0; p < count; p++) { 366 FeatureInfo fi = list.get(p); 367 System.out.print("feature:"); 368 if (fi.name != null) System.out.println(fi.name); 369 else System.out.println("reqGlEsVersion=0x" 370 + Integer.toHexString(fi.reqGlEsVersion)); 371 } 372 } catch (RemoteException e) { 373 System.err.println(e.toString()); 374 System.err.println(PM_NOT_RUNNING_ERR); 375 } 376 } 377 378 /** 379 * Lists all of the libraries supported by the current device. 380 * 381 * pm list libraries 382 */ 383 private void runListLibraries() { 384 try { 385 List<String> list = new ArrayList<String>(); 386 String[] rawList = mPm.getSystemSharedLibraryNames(); 387 for (int i=0; i<rawList.length; i++) { 388 list.add(rawList[i]); 389 } 390 391 392 // Sort by name 393 Collections.sort(list, new Comparator<String>() { 394 public int compare(String o1, String o2) { 395 if (o1 == o2) return 0; 396 if (o1 == null) return -1; 397 if (o2 == null) return 1; 398 return o1.compareTo(o2); 399 } 400 }); 401 402 int count = (list != null) ? list.size() : 0; 403 for (int p = 0; p < count; p++) { 404 String lib = list.get(p); 405 System.out.print("library:"); 406 System.out.println(lib); 407 } 408 } catch (RemoteException e) { 409 System.err.println(e.toString()); 410 System.err.println(PM_NOT_RUNNING_ERR); 411 } 412 } 413 414 /** 415 * Lists all of the installed instrumentation, or all for a given package 416 * 417 * pm list instrumentation [package] [-f] 418 */ 419 private void runListInstrumentation() { 420 int flags = 0; // flags != 0 is only used to request meta-data 421 boolean showPackage = false; 422 String targetPackage = null; 423 424 try { 425 String opt; 426 while ((opt=nextArg()) != null) { 427 if (opt.equals("-f")) { 428 showPackage = true; 429 } else if (opt.charAt(0) != '-') { 430 targetPackage = opt; 431 } else { 432 System.err.println("Error: Unknown option: " + opt); 433 return; 434 } 435 } 436 } catch (RuntimeException ex) { 437 System.err.println("Error: " + ex.toString()); 438 return; 439 } 440 441 try { 442 List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags); 443 444 // Sort by target package 445 Collections.sort(list, new Comparator<InstrumentationInfo>() { 446 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 447 return o1.targetPackage.compareTo(o2.targetPackage); 448 } 449 }); 450 451 int count = (list != null) ? list.size() : 0; 452 for (int p = 0; p < count; p++) { 453 InstrumentationInfo ii = list.get(p); 454 System.out.print("instrumentation:"); 455 if (showPackage) { 456 System.out.print(ii.sourceDir); 457 System.out.print("="); 458 } 459 ComponentName cn = new ComponentName(ii.packageName, ii.name); 460 System.out.print(cn.flattenToShortString()); 461 System.out.print(" (target="); 462 System.out.print(ii.targetPackage); 463 System.out.println(")"); 464 } 465 } catch (RemoteException e) { 466 System.err.println(e.toString()); 467 System.err.println(PM_NOT_RUNNING_ERR); 468 } 469 } 470 471 /** 472 * Lists all the known permission groups. 473 */ 474 private void runListPermissionGroups() { 475 try { 476 List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0); 477 478 int count = pgs.size(); 479 for (int p = 0 ; p < count ; p++) { 480 PermissionGroupInfo pgi = pgs.get(p); 481 System.out.print("permission group:"); 482 System.out.println(pgi.name); 483 } 484 } catch (RemoteException e) { 485 System.err.println(e.toString()); 486 System.err.println(PM_NOT_RUNNING_ERR); 487 } 488 } 489 490 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) { 491 if (nonLocalized != null) { 492 return nonLocalized.toString(); 493 } 494 if (res != 0) { 495 Resources r = getResources(pii); 496 if (r != null) { 497 return r.getString(res); 498 } 499 } 500 return null; 501 } 502 503 /** 504 * Lists all the permissions in a group. 505 */ 506 private void runListPermissions() { 507 try { 508 boolean labels = false; 509 boolean groups = false; 510 boolean userOnly = false; 511 boolean summary = false; 512 boolean dangerousOnly = false; 513 String opt; 514 while ((opt=nextOption()) != null) { 515 if (opt.equals("-f")) { 516 labels = true; 517 } else if (opt.equals("-g")) { 518 groups = true; 519 } else if (opt.equals("-s")) { 520 groups = true; 521 labels = true; 522 summary = true; 523 } else if (opt.equals("-u")) { 524 userOnly = true; 525 } else if (opt.equals("-d")) { 526 dangerousOnly = true; 527 } else { 528 System.err.println("Error: Unknown option: " + opt); 529 return; 530 } 531 } 532 533 String grp = nextOption(); 534 ArrayList<String> groupList = new ArrayList<String>(); 535 if (groups) { 536 List<PermissionGroupInfo> infos = 537 mPm.getAllPermissionGroups(0); 538 for (int i=0; i<infos.size(); i++) { 539 groupList.add(infos.get(i).name); 540 } 541 groupList.add(null); 542 } else { 543 groupList.add(grp); 544 } 545 546 if (dangerousOnly) { 547 System.out.println("Dangerous Permissions:"); 548 System.out.println(""); 549 doListPermissions(groupList, groups, labels, summary, 550 PermissionInfo.PROTECTION_DANGEROUS, 551 PermissionInfo.PROTECTION_DANGEROUS); 552 if (userOnly) { 553 System.out.println("Normal Permissions:"); 554 System.out.println(""); 555 doListPermissions(groupList, groups, labels, summary, 556 PermissionInfo.PROTECTION_NORMAL, 557 PermissionInfo.PROTECTION_NORMAL); 558 } 559 } else if (userOnly) { 560 System.out.println("Dangerous and Normal Permissions:"); 561 System.out.println(""); 562 doListPermissions(groupList, groups, labels, summary, 563 PermissionInfo.PROTECTION_NORMAL, 564 PermissionInfo.PROTECTION_DANGEROUS); 565 } else { 566 System.out.println("All Permissions:"); 567 System.out.println(""); 568 doListPermissions(groupList, groups, labels, summary, 569 -10000, 10000); 570 } 571 } catch (RemoteException e) { 572 System.err.println(e.toString()); 573 System.err.println(PM_NOT_RUNNING_ERR); 574 } 575 } 576 577 private void doListPermissions(ArrayList<String> groupList, 578 boolean groups, boolean labels, boolean summary, 579 int startProtectionLevel, int endProtectionLevel) 580 throws RemoteException { 581 for (int i=0; i<groupList.size(); i++) { 582 String groupName = groupList.get(i); 583 String prefix = ""; 584 if (groups) { 585 if (i > 0) System.out.println(""); 586 if (groupName != null) { 587 PermissionGroupInfo pgi = mPm.getPermissionGroupInfo( 588 groupName, 0); 589 if (summary) { 590 Resources res = getResources(pgi); 591 if (res != null) { 592 System.out.print(loadText(pgi, pgi.labelRes, 593 pgi.nonLocalizedLabel) + ": "); 594 } else { 595 System.out.print(pgi.name + ": "); 596 597 } 598 } else { 599 System.out.println((labels ? "+ " : "") 600 + "group:" + pgi.name); 601 if (labels) { 602 System.out.println(" package:" + pgi.packageName); 603 Resources res = getResources(pgi); 604 if (res != null) { 605 System.out.println(" label:" 606 + loadText(pgi, pgi.labelRes, 607 pgi.nonLocalizedLabel)); 608 System.out.println(" description:" 609 + loadText(pgi, pgi.descriptionRes, 610 pgi.nonLocalizedDescription)); 611 } 612 } 613 } 614 } else { 615 System.out.println(((labels && !summary) 616 ? "+ " : "") + "ungrouped:"); 617 } 618 prefix = " "; 619 } 620 List<PermissionInfo> ps = mPm.queryPermissionsByGroup( 621 groupList.get(i), 0); 622 int count = ps.size(); 623 boolean first = true; 624 for (int p = 0 ; p < count ; p++) { 625 PermissionInfo pi = ps.get(p); 626 if (groups && groupName == null && pi.group != null) { 627 continue; 628 } 629 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 630 if (base < startProtectionLevel 631 || base > endProtectionLevel) { 632 continue; 633 } 634 if (summary) { 635 if (first) { 636 first = false; 637 } else { 638 System.out.print(", "); 639 } 640 Resources res = getResources(pi); 641 if (res != null) { 642 System.out.print(loadText(pi, pi.labelRes, 643 pi.nonLocalizedLabel)); 644 } else { 645 System.out.print(pi.name); 646 } 647 } else { 648 System.out.println(prefix + (labels ? "+ " : "") 649 + "permission:" + pi.name); 650 if (labels) { 651 System.out.println(prefix + " package:" + pi.packageName); 652 Resources res = getResources(pi); 653 if (res != null) { 654 System.out.println(prefix + " label:" 655 + loadText(pi, pi.labelRes, 656 pi.nonLocalizedLabel)); 657 System.out.println(prefix + " description:" 658 + loadText(pi, pi.descriptionRes, 659 pi.nonLocalizedDescription)); 660 } 661 System.out.println(prefix + " protectionLevel:" 662 + PermissionInfo.protectionToString(pi.protectionLevel)); 663 } 664 } 665 } 666 667 if (summary) { 668 System.out.println(""); 669 } 670 } 671 } 672 673 private void runPath() { 674 String pkg = nextArg(); 675 if (pkg == null) { 676 System.err.println("Error: no package specified"); 677 return; 678 } 679 displayPackageFilePath(pkg); 680 } 681 682 private void runDump() { 683 String pkg = nextArg(); 684 if (pkg == null) { 685 System.err.println("Error: no package specified"); 686 return; 687 } 688 ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg); 689 } 690 691 class PackageInstallObserver extends IPackageInstallObserver.Stub { 692 boolean finished; 693 int result; 694 695 public void packageInstalled(String name, int status) { 696 synchronized( this) { 697 finished = true; 698 result = status; 699 notifyAll(); 700 } 701 } 702 } 703 704 /** 705 * Converts a failure code into a string by using reflection to find a matching constant 706 * in PackageManager. 707 */ 708 private String installFailureToString(int result) { 709 Field[] fields = PackageManager.class.getFields(); 710 for (Field f: fields) { 711 if (f.getType() == int.class) { 712 int modifiers = f.getModifiers(); 713 // only look at public final static fields. 714 if (((modifiers & Modifier.FINAL) != 0) && 715 ((modifiers & Modifier.PUBLIC) != 0) && 716 ((modifiers & Modifier.STATIC) != 0)) { 717 String fieldName = f.getName(); 718 if (fieldName.startsWith("INSTALL_FAILED_") || 719 fieldName.startsWith("INSTALL_PARSE_FAILED_")) { 720 // get the int value and compare it to result. 721 try { 722 if (result == f.getInt(null)) { 723 return fieldName; 724 } 725 } catch (IllegalAccessException e) { 726 // this shouldn't happen since we only look for public static fields. 727 } 728 } 729 } 730 } 731 } 732 733 // couldn't find a matching constant? return the value 734 return Integer.toString(result); 735 } 736 737 private void runSetInstallLocation() { 738 int loc; 739 740 String arg = nextArg(); 741 if (arg == null) { 742 System.err.println("Error: no install location specified."); 743 return; 744 } 745 try { 746 loc = Integer.parseInt(arg); 747 } catch (NumberFormatException e) { 748 System.err.println("Error: install location has to be a number."); 749 return; 750 } 751 try { 752 if (!mPm.setInstallLocation(loc)) { 753 System.err.println("Error: install location has to be a number."); 754 } 755 } catch (RemoteException e) { 756 System.err.println(e.toString()); 757 System.err.println(PM_NOT_RUNNING_ERR); 758 } 759 } 760 761 private void runGetInstallLocation() { 762 try { 763 int loc = mPm.getInstallLocation(); 764 String locStr = "invalid"; 765 if (loc == PackageHelper.APP_INSTALL_AUTO) { 766 locStr = "auto"; 767 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) { 768 locStr = "internal"; 769 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) { 770 locStr = "external"; 771 } 772 System.out.println(loc + "[" + locStr + "]"); 773 } catch (RemoteException e) { 774 System.err.println(e.toString()); 775 System.err.println(PM_NOT_RUNNING_ERR); 776 } 777 } 778 779 private void runInstall() { 780 int installFlags = PackageManager.INSTALL_ALL_USERS; 781 String installerPackageName = null; 782 783 String opt; 784 785 String algo = null; 786 byte[] iv = null; 787 byte[] key = null; 788 789 String macAlgo = null; 790 byte[] macKey = null; 791 byte[] tag = null; 792 String originatingUriString = null; 793 String referrer = null; 794 795 while ((opt=nextOption()) != null) { 796 if (opt.equals("-l")) { 797 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 798 } else if (opt.equals("-r")) { 799 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 800 } else if (opt.equals("-i")) { 801 installerPackageName = nextOptionData(); 802 if (installerPackageName == null) { 803 System.err.println("Error: no value specified for -i"); 804 return; 805 } 806 } else if (opt.equals("-t")) { 807 installFlags |= PackageManager.INSTALL_ALLOW_TEST; 808 } else if (opt.equals("-s")) { 809 // Override if -s option is specified. 810 installFlags |= PackageManager.INSTALL_EXTERNAL; 811 } else if (opt.equals("-f")) { 812 // Override if -s option is specified. 813 installFlags |= PackageManager.INSTALL_INTERNAL; 814 } else if (opt.equals("-d")) { 815 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 816 } else if (opt.equals("--algo")) { 817 algo = nextOptionData(); 818 if (algo == null) { 819 System.err.println("Error: must supply argument for --algo"); 820 return; 821 } 822 } else if (opt.equals("--iv")) { 823 iv = hexToBytes(nextOptionData()); 824 if (iv == null) { 825 System.err.println("Error: must supply argument for --iv"); 826 return; 827 } 828 } else if (opt.equals("--key")) { 829 key = hexToBytes(nextOptionData()); 830 if (key == null) { 831 System.err.println("Error: must supply argument for --key"); 832 return; 833 } 834 } else if (opt.equals("--macalgo")) { 835 macAlgo = nextOptionData(); 836 if (macAlgo == null) { 837 System.err.println("Error: must supply argument for --macalgo"); 838 return; 839 } 840 } else if (opt.equals("--mackey")) { 841 macKey = hexToBytes(nextOptionData()); 842 if (macKey == null) { 843 System.err.println("Error: must supply argument for --mackey"); 844 return; 845 } 846 } else if (opt.equals("--tag")) { 847 tag = hexToBytes(nextOptionData()); 848 if (tag == null) { 849 System.err.println("Error: must supply argument for --tag"); 850 return; 851 } 852 } else if (opt.equals("--originating-uri")) { 853 originatingUriString = nextOptionData(); 854 if (originatingUriString == null) { 855 System.err.println("Error: must supply argument for --originating-uri"); 856 return; 857 } 858 } else if (opt.equals("--referrer")) { 859 referrer = nextOptionData(); 860 if (referrer == null) { 861 System.err.println("Error: must supply argument for --referrer"); 862 return; 863 } 864 } else { 865 System.err.println("Error: Unknown option: " + opt); 866 return; 867 } 868 } 869 870 final ContainerEncryptionParams encryptionParams; 871 if (algo != null || iv != null || key != null || macAlgo != null || macKey != null 872 || tag != null) { 873 if (algo == null || iv == null || key == null) { 874 System.err.println("Error: all of --algo, --iv, and --key must be specified"); 875 return; 876 } 877 878 if (macAlgo != null || macKey != null || tag != null) { 879 if (macAlgo == null || macKey == null || tag == null) { 880 System.err.println("Error: all of --macalgo, --mackey, and --tag must " 881 + "be specified"); 882 return; 883 } 884 } 885 886 try { 887 final SecretKey encKey = new SecretKeySpec(key, "RAW"); 888 889 final SecretKey macSecretKey; 890 if (macKey == null || macKey.length == 0) { 891 macSecretKey = null; 892 } else { 893 macSecretKey = new SecretKeySpec(macKey, "RAW"); 894 } 895 896 encryptionParams = new ContainerEncryptionParams(algo, new IvParameterSpec(iv), 897 encKey, macAlgo, null, macSecretKey, tag, -1, -1, -1); 898 } catch (InvalidAlgorithmParameterException e) { 899 e.printStackTrace(); 900 return; 901 } 902 } else { 903 encryptionParams = null; 904 } 905 906 final Uri apkURI; 907 final Uri verificationURI; 908 final Uri originatingURI; 909 final Uri referrerURI; 910 911 if (originatingUriString != null) { 912 originatingURI = Uri.parse(originatingUriString); 913 } else { 914 originatingURI = null; 915 } 916 917 if (referrer != null) { 918 referrerURI = Uri.parse(referrer); 919 } else { 920 referrerURI = null; 921 } 922 923 // Populate apkURI, must be present 924 final String apkFilePath = nextArg(); 925 System.err.println("\tpkg: " + apkFilePath); 926 if (apkFilePath != null) { 927 apkURI = Uri.fromFile(new File(apkFilePath)); 928 } else { 929 System.err.println("Error: no package specified"); 930 return; 931 } 932 933 // Populate verificationURI, optionally present 934 final String verificationFilePath = nextArg(); 935 if (verificationFilePath != null) { 936 System.err.println("\tver: " + verificationFilePath); 937 verificationURI = Uri.fromFile(new File(verificationFilePath)); 938 } else { 939 verificationURI = null; 940 } 941 942 PackageInstallObserver obs = new PackageInstallObserver(); 943 try { 944 VerificationParams verificationParams = new VerificationParams(verificationURI, 945 originatingURI, referrerURI, VerificationParams.NO_UID, null); 946 947 mPm.installPackageWithVerificationAndEncryption(apkURI, obs, installFlags, 948 installerPackageName, verificationParams, encryptionParams); 949 950 synchronized (obs) { 951 while (!obs.finished) { 952 try { 953 obs.wait(); 954 } catch (InterruptedException e) { 955 } 956 } 957 if (obs.result == PackageManager.INSTALL_SUCCEEDED) { 958 System.out.println("Success"); 959 } else { 960 System.err.println("Failure [" 961 + installFailureToString(obs.result) 962 + "]"); 963 } 964 } 965 } catch (RemoteException e) { 966 System.err.println(e.toString()); 967 System.err.println(PM_NOT_RUNNING_ERR); 968 } 969 } 970 971 /** 972 * Convert a string containing hex-encoded bytes to a byte array. 973 * 974 * @param input String containing hex-encoded bytes 975 * @return input as an array of bytes 976 */ 977 private byte[] hexToBytes(String input) { 978 if (input == null) { 979 return null; 980 } 981 982 final int inputLength = input.length(); 983 if ((inputLength % 2) != 0) { 984 System.err.print("Invalid length; must be multiple of 2"); 985 return null; 986 } 987 988 final int byteLength = inputLength / 2; 989 final byte[] output = new byte[byteLength]; 990 991 int inputIndex = 0; 992 int byteIndex = 0; 993 while (inputIndex < inputLength) { 994 output[byteIndex++] = (byte) Integer.parseInt( 995 input.substring(inputIndex, inputIndex + 2), 16); 996 inputIndex += 2; 997 } 998 999 return output; 1000 } 1001 1002 public void runCreateUser() { 1003 String name; 1004 String arg = nextArg(); 1005 if (arg == null) { 1006 System.err.println("Error: no user name specified."); 1007 return; 1008 } 1009 name = arg; 1010 try { 1011 final UserInfo info = mUm.createUser(name, 0); 1012 if (info != null) { 1013 System.out.println("Success: created user id " + info.id); 1014 } else { 1015 System.err.println("Error: couldn't create User."); 1016 } 1017 } catch (RemoteException e) { 1018 System.err.println(e.toString()); 1019 System.err.println(PM_NOT_RUNNING_ERR); 1020 } 1021 1022 } 1023 1024 public void runRemoveUser() { 1025 int userId; 1026 String arg = nextArg(); 1027 if (arg == null) { 1028 System.err.println("Error: no user id specified."); 1029 return; 1030 } 1031 try { 1032 userId = Integer.parseInt(arg); 1033 } catch (NumberFormatException e) { 1034 System.err.println("Error: user id '" + arg + "' is not a number."); 1035 return; 1036 } 1037 try { 1038 if (mUm.removeUser(userId)) { 1039 System.out.println("Success: removed user"); 1040 } else { 1041 System.err.println("Error: couldn't remove user id " + userId); 1042 } 1043 } catch (RemoteException e) { 1044 System.err.println(e.toString()); 1045 System.err.println(PM_NOT_RUNNING_ERR); 1046 } 1047 } 1048 1049 public void runListUsers() { 1050 try { 1051 List<UserInfo> users = mUm.getUsers(false); 1052 if (users == null) { 1053 System.err.println("Error: couldn't get users"); 1054 } else { 1055 System.out.println("Users:"); 1056 for (int i = 0; i < users.size(); i++) { 1057 System.out.println("\t" + users.get(i).toString()); 1058 } 1059 } 1060 } catch (RemoteException e) { 1061 System.err.println(e.toString()); 1062 System.err.println(PM_NOT_RUNNING_ERR); 1063 } 1064 } 1065 1066 public void runGetMaxUsers() { 1067 System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers()); 1068 } 1069 1070 class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 1071 boolean finished; 1072 boolean result; 1073 1074 public void packageDeleted(String packageName, int returnCode) { 1075 synchronized (this) { 1076 finished = true; 1077 result = returnCode == PackageManager.DELETE_SUCCEEDED; 1078 notifyAll(); 1079 } 1080 } 1081 } 1082 1083 private void runUninstall() { 1084 int unInstallFlags = PackageManager.DELETE_ALL_USERS; 1085 1086 String opt; 1087 while ((opt=nextOption()) != null) { 1088 if (opt.equals("-k")) { 1089 unInstallFlags |= PackageManager.DELETE_KEEP_DATA; 1090 } else { 1091 System.err.println("Error: Unknown option: " + opt); 1092 return; 1093 } 1094 } 1095 1096 String pkg = nextArg(); 1097 if (pkg == null) { 1098 System.err.println("Error: no package specified"); 1099 showUsage(); 1100 return; 1101 } 1102 boolean result = deletePackage(pkg, unInstallFlags); 1103 if (result) { 1104 System.out.println("Success"); 1105 } else { 1106 System.out.println("Failure"); 1107 } 1108 } 1109 1110 private boolean deletePackage(String pkg, int unInstallFlags) { 1111 PackageDeleteObserver obs = new PackageDeleteObserver(); 1112 try { 1113 mPm.deletePackageAsUser(pkg, obs, UserHandle.USER_OWNER, unInstallFlags); 1114 1115 synchronized (obs) { 1116 while (!obs.finished) { 1117 try { 1118 obs.wait(); 1119 } catch (InterruptedException e) { 1120 } 1121 } 1122 } 1123 } catch (RemoteException e) { 1124 System.err.println(e.toString()); 1125 System.err.println(PM_NOT_RUNNING_ERR); 1126 } 1127 return obs.result; 1128 } 1129 1130 static class ClearDataObserver extends IPackageDataObserver.Stub { 1131 boolean finished; 1132 boolean result; 1133 1134 @Override 1135 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1136 synchronized (this) { 1137 finished = true; 1138 result = succeeded; 1139 notifyAll(); 1140 } 1141 } 1142 1143 } 1144 1145 private void runClear() { 1146 int userId = 0; 1147 String option = nextOption(); 1148 if (option != null && option.equals("--user")) { 1149 String optionData = nextOptionData(); 1150 if (optionData == null || !isNumber(optionData)) { 1151 System.err.println("Error: no USER_ID specified"); 1152 showUsage(); 1153 return; 1154 } else { 1155 userId = Integer.parseInt(optionData); 1156 } 1157 } 1158 1159 String pkg = nextArg(); 1160 if (pkg == null) { 1161 System.err.println("Error: no package specified"); 1162 showUsage(); 1163 return; 1164 } 1165 1166 ClearDataObserver obs = new ClearDataObserver(); 1167 try { 1168 ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId); 1169 synchronized (obs) { 1170 while (!obs.finished) { 1171 try { 1172 obs.wait(); 1173 } catch (InterruptedException e) { 1174 } 1175 } 1176 } 1177 1178 if (obs.result) { 1179 System.err.println("Success"); 1180 } else { 1181 System.err.println("Failed"); 1182 } 1183 } catch (RemoteException e) { 1184 System.err.println(e.toString()); 1185 System.err.println(PM_NOT_RUNNING_ERR); 1186 } 1187 } 1188 1189 private static String enabledSettingToString(int state) { 1190 switch (state) { 1191 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1192 return "default"; 1193 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1194 return "enabled"; 1195 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1196 return "disabled"; 1197 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1198 return "disabled-user"; 1199 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1200 return "disabled-until-used"; 1201 } 1202 return "unknown"; 1203 } 1204 1205 private static boolean isNumber(String s) { 1206 try { 1207 Integer.parseInt(s); 1208 } catch (NumberFormatException nfe) { 1209 return false; 1210 } 1211 return true; 1212 } 1213 1214 private void runSetEnabledSetting(int state) { 1215 int userId = 0; 1216 String option = nextOption(); 1217 if (option != null && option.equals("--user")) { 1218 String optionData = nextOptionData(); 1219 if (optionData == null || !isNumber(optionData)) { 1220 System.err.println("Error: no USER_ID specified"); 1221 showUsage(); 1222 return; 1223 } else { 1224 userId = Integer.parseInt(optionData); 1225 } 1226 } 1227 1228 String pkg = nextArg(); 1229 if (pkg == null) { 1230 System.err.println("Error: no package or component specified"); 1231 showUsage(); 1232 return; 1233 } 1234 ComponentName cn = ComponentName.unflattenFromString(pkg); 1235 if (cn == null) { 1236 try { 1237 mPm.setApplicationEnabledSetting(pkg, state, 0, userId, 1238 "shell:" + android.os.Process.myUid()); 1239 System.err.println("Package " + pkg + " new state: " 1240 + enabledSettingToString( 1241 mPm.getApplicationEnabledSetting(pkg, userId))); 1242 } catch (RemoteException e) { 1243 System.err.println(e.toString()); 1244 System.err.println(PM_NOT_RUNNING_ERR); 1245 } 1246 } else { 1247 try { 1248 mPm.setComponentEnabledSetting(cn, state, 0, userId); 1249 System.err.println("Component " + cn.toShortString() + " new state: " 1250 + enabledSettingToString( 1251 mPm.getComponentEnabledSetting(cn, userId))); 1252 } catch (RemoteException e) { 1253 System.err.println(e.toString()); 1254 System.err.println(PM_NOT_RUNNING_ERR); 1255 } 1256 } 1257 } 1258 1259 private void runGrantRevokePermission(boolean grant) { 1260 String pkg = nextArg(); 1261 if (pkg == null) { 1262 System.err.println("Error: no package specified"); 1263 showUsage(); 1264 return; 1265 } 1266 String perm = nextArg(); 1267 if (perm == null) { 1268 System.err.println("Error: no permission specified"); 1269 showUsage(); 1270 return; 1271 } 1272 try { 1273 if (grant) { 1274 mPm.grantPermission(pkg, perm); 1275 } else { 1276 mPm.revokePermission(pkg, perm); 1277 } 1278 } catch (RemoteException e) { 1279 System.err.println(e.toString()); 1280 System.err.println(PM_NOT_RUNNING_ERR); 1281 } catch (IllegalArgumentException e) { 1282 System.err.println("Bad argument: " + e.toString()); 1283 showUsage(); 1284 } catch (SecurityException e) { 1285 System.err.println("Operation not allowed: " + e.toString()); 1286 } 1287 } 1288 1289 private void runSetPermissionEnforced() { 1290 final String permission = nextArg(); 1291 if (permission == null) { 1292 System.err.println("Error: no permission specified"); 1293 showUsage(); 1294 return; 1295 } 1296 final String enforcedRaw = nextArg(); 1297 if (enforcedRaw == null) { 1298 System.err.println("Error: no enforcement specified"); 1299 showUsage(); 1300 return; 1301 } 1302 final boolean enforced = Boolean.parseBoolean(enforcedRaw); 1303 try { 1304 mPm.setPermissionEnforced(permission, enforced); 1305 } catch (RemoteException e) { 1306 System.err.println(e.toString()); 1307 System.err.println(PM_NOT_RUNNING_ERR); 1308 } catch (IllegalArgumentException e) { 1309 System.err.println("Bad argument: " + e.toString()); 1310 showUsage(); 1311 } catch (SecurityException e) { 1312 System.err.println("Operation not allowed: " + e.toString()); 1313 } 1314 } 1315 1316 static class ClearCacheObserver extends IPackageDataObserver.Stub { 1317 boolean finished; 1318 boolean result; 1319 1320 @Override 1321 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1322 synchronized (this) { 1323 finished = true; 1324 result = succeeded; 1325 notifyAll(); 1326 } 1327 } 1328 1329 } 1330 1331 private void runTrimCaches() { 1332 String size = nextArg(); 1333 if (size == null) { 1334 System.err.println("Error: no size specified"); 1335 showUsage(); 1336 return; 1337 } 1338 int len = size.length(); 1339 long multiplier = 1; 1340 if (len > 1) { 1341 char c = size.charAt(len-1); 1342 if (c == 'K' || c == 'k') { 1343 multiplier = 1024L; 1344 } else if (c == 'M' || c == 'm') { 1345 multiplier = 1024L*1024L; 1346 } else if (c == 'G' || c == 'g') { 1347 multiplier = 1024L*1024L*1024L; 1348 } else { 1349 System.err.println("Invalid suffix: " + c); 1350 showUsage(); 1351 return; 1352 } 1353 size = size.substring(0, len-1); 1354 } 1355 long sizeVal; 1356 try { 1357 sizeVal = Long.parseLong(size) * multiplier; 1358 } catch (NumberFormatException e) { 1359 System.err.println("Error: expected number at: " + size); 1360 showUsage(); 1361 return; 1362 } 1363 ClearDataObserver obs = new ClearDataObserver(); 1364 try { 1365 mPm.freeStorageAndNotify(sizeVal, obs); 1366 synchronized (obs) { 1367 while (!obs.finished) { 1368 try { 1369 obs.wait(); 1370 } catch (InterruptedException e) { 1371 } 1372 } 1373 } 1374 } catch (RemoteException e) { 1375 System.err.println(e.toString()); 1376 System.err.println(PM_NOT_RUNNING_ERR); 1377 } catch (IllegalArgumentException e) { 1378 System.err.println("Bad argument: " + e.toString()); 1379 showUsage(); 1380 } catch (SecurityException e) { 1381 System.err.println("Operation not allowed: " + e.toString()); 1382 } 1383 } 1384 1385 /** 1386 * Displays the package file for a package. 1387 * @param pckg 1388 */ 1389 private void displayPackageFilePath(String pckg) { 1390 try { 1391 PackageInfo info = mPm.getPackageInfo(pckg, 0, 0); 1392 if (info != null && info.applicationInfo != null) { 1393 System.out.print("package:"); 1394 System.out.println(info.applicationInfo.sourceDir); 1395 } 1396 } catch (RemoteException e) { 1397 System.err.println(e.toString()); 1398 System.err.println(PM_NOT_RUNNING_ERR); 1399 } 1400 } 1401 1402 private Resources getResources(PackageItemInfo pii) { 1403 Resources res = mResourceCache.get(pii.packageName); 1404 if (res != null) return res; 1405 1406 try { 1407 ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0); 1408 AssetManager am = new AssetManager(); 1409 am.addAssetPath(ai.publicSourceDir); 1410 res = new Resources(am, null, null); 1411 mResourceCache.put(pii.packageName, res); 1412 return res; 1413 } catch (RemoteException e) { 1414 System.err.println(e.toString()); 1415 System.err.println(PM_NOT_RUNNING_ERR); 1416 return null; 1417 } 1418 } 1419 1420 private String nextOption() { 1421 if (mNextArg >= mArgs.length) { 1422 return null; 1423 } 1424 String arg = mArgs[mNextArg]; 1425 if (!arg.startsWith("-")) { 1426 return null; 1427 } 1428 mNextArg++; 1429 if (arg.equals("--")) { 1430 return null; 1431 } 1432 if (arg.length() > 1 && arg.charAt(1) != '-') { 1433 if (arg.length() > 2) { 1434 mCurArgData = arg.substring(2); 1435 return arg.substring(0, 2); 1436 } else { 1437 mCurArgData = null; 1438 return arg; 1439 } 1440 } 1441 mCurArgData = null; 1442 return arg; 1443 } 1444 1445 private String nextOptionData() { 1446 if (mCurArgData != null) { 1447 return mCurArgData; 1448 } 1449 if (mNextArg >= mArgs.length) { 1450 return null; 1451 } 1452 String data = mArgs[mNextArg]; 1453 mNextArg++; 1454 return data; 1455 } 1456 1457 private String nextArg() { 1458 if (mNextArg >= mArgs.length) { 1459 return null; 1460 } 1461 String arg = mArgs[mNextArg]; 1462 mNextArg++; 1463 return arg; 1464 } 1465 1466 private static void showUsage() { 1467 System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]"); 1468 System.err.println(" pm list permission-groups"); 1469 System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); 1470 System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); 1471 System.err.println(" pm list features"); 1472 System.err.println(" pm list libraries"); 1473 System.err.println(" pm list users"); 1474 System.err.println(" pm path PACKAGE"); 1475 System.err.println(" pm dump PACKAGE"); 1476 System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]"); 1477 System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]"); 1478 System.err.println(" [--originating-uri <URI>] [--referrer <URI>] PATH"); 1479 System.err.println(" pm uninstall [-k] PACKAGE"); 1480 System.err.println(" pm clear [--user USER_ID] PACKAGE"); 1481 System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1482 System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1483 System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 1484 System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 1485 System.err.println(" pm grant PACKAGE PERMISSION"); 1486 System.err.println(" pm revoke PACKAGE PERMISSION"); 1487 System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]"); 1488 System.err.println(" pm get-install-location"); 1489 System.err.println(" pm set-permission-enforced PERMISSION [true|false]"); 1490 System.err.println(" pm trim-caches DESIRED_FREE_SPACE"); 1491 System.err.println(" pm create-user USER_NAME"); 1492 System.err.println(" pm remove-user USER_ID"); 1493 System.err.println(" pm get-max-users"); 1494 System.err.println(""); 1495 System.err.println("pm list packages: prints all packages, optionally only"); 1496 System.err.println(" those whose package name contains the text in FILTER. Options:"); 1497 System.err.println(" -f: see their associated file."); 1498 System.err.println(" -d: filter to only show disbled packages."); 1499 System.err.println(" -e: filter to only show enabled packages."); 1500 System.err.println(" -s: filter to only show system packages."); 1501 System.err.println(" -3: filter to only show third party packages."); 1502 System.err.println(" -i: see the installer for the packages."); 1503 System.err.println(" -u: also include uninstalled packages."); 1504 System.err.println(""); 1505 System.err.println("pm list permission-groups: prints all known permission groups."); 1506 System.err.println(""); 1507 System.err.println("pm list permissions: prints all known permissions, optionally only"); 1508 System.err.println(" those in GROUP. Options:"); 1509 System.err.println(" -g: organize by group."); 1510 System.err.println(" -f: print all information."); 1511 System.err.println(" -s: short summary."); 1512 System.err.println(" -d: only list dangerous permissions."); 1513 System.err.println(" -u: list only the permissions users will see."); 1514 System.err.println(""); 1515 System.err.println("pm list instrumentation: use to list all test packages; optionally"); 1516 System.err.println(" supply <TARGET-PACKAGE> to list the test packages for a particular"); 1517 System.err.println(" application. Options:"); 1518 System.err.println(" -f: list the .apk file for the test package."); 1519 System.err.println(""); 1520 System.err.println("pm list features: prints all features of the system."); 1521 System.err.println(""); 1522 System.err.println("pm list users: prints all users on the system."); 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 w ith the given PACKAGE."); 1527 System.err.println(""); 1528 System.err.println("pm install: installs a package to the system. Options:"); 1529 System.err.println(" -l: install the package with FORWARD_LOCK."); 1530 System.err.println(" -r: reinstall an exisiting app, keeping its data."); 1531 System.err.println(" -t: allow test .apks to be installed."); 1532 System.err.println(" -i: specify the installer package name."); 1533 System.err.println(" -s: install package on sdcard."); 1534 System.err.println(" -f: install package on internal flash."); 1535 System.err.println(" -d: allow version code downgrade."); 1536 System.err.println(""); 1537 System.err.println("pm uninstall: removes a package from the system. Options:"); 1538 System.err.println(" -k: keep the data and cache directories around after package removal."); 1539 System.err.println(""); 1540 System.err.println("pm clear: deletes all data associated with a package."); 1541 System.err.println(""); 1542 System.err.println("pm enable, disable, disable-user, disable-until-used: these commands"); 1543 System.err.println(" change the enabled state of a given package or component (written"); 1544 System.err.println(" as \"package/class\")."); 1545 System.err.println(""); 1546 System.err.println("pm grant, revoke: these commands either grant or revoke permissions"); 1547 System.err.println(" to applications. Only optional permissions the application has"); 1548 System.err.println(" declared can be granted or revoked."); 1549 System.err.println(""); 1550 System.err.println("pm get-install-location: returns the current install location."); 1551 System.err.println(" 0 [auto]: Let system decide the best location"); 1552 System.err.println(" 1 [internal]: Install on internal device storage"); 1553 System.err.println(" 2 [external]: Install on external media"); 1554 System.err.println(""); 1555 System.err.println("pm set-install-location: changes the default install location."); 1556 System.err.println(" NOTE: this is only intended for debugging; using this can cause"); 1557 System.err.println(" applications to break and other undersireable behavior."); 1558 System.err.println(" 0 [auto]: Let system decide the best location"); 1559 System.err.println(" 1 [internal]: Install on internal device storage"); 1560 System.err.println(" 2 [external]: Install on external media"); 1561 System.err.println(""); 1562 System.err.println("pm trim-caches: trim cache files to reach the given free space."); 1563 System.err.println(""); 1564 System.err.println("pm create-user: create a new user with the given USER_NAME,"); 1565 System.err.println(" printing the new user identifier of the user."); 1566 System.err.println(""); 1567 System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,"); 1568 System.err.println(" deleting all data associated with that user"); 1569 } 1570} 1571