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