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