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 = 0; 869 int userId = UserHandle.USER_ALL; 870 String installerPackageName = null; 871 872 String opt; 873 874 String originatingUriString = null; 875 String referrer = null; 876 String abi = null; 877 878 while ((opt=nextOption()) != null) { 879 if (opt.equals("-l")) { 880 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 881 } else if (opt.equals("-r")) { 882 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 883 } else if (opt.equals("-i")) { 884 installerPackageName = nextOptionData(); 885 if (installerPackageName == null) { 886 System.err.println("Error: no value specified for -i"); 887 return; 888 } 889 } else if (opt.equals("-t")) { 890 installFlags |= PackageManager.INSTALL_ALLOW_TEST; 891 } else if (opt.equals("-s")) { 892 // Override if -s option is specified. 893 installFlags |= PackageManager.INSTALL_EXTERNAL; 894 } else if (opt.equals("-f")) { 895 // Override if -s option is specified. 896 installFlags |= PackageManager.INSTALL_INTERNAL; 897 } else if (opt.equals("-d")) { 898 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 899 } else if (opt.equals("--originating-uri")) { 900 originatingUriString = nextOptionData(); 901 if (originatingUriString == null) { 902 System.err.println("Error: must supply argument for --originating-uri"); 903 return; 904 } 905 } else if (opt.equals("--referrer")) { 906 referrer = nextOptionData(); 907 if (referrer == null) { 908 System.err.println("Error: must supply argument for --referrer"); 909 return; 910 } 911 } else if (opt.equals("--abi")) { 912 abi = checkAbiArgument(nextOptionData()); 913 } else if (opt.equals("--user")) { 914 userId = Integer.parseInt(nextOptionData()); 915 } else { 916 System.err.println("Error: Unknown option: " + opt); 917 return; 918 } 919 } 920 921 if (userId == UserHandle.USER_ALL) { 922 userId = UserHandle.USER_OWNER; 923 installFlags |= PackageManager.INSTALL_ALL_USERS; 924 } 925 926 final Uri verificationURI; 927 final Uri originatingURI; 928 final Uri referrerURI; 929 930 if (originatingUriString != null) { 931 originatingURI = Uri.parse(originatingUriString); 932 } else { 933 originatingURI = null; 934 } 935 936 if (referrer != null) { 937 referrerURI = Uri.parse(referrer); 938 } else { 939 referrerURI = null; 940 } 941 942 // Populate apkURI, must be present 943 final String apkFilePath = nextArg(); 944 System.err.println("\tpkg: " + apkFilePath); 945 if (apkFilePath == null) { 946 System.err.println("Error: no package specified"); 947 return; 948 } 949 950 // Populate verificationURI, optionally present 951 final String verificationFilePath = nextArg(); 952 if (verificationFilePath != null) { 953 System.err.println("\tver: " + verificationFilePath); 954 verificationURI = Uri.fromFile(new File(verificationFilePath)); 955 } else { 956 verificationURI = null; 957 } 958 959 LocalPackageInstallObserver obs = new LocalPackageInstallObserver(); 960 try { 961 VerificationParams verificationParams = new VerificationParams(verificationURI, 962 originatingURI, referrerURI, VerificationParams.NO_UID, null); 963 964 mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags, 965 installerPackageName, verificationParams, abi, userId); 966 967 synchronized (obs) { 968 while (!obs.finished) { 969 try { 970 obs.wait(); 971 } catch (InterruptedException e) { 972 } 973 } 974 if (obs.result == PackageManager.INSTALL_SUCCEEDED) { 975 System.out.println("Success"); 976 } else { 977 System.err.println("Failure [" 978 + installFailureToString(obs) 979 + "]"); 980 } 981 } 982 } catch (RemoteException e) { 983 System.err.println(e.toString()); 984 System.err.println(PM_NOT_RUNNING_ERR); 985 } 986 } 987 988 private void runInstallCreate() throws RemoteException { 989 int userId = UserHandle.USER_ALL; 990 String installerPackageName = null; 991 992 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 993 994 String opt; 995 while ((opt = nextOption()) != null) { 996 if (opt.equals("-l")) { 997 params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 998 } else if (opt.equals("-r")) { 999 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1000 } else if (opt.equals("-i")) { 1001 installerPackageName = nextArg(); 1002 if (installerPackageName == null) { 1003 throw new IllegalArgumentException("Missing installer package"); 1004 } 1005 } else if (opt.equals("-t")) { 1006 params.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 1007 } else if (opt.equals("-s")) { 1008 params.installFlags |= PackageManager.INSTALL_EXTERNAL; 1009 } else if (opt.equals("-f")) { 1010 params.installFlags |= PackageManager.INSTALL_INTERNAL; 1011 } else if (opt.equals("-d")) { 1012 params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 1013 } else if (opt.equals("--originating-uri")) { 1014 params.originatingUri = Uri.parse(nextOptionData()); 1015 } else if (opt.equals("--referrer")) { 1016 params.referrerUri = Uri.parse(nextOptionData()); 1017 } else if (opt.equals("-p")) { 1018 params.mode = SessionParams.MODE_INHERIT_EXISTING; 1019 params.appPackageName = nextOptionData(); 1020 if (params.appPackageName == null) { 1021 throw new IllegalArgumentException("Missing inherit package name"); 1022 } 1023 } else if (opt.equals("-S")) { 1024 params.setSize(Long.parseLong(nextOptionData())); 1025 } else if (opt.equals("--abi")) { 1026 params.abiOverride = checkAbiArgument(nextOptionData()); 1027 } else if (opt.equals("--user")) { 1028 userId = Integer.parseInt(nextOptionData()); 1029 } else { 1030 throw new IllegalArgumentException("Unknown option " + opt); 1031 } 1032 } 1033 1034 if (userId == UserHandle.USER_ALL) { 1035 userId = UserHandle.USER_OWNER; 1036 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 1037 } 1038 1039 final int sessionId = mInstaller.createSession(params, installerPackageName, userId); 1040 1041 // NOTE: adb depends on parsing this string 1042 System.out.println("Success: created install session [" + sessionId + "]"); 1043 } 1044 1045 private void runInstallWrite() throws IOException, RemoteException { 1046 long sizeBytes = -1; 1047 1048 String opt; 1049 while ((opt = nextOption()) != null) { 1050 if (opt.equals("-S")) { 1051 sizeBytes = Long.parseLong(nextOptionData()); 1052 } else { 1053 throw new IllegalArgumentException("Unknown option: " + opt); 1054 } 1055 } 1056 1057 final int sessionId = Integer.parseInt(nextArg()); 1058 final String splitName = nextArg(); 1059 1060 String path = nextArg(); 1061 if ("-".equals(path)) { 1062 path = null; 1063 } else if (path != null) { 1064 final File file = new File(path); 1065 if (file.isFile()) { 1066 sizeBytes = file.length(); 1067 } 1068 } 1069 1070 final SessionInfo info = mInstaller.getSessionInfo(sessionId); 1071 1072 PackageInstaller.Session session = null; 1073 InputStream in = null; 1074 OutputStream out = null; 1075 try { 1076 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 1077 1078 if (path != null) { 1079 in = new FileInputStream(path); 1080 } else { 1081 in = new SizedInputStream(System.in, sizeBytes); 1082 } 1083 out = session.openWrite(splitName, 0, sizeBytes); 1084 1085 int total = 0; 1086 byte[] buffer = new byte[65536]; 1087 int c; 1088 while ((c = in.read(buffer)) != -1) { 1089 total += c; 1090 out.write(buffer, 0, c); 1091 1092 if (info.sizeBytes > 0) { 1093 final float fraction = ((float) c / (float) info.sizeBytes); 1094 session.addProgress(fraction); 1095 } 1096 } 1097 session.fsync(out); 1098 1099 System.out.println("Success: streamed " + total + " bytes"); 1100 } finally { 1101 IoUtils.closeQuietly(out); 1102 IoUtils.closeQuietly(in); 1103 IoUtils.closeQuietly(session); 1104 } 1105 } 1106 1107 private void runInstallCommit() throws RemoteException { 1108 final int sessionId = Integer.parseInt(nextArg()); 1109 1110 PackageInstaller.Session session = null; 1111 try { 1112 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 1113 1114 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1115 session.commit(receiver.getIntentSender()); 1116 1117 final Intent result = receiver.getResult(); 1118 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1119 PackageInstaller.STATUS_FAILURE); 1120 if (status == PackageInstaller.STATUS_SUCCESS) { 1121 System.out.println("Success"); 1122 } else { 1123 Log.e(TAG, "Failure details: " + result.getExtras()); 1124 System.out.println("Failure [" 1125 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1126 return; 1127 } 1128 } finally { 1129 IoUtils.closeQuietly(session); 1130 } 1131 } 1132 1133 private void runInstallAbandon() throws RemoteException { 1134 final int sessionId = Integer.parseInt(nextArg()); 1135 1136 PackageInstaller.Session session = null; 1137 try { 1138 session = new PackageInstaller.Session(mInstaller.openSession(sessionId)); 1139 session.abandon(); 1140 System.out.println("Success"); 1141 } finally { 1142 IoUtils.closeQuietly(session); 1143 } 1144 } 1145 1146 private void runSetInstaller() throws RemoteException { 1147 final String targetPackage = nextArg(); 1148 final String installerPackageName = nextArg(); 1149 1150 if (targetPackage == null || installerPackageName == null) { 1151 throw new IllegalArgumentException( 1152 "must provide both target and installer package names"); 1153 } 1154 1155 mPm.setInstallerPackageName(targetPackage, installerPackageName); 1156 System.out.println("Success"); 1157 } 1158 1159 public void runCreateUser() { 1160 String name; 1161 int userId = -1; 1162 int flags = 0; 1163 String opt; 1164 while ((opt = nextOption()) != null) { 1165 if ("--profileOf".equals(opt)) { 1166 String optionData = nextOptionData(); 1167 if (optionData == null || !isNumber(optionData)) { 1168 System.err.println("Error: no USER_ID specified"); 1169 showUsage(); 1170 return; 1171 } else { 1172 userId = Integer.parseInt(optionData); 1173 } 1174 } else if ("--managed".equals(opt)) { 1175 flags |= UserInfo.FLAG_MANAGED_PROFILE; 1176 } else { 1177 System.err.println("Error: unknown option " + opt); 1178 showUsage(); 1179 return; 1180 } 1181 } 1182 String arg = nextArg(); 1183 if (arg == null) { 1184 System.err.println("Error: no user name specified."); 1185 return; 1186 } 1187 name = arg; 1188 try { 1189 UserInfo info = null; 1190 if (userId < 0) { 1191 info = mUm.createUser(name, flags); 1192 } else { 1193 info = mUm.createProfileForUser(name, flags, userId); 1194 } 1195 if (info != null) { 1196 System.out.println("Success: created user id " + info.id); 1197 } else { 1198 System.err.println("Error: couldn't create User."); 1199 } 1200 } catch (RemoteException e) { 1201 System.err.println(e.toString()); 1202 System.err.println(PM_NOT_RUNNING_ERR); 1203 } 1204 1205 } 1206 1207 public void runRemoveUser() { 1208 int userId; 1209 String arg = nextArg(); 1210 if (arg == null) { 1211 System.err.println("Error: no user id specified."); 1212 return; 1213 } 1214 try { 1215 userId = Integer.parseInt(arg); 1216 } catch (NumberFormatException e) { 1217 System.err.println("Error: user id '" + arg + "' is not a number."); 1218 return; 1219 } 1220 try { 1221 if (mUm.removeUser(userId)) { 1222 System.out.println("Success: removed user"); 1223 } else { 1224 System.err.println("Error: couldn't remove user id " + userId); 1225 } 1226 } catch (RemoteException e) { 1227 System.err.println(e.toString()); 1228 System.err.println(PM_NOT_RUNNING_ERR); 1229 } 1230 } 1231 1232 public void runListUsers() { 1233 try { 1234 IActivityManager am = ActivityManagerNative.getDefault(); 1235 1236 List<UserInfo> users = mUm.getUsers(false); 1237 if (users == null) { 1238 System.err.println("Error: couldn't get users"); 1239 } else { 1240 System.out.println("Users:"); 1241 for (int i = 0; i < users.size(); i++) { 1242 String running = am.isUserRunning(users.get(i).id, false) ? " running" : ""; 1243 System.out.println("\t" + users.get(i).toString() + running); 1244 } 1245 } 1246 } catch (RemoteException e) { 1247 System.err.println(e.toString()); 1248 System.err.println(PM_NOT_RUNNING_ERR); 1249 } 1250 } 1251 1252 public void runGetMaxUsers() { 1253 System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers()); 1254 } 1255 1256 public void runForceDexOpt() { 1257 final String packageName = nextArg(); 1258 try { 1259 mPm.forceDexOpt(packageName); 1260 } catch (RemoteException e) { 1261 throw e.rethrowAsRuntimeException(); 1262 } 1263 } 1264 1265 private void runUninstall() throws RemoteException { 1266 int flags = 0; 1267 int userId = UserHandle.USER_ALL; 1268 1269 String opt; 1270 while ((opt=nextOption()) != null) { 1271 if (opt.equals("-k")) { 1272 flags |= PackageManager.DELETE_KEEP_DATA; 1273 } else if (opt.equals("--user")) { 1274 String param = nextArg(); 1275 if (isNumber(param)) { 1276 userId = Integer.parseInt(param); 1277 } else { 1278 showUsage(); 1279 System.err.println("Error: Invalid user: " + param); 1280 return; 1281 } 1282 } else { 1283 System.err.println("Error: Unknown option: " + opt); 1284 return; 1285 } 1286 } 1287 1288 String pkg = nextArg(); 1289 if (pkg == null) { 1290 System.err.println("Error: no package specified"); 1291 showUsage(); 1292 return; 1293 } 1294 1295 if (userId == UserHandle.USER_ALL) { 1296 userId = UserHandle.USER_OWNER; 1297 flags |= PackageManager.DELETE_ALL_USERS; 1298 } else { 1299 PackageInfo info; 1300 try { 1301 info = mPm.getPackageInfo(pkg, 0, userId); 1302 } catch (RemoteException e) { 1303 System.err.println(e.toString()); 1304 System.err.println(PM_NOT_RUNNING_ERR); 1305 return; 1306 } 1307 if (info == null) { 1308 System.err.println("Failure - not installed for " + userId); 1309 return; 1310 } 1311 final boolean isSystem = 1312 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 1313 // If we are being asked to delete a system app for just one 1314 // user set flag so it disables rather than reverting to system 1315 // version of the app. 1316 if (isSystem) { 1317 flags |= PackageManager.DELETE_SYSTEM_APP; 1318 } 1319 } 1320 1321 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 1322 mInstaller.uninstall(pkg, flags, receiver.getIntentSender(), userId); 1323 1324 final Intent result = receiver.getResult(); 1325 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1326 PackageInstaller.STATUS_FAILURE); 1327 if (status == PackageInstaller.STATUS_SUCCESS) { 1328 System.out.println("Success"); 1329 } else { 1330 Log.e(TAG, "Failure details: " + result.getExtras()); 1331 System.out.println("Failure [" 1332 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 1333 } 1334 } 1335 1336 static class ClearDataObserver extends IPackageDataObserver.Stub { 1337 boolean finished; 1338 boolean result; 1339 1340 @Override 1341 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1342 synchronized (this) { 1343 finished = true; 1344 result = succeeded; 1345 notifyAll(); 1346 } 1347 } 1348 } 1349 1350 private void runClear() { 1351 int userId = 0; 1352 String option = nextOption(); 1353 if (option != null && option.equals("--user")) { 1354 String optionData = nextOptionData(); 1355 if (optionData == null || !isNumber(optionData)) { 1356 System.err.println("Error: no USER_ID specified"); 1357 showUsage(); 1358 return; 1359 } else { 1360 userId = Integer.parseInt(optionData); 1361 } 1362 } 1363 1364 String pkg = nextArg(); 1365 if (pkg == null) { 1366 System.err.println("Error: no package specified"); 1367 showUsage(); 1368 return; 1369 } 1370 1371 ClearDataObserver obs = new ClearDataObserver(); 1372 try { 1373 ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId); 1374 synchronized (obs) { 1375 while (!obs.finished) { 1376 try { 1377 obs.wait(); 1378 } catch (InterruptedException e) { 1379 } 1380 } 1381 } 1382 1383 if (obs.result) { 1384 System.err.println("Success"); 1385 } else { 1386 System.err.println("Failed"); 1387 } 1388 } catch (RemoteException e) { 1389 System.err.println(e.toString()); 1390 System.err.println(PM_NOT_RUNNING_ERR); 1391 } 1392 } 1393 1394 private static String enabledSettingToString(int state) { 1395 switch (state) { 1396 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: 1397 return "default"; 1398 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: 1399 return "enabled"; 1400 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: 1401 return "disabled"; 1402 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: 1403 return "disabled-user"; 1404 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: 1405 return "disabled-until-used"; 1406 } 1407 return "unknown"; 1408 } 1409 1410 private static boolean isNumber(String s) { 1411 try { 1412 Integer.parseInt(s); 1413 } catch (NumberFormatException nfe) { 1414 return false; 1415 } 1416 return true; 1417 } 1418 1419 private void runSetEnabledSetting(int state) { 1420 int userId = 0; 1421 String option = nextOption(); 1422 if (option != null && option.equals("--user")) { 1423 String optionData = nextOptionData(); 1424 if (optionData == null || !isNumber(optionData)) { 1425 System.err.println("Error: no USER_ID specified"); 1426 showUsage(); 1427 return; 1428 } else { 1429 userId = Integer.parseInt(optionData); 1430 } 1431 } 1432 1433 String pkg = nextArg(); 1434 if (pkg == null) { 1435 System.err.println("Error: no package or component specified"); 1436 showUsage(); 1437 return; 1438 } 1439 ComponentName cn = ComponentName.unflattenFromString(pkg); 1440 if (cn == null) { 1441 try { 1442 mPm.setApplicationEnabledSetting(pkg, state, 0, userId, 1443 "shell:" + android.os.Process.myUid()); 1444 System.err.println("Package " + pkg + " new state: " 1445 + enabledSettingToString( 1446 mPm.getApplicationEnabledSetting(pkg, userId))); 1447 } catch (RemoteException e) { 1448 System.err.println(e.toString()); 1449 System.err.println(PM_NOT_RUNNING_ERR); 1450 } 1451 } else { 1452 try { 1453 mPm.setComponentEnabledSetting(cn, state, 0, userId); 1454 System.err.println("Component " + cn.toShortString() + " new state: " 1455 + enabledSettingToString( 1456 mPm.getComponentEnabledSetting(cn, userId))); 1457 } catch (RemoteException e) { 1458 System.err.println(e.toString()); 1459 System.err.println(PM_NOT_RUNNING_ERR); 1460 } 1461 } 1462 } 1463 1464 private void runSetHiddenSetting(boolean state) { 1465 int userId = 0; 1466 String option = nextOption(); 1467 if (option != null && option.equals("--user")) { 1468 String optionData = nextOptionData(); 1469 if (optionData == null || !isNumber(optionData)) { 1470 System.err.println("Error: no USER_ID specified"); 1471 showUsage(); 1472 return; 1473 } else { 1474 userId = Integer.parseInt(optionData); 1475 } 1476 } 1477 1478 String pkg = nextArg(); 1479 if (pkg == null) { 1480 System.err.println("Error: no package or component specified"); 1481 showUsage(); 1482 return; 1483 } 1484 try { 1485 mPm.setApplicationHiddenSettingAsUser(pkg, state, userId); 1486 System.err.println("Package " + pkg + " new hidden state: " 1487 + mPm.getApplicationHiddenSettingAsUser(pkg, userId)); 1488 } catch (RemoteException e) { 1489 System.err.println(e.toString()); 1490 System.err.println(PM_NOT_RUNNING_ERR); 1491 } 1492 } 1493 1494 private void runGrantRevokePermission(boolean grant) { 1495 String pkg = nextArg(); 1496 if (pkg == null) { 1497 System.err.println("Error: no package specified"); 1498 showUsage(); 1499 return; 1500 } 1501 String perm = nextArg(); 1502 if (perm == null) { 1503 System.err.println("Error: no permission specified"); 1504 showUsage(); 1505 return; 1506 } 1507 try { 1508 if (grant) { 1509 mPm.grantPermission(pkg, perm); 1510 } else { 1511 mPm.revokePermission(pkg, perm); 1512 } 1513 } catch (RemoteException e) { 1514 System.err.println(e.toString()); 1515 System.err.println(PM_NOT_RUNNING_ERR); 1516 } catch (IllegalArgumentException e) { 1517 System.err.println("Bad argument: " + e.toString()); 1518 showUsage(); 1519 } catch (SecurityException e) { 1520 System.err.println("Operation not allowed: " + e.toString()); 1521 } 1522 } 1523 1524 private void runSetPermissionEnforced() { 1525 final String permission = nextArg(); 1526 if (permission == null) { 1527 System.err.println("Error: no permission specified"); 1528 showUsage(); 1529 return; 1530 } 1531 final String enforcedRaw = nextArg(); 1532 if (enforcedRaw == null) { 1533 System.err.println("Error: no enforcement specified"); 1534 showUsage(); 1535 return; 1536 } 1537 final boolean enforced = Boolean.parseBoolean(enforcedRaw); 1538 try { 1539 mPm.setPermissionEnforced(permission, enforced); 1540 } catch (RemoteException e) { 1541 System.err.println(e.toString()); 1542 System.err.println(PM_NOT_RUNNING_ERR); 1543 } catch (IllegalArgumentException e) { 1544 System.err.println("Bad argument: " + e.toString()); 1545 showUsage(); 1546 } catch (SecurityException e) { 1547 System.err.println("Operation not allowed: " + e.toString()); 1548 } 1549 } 1550 1551 static class ClearCacheObserver extends IPackageDataObserver.Stub { 1552 boolean finished; 1553 boolean result; 1554 1555 @Override 1556 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { 1557 synchronized (this) { 1558 finished = true; 1559 result = succeeded; 1560 notifyAll(); 1561 } 1562 } 1563 1564 } 1565 1566 private void runTrimCaches() { 1567 String size = nextArg(); 1568 if (size == null) { 1569 System.err.println("Error: no size specified"); 1570 showUsage(); 1571 return; 1572 } 1573 int len = size.length(); 1574 long multiplier = 1; 1575 if (len > 1) { 1576 char c = size.charAt(len-1); 1577 if (c == 'K' || c == 'k') { 1578 multiplier = 1024L; 1579 } else if (c == 'M' || c == 'm') { 1580 multiplier = 1024L*1024L; 1581 } else if (c == 'G' || c == 'g') { 1582 multiplier = 1024L*1024L*1024L; 1583 } else { 1584 System.err.println("Invalid suffix: " + c); 1585 showUsage(); 1586 return; 1587 } 1588 size = size.substring(0, len-1); 1589 } 1590 long sizeVal; 1591 try { 1592 sizeVal = Long.parseLong(size) * multiplier; 1593 } catch (NumberFormatException e) { 1594 System.err.println("Error: expected number at: " + size); 1595 showUsage(); 1596 return; 1597 } 1598 ClearDataObserver obs = new ClearDataObserver(); 1599 try { 1600 mPm.freeStorageAndNotify(sizeVal, obs); 1601 synchronized (obs) { 1602 while (!obs.finished) { 1603 try { 1604 obs.wait(); 1605 } catch (InterruptedException e) { 1606 } 1607 } 1608 } 1609 } catch (RemoteException e) { 1610 System.err.println(e.toString()); 1611 System.err.println(PM_NOT_RUNNING_ERR); 1612 } catch (IllegalArgumentException e) { 1613 System.err.println("Bad argument: " + e.toString()); 1614 showUsage(); 1615 } catch (SecurityException e) { 1616 System.err.println("Operation not allowed: " + e.toString()); 1617 } 1618 } 1619 1620 /** 1621 * Displays the package file for a package. 1622 * @param pckg 1623 */ 1624 private void displayPackageFilePath(String pckg) { 1625 try { 1626 PackageInfo info = mPm.getPackageInfo(pckg, 0, 0); 1627 if (info != null && info.applicationInfo != null) { 1628 System.out.print("package:"); 1629 System.out.println(info.applicationInfo.sourceDir); 1630 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { 1631 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { 1632 System.out.print("package:"); 1633 System.out.println(splitSourceDir); 1634 } 1635 } 1636 } 1637 } catch (RemoteException e) { 1638 System.err.println(e.toString()); 1639 System.err.println(PM_NOT_RUNNING_ERR); 1640 } 1641 } 1642 1643 private Resources getResources(PackageItemInfo pii) { 1644 Resources res = mResourceCache.get(pii.packageName); 1645 if (res != null) return res; 1646 1647 try { 1648 ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0); 1649 AssetManager am = new AssetManager(); 1650 am.addAssetPath(ai.publicSourceDir); 1651 res = new Resources(am, null, null); 1652 mResourceCache.put(pii.packageName, res); 1653 return res; 1654 } catch (RemoteException e) { 1655 System.err.println(e.toString()); 1656 System.err.println(PM_NOT_RUNNING_ERR); 1657 return null; 1658 } 1659 } 1660 1661 private static String checkAbiArgument(String abi) { 1662 if (TextUtils.isEmpty(abi)) { 1663 throw new IllegalArgumentException("Missing ABI argument"); 1664 } 1665 1666 if ("-".equals(abi)) { 1667 return abi; 1668 } 1669 1670 final String[] supportedAbis = Build.SUPPORTED_ABIS; 1671 for (String supportedAbi : supportedAbis) { 1672 if (supportedAbi.equals(abi)) { 1673 return abi; 1674 } 1675 } 1676 1677 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 1678 } 1679 1680 private static class LocalIntentReceiver { 1681 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 1682 1683 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 1684 @Override 1685 public int send(int code, Intent intent, String resolvedType, 1686 IIntentReceiver finishedReceiver, String requiredPermission) { 1687 try { 1688 mResult.offer(intent, 5, TimeUnit.SECONDS); 1689 } catch (InterruptedException e) { 1690 throw new RuntimeException(e); 1691 } 1692 return 0; 1693 } 1694 }; 1695 1696 public IntentSender getIntentSender() { 1697 return new IntentSender((IIntentSender) mLocalSender); 1698 } 1699 1700 public Intent getResult() { 1701 try { 1702 return mResult.take(); 1703 } catch (InterruptedException e) { 1704 throw new RuntimeException(e); 1705 } 1706 } 1707 } 1708 1709 private String nextOption() { 1710 if (mNextArg >= mArgs.length) { 1711 return null; 1712 } 1713 String arg = mArgs[mNextArg]; 1714 if (!arg.startsWith("-")) { 1715 return null; 1716 } 1717 mNextArg++; 1718 if (arg.equals("--")) { 1719 return null; 1720 } 1721 if (arg.length() > 1 && arg.charAt(1) != '-') { 1722 if (arg.length() > 2) { 1723 mCurArgData = arg.substring(2); 1724 return arg.substring(0, 2); 1725 } else { 1726 mCurArgData = null; 1727 return arg; 1728 } 1729 } 1730 mCurArgData = null; 1731 return arg; 1732 } 1733 1734 private String nextOptionData() { 1735 if (mCurArgData != null) { 1736 return mCurArgData; 1737 } 1738 if (mNextArg >= mArgs.length) { 1739 return null; 1740 } 1741 String data = mArgs[mNextArg]; 1742 mNextArg++; 1743 return data; 1744 } 1745 1746 private String nextArg() { 1747 if (mNextArg >= mArgs.length) { 1748 return null; 1749 } 1750 String arg = mArgs[mNextArg]; 1751 mNextArg++; 1752 return arg; 1753 } 1754 1755 private static void showUsage() { 1756 System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]"); 1757 System.err.println(" pm list permission-groups"); 1758 System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); 1759 System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); 1760 System.err.println(" pm list features"); 1761 System.err.println(" pm list libraries"); 1762 System.err.println(" pm list users"); 1763 System.err.println(" pm path PACKAGE"); 1764 System.err.println(" pm dump PACKAGE"); 1765 System.err.println(" pm install [-lrtsfd] [-i PACKAGE] [PATH]"); 1766 System.err.println(" pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]"); 1767 System.err.println(" pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]"); 1768 System.err.println(" pm install-commit SESSION_ID"); 1769 System.err.println(" pm install-abandon SESSION_ID"); 1770 System.err.println(" pm uninstall [-k] [--user USER_ID] PACKAGE"); 1771 System.err.println(" pm set-installer PACKAGE INSTALLER"); 1772 System.err.println(" pm clear [--user USER_ID] PACKAGE"); 1773 System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1774 System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); 1775 System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); 1776 System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT"); 1777 System.err.println(" pm hide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1778 System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT"); 1779 System.err.println(" pm grant PACKAGE PERMISSION"); 1780 System.err.println(" pm revoke PACKAGE PERMISSION"); 1781 System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]"); 1782 System.err.println(" pm get-install-location"); 1783 System.err.println(" pm set-permission-enforced PERMISSION [true|false]"); 1784 System.err.println(" pm trim-caches DESIRED_FREE_SPACE"); 1785 System.err.println(" pm create-user [--profileOf USER_ID] [--managed] USER_NAME"); 1786 System.err.println(" pm remove-user USER_ID"); 1787 System.err.println(" pm get-max-users"); 1788 System.err.println(""); 1789 System.err.println("pm list packages: prints all packages, optionally only"); 1790 System.err.println(" those whose package name contains the text in FILTER. Options:"); 1791 System.err.println(" -f: see their associated file."); 1792 System.err.println(" -d: filter to only show disbled packages."); 1793 System.err.println(" -e: filter to only show enabled packages."); 1794 System.err.println(" -s: filter to only show system packages."); 1795 System.err.println(" -3: filter to only show third party packages."); 1796 System.err.println(" -i: see the installer for the packages."); 1797 System.err.println(" -u: also include uninstalled packages."); 1798 System.err.println(""); 1799 System.err.println("pm list permission-groups: prints all known permission groups."); 1800 System.err.println(""); 1801 System.err.println("pm list permissions: prints all known permissions, optionally only"); 1802 System.err.println(" those in GROUP. Options:"); 1803 System.err.println(" -g: organize by group."); 1804 System.err.println(" -f: print all information."); 1805 System.err.println(" -s: short summary."); 1806 System.err.println(" -d: only list dangerous permissions."); 1807 System.err.println(" -u: list only the permissions users will see."); 1808 System.err.println(""); 1809 System.err.println("pm list instrumentation: use to list all test packages; optionally"); 1810 System.err.println(" supply <TARGET-PACKAGE> to list the test packages for a particular"); 1811 System.err.println(" application. Options:"); 1812 System.err.println(" -f: list the .apk file for the test package."); 1813 System.err.println(""); 1814 System.err.println("pm list features: prints all features of the system."); 1815 System.err.println(""); 1816 System.err.println("pm list users: prints all users on the system."); 1817 System.err.println(""); 1818 System.err.println("pm path: print the path to the .apk of the given PACKAGE."); 1819 System.err.println(""); 1820 System.err.println("pm dump: print system state associated with the given PACKAGE."); 1821 System.err.println(""); 1822 System.err.println("pm install: install a single legacy package"); 1823 System.err.println("pm install-create: create an install session"); 1824 System.err.println(" -l: forward lock application"); 1825 System.err.println(" -r: replace existing application"); 1826 System.err.println(" -t: allow test packages"); 1827 System.err.println(" -i: specify the installer package name"); 1828 System.err.println(" -s: install application on sdcard"); 1829 System.err.println(" -f: install application on internal flash"); 1830 System.err.println(" -d: allow version code downgrade"); 1831 System.err.println(" -p: partial application install"); 1832 System.err.println(" -S: size in bytes of entire session"); 1833 System.err.println(""); 1834 System.err.println("pm install-write: write a package into existing session; path may"); 1835 System.err.println(" be '-' to read from stdin"); 1836 System.err.println(" -S: size in bytes of package, required for stdin"); 1837 System.err.println(""); 1838 System.err.println("pm install-commit: perform install of fully staged session"); 1839 System.err.println("pm install-abandon: abandon session"); 1840 System.err.println(""); 1841 System.err.println("pm set-installer: set installer package name"); 1842 System.err.println(""); 1843 System.err.println("pm uninstall: removes a package from the system. Options:"); 1844 System.err.println(" -k: keep the data and cache directories around after package removal."); 1845 System.err.println(""); 1846 System.err.println("pm clear: deletes all data associated with a package."); 1847 System.err.println(""); 1848 System.err.println("pm enable, disable, disable-user, disable-until-used: these commands"); 1849 System.err.println(" change the enabled state of a given package or component (written"); 1850 System.err.println(" as \"package/class\")."); 1851 System.err.println(""); 1852 System.err.println("pm grant, revoke: these commands either grant or revoke permissions"); 1853 System.err.println(" to applications. Only optional permissions the application has"); 1854 System.err.println(" declared can be granted or revoked."); 1855 System.err.println(""); 1856 System.err.println("pm get-install-location: returns the current install location."); 1857 System.err.println(" 0 [auto]: Let system decide the best location"); 1858 System.err.println(" 1 [internal]: Install on internal device storage"); 1859 System.err.println(" 2 [external]: Install on external media"); 1860 System.err.println(""); 1861 System.err.println("pm set-install-location: changes the default install location."); 1862 System.err.println(" NOTE: this is only intended for debugging; using this can cause"); 1863 System.err.println(" applications to break and other undersireable behavior."); 1864 System.err.println(" 0 [auto]: Let system decide the best location"); 1865 System.err.println(" 1 [internal]: Install on internal device storage"); 1866 System.err.println(" 2 [external]: Install on external media"); 1867 System.err.println(""); 1868 System.err.println("pm trim-caches: trim cache files to reach the given free space."); 1869 System.err.println(""); 1870 System.err.println("pm create-user: create a new user with the given USER_NAME,"); 1871 System.err.println(" printing the new user identifier of the user."); 1872 System.err.println(""); 1873 System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,"); 1874 System.err.println(" deleting all data associated with that user"); 1875 System.err.println(""); 1876 } 1877} 1878