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