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