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