Pm.java revision a0907436c01fd8c545a6b5c7b28bc3bc9db59270
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 android.app.ActivityManager; 20import android.app.ActivityManagerNative; 21import android.app.IActivityManager; 22import android.app.PackageInstallObserver; 23import android.content.ComponentName; 24import android.content.IIntentReceiver; 25import android.content.IIntentSender; 26import android.content.Intent; 27import android.content.IntentSender; 28import android.content.pm.ApplicationInfo; 29import android.content.pm.FeatureInfo; 30import android.content.pm.IPackageDataObserver; 31import android.content.pm.IPackageInstaller; 32import android.content.pm.IPackageManager; 33import android.content.pm.InstrumentationInfo; 34import android.content.pm.PackageInfo; 35import android.content.pm.PackageInstaller; 36import android.content.pm.PackageInstaller.SessionInfo; 37import android.content.pm.PackageInstaller.SessionParams; 38import android.content.pm.PackageItemInfo; 39import android.content.pm.PackageManager; 40import android.content.pm.ParceledListSlice; 41import android.content.pm.PermissionGroupInfo; 42import android.content.pm.PermissionInfo; 43import android.content.pm.UserInfo; 44import android.content.pm.VerificationParams; 45import android.content.res.AssetManager; 46import android.content.res.Resources; 47import android.net.Uri; 48import android.os.Build; 49import android.os.Bundle; 50import android.os.IUserManager; 51import android.os.Process; 52import android.os.RemoteException; 53import android.os.ServiceManager; 54import android.os.UserHandle; 55import android.os.UserManager; 56import android.text.TextUtils; 57import android.util.Log; 58 59import com.android.internal.content.PackageHelper; 60import com.android.internal.util.ArrayUtils; 61import com.android.internal.util.SizedInputStream; 62 63import libcore.io.IoUtils; 64 65import java.io.File; 66import java.io.FileDescriptor; 67import java.io.FileInputStream; 68import java.io.IOException; 69import java.io.InputStream; 70import java.io.OutputStream; 71import java.lang.reflect.Field; 72import java.lang.reflect.Modifier; 73import java.util.ArrayList; 74import java.util.Collections; 75import java.util.Comparator; 76import java.util.List; 77import java.util.WeakHashMap; 78import java.util.concurrent.SynchronousQueue; 79import java.util.concurrent.TimeUnit; 80 81public final class Pm { 82 private static final String TAG = "Pm"; 83 84 IPackageManager mPm; 85 IPackageInstaller mInstaller; 86 IUserManager mUm; 87 88 private WeakHashMap<String, Resources> mResourceCache 89 = new WeakHashMap<String, Resources>(); 90 91 private String[] mArgs; 92 private int mNextArg; 93 private String mCurArgData; 94 95 private static final String PM_NOT_RUNNING_ERR = 96 "Error: Could not access the Package Manager. Is the system running?"; 97 98 public static void main(String[] args) { 99 try { 100 new Pm().run(args); 101 } catch (Exception e) { 102 Log.e(TAG, "Error", e); 103 System.err.println("Error: " + e); 104 if (e instanceof RemoteException) { 105 System.err.println(PM_NOT_RUNNING_ERR); 106 } 107 } 108 } 109 110 public void run(String[] args) throws IOException, RemoteException { 111 boolean validCommand = false; 112 if (args.length < 1) { 113 showUsage(); 114 return; 115 } 116 117 mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user")); 118 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 119 if (mPm == null) { 120 System.err.println(PM_NOT_RUNNING_ERR); 121 return; 122 } 123 mInstaller = mPm.getPackageInstaller(); 124 125 mArgs = args; 126 String op = args[0]; 127 mNextArg = 1; 128 129 if ("list".equals(op)) { 130 runList(); 131 return; 132 } 133 134 if ("path".equals(op)) { 135 runPath(); 136 return; 137 } 138 139 if ("dump".equals(op)) { 140 runDump(); 141 return; 142 } 143 144 if ("install".equals(op)) { 145 runInstall(); 146 return; 147 } 148 149 if ("install-create".equals(op)) { 150 runInstallCreate(); 151 return; 152 } 153 154 if ("install-write".equals(op)) { 155 runInstallWrite(); 156 return; 157 } 158 159 if ("install-commit".equals(op)) { 160 runInstallCommit(); 161 return; 162 } 163 164 if ("install-abandon".equals(op) || "install-destroy".equals(op)) { 165 runInstallAbandon(); 166 return; 167 } 168 169 if ("set-installer".equals(op)) { 170 runSetInstaller(); 171 return; 172 } 173 174 if ("uninstall".equals(op)) { 175 runUninstall(); 176 return; 177 } 178 179 if ("clear".equals(op)) { 180 runClear(); 181 return; 182 } 183 184 if ("enable".equals(op)) { 185 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 186 return; 187 } 188 189 if ("disable".equals(op)) { 190 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 191 return; 192 } 193 194 if ("disable-user".equals(op)) { 195 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER); 196 return; 197 } 198 199 if ("disable-until-used".equals(op)) { 200 runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED); 201 return; 202 } 203 204 if ("hide".equals(op)) { 205 runSetHiddenSetting(true); 206 return; 207 } 208 209 if ("unhide".equals(op)) { 210 runSetHiddenSetting(false); 211 return; 212 } 213 214 if ("grant".equals(op)) { 215 runGrantRevokePermission(true); 216 return; 217 } 218 219 if ("revoke".equals(op)) { 220 runGrantRevokePermission(false); 221 return; 222 } 223 224 if ("set-permission-enforced".equals(op)) { 225 runSetPermissionEnforced(); 226 return; 227 } 228 229 if ("set-install-location".equals(op)) { 230 runSetInstallLocation(); 231 return; 232 } 233 234 if ("get-install-location".equals(op)) { 235 runGetInstallLocation(); 236 return; 237 } 238 239 if ("trim-caches".equals(op)) { 240 runTrimCaches(); 241 return; 242 } 243 244 if ("create-user".equals(op)) { 245 runCreateUser(); 246 return; 247 } 248 249 if ("remove-user".equals(op)) { 250 runRemoveUser(); 251 return; 252 } 253 254 if ("get-max-users".equals(op)) { 255 runGetMaxUsers(); 256 return; 257 } 258 259 if ("force-dex-opt".equals(op)) { 260 runForceDexOpt(); 261 return; 262 } 263 264 try { 265 if (args.length == 1) { 266 if (args[0].equalsIgnoreCase("-l")) { 267 validCommand = true; 268 runListPackages(false); 269 } else if (args[0].equalsIgnoreCase("-lf")){ 270 validCommand = true; 271 runListPackages(true); 272 } 273 } else if (args.length == 2) { 274 if (args[0].equalsIgnoreCase("-p")) { 275 validCommand = true; 276 displayPackageFilePath(args[1]); 277 } 278 } 279 } finally { 280 if (validCommand == false) { 281 if (op != null) { 282 System.err.println("Error: unknown command '" + op + "'"); 283 } 284 showUsage(); 285 } 286 } 287 } 288 289 /** 290 * Execute the list sub-command. 291 * 292 * pm list [package | packages] 293 * pm list permission-groups 294 * pm list permissions 295 * pm list features 296 * pm list libraries 297 * pm list instrumentation 298 */ 299 private void runList() { 300 String type = nextArg(); 301 if (type == null) { 302 System.err.println("Error: didn't specify type of data to list"); 303 return; 304 } 305 if ("package".equals(type) || "packages".equals(type)) { 306 runListPackages(false); 307 } else if ("permission-groups".equals(type)) { 308 runListPermissionGroups(); 309 } else if ("permissions".equals(type)) { 310 runListPermissions(); 311 } else if ("features".equals(type)) { 312 runListFeatures(); 313 } else if ("libraries".equals(type)) { 314 runListLibraries(); 315 } else if ("instrumentation".equals(type)) { 316 runListInstrumentation(); 317 } else if ("users".equals(type)) { 318 runListUsers(); 319 } else { 320 System.err.println("Error: unknown list type '" + type + "'"); 321 } 322 } 323 324 /** 325 * Lists all the installed packages. 326 */ 327 private void runListPackages(boolean showApplicationPackage) { 328 int getFlags = 0; 329 boolean listDisabled = false, listEnabled = false; 330 boolean listSystem = false, listThirdParty = false; 331 boolean listInstaller = false; 332 int userId = UserHandle.USER_OWNER; 333 try { 334 String opt; 335 while ((opt=nextOption()) != null) { 336 if (opt.equals("-l")) { 337 // old compat 338 } else if (opt.equals("-lf")) { 339 showApplicationPackage = true; 340 } else if (opt.equals("-f")) { 341 showApplicationPackage = true; 342 } else if (opt.equals("-d")) { 343 listDisabled = true; 344 } else if (opt.equals("-e")) { 345 listEnabled = true; 346 } else if (opt.equals("-s")) { 347 listSystem = true; 348 } else if (opt.equals("-3")) { 349 listThirdParty = true; 350 } else if (opt.equals("-i")) { 351 listInstaller = true; 352 } else if (opt.equals("--user")) { 353 userId = Integer.parseInt(nextArg()); 354 } else if (opt.equals("-u")) { 355 getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; 356 } else { 357 System.err.println("Error: Unknown option: " + opt); 358 return; 359 } 360 } 361 } catch (RuntimeException ex) { 362 System.err.println("Error: " + ex.toString()); 363 return; 364 } 365 366 String filter = nextArg(); 367 368 try { 369 final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags, userId); 370 371 int count = packages.size(); 372 for (int p = 0 ; p < count ; p++) { 373 PackageInfo info = packages.get(p); 374 if (filter != null && !info.packageName.contains(filter)) { 375 continue; 376 } 377 final boolean isSystem = 378 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; 379 if ((!listDisabled || !info.applicationInfo.enabled) && 380 (!listEnabled || info.applicationInfo.enabled) && 381 (!listSystem || isSystem) && 382 (!listThirdParty || !isSystem)) { 383 System.out.print("package:"); 384 if (showApplicationPackage) { 385 System.out.print(info.applicationInfo.sourceDir); 386 System.out.print("="); 387 } 388 System.out.print(info.packageName); 389 if (listInstaller) { 390 System.out.print(" installer="); 391 System.out.print(mPm.getInstallerPackageName(info.packageName)); 392 } 393 System.out.println(); 394 } 395 } 396 } catch (RemoteException e) { 397 System.err.println(e.toString()); 398 System.err.println(PM_NOT_RUNNING_ERR); 399 } 400 } 401 402 @SuppressWarnings("unchecked") 403 private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags, int userId) 404 throws RemoteException { 405 ParceledListSlice<PackageInfo> slice = pm.getInstalledPackages(flags, userId); 406 return slice.getList(); 407 } 408 409 /** 410 * Lists all of the features supported by the current device. 411 * 412 * pm list features 413 */ 414 private void runListFeatures() { 415 try { 416 List<FeatureInfo> list = new ArrayList<FeatureInfo>(); 417 FeatureInfo[] rawList = mPm.getSystemAvailableFeatures(); 418 for (int i=0; i<rawList.length; i++) { 419 list.add(rawList[i]); 420 } 421 422 423 // Sort by name 424 Collections.sort(list, new Comparator<FeatureInfo>() { 425 public int compare(FeatureInfo o1, FeatureInfo o2) { 426 if (o1.name == o2.name) return 0; 427 if (o1.name == null) return -1; 428 if (o2.name == null) return 1; 429 return o1.name.compareTo(o2.name); 430 } 431 }); 432 433 int count = (list != null) ? list.size() : 0; 434 for (int p = 0; p < count; p++) { 435 FeatureInfo fi = list.get(p); 436 System.out.print("feature:"); 437 if (fi.name != null) System.out.println(fi.name); 438 else System.out.println("reqGlEsVersion=0x" 439 + Integer.toHexString(fi.reqGlEsVersion)); 440 } 441 } catch (RemoteException e) { 442 System.err.println(e.toString()); 443 System.err.println(PM_NOT_RUNNING_ERR); 444 } 445 } 446 447 /** 448 * Lists all of the libraries supported by the current device. 449 * 450 * pm list libraries 451 */ 452 private void runListLibraries() { 453 try { 454 List<String> list = new ArrayList<String>(); 455 String[] rawList = mPm.getSystemSharedLibraryNames(); 456 for (int i=0; i<rawList.length; i++) { 457 list.add(rawList[i]); 458 } 459 460 461 // Sort by name 462 Collections.sort(list, new Comparator<String>() { 463 public int compare(String o1, String o2) { 464 if (o1 == o2) return 0; 465 if (o1 == null) return -1; 466 if (o2 == null) return 1; 467 return o1.compareTo(o2); 468 } 469 }); 470 471 int count = (list != null) ? list.size() : 0; 472 for (int p = 0; p < count; p++) { 473 String lib = list.get(p); 474 System.out.print("library:"); 475 System.out.println(lib); 476 } 477 } catch (RemoteException e) { 478 System.err.println(e.toString()); 479 System.err.println(PM_NOT_RUNNING_ERR); 480 } 481 } 482 483 /** 484 * Lists all of the installed instrumentation, or all for a given package 485 * 486 * pm list instrumentation [package] [-f] 487 */ 488 private void runListInstrumentation() { 489 int flags = 0; // flags != 0 is only used to request meta-data 490 boolean showPackage = false; 491 String targetPackage = null; 492 493 try { 494 String opt; 495 while ((opt=nextArg()) != null) { 496 if (opt.equals("-f")) { 497 showPackage = true; 498 } else if (opt.charAt(0) != '-') { 499 targetPackage = opt; 500 } else { 501 System.err.println("Error: Unknown option: " + opt); 502 return; 503 } 504 } 505 } catch (RuntimeException ex) { 506 System.err.println("Error: " + ex.toString()); 507 return; 508 } 509 510 try { 511 List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags); 512 513 // Sort by target package 514 Collections.sort(list, new Comparator<InstrumentationInfo>() { 515 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 516 return o1.targetPackage.compareTo(o2.targetPackage); 517 } 518 }); 519 520 int count = (list != null) ? list.size() : 0; 521 for (int p = 0; p < count; p++) { 522 InstrumentationInfo ii = list.get(p); 523 System.out.print("instrumentation:"); 524 if (showPackage) { 525 System.out.print(ii.sourceDir); 526 System.out.print("="); 527 } 528 ComponentName cn = new ComponentName(ii.packageName, ii.name); 529 System.out.print(cn.flattenToShortString()); 530 System.out.print(" (target="); 531 System.out.print(ii.targetPackage); 532 System.out.println(")"); 533 } 534 } catch (RemoteException e) { 535 System.err.println(e.toString()); 536 System.err.println(PM_NOT_RUNNING_ERR); 537 } 538 } 539 540 /** 541 * Lists all the known permission groups. 542 */ 543 private void runListPermissionGroups() { 544 try { 545 List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0); 546 547 int count = pgs.size(); 548 for (int p = 0 ; p < count ; p++) { 549 PermissionGroupInfo pgi = pgs.get(p); 550 System.out.print("permission group:"); 551 System.out.println(pgi.name); 552 } 553 } catch (RemoteException e) { 554 System.err.println(e.toString()); 555 System.err.println(PM_NOT_RUNNING_ERR); 556 } 557 } 558 559 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) { 560 if (nonLocalized != null) { 561 return nonLocalized.toString(); 562 } 563 if (res != 0) { 564 Resources r = getResources(pii); 565 if (r != null) { 566 return r.getString(res); 567 } 568 } 569 return null; 570 } 571 572 /** 573 * Lists all the permissions in a group. 574 */ 575 private void runListPermissions() { 576 try { 577 boolean labels = false; 578 boolean groups = false; 579 boolean userOnly = false; 580 boolean summary = false; 581 boolean dangerousOnly = false; 582 String opt; 583 while ((opt=nextOption()) != null) { 584 if (opt.equals("-f")) { 585 labels = true; 586 } else if (opt.equals("-g")) { 587 groups = true; 588 } else if (opt.equals("-s")) { 589 groups = true; 590 labels = true; 591 summary = true; 592 } else if (opt.equals("-u")) { 593 userOnly = true; 594 } else if (opt.equals("-d")) { 595 dangerousOnly = true; 596 } else { 597 System.err.println("Error: Unknown option: " + opt); 598 return; 599 } 600 } 601 602 String grp = nextOption(); 603 ArrayList<String> groupList = new ArrayList<String>(); 604 if (groups) { 605 List<PermissionGroupInfo> infos = 606 mPm.getAllPermissionGroups(0); 607 for (int i=0; i<infos.size(); i++) { 608 groupList.add(infos.get(i).name); 609 } 610 groupList.add(null); 611 } else { 612 groupList.add(grp); 613 } 614 615 if (dangerousOnly) { 616 System.out.println("Dangerous Permissions:"); 617 System.out.println(""); 618 doListPermissions(groupList, groups, labels, summary, 619 PermissionInfo.PROTECTION_DANGEROUS, 620 PermissionInfo.PROTECTION_DANGEROUS); 621 if (userOnly) { 622 System.out.println("Normal Permissions:"); 623 System.out.println(""); 624 doListPermissions(groupList, groups, labels, summary, 625 PermissionInfo.PROTECTION_NORMAL, 626 PermissionInfo.PROTECTION_NORMAL); 627 } 628 } else if (userOnly) { 629 System.out.println("Dangerous and Normal Permissions:"); 630 System.out.println(""); 631 doListPermissions(groupList, groups, labels, summary, 632 PermissionInfo.PROTECTION_NORMAL, 633 PermissionInfo.PROTECTION_DANGEROUS); 634 } else { 635 System.out.println("All Permissions:"); 636 System.out.println(""); 637 doListPermissions(groupList, groups, labels, summary, 638 -10000, 10000); 639 } 640 } catch (RemoteException e) { 641 System.err.println(e.toString()); 642 System.err.println(PM_NOT_RUNNING_ERR); 643 } 644 } 645 646 private void doListPermissions(ArrayList<String> groupList, 647 boolean groups, boolean labels, boolean summary, 648 int startProtectionLevel, int endProtectionLevel) 649 throws RemoteException { 650 for (int i=0; i<groupList.size(); i++) { 651 String groupName = groupList.get(i); 652 String prefix = ""; 653 if (groups) { 654 if (i > 0) System.out.println(""); 655 if (groupName != null) { 656 PermissionGroupInfo pgi = mPm.getPermissionGroupInfo( 657 groupName, 0); 658 if (summary) { 659 Resources res = getResources(pgi); 660 if (res != null) { 661 System.out.print(loadText(pgi, pgi.labelRes, 662 pgi.nonLocalizedLabel) + ": "); 663 } else { 664 System.out.print(pgi.name + ": "); 665 666 } 667 } else { 668 System.out.println((labels ? "+ " : "") 669 + "group:" + pgi.name); 670 if (labels) { 671 System.out.println(" package:" + pgi.packageName); 672 Resources res = getResources(pgi); 673 if (res != null) { 674 System.out.println(" label:" 675 + loadText(pgi, pgi.labelRes, 676 pgi.nonLocalizedLabel)); 677 System.out.println(" description:" 678 + loadText(pgi, pgi.descriptionRes, 679 pgi.nonLocalizedDescription)); 680 } 681 } 682 } 683 } else { 684 System.out.println(((labels && !summary) 685 ? "+ " : "") + "ungrouped:"); 686 } 687 prefix = " "; 688 } 689 List<PermissionInfo> ps = mPm.queryPermissionsByGroup( 690 groupList.get(i), 0); 691 int count = ps.size(); 692 boolean first = true; 693 for (int p = 0 ; p < count ; p++) { 694 PermissionInfo pi = ps.get(p); 695 if (groups && groupName == null && pi.group != null) { 696 continue; 697 } 698 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 699 if (base < startProtectionLevel 700 || base > endProtectionLevel) { 701 continue; 702 } 703 if (summary) { 704 if (first) { 705 first = false; 706 } else { 707 System.out.print(", "); 708 } 709 Resources res = getResources(pi); 710 if (res != null) { 711 System.out.print(loadText(pi, pi.labelRes, 712 pi.nonLocalizedLabel)); 713 } else { 714 System.out.print(pi.name); 715 } 716 } else { 717 System.out.println(prefix + (labels ? "+ " : "") 718 + "permission:" + pi.name); 719 if (labels) { 720 System.out.println(prefix + " package:" + pi.packageName); 721 Resources res = getResources(pi); 722 if (res != null) { 723 System.out.println(prefix + " label:" 724 + loadText(pi, pi.labelRes, 725 pi.nonLocalizedLabel)); 726 System.out.println(prefix + " description:" 727 + loadText(pi, pi.descriptionRes, 728 pi.nonLocalizedDescription)); 729 } 730 System.out.println(prefix + " protectionLevel:" 731 + PermissionInfo.protectionToString(pi.protectionLevel)); 732 } 733 } 734 } 735 736 if (summary) { 737 System.out.println(""); 738 } 739 } 740 } 741 742 private void runPath() { 743 String pkg = nextArg(); 744 if (pkg == null) { 745 System.err.println("Error: no package specified"); 746 return; 747 } 748 displayPackageFilePath(pkg); 749 } 750 751 private void runDump() { 752 String pkg = nextArg(); 753 if (pkg == null) { 754 System.err.println("Error: no package specified"); 755 return; 756 } 757 ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg); 758 } 759 760 class LocalPackageInstallObserver extends PackageInstallObserver { 761 boolean finished; 762 int result; 763 String extraPermission; 764 String extraPackage; 765 766 @Override 767 public void onPackageInstalled(String name, int status, String msg, Bundle extras) { 768 synchronized (this) { 769 finished = true; 770 result = status; 771 if (status == PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION) { 772 extraPermission = extras.getString( 773 PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION); 774 extraPackage = extras.getString( 775 PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE); 776 } 777 notifyAll(); 778 } 779 } 780 } 781 782 /** 783 * Converts a failure code into a string by using reflection to find a matching constant 784 * in PackageManager. 785 */ 786 private String installFailureToString(LocalPackageInstallObserver obs) { 787 final int result = obs.result; 788 Field[] fields = PackageManager.class.getFields(); 789 for (Field f: fields) { 790 if (f.getType() == int.class) { 791 int modifiers = f.getModifiers(); 792 // only look at public final static fields. 793 if (((modifiers & Modifier.FINAL) != 0) && 794 ((modifiers & Modifier.PUBLIC) != 0) && 795 ((modifiers & Modifier.STATIC) != 0)) { 796 String fieldName = f.getName(); 797 if (fieldName.startsWith("INSTALL_FAILED_") || 798 fieldName.startsWith("INSTALL_PARSE_FAILED_")) { 799 // get the int value and compare it to result. 800 try { 801 if (result == f.getInt(null)) { 802 StringBuilder sb = new StringBuilder(64); 803 sb.append(fieldName); 804 if (obs.extraPermission != null) { 805 sb.append(" perm="); 806 sb.append(obs.extraPermission); 807 } 808 if (obs.extraPackage != null) { 809 sb.append(" pkg=" + obs.extraPackage); 810 } 811 return sb.toString(); 812 } 813 } catch (IllegalAccessException e) { 814 // this shouldn't happen since we only look for public static fields. 815 } 816 } 817 } 818 } 819 } 820 821 // couldn't find a matching constant? return the value 822 return Integer.toString(result); 823 } 824 825 private void runSetInstallLocation() { 826 int loc; 827 828 String arg = nextArg(); 829 if (arg == null) { 830 System.err.println("Error: no install location specified."); 831 return; 832 } 833 try { 834 loc = Integer.parseInt(arg); 835 } catch (NumberFormatException e) { 836 System.err.println("Error: install location has to be a number."); 837 return; 838 } 839 try { 840 if (!mPm.setInstallLocation(loc)) { 841 System.err.println("Error: install location has to be a number."); 842 } 843 } catch (RemoteException e) { 844 System.err.println(e.toString()); 845 System.err.println(PM_NOT_RUNNING_ERR); 846 } 847 } 848 849 private void runGetInstallLocation() { 850 try { 851 int loc = mPm.getInstallLocation(); 852 String locStr = "invalid"; 853 if (loc == PackageHelper.APP_INSTALL_AUTO) { 854 locStr = "auto"; 855 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) { 856 locStr = "internal"; 857 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) { 858 locStr = "external"; 859 } 860 System.out.println(loc + "[" + locStr + "]"); 861 } catch (RemoteException e) { 862 System.err.println(e.toString()); 863 System.err.println(PM_NOT_RUNNING_ERR); 864 } 865 } 866 867 private void runInstall() { 868 int installFlags = PackageManager.INSTALL_ALL_USERS; 869 String installerPackageName = null; 870 871 String opt; 872 873 String originatingUriString = null; 874 String referrer = null; 875 String abi = null; 876 877 while ((opt=nextOption()) != null) { 878 if (opt.equals("-l")) { 879 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 880 } else if (opt.equals("-r")) { 881 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 882 } else if (opt.equals("-i")) { 883 installerPackageName = nextOptionData(); 884 if (installerPackageName == null) { 885 System.err.println("Error: no value specified for -i"); 886 return; 887 } 888 } else if (opt.equals("-t")) { 889 installFlags |= PackageManager.INSTALL_ALLOW_TEST; 890 } else if (opt.equals("-s")) { 891 // Override if -s option is specified. 892 installFlags |= PackageManager.INSTALL_EXTERNAL; 893 } else if (opt.equals("-f")) { 894 // Override if -s option is specified. 895 installFlags |= PackageManager.INSTALL_INTERNAL; 896 } else if (opt.equals("-d")) { 897 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 898 } else if (opt.equals("--originating-uri")) { 899 originatingUriString = nextOptionData(); 900 if (originatingUriString == null) { 901 System.err.println("Error: must supply argument for --originating-uri"); 902 return; 903 } 904 } else if (opt.equals("--referrer")) { 905 referrer = nextOptionData(); 906 if (referrer == null) { 907 System.err.println("Error: must supply argument for --referrer"); 908 return; 909 } 910 } else if (opt.equals("--abi")) { 911 abi = checkAbiArgument(nextOptionData()); 912 } else { 913 System.err.println("Error: Unknown option: " + opt); 914 return; 915 } 916 } 917 918 final Uri verificationURI; 919 final Uri originatingURI; 920 final Uri referrerURI; 921 922 if (originatingUriString != null) { 923 originatingURI = Uri.parse(originatingUriString); 924 } else { 925 originatingURI = null; 926 } 927 928 if (referrer != null) { 929 referrerURI = Uri.parse(referrer); 930 } else { 931 referrerURI = null; 932 } 933 934 // Populate apkURI, must be present 935 final String apkFilePath = nextArg(); 936 System.err.println("\tpkg: " + apkFilePath); 937 if (apkFilePath == null) { 938 System.err.println("Error: no package specified"); 939 return; 940 } 941 942 // Populate verificationURI, optionally present 943 final String verificationFilePath = nextArg(); 944 if (verificationFilePath != null) { 945 System.err.println("\tver: " + verificationFilePath); 946 verificationURI = Uri.fromFile(new File(verificationFilePath)); 947 } else { 948 verificationURI = null; 949 } 950 951 LocalPackageInstallObserver obs = new LocalPackageInstallObserver(); 952 try { 953 VerificationParams verificationParams = new VerificationParams(verificationURI, 954 originatingURI, referrerURI, VerificationParams.NO_UID, null); 955 956 mPm.installPackage(apkFilePath, obs.getBinder(), installFlags, installerPackageName, 957 verificationParams, abi); 958 959 synchronized (obs) { 960 while (!obs.finished) { 961 try { 962 obs.wait(); 963 } catch (InterruptedException e) { 964 } 965 } 966 if (obs.result == PackageManager.INSTALL_SUCCEEDED) { 967 System.out.println("Success"); 968 } else { 969 System.err.println("Failure [" 970 + installFailureToString(obs) 971 + "]"); 972 } 973 } 974 } catch (RemoteException e) { 975 System.err.println(e.toString()); 976 System.err.println(PM_NOT_RUNNING_ERR); 977 } 978 } 979 980 private void runInstallCreate() throws RemoteException { 981 String installerPackageName = null; 982 983 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 984 params.installFlags = PackageManager.INSTALL_ALL_USERS; 985 986 String opt; 987 while ((opt = nextOption()) != null) { 988 if (opt.equals("-l")) { 989 params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 990 } else if (opt.equals("-r")) { 991 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 992 } else if (opt.equals("-i")) { 993 installerPackageName = nextArg(); 994 if (installerPackageName == null) { 995 throw new IllegalArgumentException("Missing installer package"); 996 } 997 } else if (opt.equals("-t")) { 998 params.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 999 } else if (opt.equals("-s")) { 1000 params.installFlags |= PackageManager.INSTALL_EXTERNAL; 1001 } else if (opt.equals("-f")) { 1002 params.installFlags |= PackageManager.INSTALL_INTERNAL; 1003 } else if (opt.equals("-d")) { 1004 params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 1005 } else if (opt.equals("-p")) { 1006 params.mode = SessionParams.MODE_INHERIT_EXISTING; 1007 } else if (opt.equals("-S")) { 1008 params.setSize(Long.parseLong(nextOptionData())); 1009 } else if (opt.equals("--abi")) { 1010 params.abiOverride = checkAbiArgument(nextOptionData()); 1011 } else { 1012 throw new IllegalArgumentException("Unknown option " + opt); 1013 } 1014 } 1015 1016 final int sessionId = mInstaller.createSession(params, installerPackageName, 1017 UserHandle.USER_OWNER); 1018 1019 // NOTE: adb depends on parsing this string 1020 System.out.println("Success: created install session [" + sessionId + "]"); 1021 } 1022 1023 private void runInstallWrite() throws IOException, RemoteException { 1024 long sizeBytes = -1; 1025 1026 String opt; 1027 while ((opt = nextOption()) != null) { 1028 if (opt.equals("-S")) { 1029 sizeBytes = Long.parseLong(nextOptionData()); 1030 } else { 1031 throw new IllegalArgumentException("Unknown option: " + opt); 1032 } 1033 } 1034 1035 final int sessionId = Integer.parseInt(nextArg()); 1036 final String splitName = nextArg(); 1037 1038 String path = nextArg(); 1039 if ("-".equals(path)) { 1040 path = null; 1041 } else if (path != null) { 1042 final File file = new File(path); 1043 if (file.isFile()) { 1044 sizeBytes = file.length(); 1045 } 1046 } 1047 1048 final SessionInfo info = mInstaller.getSessionInfo(sessionId); 1049 1050 PackageInstaller.Session session = null; 1051 InputStream in = null; 1052 OutputStream out = null; 1053 try { 1054 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 1055 1056 if (path != null) { 1057 in = new FileInputStream(path); 1058 } else { 1059 in = new SizedInputStream(System.in, sizeBytes); 1060 } 1061 out = session.openWrite(splitName, 0, sizeBytes); 1062 1063 int total = 0; 1064 byte[] buffer = new byte[65536]; 1065 int c; 1066 while ((c = in.read(buffer)) != -1) { 1067 total += c; 1068 out.write(buffer, 0, c); 1069 1070 if (info.sizeBytes > 0) { 1071 final float fraction = ((float) c / (float) info.sizeBytes); 1072 session.addProgress(fraction); 1073 } 1074 } 1075 session.fsync(out); 1076 1077 System.out.println("Success: streamed " + total + " bytes"); 1078 } finally { 1079 IoUtils.closeQuietly(out); 1080 IoUtils.closeQuietly(in); 1081 IoUtils.closeQuietly(session); 1082 } 1083 } 1084 1085 private void runInstallCommit() throws RemoteException { 1086 final int sessionId = Integer.parseInt(nextArg()); 1087 1088 PackageInstaller.Session session = null; 1089 try { 1090 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 1091 1092 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1093 session.commit(receiver.getIntentSender()); 1094 1095 final Intent result = receiver.getResult(); 1096 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1097 PackageInstaller.STATUS_FAILURE); 1098 if (status == PackageInstaller.STATUS_SUCCESS) { 1099 System.out.println("Success"); 1100 } else { 1101 Log.e(TAG, "Failure details: " + result.getExtras()); 1102 System.out.println("Failure [" 1103 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1104 return; 1105 } 1106 } finally { 1107 IoUtils.closeQuietly(session); 1108 } 1109 } 1110 1111 private void runInstallAbandon() throws RemoteException { 1112 final int sessionId = Integer.parseInt(nextArg()); 1113 1114 PackageInstaller.Session session = null; 1115 try { 1116 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 1117 session.abandon(); 1118 System.out.println("Success"); 1119 } finally { 1120 IoUtils.closeQuietly(session); 1121 } 1122 } 1123 1124 private void runSetInstaller() throws RemoteException { 1125 final String targetPackage = nextArg(); 1126 final String installerPackageName = nextArg(); 1127 1128 if (targetPackage == null || installerPackageName == null) { 1129 throw new IllegalArgumentException( 1130 "must provide both target and installer package names"); 1131 } 1132 1133 mPm.setInstallerPackageName(targetPackage, installerPackageName); 1134 System.out.println("Success"); 1135 } 1136 1137 public void runCreateUser() { 1138 String name; 1139 int userId = -1; 1140 int flags = 0; 1141 String opt; 1142 while ((opt = nextOption()) != null) { 1143 if ("--profileOf".equals(opt)) { 1144 String optionData = nextOptionData(); 1145 if (optionData == null || !isNumber(optionData)) { 1146 System.err.println("Error: no USER_ID specified"); 1147 showUsage(); 1148 return; 1149 } else { 1150 userId = Integer.parseInt(optionData); 1151 } 1152 } else if ("--managed".equals(opt)) { 1153 flags |= UserInfo.FLAG_MANAGED_PROFILE; 1154 } else { 1155 System.err.println("Error: unknown option " + opt); 1156 showUsage(); 1157 return; 1158 } 1159 } 1160 String arg = nextArg(); 1161 if (arg == null) { 1162 System.err.println("Error: no user name specified."); 1163 return; 1164 } 1165 name = arg; 1166 try { 1167 UserInfo info = null; 1168 if (userId < 0) { 1169 info = mUm.createUser(name, flags); 1170 } else { 1171 if (Process.myUid() != 0) { 1172 System.err.println("Error: not running as root."); 1173 return; 1174 } 1175 info = mUm.createProfileForUser(name, flags, userId); 1176 } 1177 if (info != null) { 1178 System.out.println("Success: created user id " + info.id); 1179 } else { 1180 System.err.println("Error: couldn't create User."); 1181 } 1182 } catch (RemoteException e) { 1183 System.err.println(e.toString()); 1184 System.err.println(PM_NOT_RUNNING_ERR); 1185 } 1186 1187 } 1188 1189 public void runRemoveUser() { 1190 int userId; 1191 String arg = nextArg(); 1192 if (arg == null) { 1193 System.err.println("Error: no user id specified."); 1194 return; 1195 } 1196 try { 1197 userId = Integer.parseInt(arg); 1198 } catch (NumberFormatException e) { 1199 System.err.println("Error: user id '" + arg + "' is not a number."); 1200 return; 1201 } 1202 try { 1203 if (mUm.removeUser(userId)) { 1204 System.out.println("Success: removed user"); 1205 } else { 1206 System.err.println("Error: couldn't remove user id " + userId); 1207 } 1208 } catch (RemoteException e) { 1209 System.err.println(e.toString()); 1210 System.err.println(PM_NOT_RUNNING_ERR); 1211 } 1212 } 1213 1214 public void runListUsers() { 1215 try { 1216 IActivityManager am = ActivityManagerNative.getDefault(); 1217 1218 List<UserInfo> users = mUm.getUsers(false); 1219 if (users == null) { 1220 System.err.println("Error: couldn't get users"); 1221 } else { 1222 System.out.println("Users:"); 1223 for (int i = 0; i < users.size(); i++) { 1224 String running = am.isUserRunning(users.get(i).id, false) ? " running" : ""; 1225 System.out.println("\t" + users.get(i).toString() + running); 1226 } 1227 } 1228 } catch (RemoteException e) { 1229 System.err.println(e.toString()); 1230 System.err.println(PM_NOT_RUNNING_ERR); 1231 } 1232 } 1233 1234 public void runGetMaxUsers() { 1235 System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers()); 1236 } 1237 1238 public void runForceDexOpt() { 1239 final String packageName = nextArg(); 1240 try { 1241 mPm.forceDexOpt(packageName); 1242 } catch (RemoteException e) { 1243 throw e.rethrowAsRuntimeException(); 1244 } 1245 } 1246 1247 private void runUninstall() throws RemoteException { 1248 int flags = 0; 1249 int userId = UserHandle.USER_ALL; 1250 1251 String opt; 1252 while ((opt=nextOption()) != null) { 1253 if (opt.equals("-k")) { 1254 flags |= PackageManager.DELETE_KEEP_DATA; 1255 } else if (opt.equals("--user")) { 1256 String param = nextArg(); 1257 if (isNumber(param)) { 1258 userId = Integer.parseInt(param); 1259 } else { 1260 showUsage(); 1261 System.err.println("Error: Invalid user: " + param); 1262 return; 1263 } 1264 } else { 1265 System.err.println("Error: Unknown option: " + opt); 1266 return; 1267 } 1268 } 1269 1270 String pkg = nextArg(); 1271 if (pkg == null) { 1272 System.err.println("Error: no package specified"); 1273 showUsage(); 1274 return; 1275 } 1276 1277 if (userId == UserHandle.USER_ALL) { 1278 userId = UserHandle.USER_OWNER; 1279 flags |= PackageManager.DELETE_ALL_USERS; 1280 } else { 1281 PackageInfo info; 1282 try { 1283 info = mPm.getPackageInfo(pkg, 0, userId); 1284 } catch (RemoteException e) { 1285 System.err.println(e.toString()); 1286 System.err.println(PM_NOT_RUNNING_ERR); 1287 return; 1288 } 1289 if (info == null) { 1290 System.err.println("Failure - not installed for " + userId); 1291 return; 1292 } 1293 final boolean isSystem = 1294 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 1295 // If we are being asked to delete a system app for just one 1296 // user set flag so it disables rather than reverting to system 1297 // version of the app. 1298 if (isSystem) { 1299 flags |= PackageManager.DELETE_SYSTEM_APP; 1300 } 1301 } 1302 1303 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1304 mInstaller.uninstall(pkg, flags, receiver.getIntentSender(), userId); 1305 1306 final Intent result = receiver.getResult(); 1307 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1308 PackageInstaller.STATUS_FAILURE); 1309 if (status == PackageInstaller.STATUS_SUCCESS) { 1310 System.out.println("Success"); 1311 } else { 1312 Log.e(TAG, "Failure details: " + result.getExtras()); 1313 System.out.println("Failure [" 1314 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1315 } 1316 } 1317 1318 static class ClearDataObserver extends IPackageDataObserver.Stub { 1319 boolean finished; 1320 boolean result; 1321 1322 @Override 1323 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1324 synchronized (this) { 1325 finished = true; 1326 result = succeeded; 1327 notifyAll(); 1328 } 1329 } 1330 } 1331 1332 private void runClear() { 1333 int userId = 0; 1334 String option = nextOption(); 1335 if (option != null && option.equals("--user")) { 1336 String optionData = nextOptionData(); 1337 if (optionData == null || !isNumber(optionData)) { 1338 System.err.println("Error: no USER_ID specified"); 1339 showUsage(); 1340 return; 1341 } else { 1342 userId = Integer.parseInt(optionData); 1343 } 1344 } 1345 1346 String pkg = nextArg(); 1347 if (pkg == null) { 1348 System.err.println("Error: no package specified"); 1349 showUsage(); 1350 return; 1351 } 1352 1353 ClearDataObserver obs = new ClearDataObserver(); 1354 try { 1355 ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId); 1356 synchronized (obs) { 1357 while (!obs.finished) { 1358 try { 1359 obs.wait(); 1360 } catch (InterruptedException e) { 1361 } 1362 } 1363 } 1364 1365 if (obs.result) { 1366 System.err.println("Success"); 1367 } else { 1368 System.err.println("Failed"); 1369 } 1370 } catch (RemoteException e) { 1371 System.err.println(e.toString()); 1372 System.err.println(PM_NOT_RUNNING_ERR); 1373 } 1374 } 1375 1376 private static String enabledSettingToString(int state) { 1377 switch (state) { 1378 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1379 return "default"; 1380 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1381 return "enabled"; 1382 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1383 return "disabled"; 1384 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1385 return "disabled-user"; 1386 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1387 return "disabled-until-used"; 1388 } 1389 return "unknown"; 1390 } 1391 1392 private static boolean isNumber(String s) { 1393 try { 1394 Integer.parseInt(s); 1395 } catch (NumberFormatException nfe) { 1396 return false; 1397 } 1398 return true; 1399 } 1400 1401 private void runSetEnabledSetting(int state) { 1402 int userId = 0; 1403 String option = nextOption(); 1404 if (option != null && option.equals("--user")) { 1405 String optionData = nextOptionData(); 1406 if (optionData == null || !isNumber(optionData)) { 1407 System.err.println("Error: no USER_ID specified"); 1408 showUsage(); 1409 return; 1410 } else { 1411 userId = Integer.parseInt(optionData); 1412 } 1413 } 1414 1415 String pkg = nextArg(); 1416 if (pkg == null) { 1417 System.err.println("Error: no package or component specified"); 1418 showUsage(); 1419 return; 1420 } 1421 ComponentName cn = ComponentName.unflattenFromString(pkg); 1422 if (cn == null) { 1423 try { 1424 mPm.setApplicationEnabledSetting(pkg, state, 0, userId, 1425 "shell:" + android.os.Process.myUid()); 1426 System.err.println("Package " + pkg + " new state: " 1427 + enabledSettingToString( 1428 mPm.getApplicationEnabledSetting(pkg, userId))); 1429 } catch (RemoteException e) { 1430 System.err.println(e.toString()); 1431 System.err.println(PM_NOT_RUNNING_ERR); 1432 } 1433 } else { 1434 try { 1435 mPm.setComponentEnabledSetting(cn, state, 0, userId); 1436 System.err.println("Component " + cn.toShortString() + " new state: " 1437 + enabledSettingToString( 1438 mPm.getComponentEnabledSetting(cn, userId))); 1439 } catch (RemoteException e) { 1440 System.err.println(e.toString()); 1441 System.err.println(PM_NOT_RUNNING_ERR); 1442 } 1443 } 1444 } 1445 1446 private void runSetHiddenSetting(boolean state) { 1447 int userId = 0; 1448 String option = nextOption(); 1449 if (option != null && option.equals("--user")) { 1450 String optionData = nextOptionData(); 1451 if (optionData == null || !isNumber(optionData)) { 1452 System.err.println("Error: no USER_ID specified"); 1453 showUsage(); 1454 return; 1455 } else { 1456 userId = Integer.parseInt(optionData); 1457 } 1458 } 1459 1460 String pkg = nextArg(); 1461 if (pkg == null) { 1462 System.err.println("Error: no package or component specified"); 1463 showUsage(); 1464 return; 1465 } 1466 try { 1467 mPm.setApplicationHiddenSettingAsUser(pkg, state, userId); 1468 System.err.println("Package " + pkg + " new hidden state: " 1469 + mPm.getApplicationHiddenSettingAsUser(pkg, userId)); 1470 } catch (RemoteException e) { 1471 System.err.println(e.toString()); 1472 System.err.println(PM_NOT_RUNNING_ERR); 1473 } 1474 } 1475 1476 private void runGrantRevokePermission(boolean grant) { 1477 String pkg = nextArg(); 1478 if (pkg == null) { 1479 System.err.println("Error: no package specified"); 1480 showUsage(); 1481 return; 1482 } 1483 String perm = nextArg(); 1484 if (perm == null) { 1485 System.err.println("Error: no permission specified"); 1486 showUsage(); 1487 return; 1488 } 1489 try { 1490 if (grant) { 1491 mPm.grantPermission(pkg, perm); 1492 } else { 1493 mPm.revokePermission(pkg, perm); 1494 } 1495 } catch (RemoteException e) { 1496 System.err.println(e.toString()); 1497 System.err.println(PM_NOT_RUNNING_ERR); 1498 } catch (IllegalArgumentException e) { 1499 System.err.println("Bad argument: " + e.toString()); 1500 showUsage(); 1501 } catch (SecurityException e) { 1502 System.err.println("Operation not allowed: " + e.toString()); 1503 } 1504 } 1505 1506 private void runSetPermissionEnforced() { 1507 final String permission = nextArg(); 1508 if (permission == null) { 1509 System.err.println("Error: no permission specified"); 1510 showUsage(); 1511 return; 1512 } 1513 final String enforcedRaw = nextArg(); 1514 if (enforcedRaw == null) { 1515 System.err.println("Error: no enforcement specified"); 1516 showUsage(); 1517 return; 1518 } 1519 final boolean enforced = Boolean.parseBoolean(enforcedRaw); 1520 try { 1521 mPm.setPermissionEnforced(permission, enforced); 1522 } catch (RemoteException e) { 1523 System.err.println(e.toString()); 1524 System.err.println(PM_NOT_RUNNING_ERR); 1525 } catch (IllegalArgumentException e) { 1526 System.err.println("Bad argument: " + e.toString()); 1527 showUsage(); 1528 } catch (SecurityException e) { 1529 System.err.println("Operation not allowed: " + e.toString()); 1530 } 1531 } 1532 1533 static class ClearCacheObserver extends IPackageDataObserver.Stub { 1534 boolean finished; 1535 boolean result; 1536 1537 @Override 1538 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1539 synchronized (this) { 1540 finished = true; 1541 result = succeeded; 1542 notifyAll(); 1543 } 1544 } 1545 1546 } 1547 1548 private void runTrimCaches() { 1549 String size = nextArg(); 1550 if (size == null) { 1551 System.err.println("Error: no size specified"); 1552 showUsage(); 1553 return; 1554 } 1555 int len = size.length(); 1556 long multiplier = 1; 1557 if (len > 1) { 1558 char c = size.charAt(len-1); 1559 if (c == 'K' || c == 'k') { 1560 multiplier = 1024L; 1561 } else if (c == 'M' || c == 'm') { 1562 multiplier = 1024L*1024L; 1563 } else if (c == 'G' || c == 'g') { 1564 multiplier = 1024L*1024L*1024L; 1565 } else { 1566 System.err.println("Invalid suffix: " + c); 1567 showUsage(); 1568 return; 1569 } 1570 size = size.substring(0, len-1); 1571 } 1572 long sizeVal; 1573 try { 1574 sizeVal = Long.parseLong(size) * multiplier; 1575 } catch (NumberFormatException e) { 1576 System.err.println("Error: expected number at: " + size); 1577 showUsage(); 1578 return; 1579 } 1580 ClearDataObserver obs = new ClearDataObserver(); 1581 try { 1582 mPm.freeStorageAndNotify(sizeVal, obs); 1583 synchronized (obs) { 1584 while (!obs.finished) { 1585 try { 1586 obs.wait(); 1587 } catch (InterruptedException e) { 1588 } 1589 } 1590 } 1591 } catch (RemoteException e) { 1592 System.err.println(e.toString()); 1593 System.err.println(PM_NOT_RUNNING_ERR); 1594 } catch (IllegalArgumentException e) { 1595 System.err.println("Bad argument: " + e.toString()); 1596 showUsage(); 1597 } catch (SecurityException e) { 1598 System.err.println("Operation not allowed: " + e.toString()); 1599 } 1600 } 1601 1602 /** 1603 * Displays the package file for a package. 1604 * @param pckg 1605 */ 1606 private void displayPackageFilePath(String pckg) { 1607 try { 1608 PackageInfo info = mPm.getPackageInfo(pckg, 0, 0); 1609 if (info != null && info.applicationInfo != null) { 1610 System.out.print("package:"); 1611 System.out.println(info.applicationInfo.sourceDir); 1612 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { 1613 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { 1614 System.out.print("package:"); 1615 System.out.println(splitSourceDir); 1616 } 1617 } 1618 } 1619 } catch (RemoteException e) { 1620 System.err.println(e.toString()); 1621 System.err.println(PM_NOT_RUNNING_ERR); 1622 } 1623 } 1624 1625 private Resources getResources(PackageItemInfo pii) { 1626 Resources res = mResourceCache.get(pii.packageName); 1627 if (res != null) return res; 1628 1629 try { 1630 ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0); 1631 AssetManager am = new AssetManager(); 1632 am.addAssetPath(ai.publicSourceDir); 1633 res = new Resources(am, null, null); 1634 mResourceCache.put(pii.packageName, res); 1635 return res; 1636 } catch (RemoteException e) { 1637 System.err.println(e.toString()); 1638 System.err.println(PM_NOT_RUNNING_ERR); 1639 return null; 1640 } 1641 } 1642 1643 private static String checkAbiArgument(String abi) { 1644 if (TextUtils.isEmpty(abi)) { 1645 throw new IllegalArgumentException("Missing ABI argument"); 1646 } 1647 1648 if ("-".equals(abi)) { 1649 return abi; 1650 } 1651 1652 final String[] supportedAbis = Build.SUPPORTED_ABIS; 1653 for (String supportedAbi : supportedAbis) { 1654 if (supportedAbi.equals(abi)) { 1655 return abi; 1656 } 1657 } 1658 1659 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 1660 } 1661 1662 private static class LocalIntentReceiver { 1663 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 1664 1665 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 1666 @Override 1667 public int send(int code, Intent intent, String resolvedType, 1668 IIntentReceiver finishedReceiver, String requiredPermission) { 1669 try { 1670 mResult.offer(intent, 5, TimeUnit.SECONDS); 1671 } catch (InterruptedException e) { 1672 throw new RuntimeException(e); 1673 } 1674 return 0; 1675 } 1676 }; 1677 1678 public IntentSender getIntentSender() { 1679 return new IntentSender((IIntentSender) mLocalSender); 1680 } 1681 1682 public Intent getResult() { 1683 try { 1684 return mResult.poll(30, TimeUnit.SECONDS); 1685 } catch (InterruptedException e) { 1686 throw new RuntimeException(e); 1687 } 1688 } 1689 } 1690 1691 private String nextOption() { 1692 if (mNextArg >= mArgs.length) { 1693 return null; 1694 } 1695 String arg = mArgs[mNextArg]; 1696 if (!arg.startsWith("-")) { 1697 return null; 1698 } 1699 mNextArg++; 1700 if (arg.equals("--")) { 1701 return null; 1702 } 1703 if (arg.length() > 1 && arg.charAt(1) != '-') { 1704 if (arg.length() > 2) { 1705 mCurArgData = arg.substring(2); 1706 return arg.substring(0, 2); 1707 } else { 1708 mCurArgData = null; 1709 return arg; 1710 } 1711 } 1712 mCurArgData = null; 1713 return arg; 1714 } 1715 1716 private String nextOptionData() { 1717 if (mCurArgData != null) { 1718 return mCurArgData; 1719 } 1720 if (mNextArg >= mArgs.length) { 1721 return null; 1722 } 1723 String data = mArgs[mNextArg]; 1724 mNextArg++; 1725 return data; 1726 } 1727 1728 private String nextArg() { 1729 if (mNextArg >= mArgs.length) { 1730 return null; 1731 } 1732 String arg = mArgs[mNextArg]; 1733 mNextArg++; 1734 return arg; 1735 } 1736 1737 private static void showUsage() { 1738 System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]"); 1739 System.err.println(" pm list permission-groups"); 1740 System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); 1741 System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); 1742 System.err.println(" pm list features"); 1743 System.err.println(" pm list libraries"); 1744 System.err.println(" pm list users"); 1745 System.err.println(" pm path PACKAGE"); 1746 System.err.println(" pm dump PACKAGE"); 1747 System.err.println(" pm install [-lrtsfd] [-i PACKAGE] [PATH]"); 1748 System.err.println(" pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]"); 1749 System.err.println(" pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]"); 1750 System.err.println(" pm install-commit SESSION_ID"); 1751 System.err.println(" pm install-abandon SESSION_ID"); 1752 System.err.println(" pm uninstall [-k] [--user USER_ID] PACKAGE"); 1753 System.err.println(" pm set-installer PACKAGE INSTALLER"); 1754 System.err.println(" pm clear [--user USER_ID] PACKAGE"); 1755 System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1756 System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1757 System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 1758 System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 1759 System.err.println(" pm hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1760 System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1761 System.err.println(" pm grant PACKAGE PERMISSION"); 1762 System.err.println(" pm revoke PACKAGE PERMISSION"); 1763 System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]"); 1764 System.err.println(" pm get-install-location"); 1765 System.err.println(" pm set-permission-enforced PERMISSION [true|false]"); 1766 System.err.println(" pm trim-caches DESIRED_FREE_SPACE"); 1767 System.err.println(" pm create-user [--profileOf USER_ID] [--managed] USER_NAME"); 1768 System.err.println(" pm remove-user USER_ID"); 1769 System.err.println(" pm get-max-users"); 1770 System.err.println(""); 1771 System.err.println("pm list packages: prints all packages, optionally only"); 1772 System.err.println(" those whose package name contains the text in FILTER. Options:"); 1773 System.err.println(" -f: see their associated file."); 1774 System.err.println(" -d: filter to only show disbled packages."); 1775 System.err.println(" -e: filter to only show enabled packages."); 1776 System.err.println(" -s: filter to only show system packages."); 1777 System.err.println(" -3: filter to only show third party packages."); 1778 System.err.println(" -i: see the installer for the packages."); 1779 System.err.println(" -u: also include uninstalled packages."); 1780 System.err.println(""); 1781 System.err.println("pm list permission-groups: prints all known permission groups."); 1782 System.err.println(""); 1783 System.err.println("pm list permissions: prints all known permissions, optionally only"); 1784 System.err.println(" those in GROUP. Options:"); 1785 System.err.println(" -g: organize by group."); 1786 System.err.println(" -f: print all information."); 1787 System.err.println(" -s: short summary."); 1788 System.err.println(" -d: only list dangerous permissions."); 1789 System.err.println(" -u: list only the permissions users will see."); 1790 System.err.println(""); 1791 System.err.println("pm list instrumentation: use to list all test packages; optionally"); 1792 System.err.println(" supply <TARGET-PACKAGE> to list the test packages for a particular"); 1793 System.err.println(" application. Options:"); 1794 System.err.println(" -f: list the .apk file for the test package."); 1795 System.err.println(""); 1796 System.err.println("pm list features: prints all features of the system."); 1797 System.err.println(""); 1798 System.err.println("pm list users: prints all users on the system."); 1799 System.err.println(""); 1800 System.err.println("pm path: print the path to the .apk of the given PACKAGE."); 1801 System.err.println(""); 1802 System.err.println("pm dump: print system state associated with the given PACKAGE."); 1803 System.err.println(""); 1804 System.err.println("pm install: install a single legacy package"); 1805 System.err.println("pm install-create: create an install session"); 1806 System.err.println(" -l: forward lock application"); 1807 System.err.println(" -r: replace existing application"); 1808 System.err.println(" -t: allow test packages"); 1809 System.err.println(" -i: specify the installer package name"); 1810 System.err.println(" -s: install application on sdcard"); 1811 System.err.println(" -f: install application on internal flash"); 1812 System.err.println(" -d: allow version code downgrade"); 1813 System.err.println(" -p: partial application install"); 1814 System.err.println(" -S: size in bytes of entire session"); 1815 System.err.println(""); 1816 System.err.println("pm install-write: write a package into existing session; path may"); 1817 System.err.println(" be '-' to read from stdin"); 1818 System.err.println(" -S: size in bytes of package, required for stdin"); 1819 System.err.println(""); 1820 System.err.println("pm install-commit: perform install of fully staged session"); 1821 System.err.println("pm install-abandon: abandon session"); 1822 System.err.println(""); 1823 System.err.println("pm set-installer: set installer package name"); 1824 System.err.println(""); 1825 System.err.println("pm uninstall: removes a package from the system. Options:"); 1826 System.err.println(" -k: keep the data and cache directories around after package removal."); 1827 System.err.println(""); 1828 System.err.println("pm clear: deletes all data associated with a package."); 1829 System.err.println(""); 1830 System.err.println("pm enable, disable, disable-user, disable-until-used: these commands"); 1831 System.err.println(" change the enabled state of a given package or component (written"); 1832 System.err.println(" as \"package/class\")."); 1833 System.err.println(""); 1834 System.err.println("pm grant, revoke: these commands either grant or revoke permissions"); 1835 System.err.println(" to applications. Only optional permissions the application has"); 1836 System.err.println(" declared can be granted or revoked."); 1837 System.err.println(""); 1838 System.err.println("pm get-install-location: returns the current install location."); 1839 System.err.println(" 0 [auto]: Let system decide the best location"); 1840 System.err.println(" 1 [internal]: Install on internal device storage"); 1841 System.err.println(" 2 [external]: Install on external media"); 1842 System.err.println(""); 1843 System.err.println("pm set-install-location: changes the default install location."); 1844 System.err.println(" NOTE: this is only intended for debugging; using this can cause"); 1845 System.err.println(" applications to break and other undersireable behavior."); 1846 System.err.println(" 0 [auto]: Let system decide the best location"); 1847 System.err.println(" 1 [internal]: Install on internal device storage"); 1848 System.err.println(" 2 [external]: Install on external media"); 1849 System.err.println(""); 1850 System.err.println("pm trim-caches: trim cache files to reach the given free space."); 1851 System.err.println(""); 1852 System.err.println("pm create-user: create a new user with the given USER_NAME,"); 1853 System.err.println(" printing the new user identifier of the user."); 1854 System.err.println(""); 1855 System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,"); 1856 System.err.println(" deleting all data associated with that user"); 1857 System.err.println(""); 1858 } 1859} 1860