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