Pm.java revision 039c68e75606e837cf021815a0210836724574ad
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.commands.pm; 18 19import android.content.ComponentName; 20import android.content.pm.ApplicationInfo; 21import android.content.pm.FeatureInfo; 22import android.content.pm.IPackageDeleteObserver; 23import android.content.pm.IPackageInstallObserver; 24import android.content.pm.IPackageManager; 25import android.content.pm.InstrumentationInfo; 26import android.content.pm.PackageInfo; 27import android.content.pm.PackageItemInfo; 28import android.content.pm.PackageManager; 29import android.content.pm.PermissionGroupInfo; 30import android.content.pm.PermissionInfo; 31import android.content.res.AssetManager; 32import android.content.res.Resources; 33import android.net.Uri; 34import android.os.RemoteException; 35import android.os.ServiceManager; 36 37import java.io.File; 38import java.lang.reflect.Field; 39import java.lang.reflect.Modifier; 40import java.util.ArrayList; 41import java.util.Collections; 42import java.util.Comparator; 43import java.util.List; 44import java.util.WeakHashMap; 45 46public final class Pm { 47 IPackageManager mPm; 48 49 private WeakHashMap<String, Resources> mResourceCache 50 = new WeakHashMap<String, Resources>(); 51 52 private String[] mArgs; 53 private int mNextArg; 54 private String mCurArgData; 55 56 private static final String PM_NOT_RUNNING_ERR = 57 "Error: Could not access the Package Manager. Is the system running?"; 58 59 public static void main(String[] args) { 60 new Pm().run(args); 61 } 62 63 public void run(String[] args) { 64 boolean validCommand = false; 65 if (args.length < 1) { 66 showUsage(); 67 return; 68 } 69 70 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 71 if (mPm == null) { 72 System.err.println(PM_NOT_RUNNING_ERR); 73 return; 74 } 75 76 mArgs = args; 77 String op = args[0]; 78 mNextArg = 1; 79 80 if ("list".equals(op)) { 81 runList(); 82 return; 83 } 84 85 if ("path".equals(op)) { 86 runPath(); 87 return; 88 } 89 90 if ("install".equals(op)) { 91 runInstall(); 92 return; 93 } 94 95 if ("uninstall".equals(op)) { 96 runUninstall(); 97 return; 98 } 99 100 if ("enable".equals(op)) { 101 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 102 return; 103 } 104 105 if ("disable".equals(op)) { 106 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 107 return; 108 } 109 110 try { 111 if (args.length == 1) { 112 if (args[0].equalsIgnoreCase("-l")) { 113 validCommand = true; 114 runListPackages(false); 115 } else if (args[0].equalsIgnoreCase("-lf")){ 116 validCommand = true; 117 runListPackages(true); 118 } 119 } else if (args.length == 2) { 120 if (args[0].equalsIgnoreCase("-p")) { 121 validCommand = true; 122 displayPackageFilePath(args[1]); 123 } 124 } 125 } finally { 126 if (validCommand == false) { 127 if (op != null) { 128 System.err.println("Error: unknown command '" + op + "'"); 129 } 130 showUsage(); 131 } 132 } 133 } 134 135 /** 136 * Execute the list sub-command. 137 * 138 * pm list [package | packages] 139 * pm list permission-groups 140 * pm list permissions 141 * pm list features 142 * pm list instrumentation 143 */ 144 private void runList() { 145 String type = nextArg(); 146 if (type == null) { 147 System.err.println("Error: didn't specify type of data to list"); 148 showUsage(); 149 return; 150 } 151 if ("package".equals(type) || "packages".equals(type)) { 152 runListPackages(false); 153 } else if ("permission-groups".equals(type)) { 154 runListPermissionGroups(); 155 } else if ("permissions".equals(type)) { 156 runListPermissions(); 157 } else if ("features".equals(type)) { 158 runListFeatures(); 159 } else if ("instrumentation".equals(type)) { 160 runListInstrumentation(); 161 } else { 162 System.err.println("Error: unknown list type '" + type + "'"); 163 showUsage(); 164 } 165 } 166 167 /** 168 * Lists all the installed packages. 169 */ 170 private void runListPackages(boolean showApplicationPackage) { 171 try { 172 String opt; 173 while ((opt=nextOption()) != null) { 174 if (opt.equals("-l")) { 175 // old compat 176 } else if (opt.equals("-lf")) { 177 showApplicationPackage = true; 178 } else if (opt.equals("-f")) { 179 showApplicationPackage = true; 180 } else { 181 System.err.println("Error: Unknown option: " + opt); 182 showUsage(); 183 return; 184 } 185 } 186 } catch (RuntimeException ex) { 187 System.err.println("Error: " + ex.toString()); 188 showUsage(); 189 return; 190 } 191 192 try { 193 List<PackageInfo> packages = mPm.getInstalledPackages(0 /* all */); 194 195 int count = packages.size(); 196 for (int p = 0 ; p < count ; p++) { 197 PackageInfo info = packages.get(p); 198 System.out.print("package:"); 199 if (showApplicationPackage) { 200 System.out.print(info.applicationInfo.sourceDir); 201 System.out.print("="); 202 } 203 System.out.println(info.packageName); 204 } 205 } catch (RemoteException e) { 206 System.err.println(e.toString()); 207 System.err.println(PM_NOT_RUNNING_ERR); 208 } 209 } 210 211 /** 212 * Lists all of the features supported by the current device. 213 * 214 * pm list features 215 */ 216 private void runListFeatures() { 217 try { 218 List<FeatureInfo> list = new ArrayList<FeatureInfo>(); 219 FeatureInfo[] rawList = mPm.getSystemAvailableFeatures(); 220 for (int i=0; i<rawList.length; i++) { 221 list.add(rawList[i]); 222 } 223 224 225 // Sort by name 226 Collections.sort(list, new Comparator<FeatureInfo>() { 227 public int compare(FeatureInfo o1, FeatureInfo o2) { 228 if (o1.name == o2.name) return 0; 229 if (o1.name == null) return -1; 230 if (o2.name == null) return 1; 231 return o1.name.compareTo(o2.name); 232 } 233 }); 234 235 int count = (list != null) ? list.size() : 0; 236 for (int p = 0; p < count; p++) { 237 FeatureInfo fi = list.get(p); 238 System.out.print("feature:"); 239 if (fi.name != null) System.out.println(fi.name); 240 else System.out.println("reqGlEsVersion=0x" 241 + Integer.toHexString(fi.reqGlEsVersion)); 242 } 243 } catch (RemoteException e) { 244 System.err.println(e.toString()); 245 System.err.println(PM_NOT_RUNNING_ERR); 246 } 247 } 248 249 /** 250 * Lists all of the installed instrumentation, or all for a given package 251 * 252 * pm list instrumentation [package] [-f] 253 */ 254 private void runListInstrumentation() { 255 int flags = 0; // flags != 0 is only used to request meta-data 256 boolean showPackage = false; 257 String targetPackage = null; 258 259 try { 260 String opt; 261 while ((opt=nextArg()) != null) { 262 if (opt.equals("-f")) { 263 showPackage = true; 264 } else if (opt.charAt(0) != '-') { 265 targetPackage = opt; 266 } else { 267 System.err.println("Error: Unknown option: " + opt); 268 showUsage(); 269 return; 270 } 271 } 272 } catch (RuntimeException ex) { 273 System.err.println("Error: " + ex.toString()); 274 showUsage(); 275 return; 276 } 277 278 try { 279 List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags); 280 281 // Sort by target package 282 Collections.sort(list, new Comparator<InstrumentationInfo>() { 283 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 284 return o1.targetPackage.compareTo(o2.targetPackage); 285 } 286 }); 287 288 int count = (list != null) ? list.size() : 0; 289 for (int p = 0; p < count; p++) { 290 InstrumentationInfo ii = list.get(p); 291 System.out.print("instrumentation:"); 292 if (showPackage) { 293 System.out.print(ii.sourceDir); 294 System.out.print("="); 295 } 296 ComponentName cn = new ComponentName(ii.packageName, ii.name); 297 System.out.print(cn.flattenToShortString()); 298 System.out.print(" (target="); 299 System.out.print(ii.targetPackage); 300 System.out.println(")"); 301 } 302 } catch (RemoteException e) { 303 System.err.println(e.toString()); 304 System.err.println(PM_NOT_RUNNING_ERR); 305 } 306 } 307 308 /** 309 * Lists all the known permission groups. 310 */ 311 private void runListPermissionGroups() { 312 try { 313 List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0); 314 315 int count = pgs.size(); 316 for (int p = 0 ; p < count ; p++) { 317 PermissionGroupInfo pgi = pgs.get(p); 318 System.out.print("permission group:"); 319 System.out.println(pgi.name); 320 } 321 } catch (RemoteException e) { 322 System.err.println(e.toString()); 323 System.err.println(PM_NOT_RUNNING_ERR); 324 } 325 } 326 327 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) { 328 if (nonLocalized != null) { 329 return nonLocalized.toString(); 330 } 331 Resources r = getResources(pii); 332 if (r != null) { 333 return r.getString(res); 334 } 335 return null; 336 } 337 338 /** 339 * Lists all the permissions in a group. 340 */ 341 private void runListPermissions() { 342 try { 343 boolean labels = false; 344 boolean groups = false; 345 boolean userOnly = false; 346 boolean summary = false; 347 boolean dangerousOnly = false; 348 String opt; 349 while ((opt=nextOption()) != null) { 350 if (opt.equals("-f")) { 351 labels = true; 352 } else if (opt.equals("-g")) { 353 groups = true; 354 } else if (opt.equals("-s")) { 355 groups = true; 356 labels = true; 357 summary = true; 358 } else if (opt.equals("-u")) { 359 userOnly = true; 360 } else if (opt.equals("-d")) { 361 dangerousOnly = true; 362 } else { 363 System.err.println("Error: Unknown option: " + opt); 364 showUsage(); 365 return; 366 } 367 } 368 369 String grp = nextOption(); 370 ArrayList<String> groupList = new ArrayList<String>(); 371 if (groups) { 372 List<PermissionGroupInfo> infos = 373 mPm.getAllPermissionGroups(0); 374 for (int i=0; i<infos.size(); i++) { 375 groupList.add(infos.get(i).name); 376 } 377 groupList.add(null); 378 } else { 379 groupList.add(grp); 380 } 381 382 if (dangerousOnly) { 383 System.out.println("Dangerous Permissions:"); 384 System.out.println(""); 385 doListPermissions(groupList, groups, labels, summary, 386 PermissionInfo.PROTECTION_DANGEROUS, 387 PermissionInfo.PROTECTION_DANGEROUS); 388 if (userOnly) { 389 System.out.println("Normal Permissions:"); 390 System.out.println(""); 391 doListPermissions(groupList, groups, labels, summary, 392 PermissionInfo.PROTECTION_NORMAL, 393 PermissionInfo.PROTECTION_NORMAL); 394 } 395 } else if (userOnly) { 396 System.out.println("Dangerous and Normal Permissions:"); 397 System.out.println(""); 398 doListPermissions(groupList, groups, labels, summary, 399 PermissionInfo.PROTECTION_NORMAL, 400 PermissionInfo.PROTECTION_DANGEROUS); 401 } else { 402 System.out.println("All Permissions:"); 403 System.out.println(""); 404 doListPermissions(groupList, groups, labels, summary, 405 -10000, 10000); 406 } 407 } catch (RemoteException e) { 408 System.err.println(e.toString()); 409 System.err.println(PM_NOT_RUNNING_ERR); 410 } 411 } 412 413 private void doListPermissions(ArrayList<String> groupList, 414 boolean groups, boolean labels, boolean summary, 415 int startProtectionLevel, int endProtectionLevel) 416 throws RemoteException { 417 for (int i=0; i<groupList.size(); i++) { 418 String groupName = groupList.get(i); 419 String prefix = ""; 420 if (groups) { 421 if (i > 0) System.out.println(""); 422 if (groupName != null) { 423 PermissionGroupInfo pgi = mPm.getPermissionGroupInfo( 424 groupName, 0); 425 if (summary) { 426 Resources res = getResources(pgi); 427 if (res != null) { 428 System.out.print(loadText(pgi, pgi.labelRes, 429 pgi.nonLocalizedLabel) + ": "); 430 } else { 431 System.out.print(pgi.name + ": "); 432 433 } 434 } else { 435 System.out.println((labels ? "+ " : "") 436 + "group:" + pgi.name); 437 if (labels) { 438 System.out.println(" package:" + pgi.packageName); 439 Resources res = getResources(pgi); 440 if (res != null) { 441 System.out.println(" label:" 442 + loadText(pgi, pgi.labelRes, 443 pgi.nonLocalizedLabel)); 444 System.out.println(" description:" 445 + loadText(pgi, pgi.descriptionRes, 446 pgi.nonLocalizedDescription)); 447 } 448 } 449 } 450 } else { 451 System.out.println(((labels && !summary) 452 ? "+ " : "") + "ungrouped:"); 453 } 454 prefix = " "; 455 } 456 List<PermissionInfo> ps = mPm.queryPermissionsByGroup( 457 groupList.get(i), 0); 458 int count = ps.size(); 459 boolean first = true; 460 for (int p = 0 ; p < count ; p++) { 461 PermissionInfo pi = ps.get(p); 462 if (groups && groupName == null && pi.group != null) { 463 continue; 464 } 465 if (pi.protectionLevel < startProtectionLevel 466 || pi.protectionLevel > endProtectionLevel) { 467 continue; 468 } 469 if (summary) { 470 if (first) { 471 first = false; 472 } else { 473 System.out.print(", "); 474 } 475 Resources res = getResources(pi); 476 if (res != null) { 477 System.out.print(loadText(pi, pi.labelRes, 478 pi.nonLocalizedLabel)); 479 } else { 480 System.out.print(pi.name); 481 } 482 } else { 483 System.out.println(prefix + (labels ? "+ " : "") 484 + "permission:" + pi.name); 485 if (labels) { 486 System.out.println(prefix + " package:" + pi.packageName); 487 Resources res = getResources(pi); 488 if (res != null) { 489 System.out.println(prefix + " label:" 490 + loadText(pi, pi.labelRes, 491 pi.nonLocalizedLabel)); 492 System.out.println(prefix + " description:" 493 + loadText(pi, pi.descriptionRes, 494 pi.nonLocalizedDescription)); 495 } 496 String protLevel = "unknown"; 497 switch(pi.protectionLevel) { 498 case PermissionInfo.PROTECTION_DANGEROUS: 499 protLevel = "dangerous"; 500 break; 501 case PermissionInfo.PROTECTION_NORMAL: 502 protLevel = "normal"; 503 break; 504 case PermissionInfo.PROTECTION_SIGNATURE: 505 protLevel = "signature"; 506 break; 507 case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: 508 protLevel = "signatureOrSystem"; 509 break; 510 } 511 System.out.println(prefix + " protectionLevel:" + protLevel); 512 } 513 } 514 } 515 516 if (summary) { 517 System.out.println(""); 518 } 519 } 520 } 521 522 private void runPath() { 523 String pkg = nextArg(); 524 if (pkg == null) { 525 System.err.println("Error: no package specified"); 526 showUsage(); 527 return; 528 } 529 displayPackageFilePath(pkg); 530 } 531 532 class PackageInstallObserver extends IPackageInstallObserver.Stub { 533 boolean finished; 534 int result; 535 536 public void packageInstalled(String name, int status) { 537 synchronized( this) { 538 finished = true; 539 result = status; 540 notifyAll(); 541 } 542 } 543 } 544 545 /** 546 * Converts a failure code into a string by using reflection to find a matching constant 547 * in PackageManager. 548 */ 549 private String installFailureToString(int result) { 550 Field[] fields = PackageManager.class.getFields(); 551 for (Field f: fields) { 552 if (f.getType() == int.class) { 553 int modifiers = f.getModifiers(); 554 // only look at public final static fields. 555 if (((modifiers & Modifier.FINAL) != 0) && 556 ((modifiers & Modifier.PUBLIC) != 0) && 557 ((modifiers & Modifier.STATIC) != 0)) { 558 String fieldName = f.getName(); 559 if (fieldName.startsWith("INSTALL_FAILED_") || 560 fieldName.startsWith("INSTALL_PARSE_FAILED_")) { 561 // get the int value and compare it to result. 562 try { 563 if (result == f.getInt(null)) { 564 return fieldName; 565 } 566 } catch (IllegalAccessException e) { 567 // this shouldn't happen since we only look for public static fields. 568 } 569 } 570 } 571 } 572 } 573 574 // couldn't find a matching constant? return the value 575 return Integer.toString(result); 576 } 577 578 private void runInstall() { 579 int installFlags = 0; 580 String installerPackageName = null; 581 582 String opt; 583 while ((opt=nextOption()) != null) { 584 if (opt.equals("-l")) { 585 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 586 } else if (opt.equals("-r")) { 587 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 588 } else if (opt.equals("-i")) { 589 installerPackageName = nextOptionData(); 590 if (installerPackageName == null) { 591 System.err.println("Error: no value specified for -i"); 592 showUsage(); 593 return; 594 } 595 } else if (opt.equals("-t")) { 596 installFlags |= PackageManager.INSTALL_ALLOW_TEST; 597 } else { 598 System.err.println("Error: Unknown option: " + opt); 599 showUsage(); 600 return; 601 } 602 } 603 604 String apkFilePath = nextArg(); 605 System.err.println("\tpkg: " + apkFilePath); 606 if (apkFilePath == null) { 607 System.err.println("Error: no package specified"); 608 showUsage(); 609 return; 610 } 611 612 PackageInstallObserver obs = new PackageInstallObserver(); 613 try { 614 mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags, 615 installerPackageName); 616 617 synchronized (obs) { 618 while (!obs.finished) { 619 try { 620 obs.wait(); 621 } catch (InterruptedException e) { 622 } 623 } 624 if (obs.result == PackageManager.INSTALL_SUCCEEDED) { 625 System.out.println("Success"); 626 } else { 627 System.err.println("Failure [" 628 + installFailureToString(obs.result) 629 + "]"); 630 } 631 } 632 } catch (RemoteException e) { 633 System.err.println(e.toString()); 634 System.err.println(PM_NOT_RUNNING_ERR); 635 } 636 } 637 638 class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 639 boolean finished; 640 boolean result; 641 642 public void packageDeleted(boolean succeeded) { 643 synchronized (this) { 644 finished = true; 645 result = succeeded; 646 notifyAll(); 647 } 648 } 649 } 650 651 private void runUninstall() { 652 int unInstallFlags = 0; 653 654 String opt = nextOption(); 655 if (opt != null && opt.equals("-k")) { 656 unInstallFlags = PackageManager.DONT_DELETE_DATA; 657 } 658 659 String pkg = nextArg(); 660 if (pkg == null) { 661 System.err.println("Error: no package specified"); 662 showUsage(); 663 return; 664 } 665 boolean result = deletePackage(pkg, unInstallFlags); 666 if (result) { 667 System.out.println("Success"); 668 } else { 669 System.out.println("Failure"); 670 } 671 } 672 673 private boolean deletePackage(String pkg, int unInstallFlags) { 674 PackageDeleteObserver obs = new PackageDeleteObserver(); 675 try { 676 mPm.deletePackage(pkg, obs, unInstallFlags); 677 678 synchronized (obs) { 679 while (!obs.finished) { 680 try { 681 obs.wait(); 682 } catch (InterruptedException e) { 683 } 684 } 685 } 686 } catch (RemoteException e) { 687 System.err.println(e.toString()); 688 System.err.println(PM_NOT_RUNNING_ERR); 689 } 690 return obs.result; 691 } 692 693 private static String enabledSettingToString(int state) { 694 switch (state) { 695 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 696 return "default"; 697 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 698 return "enabled"; 699 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 700 return "disabled"; 701 } 702 return "unknown"; 703 } 704 705 private void runSetEnabledSetting(int state) { 706 String pkg = nextArg(); 707 if (pkg == null) { 708 System.err.println("Error: no package or component specified"); 709 showUsage(); 710 return; 711 } 712 ComponentName cn = ComponentName.unflattenFromString(pkg); 713 if (cn == null) { 714 try { 715 mPm.setApplicationEnabledSetting(pkg, state, 0); 716 System.err.println("Package " + pkg + " new state: " 717 + enabledSettingToString( 718 mPm.getApplicationEnabledSetting(pkg))); 719 } catch (RemoteException e) { 720 System.err.println(e.toString()); 721 System.err.println(PM_NOT_RUNNING_ERR); 722 } 723 } else { 724 try { 725 mPm.setComponentEnabledSetting(cn, state, 0); 726 System.err.println("Component " + cn.toShortString() + " new state: " 727 + enabledSettingToString( 728 mPm.getComponentEnabledSetting(cn))); 729 } catch (RemoteException e) { 730 System.err.println(e.toString()); 731 System.err.println(PM_NOT_RUNNING_ERR); 732 } 733 } 734 } 735 736 /** 737 * Displays the package file for a package. 738 * @param pckg 739 */ 740 private void displayPackageFilePath(String pckg) { 741 try { 742 PackageInfo info = mPm.getPackageInfo(pckg, 0); 743 if (info != null && info.applicationInfo != null) { 744 System.out.print("package:"); 745 System.out.println(info.applicationInfo.sourceDir); 746 } 747 } catch (RemoteException e) { 748 System.err.println(e.toString()); 749 System.err.println(PM_NOT_RUNNING_ERR); 750 } 751 } 752 753 private Resources getResources(PackageItemInfo pii) { 754 Resources res = mResourceCache.get(pii.packageName); 755 if (res != null) return res; 756 757 try { 758 ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0); 759 AssetManager am = new AssetManager(); 760 am.addAssetPath(ai.publicSourceDir); 761 res = new Resources(am, null, null); 762 mResourceCache.put(pii.packageName, res); 763 return res; 764 } catch (RemoteException e) { 765 System.err.println(e.toString()); 766 System.err.println(PM_NOT_RUNNING_ERR); 767 return null; 768 } 769 } 770 771 private String nextOption() { 772 if (mNextArg >= mArgs.length) { 773 return null; 774 } 775 String arg = mArgs[mNextArg]; 776 if (!arg.startsWith("-")) { 777 return null; 778 } 779 mNextArg++; 780 if (arg.equals("--")) { 781 return null; 782 } 783 if (arg.length() > 1 && arg.charAt(1) != '-') { 784 if (arg.length() > 2) { 785 mCurArgData = arg.substring(2); 786 return arg.substring(0, 2); 787 } else { 788 mCurArgData = null; 789 return arg; 790 } 791 } 792 mCurArgData = null; 793 return arg; 794 } 795 796 private String nextOptionData() { 797 if (mCurArgData != null) { 798 return mCurArgData; 799 } 800 if (mNextArg >= mArgs.length) { 801 return null; 802 } 803 String data = mArgs[mNextArg]; 804 mNextArg++; 805 return data; 806 } 807 808 private String nextArg() { 809 if (mNextArg >= mArgs.length) { 810 return null; 811 } 812 String arg = mArgs[mNextArg]; 813 mNextArg++; 814 return arg; 815 } 816 817 private static void showUsage() { 818 System.err.println("usage: pm [list|path|install|uninstall]"); 819 System.err.println(" pm list packages [-f]"); 820 System.err.println(" pm list permission-groups"); 821 System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); 822 System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); 823 System.err.println(" pm list features"); 824 System.err.println(" pm path PACKAGE"); 825 System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] PATH"); 826 System.err.println(" pm uninstall [-k] PACKAGE"); 827 System.err.println(" pm enable PACKAGE_OR_COMPONENT"); 828 System.err.println(" pm disable PACKAGE_OR_COMPONENT"); 829 System.err.println(""); 830 System.err.println("The list packages command prints all packages. Options:"); 831 System.err.println(" -f: see their associated file."); 832 System.err.println(""); 833 System.err.println("The list permission-groups command prints all known"); 834 System.err.println("permission groups."); 835 System.err.println(""); 836 System.err.println("The list permissions command prints all known"); 837 System.err.println("permissions, optionally only those in GROUP. Options:"); 838 System.err.println(" -g: organize by group."); 839 System.err.println(" -f: print all information."); 840 System.err.println(" -s: short summary."); 841 System.err.println(" -d: only list dangerous permissions."); 842 System.err.println(" -u: list only the permissions users will see."); 843 System.err.println(""); 844 System.err.println("The list instrumentation command prints all instrumentations,"); 845 System.err.println("or only those that target a specified package. Options:"); 846 System.err.println(" -f: see their associated file."); 847 System.err.println(""); 848 System.err.println("The list features command prints all features of the system."); 849 System.err.println(""); 850 System.err.println("The path command prints the path to the .apk of a package."); 851 System.err.println(""); 852 System.err.println("The install command installs a package to the system. Options:"); 853 System.err.println(" -l: install the package with FORWARD_LOCK."); 854 System.err.println(" -r: reinstall an exisiting app, keeping its data."); 855 System.err.println(" -t: allow test .apks to be installed."); 856 System.err.println(" -i: specify the installer package name."); 857 System.err.println(""); 858 System.err.println("The uninstall command removes a package from the system. Options:"); 859 System.err.println(" -k: keep the data and cache directories around."); 860 System.err.println("after the package removal."); 861 System.err.println(""); 862 System.err.println("The enable and disable commands change the enabled state of"); 863 System.err.println("a given package or component (written as \"package/class\")."); 864 } 865} 866