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