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