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