Pm.java revision 0e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3
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.FeatureInfo; 25import android.content.pm.IPackageDataObserver; 26import android.content.pm.IPackageDeleteObserver; 27import android.content.pm.IPackageInstallObserver; 28import android.content.pm.IPackageManager; 29import android.content.pm.InstrumentationInfo; 30import android.content.pm.PackageInfo; 31import android.content.pm.PackageItemInfo; 32import android.content.pm.PackageManager; 33import android.content.pm.ParceledListSlice; 34import android.content.pm.PermissionGroupInfo; 35import android.content.pm.PermissionInfo; 36import android.content.res.AssetManager; 37import android.content.res.Resources; 38import android.net.Uri; 39import android.os.Parcel; 40import android.os.RemoteException; 41import android.os.ServiceManager; 42 43import java.io.File; 44import java.lang.reflect.Field; 45import java.lang.reflect.Modifier; 46import java.util.ArrayList; 47import java.util.Collections; 48import java.util.Comparator; 49import java.util.List; 50import java.util.WeakHashMap; 51 52public final class Pm { 53 IPackageManager mPm; 54 55 private WeakHashMap<String, Resources> mResourceCache 56 = new WeakHashMap<String, Resources>(); 57 58 private String[] mArgs; 59 private int mNextArg; 60 private String mCurArgData; 61 62 private static final String PM_NOT_RUNNING_ERR = 63 "Error: Could not access the Package Manager. Is the system running?"; 64 65 public static void main(String[] args) { 66 new Pm().run(args); 67 } 68 69 public void run(String[] args) { 70 boolean validCommand = false; 71 if (args.length < 1) { 72 showUsage(); 73 return; 74 } 75 76 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 77 if (mPm == null) { 78 System.err.println(PM_NOT_RUNNING_ERR); 79 return; 80 } 81 82 mArgs = args; 83 String op = args[0]; 84 mNextArg = 1; 85 86 if ("list".equals(op)) { 87 runList(); 88 return; 89 } 90 91 if ("path".equals(op)) { 92 runPath(); 93 return; 94 } 95 96 if ("install".equals(op)) { 97 runInstall(); 98 return; 99 } 100 101 if ("uninstall".equals(op)) { 102 runUninstall(); 103 return; 104 } 105 106 if ("clear".equals(op)) { 107 runClear(); 108 return; 109 } 110 111 if ("enable".equals(op)) { 112 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 113 return; 114 } 115 116 if ("disable".equals(op)) { 117 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 118 return; 119 } 120 121 if ("setInstallLocation".equals(op)) { 122 runSetInstallLocation(); 123 return; 124 } 125 126 if ("getInstallLocation".equals(op)) { 127 runGetInstallLocation(); 128 return; 129 } 130 131 try { 132 if (args.length == 1) { 133 if (args[0].equalsIgnoreCase("-l")) { 134 validCommand = true; 135 runListPackages(false); 136 } else if (args[0].equalsIgnoreCase("-lf")){ 137 validCommand = true; 138 runListPackages(true); 139 } 140 } else if (args.length == 2) { 141 if (args[0].equalsIgnoreCase("-p")) { 142 validCommand = true; 143 displayPackageFilePath(args[1]); 144 } 145 } 146 } finally { 147 if (validCommand == false) { 148 if (op != null) { 149 System.err.println("Error: unknown command '" + op + "'"); 150 } 151 showUsage(); 152 } 153 } 154 } 155 156 /** 157 * Execute the list sub-command. 158 * 159 * pm list [package | packages] 160 * pm list permission-groups 161 * pm list permissions 162 * pm list features 163 * pm list libraries 164 * pm list instrumentation 165 */ 166 private void runList() { 167 String type = nextArg(); 168 if (type == null) { 169 System.err.println("Error: didn't specify type of data to list"); 170 showUsage(); 171 return; 172 } 173 if ("package".equals(type) || "packages".equals(type)) { 174 runListPackages(false); 175 } else if ("permission-groups".equals(type)) { 176 runListPermissionGroups(); 177 } else if ("permissions".equals(type)) { 178 runListPermissions(); 179 } else if ("features".equals(type)) { 180 runListFeatures(); 181 } else if ("libraries".equals(type)) { 182 runListLibraries(); 183 } else if ("instrumentation".equals(type)) { 184 runListInstrumentation(); 185 } else { 186 System.err.println("Error: unknown list type '" + type + "'"); 187 showUsage(); 188 } 189 } 190 191 /** 192 * Lists all the installed packages. 193 */ 194 private void runListPackages(boolean showApplicationPackage) { 195 int getFlags = 0; 196 boolean listDisabled = false, listEnabled = false; 197 try { 198 String opt; 199 while ((opt=nextOption()) != null) { 200 if (opt.equals("-l")) { 201 // old compat 202 } else if (opt.equals("-lf")) { 203 showApplicationPackage = true; 204 } else if (opt.equals("-f")) { 205 showApplicationPackage = true; 206 } else if (opt.equals("-d")) { 207 listDisabled = true; 208 } else if (opt.equals("-e")) { 209 listEnabled = true; 210 } else if (opt.equals("-u")) { 211 getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; 212 } else { 213 System.err.println("Error: Unknown option: " + opt); 214 showUsage(); 215 return; 216 } 217 } 218 } catch (RuntimeException ex) { 219 System.err.println("Error: " + ex.toString()); 220 showUsage(); 221 return; 222 } 223 224 String filter = nextArg(); 225 226 try { 227 final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags); 228 229 int count = packages.size(); 230 for (int p = 0 ; p < count ; p++) { 231 PackageInfo info = packages.get(p); 232 if (filter != null && !info.packageName.contains(filter)) { 233 continue; 234 } 235 if ((!listDisabled || !info.applicationInfo.enabled) && 236 (!listEnabled || info.applicationInfo.enabled)) { 237 System.out.print("package:"); 238 if (showApplicationPackage) { 239 System.out.print(info.applicationInfo.sourceDir); 240 System.out.print("="); 241 } 242 System.out.println(info.packageName); 243 } 244 } 245 } catch (RemoteException e) { 246 System.err.println(e.toString()); 247 System.err.println(PM_NOT_RUNNING_ERR); 248 } 249 } 250 251 @SuppressWarnings("unchecked") 252 private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags) 253 throws RemoteException { 254 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); 255 PackageInfo lastItem = null; 256 ParceledListSlice<PackageInfo> slice; 257 258 do { 259 final String lastKey = lastItem != null ? lastItem.packageName : null; 260 slice = pm.getInstalledPackages(flags, lastKey); 261 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); 262 } while (!slice.isLastSlice()); 263 264 return packageInfos; 265 } 266 267 /** 268 * Lists all of the features supported by the current device. 269 * 270 * pm list features 271 */ 272 private void runListFeatures() { 273 try { 274 List<FeatureInfo> list = new ArrayList<FeatureInfo>(); 275 FeatureInfo[] rawList = mPm.getSystemAvailableFeatures(); 276 for (int i=0; i<rawList.length; i++) { 277 list.add(rawList[i]); 278 } 279 280 281 // Sort by name 282 Collections.sort(list, new Comparator<FeatureInfo>() { 283 public int compare(FeatureInfo o1, FeatureInfo o2) { 284 if (o1.name == o2.name) return 0; 285 if (o1.name == null) return -1; 286 if (o2.name == null) return 1; 287 return o1.name.compareTo(o2.name); 288 } 289 }); 290 291 int count = (list != null) ? list.size() : 0; 292 for (int p = 0; p < count; p++) { 293 FeatureInfo fi = list.get(p); 294 System.out.print("feature:"); 295 if (fi.name != null) System.out.println(fi.name); 296 else System.out.println("reqGlEsVersion=0x" 297 + Integer.toHexString(fi.reqGlEsVersion)); 298 } 299 } catch (RemoteException e) { 300 System.err.println(e.toString()); 301 System.err.println(PM_NOT_RUNNING_ERR); 302 } 303 } 304 305 /** 306 * Lists all of the libraries supported by the current device. 307 * 308 * pm list libraries 309 */ 310 private void runListLibraries() { 311 try { 312 List<String> list = new ArrayList<String>(); 313 String[] rawList = mPm.getSystemSharedLibraryNames(); 314 for (int i=0; i<rawList.length; i++) { 315 list.add(rawList[i]); 316 } 317 318 319 // Sort by name 320 Collections.sort(list, new Comparator<String>() { 321 public int compare(String o1, String o2) { 322 if (o1 == o2) return 0; 323 if (o1 == null) return -1; 324 if (o2 == null) return 1; 325 return o1.compareTo(o2); 326 } 327 }); 328 329 int count = (list != null) ? list.size() : 0; 330 for (int p = 0; p < count; p++) { 331 String lib = list.get(p); 332 System.out.print("library:"); 333 System.out.println(lib); 334 } 335 } catch (RemoteException e) { 336 System.err.println(e.toString()); 337 System.err.println(PM_NOT_RUNNING_ERR); 338 } 339 } 340 341 /** 342 * Lists all of the installed instrumentation, or all for a given package 343 * 344 * pm list instrumentation [package] [-f] 345 */ 346 private void runListInstrumentation() { 347 int flags = 0; // flags != 0 is only used to request meta-data 348 boolean showPackage = false; 349 String targetPackage = null; 350 351 try { 352 String opt; 353 while ((opt=nextArg()) != null) { 354 if (opt.equals("-f")) { 355 showPackage = true; 356 } else if (opt.charAt(0) != '-') { 357 targetPackage = opt; 358 } else { 359 System.err.println("Error: Unknown option: " + opt); 360 showUsage(); 361 return; 362 } 363 } 364 } catch (RuntimeException ex) { 365 System.err.println("Error: " + ex.toString()); 366 showUsage(); 367 return; 368 } 369 370 try { 371 List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags); 372 373 // Sort by target package 374 Collections.sort(list, new Comparator<InstrumentationInfo>() { 375 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 376 return o1.targetPackage.compareTo(o2.targetPackage); 377 } 378 }); 379 380 int count = (list != null) ? list.size() : 0; 381 for (int p = 0; p < count; p++) { 382 InstrumentationInfo ii = list.get(p); 383 System.out.print("instrumentation:"); 384 if (showPackage) { 385 System.out.print(ii.sourceDir); 386 System.out.print("="); 387 } 388 ComponentName cn = new ComponentName(ii.packageName, ii.name); 389 System.out.print(cn.flattenToShortString()); 390 System.out.print(" (target="); 391 System.out.print(ii.targetPackage); 392 System.out.println(")"); 393 } 394 } catch (RemoteException e) { 395 System.err.println(e.toString()); 396 System.err.println(PM_NOT_RUNNING_ERR); 397 } 398 } 399 400 /** 401 * Lists all the known permission groups. 402 */ 403 private void runListPermissionGroups() { 404 try { 405 List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0); 406 407 int count = pgs.size(); 408 for (int p = 0 ; p < count ; p++) { 409 PermissionGroupInfo pgi = pgs.get(p); 410 System.out.print("permission group:"); 411 System.out.println(pgi.name); 412 } 413 } catch (RemoteException e) { 414 System.err.println(e.toString()); 415 System.err.println(PM_NOT_RUNNING_ERR); 416 } 417 } 418 419 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) { 420 if (nonLocalized != null) { 421 return nonLocalized.toString(); 422 } 423 Resources r = getResources(pii); 424 if (r != null) { 425 return r.getString(res); 426 } 427 return null; 428 } 429 430 /** 431 * Lists all the permissions in a group. 432 */ 433 private void runListPermissions() { 434 try { 435 boolean labels = false; 436 boolean groups = false; 437 boolean userOnly = false; 438 boolean summary = false; 439 boolean dangerousOnly = false; 440 String opt; 441 while ((opt=nextOption()) != null) { 442 if (opt.equals("-f")) { 443 labels = true; 444 } else if (opt.equals("-g")) { 445 groups = true; 446 } else if (opt.equals("-s")) { 447 groups = true; 448 labels = true; 449 summary = true; 450 } else if (opt.equals("-u")) { 451 userOnly = true; 452 } else if (opt.equals("-d")) { 453 dangerousOnly = true; 454 } else { 455 System.err.println("Error: Unknown option: " + opt); 456 showUsage(); 457 return; 458 } 459 } 460 461 String grp = nextOption(); 462 ArrayList<String> groupList = new ArrayList<String>(); 463 if (groups) { 464 List<PermissionGroupInfo> infos = 465 mPm.getAllPermissionGroups(0); 466 for (int i=0; i<infos.size(); i++) { 467 groupList.add(infos.get(i).name); 468 } 469 groupList.add(null); 470 } else { 471 groupList.add(grp); 472 } 473 474 if (dangerousOnly) { 475 System.out.println("Dangerous Permissions:"); 476 System.out.println(""); 477 doListPermissions(groupList, groups, labels, summary, 478 PermissionInfo.PROTECTION_DANGEROUS, 479 PermissionInfo.PROTECTION_DANGEROUS); 480 if (userOnly) { 481 System.out.println("Normal Permissions:"); 482 System.out.println(""); 483 doListPermissions(groupList, groups, labels, summary, 484 PermissionInfo.PROTECTION_NORMAL, 485 PermissionInfo.PROTECTION_NORMAL); 486 } 487 } else if (userOnly) { 488 System.out.println("Dangerous and Normal Permissions:"); 489 System.out.println(""); 490 doListPermissions(groupList, groups, labels, summary, 491 PermissionInfo.PROTECTION_NORMAL, 492 PermissionInfo.PROTECTION_DANGEROUS); 493 } else { 494 System.out.println("All Permissions:"); 495 System.out.println(""); 496 doListPermissions(groupList, groups, labels, summary, 497 -10000, 10000); 498 } 499 } catch (RemoteException e) { 500 System.err.println(e.toString()); 501 System.err.println(PM_NOT_RUNNING_ERR); 502 } 503 } 504 505 private void doListPermissions(ArrayList<String> groupList, 506 boolean groups, boolean labels, boolean summary, 507 int startProtectionLevel, int endProtectionLevel) 508 throws RemoteException { 509 for (int i=0; i<groupList.size(); i++) { 510 String groupName = groupList.get(i); 511 String prefix = ""; 512 if (groups) { 513 if (i > 0) System.out.println(""); 514 if (groupName != null) { 515 PermissionGroupInfo pgi = mPm.getPermissionGroupInfo( 516 groupName, 0); 517 if (summary) { 518 Resources res = getResources(pgi); 519 if (res != null) { 520 System.out.print(loadText(pgi, pgi.labelRes, 521 pgi.nonLocalizedLabel) + ": "); 522 } else { 523 System.out.print(pgi.name + ": "); 524 525 } 526 } else { 527 System.out.println((labels ? "+ " : "") 528 + "group:" + pgi.name); 529 if (labels) { 530 System.out.println(" package:" + pgi.packageName); 531 Resources res = getResources(pgi); 532 if (res != null) { 533 System.out.println(" label:" 534 + loadText(pgi, pgi.labelRes, 535 pgi.nonLocalizedLabel)); 536 System.out.println(" description:" 537 + loadText(pgi, pgi.descriptionRes, 538 pgi.nonLocalizedDescription)); 539 } 540 } 541 } 542 } else { 543 System.out.println(((labels && !summary) 544 ? "+ " : "") + "ungrouped:"); 545 } 546 prefix = " "; 547 } 548 List<PermissionInfo> ps = mPm.queryPermissionsByGroup( 549 groupList.get(i), 0); 550 int count = ps.size(); 551 boolean first = true; 552 for (int p = 0 ; p < count ; p++) { 553 PermissionInfo pi = ps.get(p); 554 if (groups && groupName == null && pi.group != null) { 555 continue; 556 } 557 if (pi.protectionLevel < startProtectionLevel 558 || pi.protectionLevel > endProtectionLevel) { 559 continue; 560 } 561 if (summary) { 562 if (first) { 563 first = false; 564 } else { 565 System.out.print(", "); 566 } 567 Resources res = getResources(pi); 568 if (res != null) { 569 System.out.print(loadText(pi, pi.labelRes, 570 pi.nonLocalizedLabel)); 571 } else { 572 System.out.print(pi.name); 573 } 574 } else { 575 System.out.println(prefix + (labels ? "+ " : "") 576 + "permission:" + pi.name); 577 if (labels) { 578 System.out.println(prefix + " package:" + pi.packageName); 579 Resources res = getResources(pi); 580 if (res != null) { 581 System.out.println(prefix + " label:" 582 + loadText(pi, pi.labelRes, 583 pi.nonLocalizedLabel)); 584 System.out.println(prefix + " description:" 585 + loadText(pi, pi.descriptionRes, 586 pi.nonLocalizedDescription)); 587 } 588 String protLevel = "unknown"; 589 switch(pi.protectionLevel) { 590 case PermissionInfo.PROTECTION_DANGEROUS: 591 protLevel = "dangerous"; 592 break; 593 case PermissionInfo.PROTECTION_NORMAL: 594 protLevel = "normal"; 595 break; 596 case PermissionInfo.PROTECTION_SIGNATURE: 597 protLevel = "signature"; 598 break; 599 case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: 600 protLevel = "signatureOrSystem"; 601 break; 602 } 603 System.out.println(prefix + " protectionLevel:" + protLevel); 604 } 605 } 606 } 607 608 if (summary) { 609 System.out.println(""); 610 } 611 } 612 } 613 614 private void runPath() { 615 String pkg = nextArg(); 616 if (pkg == null) { 617 System.err.println("Error: no package specified"); 618 showUsage(); 619 return; 620 } 621 displayPackageFilePath(pkg); 622 } 623 624 class PackageInstallObserver extends IPackageInstallObserver.Stub { 625 boolean finished; 626 int result; 627 628 public void packageInstalled(String name, int status) { 629 synchronized( this) { 630 finished = true; 631 result = status; 632 notifyAll(); 633 } 634 } 635 } 636 637 /** 638 * Converts a failure code into a string by using reflection to find a matching constant 639 * in PackageManager. 640 */ 641 private String installFailureToString(int result) { 642 Field[] fields = PackageManager.class.getFields(); 643 for (Field f: fields) { 644 if (f.getType() == int.class) { 645 int modifiers = f.getModifiers(); 646 // only look at public final static fields. 647 if (((modifiers & Modifier.FINAL) != 0) && 648 ((modifiers & Modifier.PUBLIC) != 0) && 649 ((modifiers & Modifier.STATIC) != 0)) { 650 String fieldName = f.getName(); 651 if (fieldName.startsWith("INSTALL_FAILED_") || 652 fieldName.startsWith("INSTALL_PARSE_FAILED_")) { 653 // get the int value and compare it to result. 654 try { 655 if (result == f.getInt(null)) { 656 return fieldName; 657 } 658 } catch (IllegalAccessException e) { 659 // this shouldn't happen since we only look for public static fields. 660 } 661 } 662 } 663 } 664 } 665 666 // couldn't find a matching constant? return the value 667 return Integer.toString(result); 668 } 669 670 private void runSetInstallLocation() { 671 int loc; 672 673 String arg = nextArg(); 674 if (arg == null) { 675 System.err.println("Error: no install location specified."); 676 showUsage(); 677 return; 678 } 679 try { 680 loc = Integer.parseInt(arg); 681 } catch (NumberFormatException e) { 682 System.err.println("Error: install location has to be a number."); 683 showUsage(); 684 return; 685 } 686 try { 687 if (!mPm.setInstallLocation(loc)) { 688 System.err.println("Error: install location has to be a number."); 689 showUsage(); 690 } 691 } catch (RemoteException e) { 692 System.err.println(e.toString()); 693 System.err.println(PM_NOT_RUNNING_ERR); 694 } 695 } 696 697 private void runGetInstallLocation() { 698 try { 699 int loc = mPm.getInstallLocation(); 700 String locStr = "invalid"; 701 if (loc == PackageHelper.APP_INSTALL_AUTO) { 702 locStr = "auto"; 703 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) { 704 locStr = "internal"; 705 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) { 706 locStr = "external"; 707 } 708 System.out.println(loc + "[" + locStr + "]"); 709 } catch (RemoteException e) { 710 System.err.println(e.toString()); 711 System.err.println(PM_NOT_RUNNING_ERR); 712 } 713 } 714 715 private void runInstall() { 716 int installFlags = 0; 717 String installerPackageName = null; 718 719 String opt; 720 while ((opt=nextOption()) != null) { 721 if (opt.equals("-l")) { 722 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 723 } else if (opt.equals("-r")) { 724 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 725 } else if (opt.equals("-i")) { 726 installerPackageName = nextOptionData(); 727 if (installerPackageName == null) { 728 System.err.println("Error: no value specified for -i"); 729 showUsage(); 730 return; 731 } 732 } else if (opt.equals("-t")) { 733 installFlags |= PackageManager.INSTALL_ALLOW_TEST; 734 } else if (opt.equals("-s")) { 735 // Override if -s option is specified. 736 installFlags |= PackageManager.INSTALL_EXTERNAL; 737 } else if (opt.equals("-f")) { 738 // Override if -s option is specified. 739 installFlags |= PackageManager.INSTALL_INTERNAL; 740 } else { 741 System.err.println("Error: Unknown option: " + opt); 742 showUsage(); 743 return; 744 } 745 } 746 747 String apkFilePath = nextArg(); 748 System.err.println("\tpkg: " + apkFilePath); 749 if (apkFilePath == null) { 750 System.err.println("Error: no package specified"); 751 showUsage(); 752 return; 753 } 754 755 PackageInstallObserver obs = new PackageInstallObserver(); 756 try { 757 mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags, 758 installerPackageName); 759 760 synchronized (obs) { 761 while (!obs.finished) { 762 try { 763 obs.wait(); 764 } catch (InterruptedException e) { 765 } 766 } 767 if (obs.result == PackageManager.INSTALL_SUCCEEDED) { 768 System.out.println("Success"); 769 } else { 770 System.err.println("Failure [" 771 + installFailureToString(obs.result) 772 + "]"); 773 } 774 } 775 } catch (RemoteException e) { 776 System.err.println(e.toString()); 777 System.err.println(PM_NOT_RUNNING_ERR); 778 } 779 } 780 781 class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 782 boolean finished; 783 boolean result; 784 785 public void packageDeleted(boolean succeeded) { 786 synchronized (this) { 787 finished = true; 788 result = succeeded; 789 notifyAll(); 790 } 791 } 792 } 793 794 private void runUninstall() { 795 int unInstallFlags = 0; 796 797 String opt = nextOption(); 798 if (opt != null && opt.equals("-k")) { 799 unInstallFlags = PackageManager.DONT_DELETE_DATA; 800 } 801 802 String pkg = nextArg(); 803 if (pkg == null) { 804 System.err.println("Error: no package specified"); 805 showUsage(); 806 return; 807 } 808 boolean result = deletePackage(pkg, unInstallFlags); 809 if (result) { 810 System.out.println("Success"); 811 } else { 812 System.out.println("Failure"); 813 } 814 } 815 816 private boolean deletePackage(String pkg, int unInstallFlags) { 817 PackageDeleteObserver obs = new PackageDeleteObserver(); 818 try { 819 mPm.deletePackage(pkg, obs, unInstallFlags); 820 821 synchronized (obs) { 822 while (!obs.finished) { 823 try { 824 obs.wait(); 825 } catch (InterruptedException e) { 826 } 827 } 828 } 829 } catch (RemoteException e) { 830 System.err.println(e.toString()); 831 System.err.println(PM_NOT_RUNNING_ERR); 832 } 833 return obs.result; 834 } 835 836 class ClearDataObserver extends IPackageDataObserver.Stub { 837 boolean finished; 838 boolean result; 839 840 @Override 841 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 842 synchronized (this) { 843 finished = true; 844 result = succeeded; 845 notifyAll(); 846 } 847 } 848 849 } 850 851 private void runClear() { 852 String pkg = nextArg(); 853 if (pkg == null) { 854 System.err.println("Error: no package specified"); 855 showUsage(); 856 return; 857 } 858 859 ClearDataObserver obs = new ClearDataObserver(); 860 try { 861 if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs)) { 862 System.err.println("Failed"); 863 } 864 865 synchronized (obs) { 866 while (!obs.finished) { 867 try { 868 obs.wait(); 869 } catch (InterruptedException e) { 870 } 871 } 872 } 873 874 if (obs.result) { 875 System.err.println("Success"); 876 } else { 877 System.err.println("Failed"); 878 } 879 } catch (RemoteException e) { 880 System.err.println(e.toString()); 881 System.err.println(PM_NOT_RUNNING_ERR); 882 } 883 } 884 885 private static String enabledSettingToString(int state) { 886 switch (state) { 887 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 888 return "default"; 889 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 890 return "enabled"; 891 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 892 return "disabled"; 893 } 894 return "unknown"; 895 } 896 897 private void runSetEnabledSetting(int state) { 898 String pkg = nextArg(); 899 if (pkg == null) { 900 System.err.println("Error: no package or component specified"); 901 showUsage(); 902 return; 903 } 904 ComponentName cn = ComponentName.unflattenFromString(pkg); 905 if (cn == null) { 906 try { 907 mPm.setApplicationEnabledSetting(pkg, state, 0); 908 System.err.println("Package " + pkg + " new state: " 909 + enabledSettingToString( 910 mPm.getApplicationEnabledSetting(pkg))); 911 } catch (RemoteException e) { 912 System.err.println(e.toString()); 913 System.err.println(PM_NOT_RUNNING_ERR); 914 } 915 } else { 916 try { 917 mPm.setComponentEnabledSetting(cn, state, 0); 918 System.err.println("Component " + cn.toShortString() + " new state: " 919 + enabledSettingToString( 920 mPm.getComponentEnabledSetting(cn))); 921 } catch (RemoteException e) { 922 System.err.println(e.toString()); 923 System.err.println(PM_NOT_RUNNING_ERR); 924 } 925 } 926 } 927 928 /** 929 * Displays the package file for a package. 930 * @param pckg 931 */ 932 private void displayPackageFilePath(String pckg) { 933 try { 934 PackageInfo info = mPm.getPackageInfo(pckg, 0); 935 if (info != null && info.applicationInfo != null) { 936 System.out.print("package:"); 937 System.out.println(info.applicationInfo.sourceDir); 938 } 939 } catch (RemoteException e) { 940 System.err.println(e.toString()); 941 System.err.println(PM_NOT_RUNNING_ERR); 942 } 943 } 944 945 private Resources getResources(PackageItemInfo pii) { 946 Resources res = mResourceCache.get(pii.packageName); 947 if (res != null) return res; 948 949 try { 950 ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0); 951 AssetManager am = new AssetManager(); 952 am.addAssetPath(ai.publicSourceDir); 953 res = new Resources(am, null, null); 954 mResourceCache.put(pii.packageName, res); 955 return res; 956 } catch (RemoteException e) { 957 System.err.println(e.toString()); 958 System.err.println(PM_NOT_RUNNING_ERR); 959 return null; 960 } 961 } 962 963 private String nextOption() { 964 if (mNextArg >= mArgs.length) { 965 return null; 966 } 967 String arg = mArgs[mNextArg]; 968 if (!arg.startsWith("-")) { 969 return null; 970 } 971 mNextArg++; 972 if (arg.equals("--")) { 973 return null; 974 } 975 if (arg.length() > 1 && arg.charAt(1) != '-') { 976 if (arg.length() > 2) { 977 mCurArgData = arg.substring(2); 978 return arg.substring(0, 2); 979 } else { 980 mCurArgData = null; 981 return arg; 982 } 983 } 984 mCurArgData = null; 985 return arg; 986 } 987 988 private String nextOptionData() { 989 if (mCurArgData != null) { 990 return mCurArgData; 991 } 992 if (mNextArg >= mArgs.length) { 993 return null; 994 } 995 String data = mArgs[mNextArg]; 996 mNextArg++; 997 return data; 998 } 999 1000 private String nextArg() { 1001 if (mNextArg >= mArgs.length) { 1002 return null; 1003 } 1004 String arg = mArgs[mNextArg]; 1005 mNextArg++; 1006 return arg; 1007 } 1008 1009 private static void showUsage() { 1010 System.err.println("usage: pm [list|path|install|uninstall]"); 1011 System.err.println(" pm list packages [-f] [-d] [-e] [-u] [FILTER]"); 1012 System.err.println(" pm list permission-groups"); 1013 System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); 1014 System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); 1015 System.err.println(" pm list features"); 1016 System.err.println(" pm list libraries"); 1017 System.err.println(" pm path PACKAGE"); 1018 System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH"); 1019 System.err.println(" pm uninstall [-k] PACKAGE"); 1020 System.err.println(" pm clear PACKAGE"); 1021 System.err.println(" pm enable PACKAGE_OR_COMPONENT"); 1022 System.err.println(" pm disable PACKAGE_OR_COMPONENT"); 1023 System.err.println(" pm setInstallLocation [0/auto] [1/internal] [2/external]"); 1024 System.err.println(""); 1025 System.err.println("The list packages command prints all packages, optionally only"); 1026 System.err.println("those whose package name contains the text in FILTER. Options:"); 1027 System.err.println(" -f: see their associated file."); 1028 System.err.println(" -d: filter to include disbled packages."); 1029 System.err.println(" -e: filter to include enabled packages."); 1030 System.err.println(" -u: also include uninstalled packages."); 1031 System.err.println(""); 1032 System.err.println("The list permission-groups command prints all known"); 1033 System.err.println("permission groups."); 1034 System.err.println(""); 1035 System.err.println("The list permissions command prints all known"); 1036 System.err.println("permissions, optionally only those in GROUP. Options:"); 1037 System.err.println(" -g: organize by group."); 1038 System.err.println(" -f: print all information."); 1039 System.err.println(" -s: short summary."); 1040 System.err.println(" -d: only list dangerous permissions."); 1041 System.err.println(" -u: list only the permissions users will see."); 1042 System.err.println(""); 1043 System.err.println("The list instrumentation command prints all instrumentations,"); 1044 System.err.println("or only those that target a specified package. Options:"); 1045 System.err.println(" -f: see their associated file."); 1046 System.err.println(""); 1047 System.err.println("The list features command prints all features of the system."); 1048 System.err.println(""); 1049 System.err.println("The path command prints the path to the .apk of a package."); 1050 System.err.println(""); 1051 System.err.println("The install command installs a package to the system. Options:"); 1052 System.err.println(" -l: install the package with FORWARD_LOCK."); 1053 System.err.println(" -r: reinstall an exisiting app, keeping its data."); 1054 System.err.println(" -t: allow test .apks to be installed."); 1055 System.err.println(" -i: specify the installer package name."); 1056 System.err.println(" -s: install package on sdcard."); 1057 System.err.println(" -f: install package on internal flash."); 1058 System.err.println(""); 1059 System.err.println("The uninstall command removes a package from the system. Options:"); 1060 System.err.println(" -k: keep the data and cache directories around."); 1061 System.err.println("after the package removal."); 1062 System.err.println(""); 1063 System.err.println("The clear command deletes all data associated with a package."); 1064 System.err.println(""); 1065 System.err.println("The enable and disable commands change the enabled state of"); 1066 System.err.println("a given package or component (written as \"package/class\")."); 1067 System.err.println(""); 1068 System.err.println("The getInstallLocation command gets the current install location"); 1069 System.err.println(" 0 [auto]: Let system decide the best location"); 1070 System.err.println(" 1 [internal]: Install on internal device storage"); 1071 System.err.println(" 2 [external]: Install on external media"); 1072 System.err.println(""); 1073 System.err.println("The setInstallLocation command changes the default install location"); 1074 System.err.println(" 0 [auto]: Let system decide the best location"); 1075 System.err.println(" 1 [internal]: Install on internal device storage"); 1076 System.err.println(" 2 [external]: Install on external media"); 1077 } 1078} 1079