PackageManagerShellCommand.java revision 115d2c189a46f535778d9dd0923f703ff2f888fe
1/* 2 * Copyright (C) 2015 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.server.pm; 18 19import android.app.ActivityManager; 20import android.content.ComponentName; 21import android.content.IIntentReceiver; 22import android.content.IIntentSender; 23import android.content.Intent; 24import android.content.IntentSender; 25import android.content.pm.ApplicationInfo; 26import android.content.pm.FeatureInfo; 27import android.content.pm.IPackageManager; 28import android.content.pm.InstrumentationInfo; 29import android.content.pm.PackageInfo; 30import android.content.pm.PackageInstaller; 31import android.content.pm.PackageItemInfo; 32import android.content.pm.PackageManager; 33import android.content.pm.ParceledListSlice; 34import android.content.pm.PermissionGroupInfo; 35import android.content.pm.PermissionInfo; 36import android.content.pm.PackageInstaller.SessionInfo; 37import android.content.pm.PackageInstaller.SessionParams; 38import android.content.pm.ResolveInfo; 39import android.content.res.AssetManager; 40import android.content.res.Resources; 41import android.net.Uri; 42import android.os.Binder; 43import android.os.Build; 44import android.os.Bundle; 45import android.os.RemoteException; 46import android.os.ShellCommand; 47import android.os.SystemProperties; 48import android.os.UserHandle; 49import android.text.TextUtils; 50import android.util.PrintWriterPrinter; 51import com.android.internal.util.SizedInputStream; 52 53import libcore.io.IoUtils; 54 55import java.io.File; 56import java.io.FileInputStream; 57import java.io.IOException; 58import java.io.InputStream; 59import java.io.OutputStream; 60import java.io.PrintWriter; 61import java.net.URISyntaxException; 62import java.util.ArrayList; 63import java.util.Collections; 64import java.util.Comparator; 65import java.util.List; 66import java.util.WeakHashMap; 67import java.util.concurrent.SynchronousQueue; 68import java.util.concurrent.TimeUnit; 69 70class PackageManagerShellCommand extends ShellCommand { 71 final IPackageManager mInterface; 72 final private WeakHashMap<String, Resources> mResourceCache = 73 new WeakHashMap<String, Resources>(); 74 int mTargetUser; 75 76 PackageManagerShellCommand(PackageManagerService service) { 77 mInterface = service; 78 } 79 80 @Override 81 public int onCommand(String cmd) { 82 if (cmd == null) { 83 return handleDefaultCommands(cmd); 84 } 85 86 final PrintWriter pw = getOutPrintWriter(); 87 try { 88 switch(cmd) { 89 case "install": 90 return runInstall(); 91 case "install-abandon": 92 case "install-destroy": 93 return runInstallAbandon(); 94 case "install-commit": 95 return runInstallCommit(); 96 case "install-create": 97 return runInstallCreate(); 98 case "install-write": 99 return runInstallWrite(); 100 case "compile": 101 return runCompile(); 102 case "list": 103 return runList(); 104 case "uninstall": 105 return runUninstall(); 106 case "resolve-activity": 107 return runResolveActivity(); 108 case "query-activities": 109 return runQueryIntentActivities(); 110 case "query-services": 111 return runQueryIntentServices(); 112 case "query-receivers": 113 return runQueryIntentReceivers(); 114 case "suspend": 115 return runSuspend(true); 116 case "unsuspend": 117 return runSuspend(false); 118 default: 119 return handleDefaultCommands(cmd); 120 } 121 } catch (RemoteException e) { 122 pw.println("Remote exception: " + e); 123 } 124 return -1; 125 } 126 127 private int runInstall() throws RemoteException { 128 final PrintWriter pw = getOutPrintWriter(); 129 final InstallParams params = makeInstallParams(); 130 final int sessionId = doCreateSession(params.sessionParams, 131 params.installerPackageName, params.userId); 132 boolean abandonSession = true; 133 try { 134 final String inPath = getNextArg(); 135 if (inPath == null && params.sessionParams.sizeBytes == 0) { 136 pw.println("Error: must either specify a package size or an APK file"); 137 return 1; 138 } 139 if (doWriteSession(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk", 140 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 141 return 1; 142 } 143 if (doCommitSession(sessionId, false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { 144 return 1; 145 } 146 abandonSession = false; 147 pw.println("Success"); 148 return 0; 149 } finally { 150 if (abandonSession) { 151 try { 152 doAbandonSession(sessionId, false /*logSuccess*/); 153 } catch (Exception ignore) { 154 } 155 } 156 } 157 } 158 159 private int runSuspend(boolean suspendedState) { 160 final PrintWriter pw = getOutPrintWriter(); 161 int userId = UserHandle.USER_SYSTEM; 162 String opt; 163 while ((opt = getNextOption()) != null) { 164 switch (opt) { 165 case "--user": 166 userId = UserHandle.parseUserArg(getNextArgRequired()); 167 break; 168 default: 169 pw.println("Error: Unknown option: " + opt); 170 return 1; 171 } 172 } 173 174 String packageName = getNextArg(); 175 if (packageName == null) { 176 pw.println("Error: package name not specified"); 177 return 1; 178 } 179 180 try { 181 mInterface.setPackageSuspendedAsUser(packageName, suspendedState, userId); 182 ApplicationInfo appInfo = mInterface.getApplicationInfo( 183 packageName, 0, userId); 184 185 pw.println("Package " + packageName + " new suspended state: " 186 + ((appInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0)); 187 return 0; 188 } catch (RemoteException e) { 189 pw.println(e.toString()); 190 return 1; 191 } 192 } 193 194 private int runInstallAbandon() throws RemoteException { 195 final int sessionId = Integer.parseInt(getNextArg()); 196 return doAbandonSession(sessionId, true /*logSuccess*/); 197 } 198 199 private int runInstallCommit() throws RemoteException { 200 final int sessionId = Integer.parseInt(getNextArg()); 201 return doCommitSession(sessionId, true /*logSuccess*/); 202 } 203 204 private int runInstallCreate() throws RemoteException { 205 final PrintWriter pw = getOutPrintWriter(); 206 final InstallParams installParams = makeInstallParams(); 207 final int sessionId = doCreateSession(installParams.sessionParams, 208 installParams.installerPackageName, installParams.userId); 209 210 // NOTE: adb depends on parsing this string 211 pw.println("Success: created install session [" + sessionId + "]"); 212 return 0; 213 } 214 215 private int runInstallWrite() throws RemoteException { 216 long sizeBytes = -1; 217 218 String opt; 219 while ((opt = getNextOption()) != null) { 220 if (opt.equals("-S")) { 221 sizeBytes = Long.parseLong(getNextArg()); 222 } else { 223 throw new IllegalArgumentException("Unknown option: " + opt); 224 } 225 } 226 227 final int sessionId = Integer.parseInt(getNextArg()); 228 final String splitName = getNextArg(); 229 final String path = getNextArg(); 230 return doWriteSession(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); 231 } 232 233 private int runCompile() throws RemoteException { 234 final PrintWriter pw = getOutPrintWriter(); 235 boolean useJitProfiles = false; 236 boolean extractOnly = false; 237 boolean forceCompilation = false; 238 String compilationMode = "default"; 239 240 String opt; 241 while ((opt = getNextOption()) != null) { 242 switch (opt) { 243 case "-m": 244 compilationMode = getNextArgRequired(); 245 break; 246 case "-f": 247 forceCompilation = true; 248 break; 249 default: 250 pw.println("Error: Unknown option: " + opt); 251 return 1; 252 } 253 } 254 255 switch (compilationMode) { 256 case "default": 257 useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false); 258 extractOnly = false; 259 break; 260 case "all": 261 useJitProfiles = false; 262 extractOnly = false; 263 break; 264 case "profile": 265 useJitProfiles = true; 266 extractOnly = false; 267 break; 268 case "extract": 269 useJitProfiles = false; 270 extractOnly = true; 271 break; 272 default: 273 pw.println("Error: Unknown compilation mode: " + compilationMode); 274 return 1; 275 } 276 277 String packageName = getNextArg(); 278 if (packageName == null) { 279 pw.println("Error: package name not specified"); 280 return 1; 281 } 282 283 boolean success = mInterface.performDexOpt(packageName, null /* instructionSet */, 284 useJitProfiles, extractOnly, forceCompilation); 285 if (success) { 286 pw.println("Success"); 287 return 0; 288 } else { 289 pw.println("Failure: package " + packageName + " could not be compiled"); 290 return 1; 291 } 292 } 293 294 private int runList() throws RemoteException { 295 final PrintWriter pw = getOutPrintWriter(); 296 final String type = getNextArg(); 297 if (type == null) { 298 pw.println("Error: didn't specify type of data to list"); 299 return -1; 300 } 301 switch(type) { 302 case "features": 303 return runListFeatures(); 304 case "instrumentation": 305 return runListInstrumentation(); 306 case "libraries": 307 return runListLibraries(); 308 case "package": 309 case "packages": 310 return runListPackages(false /*showSourceDir*/); 311 case "permission-groups": 312 return runListPermissionGroups(); 313 case "permissions": 314 return runListPermissions(); 315 } 316 pw.println("Error: unknown list type '" + type + "'"); 317 return -1; 318 } 319 320 private int runListFeatures() throws RemoteException { 321 final PrintWriter pw = getOutPrintWriter(); 322 final List<FeatureInfo> list = new ArrayList<FeatureInfo>(); 323 final FeatureInfo[] rawList = mInterface.getSystemAvailableFeatures(); 324 for (int i=0; i<rawList.length; i++) { 325 list.add(rawList[i]); 326 } 327 328 // sort by name 329 Collections.sort(list, new Comparator<FeatureInfo>() { 330 public int compare(FeatureInfo o1, FeatureInfo o2) { 331 if (o1.name == o2.name) return 0; 332 if (o1.name == null) return -1; 333 if (o2.name == null) return 1; 334 return o1.name.compareTo(o2.name); 335 } 336 }); 337 338 final int count = (list != null) ? list.size() : 0; 339 for (int p = 0; p < count; p++) { 340 FeatureInfo fi = list.get(p); 341 pw.print("feature:"); 342 if (fi.name != null) { 343 pw.print(fi.name); 344 if (fi.version > 0) { 345 pw.print("="); 346 pw.print(fi.version); 347 } 348 pw.println(); 349 } else { 350 pw.println("reqGlEsVersion=0x" 351 + Integer.toHexString(fi.reqGlEsVersion)); 352 } 353 } 354 return 0; 355 } 356 357 private int runListInstrumentation() throws RemoteException { 358 final PrintWriter pw = getOutPrintWriter(); 359 boolean showSourceDir = false; 360 String targetPackage = null; 361 362 try { 363 String opt; 364 while ((opt = getNextArg()) != null) { 365 switch (opt) { 366 case "-f": 367 showSourceDir = true; 368 break; 369 default: 370 if (opt.charAt(0) != '-') { 371 targetPackage = opt; 372 } else { 373 pw.println("Error: Unknown option: " + opt); 374 return -1; 375 } 376 break; 377 } 378 } 379 } catch (RuntimeException ex) { 380 pw.println("Error: " + ex.toString()); 381 return -1; 382 } 383 384 final List<InstrumentationInfo> list = 385 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/); 386 387 // sort by target package 388 Collections.sort(list, new Comparator<InstrumentationInfo>() { 389 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { 390 return o1.targetPackage.compareTo(o2.targetPackage); 391 } 392 }); 393 394 final int count = (list != null) ? list.size() : 0; 395 for (int p = 0; p < count; p++) { 396 final InstrumentationInfo ii = list.get(p); 397 pw.print("instrumentation:"); 398 if (showSourceDir) { 399 pw.print(ii.sourceDir); 400 pw.print("="); 401 } 402 final ComponentName cn = new ComponentName(ii.packageName, ii.name); 403 pw.print(cn.flattenToShortString()); 404 pw.print(" (target="); 405 pw.print(ii.targetPackage); 406 pw.println(")"); 407 } 408 return 0; 409 } 410 411 private int runListLibraries() throws RemoteException { 412 final PrintWriter pw = getOutPrintWriter(); 413 final List<String> list = new ArrayList<String>(); 414 final String[] rawList = mInterface.getSystemSharedLibraryNames(); 415 for (int i = 0; i < rawList.length; i++) { 416 list.add(rawList[i]); 417 } 418 419 // sort by name 420 Collections.sort(list, new Comparator<String>() { 421 public int compare(String o1, String o2) { 422 if (o1 == o2) return 0; 423 if (o1 == null) return -1; 424 if (o2 == null) return 1; 425 return o1.compareTo(o2); 426 } 427 }); 428 429 final int count = (list != null) ? list.size() : 0; 430 for (int p = 0; p < count; p++) { 431 String lib = list.get(p); 432 pw.print("library:"); 433 pw.println(lib); 434 } 435 return 0; 436 } 437 438 private int runListPackages(boolean showSourceDir) throws RemoteException { 439 final PrintWriter pw = getOutPrintWriter(); 440 int getFlags = 0; 441 boolean listDisabled = false, listEnabled = false; 442 boolean listSystem = false, listThirdParty = false; 443 boolean listInstaller = false; 444 int userId = UserHandle.USER_SYSTEM; 445 try { 446 String opt; 447 while ((opt = getNextOption()) != null) { 448 switch (opt) { 449 case "-d": 450 listDisabled = true; 451 break; 452 case "-e": 453 listEnabled = true; 454 break; 455 case "-f": 456 showSourceDir = true; 457 break; 458 case "-i": 459 listInstaller = true; 460 break; 461 case "-l": 462 // old compat 463 break; 464 case "-lf": 465 showSourceDir = true; 466 break; 467 case "-s": 468 listSystem = true; 469 break; 470 case "-u": 471 getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; 472 break; 473 case "-3": 474 listThirdParty = true; 475 break; 476 case "--user": 477 userId = UserHandle.parseUserArg(getNextArgRequired()); 478 break; 479 default: 480 pw.println("Error: Unknown option: " + opt); 481 return -1; 482 } 483 } 484 } catch (RuntimeException ex) { 485 pw.println("Error: " + ex.toString()); 486 return -1; 487 } 488 489 final String filter = getNextArg(); 490 491 @SuppressWarnings("unchecked") 492 final ParceledListSlice<PackageInfo> slice = 493 mInterface.getInstalledPackages(getFlags, userId); 494 final List<PackageInfo> packages = slice.getList(); 495 496 final int count = packages.size(); 497 for (int p = 0; p < count; p++) { 498 final PackageInfo info = packages.get(p); 499 if (filter != null && !info.packageName.contains(filter)) { 500 continue; 501 } 502 final boolean isSystem = 503 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; 504 if ((!listDisabled || !info.applicationInfo.enabled) && 505 (!listEnabled || info.applicationInfo.enabled) && 506 (!listSystem || isSystem) && 507 (!listThirdParty || !isSystem)) { 508 pw.print("package:"); 509 if (showSourceDir) { 510 pw.print(info.applicationInfo.sourceDir); 511 pw.print("="); 512 } 513 pw.print(info.packageName); 514 if (listInstaller) { 515 pw.print(" installer="); 516 pw.print(mInterface.getInstallerPackageName(info.packageName)); 517 } 518 pw.println(); 519 } 520 } 521 return 0; 522 } 523 524 private int runListPermissionGroups() throws RemoteException { 525 final PrintWriter pw = getOutPrintWriter(); 526 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0); 527 528 final int count = pgs.size(); 529 for (int p = 0; p < count ; p++) { 530 final PermissionGroupInfo pgi = pgs.get(p); 531 pw.print("permission group:"); 532 pw.println(pgi.name); 533 } 534 return 0; 535 } 536 537 private int runListPermissions() throws RemoteException { 538 final PrintWriter pw = getOutPrintWriter(); 539 boolean labels = false; 540 boolean groups = false; 541 boolean userOnly = false; 542 boolean summary = false; 543 boolean dangerousOnly = false; 544 String opt; 545 while ((opt = getNextOption()) != null) { 546 switch (opt) { 547 case "-d": 548 dangerousOnly = true; 549 break; 550 case "-f": 551 labels = true; 552 break; 553 case "-g": 554 groups = true; 555 break; 556 case "-s": 557 groups = true; 558 labels = true; 559 summary = true; 560 break; 561 case "-u": 562 userOnly = true; 563 break; 564 default: 565 pw.println("Error: Unknown option: " + opt); 566 return 1; 567 } 568 } 569 570 final ArrayList<String> groupList = new ArrayList<String>(); 571 if (groups) { 572 final List<PermissionGroupInfo> infos = 573 mInterface.getAllPermissionGroups(0 /*flags*/); 574 final int count = infos.size(); 575 for (int i = 0; i < count; i++) { 576 groupList.add(infos.get(i).name); 577 } 578 groupList.add(null); 579 } else { 580 final String grp = getNextArg(); 581 groupList.add(grp); 582 } 583 584 if (dangerousOnly) { 585 pw.println("Dangerous Permissions:"); 586 pw.println(""); 587 doListPermissions(groupList, groups, labels, summary, 588 PermissionInfo.PROTECTION_DANGEROUS, 589 PermissionInfo.PROTECTION_DANGEROUS); 590 if (userOnly) { 591 pw.println("Normal Permissions:"); 592 pw.println(""); 593 doListPermissions(groupList, groups, labels, summary, 594 PermissionInfo.PROTECTION_NORMAL, 595 PermissionInfo.PROTECTION_NORMAL); 596 } 597 } else if (userOnly) { 598 pw.println("Dangerous and Normal Permissions:"); 599 pw.println(""); 600 doListPermissions(groupList, groups, labels, summary, 601 PermissionInfo.PROTECTION_NORMAL, 602 PermissionInfo.PROTECTION_DANGEROUS); 603 } else { 604 pw.println("All Permissions:"); 605 pw.println(""); 606 doListPermissions(groupList, groups, labels, summary, 607 -10000, 10000); 608 } 609 return 0; 610 } 611 612 private int runUninstall() throws RemoteException { 613 final PrintWriter pw = getOutPrintWriter(); 614 int flags = 0; 615 int userId = UserHandle.USER_ALL; 616 617 String opt; 618 while ((opt = getNextOption()) != null) { 619 switch (opt) { 620 case "-k": 621 flags |= PackageManager.DELETE_KEEP_DATA; 622 break; 623 case "--user": 624 userId = UserHandle.parseUserArg(getNextArgRequired()); 625 break; 626 default: 627 pw.println("Error: Unknown option: " + opt); 628 return 1; 629 } 630 } 631 632 String packageName = getNextArg(); 633 if (packageName == null) { 634 pw.println("Error: package name not specified"); 635 return 1; 636 } 637 638 userId = translateUserId(userId, "runUninstall"); 639 if (userId == UserHandle.USER_ALL) { 640 userId = UserHandle.USER_SYSTEM; 641 flags |= PackageManager.DELETE_ALL_USERS; 642 } else { 643 final PackageInfo info = mInterface.getPackageInfo(packageName, 0, userId); 644 if (info == null) { 645 pw.println("Failure [not installed for " + userId + "]"); 646 return 1; 647 } 648 final boolean isSystem = 649 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 650 // If we are being asked to delete a system app for just one 651 // user set flag so it disables rather than reverting to system 652 // version of the app. 653 if (isSystem) { 654 flags |= PackageManager.DELETE_SYSTEM_APP; 655 } 656 } 657 658 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 659 mInterface.getPackageInstaller().uninstall(packageName, null /*callerPackageName*/, flags, 660 receiver.getIntentSender(), userId); 661 662 final Intent result = receiver.getResult(); 663 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 664 PackageInstaller.STATUS_FAILURE); 665 if (status == PackageInstaller.STATUS_SUCCESS) { 666 pw.println("Success"); 667 return 0; 668 } else { 669 pw.println("Failure [" 670 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 671 return 1; 672 } 673 } 674 675 private Intent parseIntentAndUser() throws URISyntaxException { 676 mTargetUser = UserHandle.USER_CURRENT; 677 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 678 @Override 679 public boolean handleOption(String opt, ShellCommand cmd) { 680 if ("--user".equals(opt)) { 681 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired()); 682 return true; 683 } 684 return false; 685 } 686 }); 687 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 688 Binder.getCallingUid(), mTargetUser, false, false, null, null); 689 return intent; 690 } 691 692 private int runResolveActivity() { 693 Intent intent; 694 try { 695 intent = parseIntentAndUser(); 696 } catch (URISyntaxException e) { 697 throw new RuntimeException(e.getMessage(), e); 698 } 699 try { 700 ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser); 701 PrintWriter pw = getOutPrintWriter(); 702 if (ri == null) { 703 pw.println("No activity found"); 704 } else { 705 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 706 ri.dump(pr, ""); 707 } 708 } catch (RemoteException e) { 709 throw new RuntimeException("Failed calling service", e); 710 } 711 return 0; 712 } 713 714 private int runQueryIntentActivities() { 715 Intent intent; 716 try { 717 intent = parseIntentAndUser(); 718 } catch (URISyntaxException e) { 719 throw new RuntimeException(e.getMessage(), e); 720 } 721 try { 722 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0, 723 mTargetUser); 724 PrintWriter pw = getOutPrintWriter(); 725 if (result == null || result.size() <= 0) { 726 pw.println("No activities found"); 727 } else { 728 pw.print(result.size()); pw.println(" activities found:"); 729 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 730 for (int i=0; i<result.size(); i++) { 731 pw.print(" Activity #"); pw.print(i); pw.println(":"); 732 result.get(i).dump(pr, " "); 733 } 734 } 735 } catch (RemoteException e) { 736 throw new RuntimeException("Failed calling service", e); 737 } 738 return 0; 739 } 740 741 private int runQueryIntentServices() { 742 Intent intent; 743 try { 744 intent = parseIntentAndUser(); 745 } catch (URISyntaxException e) { 746 throw new RuntimeException(e.getMessage(), e); 747 } 748 try { 749 List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0, 750 mTargetUser); 751 PrintWriter pw = getOutPrintWriter(); 752 if (result == null || result.size() <= 0) { 753 pw.println("No services found"); 754 } else { 755 pw.print(result.size()); pw.println(" services found:"); 756 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 757 for (int i=0; i<result.size(); i++) { 758 pw.print(" Service #"); pw.print(i); pw.println(":"); 759 result.get(i).dump(pr, " "); 760 } 761 } 762 } catch (RemoteException e) { 763 throw new RuntimeException("Failed calling service", e); 764 } 765 return 0; 766 } 767 768 private int runQueryIntentReceivers() { 769 Intent intent; 770 try { 771 intent = parseIntentAndUser(); 772 } catch (URISyntaxException e) { 773 throw new RuntimeException(e.getMessage(), e); 774 } 775 try { 776 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0, 777 mTargetUser); 778 PrintWriter pw = getOutPrintWriter(); 779 if (result == null || result.size() <= 0) { 780 pw.println("No receivers found"); 781 } else { 782 pw.print(result.size()); pw.println(" receivers found:"); 783 PrintWriterPrinter pr = new PrintWriterPrinter(pw); 784 for (int i=0; i<result.size(); i++) { 785 pw.print(" Receiver #"); pw.print(i); pw.println(":"); 786 result.get(i).dump(pr, " "); 787 } 788 } 789 } catch (RemoteException e) { 790 throw new RuntimeException("Failed calling service", e); 791 } 792 return 0; 793 } 794 795 private static class InstallParams { 796 SessionParams sessionParams; 797 String installerPackageName; 798 int userId = UserHandle.USER_ALL; 799 } 800 801 private InstallParams makeInstallParams() { 802 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); 803 final InstallParams params = new InstallParams(); 804 params.sessionParams = sessionParams; 805 String opt; 806 while ((opt = getNextOption()) != null) { 807 switch (opt) { 808 case "-l": 809 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 810 break; 811 case "-r": 812 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 813 break; 814 case "-i": 815 params.installerPackageName = getNextArg(); 816 if (params.installerPackageName == null) { 817 throw new IllegalArgumentException("Missing installer package"); 818 } 819 break; 820 case "-t": 821 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST; 822 break; 823 case "-s": 824 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL; 825 break; 826 case "-f": 827 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL; 828 break; 829 case "-d": 830 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; 831 break; 832 case "-g": 833 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; 834 break; 835 case "--originating-uri": 836 sessionParams.originatingUri = Uri.parse(getNextArg()); 837 break; 838 case "--referrer": 839 sessionParams.referrerUri = Uri.parse(getNextArg()); 840 break; 841 case "-p": 842 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING; 843 sessionParams.appPackageName = getNextArg(); 844 if (sessionParams.appPackageName == null) { 845 throw new IllegalArgumentException("Missing inherit package name"); 846 } 847 break; 848 case "-S": 849 sessionParams.setSize(Long.parseLong(getNextArg())); 850 break; 851 case "--abi": 852 sessionParams.abiOverride = checkAbiArgument(getNextArg()); 853 break; 854 case "--ephemeral": 855 sessionParams.installFlags |= PackageManager.INSTALL_EPHEMERAL; 856 break; 857 case "--user": 858 params.userId = UserHandle.parseUserArg(getNextArgRequired()); 859 break; 860 case "--install-location": 861 sessionParams.installLocation = Integer.parseInt(getNextArg()); 862 break; 863 case "--force-uuid": 864 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID; 865 sessionParams.volumeUuid = getNextArg(); 866 if ("internal".equals(sessionParams.volumeUuid)) { 867 sessionParams.volumeUuid = null; 868 } 869 break; 870 default: 871 throw new IllegalArgumentException("Unknown option " + opt); 872 } 873 } 874 return params; 875 } 876 877 private static String checkAbiArgument(String abi) { 878 if (TextUtils.isEmpty(abi)) { 879 throw new IllegalArgumentException("Missing ABI argument"); 880 } 881 882 if ("-".equals(abi)) { 883 return abi; 884 } 885 886 final String[] supportedAbis = Build.SUPPORTED_ABIS; 887 for (String supportedAbi : supportedAbis) { 888 if (supportedAbi.equals(abi)) { 889 return abi; 890 } 891 } 892 893 throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); 894 } 895 896 private int translateUserId(int userId, String logContext) { 897 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 898 userId, true, true, logContext, "pm command"); 899 } 900 901 private int doCreateSession(SessionParams params, String installerPackageName, int userId) 902 throws RemoteException { 903 userId = translateUserId(userId, "runInstallCreate"); 904 if (userId == UserHandle.USER_ALL) { 905 userId = UserHandle.USER_SYSTEM; 906 params.installFlags |= PackageManager.INSTALL_ALL_USERS; 907 } 908 909 final int sessionId = mInterface.getPackageInstaller() 910 .createSession(params, installerPackageName, userId); 911 return sessionId; 912 } 913 914 private int doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName, 915 boolean logSuccess) throws RemoteException { 916 final PrintWriter pw = getOutPrintWriter(); 917 if ("-".equals(inPath)) { 918 inPath = null; 919 } else if (inPath != null) { 920 final File file = new File(inPath); 921 if (file.isFile()) { 922 sizeBytes = file.length(); 923 } 924 } 925 926 final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId); 927 928 PackageInstaller.Session session = null; 929 InputStream in = null; 930 OutputStream out = null; 931 try { 932 session = new PackageInstaller.Session( 933 mInterface.getPackageInstaller().openSession(sessionId)); 934 935 if (inPath != null) { 936 in = new FileInputStream(inPath); 937 } else { 938 in = new SizedInputStream(getRawInputStream(), sizeBytes); 939 } 940 out = session.openWrite(splitName, 0, sizeBytes); 941 942 int total = 0; 943 byte[] buffer = new byte[65536]; 944 int c; 945 while ((c = in.read(buffer)) != -1) { 946 total += c; 947 out.write(buffer, 0, c); 948 949 if (info.sizeBytes > 0) { 950 final float fraction = ((float) c / (float) info.sizeBytes); 951 session.addProgress(fraction); 952 } 953 } 954 session.fsync(out); 955 956 if (logSuccess) { 957 pw.println("Success: streamed " + total + " bytes"); 958 } 959 return 0; 960 } catch (IOException e) { 961 pw.println("Error: failed to write; " + e.getMessage()); 962 return 1; 963 } finally { 964 IoUtils.closeQuietly(out); 965 IoUtils.closeQuietly(in); 966 IoUtils.closeQuietly(session); 967 } 968 } 969 970 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException { 971 final PrintWriter pw = getOutPrintWriter(); 972 PackageInstaller.Session session = null; 973 try { 974 session = new PackageInstaller.Session( 975 mInterface.getPackageInstaller().openSession(sessionId)); 976 977 final LocalIntentReceiver receiver = new LocalIntentReceiver(); 978 session.commit(receiver.getIntentSender()); 979 980 final Intent result = receiver.getResult(); 981 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 982 PackageInstaller.STATUS_FAILURE); 983 if (status == PackageInstaller.STATUS_SUCCESS) { 984 if (logSuccess) { 985 System.out.println("Success"); 986 } 987 } else { 988 pw.println("Failure [" 989 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]"); 990 } 991 return status; 992 } finally { 993 IoUtils.closeQuietly(session); 994 } 995 } 996 997 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException { 998 final PrintWriter pw = getOutPrintWriter(); 999 PackageInstaller.Session session = null; 1000 try { 1001 session = new PackageInstaller.Session( 1002 mInterface.getPackageInstaller().openSession(sessionId)); 1003 session.abandon(); 1004 if (logSuccess) { 1005 pw.println("Success"); 1006 } 1007 return 0; 1008 } finally { 1009 IoUtils.closeQuietly(session); 1010 } 1011 } 1012 1013 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels, 1014 boolean summary, int startProtectionLevel, int endProtectionLevel) 1015 throws RemoteException { 1016 final PrintWriter pw = getOutPrintWriter(); 1017 final int groupCount = groupList.size(); 1018 for (int i = 0; i < groupCount; i++) { 1019 String groupName = groupList.get(i); 1020 String prefix = ""; 1021 if (groups) { 1022 if (i > 0) { 1023 pw.println(""); 1024 } 1025 if (groupName != null) { 1026 PermissionGroupInfo pgi = 1027 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/); 1028 if (summary) { 1029 Resources res = getResources(pgi); 1030 if (res != null) { 1031 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": "); 1032 } else { 1033 pw.print(pgi.name + ": "); 1034 1035 } 1036 } else { 1037 pw.println((labels ? "+ " : "") + "group:" + pgi.name); 1038 if (labels) { 1039 pw.println(" package:" + pgi.packageName); 1040 Resources res = getResources(pgi); 1041 if (res != null) { 1042 pw.println(" label:" 1043 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel)); 1044 pw.println(" description:" 1045 + loadText(pgi, pgi.descriptionRes, 1046 pgi.nonLocalizedDescription)); 1047 } 1048 } 1049 } 1050 } else { 1051 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:"); 1052 } 1053 prefix = " "; 1054 } 1055 List<PermissionInfo> ps = 1056 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/); 1057 final int count = ps.size(); 1058 boolean first = true; 1059 for (int p = 0 ; p < count ; p++) { 1060 PermissionInfo pi = ps.get(p); 1061 if (groups && groupName == null && pi.group != null) { 1062 continue; 1063 } 1064 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 1065 if (base < startProtectionLevel 1066 || base > endProtectionLevel) { 1067 continue; 1068 } 1069 if (summary) { 1070 if (first) { 1071 first = false; 1072 } else { 1073 pw.print(", "); 1074 } 1075 Resources res = getResources(pi); 1076 if (res != null) { 1077 pw.print(loadText(pi, pi.labelRes, 1078 pi.nonLocalizedLabel)); 1079 } else { 1080 pw.print(pi.name); 1081 } 1082 } else { 1083 pw.println(prefix + (labels ? "+ " : "") 1084 + "permission:" + pi.name); 1085 if (labels) { 1086 pw.println(prefix + " package:" + pi.packageName); 1087 Resources res = getResources(pi); 1088 if (res != null) { 1089 pw.println(prefix + " label:" 1090 + loadText(pi, pi.labelRes, 1091 pi.nonLocalizedLabel)); 1092 pw.println(prefix + " description:" 1093 + loadText(pi, pi.descriptionRes, 1094 pi.nonLocalizedDescription)); 1095 } 1096 pw.println(prefix + " protectionLevel:" 1097 + PermissionInfo.protectionToString(pi.protectionLevel)); 1098 } 1099 } 1100 } 1101 1102 if (summary) { 1103 pw.println(""); 1104 } 1105 } 1106 } 1107 1108 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) 1109 throws RemoteException { 1110 if (nonLocalized != null) { 1111 return nonLocalized.toString(); 1112 } 1113 if (res != 0) { 1114 Resources r = getResources(pii); 1115 if (r != null) { 1116 try { 1117 return r.getString(res); 1118 } catch (Resources.NotFoundException e) { 1119 } 1120 } 1121 } 1122 return null; 1123 } 1124 1125 private Resources getResources(PackageItemInfo pii) throws RemoteException { 1126 Resources res = mResourceCache.get(pii.packageName); 1127 if (res != null) return res; 1128 1129 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0); 1130 AssetManager am = new AssetManager(); 1131 am.addAssetPath(ai.publicSourceDir); 1132 res = new Resources(am, null, null); 1133 mResourceCache.put(pii.packageName, res); 1134 return res; 1135 } 1136 1137 @Override 1138 public void onHelp() { 1139 final PrintWriter pw = getOutPrintWriter(); 1140 pw.println("Package manager (package) commands:"); 1141 pw.println(" help"); 1142 pw.println(" Print this help text."); 1143 pw.println(""); 1144 pw.println(" compile [-m MODE] [-f] TARGET-PACKAGE"); 1145 pw.println(" Trigger compilation of TARGET-PACKAGE."); 1146 pw.println(" Options:"); 1147 pw.println(" -m: select compilation mode"); 1148 pw.println(" MODE can be one of \"default\", \"all\", \"profile\", and \"extract\""); 1149 pw.println(" -f: force compilation even if not needed"); 1150 pw.println(" list features"); 1151 pw.println(" Prints all features of the system."); 1152 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]"); 1153 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE"); 1154 pw.println(" Options:"); 1155 pw.println(" -f: dump the name of the .apk file containing the test package"); 1156 pw.println(" list libraries"); 1157 pw.println(" Prints all system libraries."); 1158 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]"); 1159 pw.println(" Prints all packages; optionally only those whose name contains"); 1160 pw.println(" the text in FILTER."); 1161 pw.println(" Options:"); 1162 pw.println(" -f: see their associated file"); 1163 pw.println(" -d: filter to only show disabled packages"); 1164 pw.println(" -e: filter to only show enabled packages"); 1165 pw.println(" -s: filter to only show system packages"); 1166 pw.println(" -3: filter to only show third party packages"); 1167 pw.println(" -i: see the installer for the packages"); 1168 pw.println(" -u: also include uninstalled packages"); 1169 pw.println(" list permission-groups"); 1170 pw.println(" Prints all known permission groups."); 1171 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); 1172 pw.println(" Prints all known permissions; optionally only those in GROUP."); 1173 pw.println(" Options:"); 1174 pw.println(" -g: organize by group"); 1175 pw.println(" -f: print all information"); 1176 pw.println(" -s: short summary"); 1177 pw.println(" -d: only list dangerous permissions"); 1178 pw.println(" -u: list only the permissions users will see"); 1179 pw.println(" resolve-activity [--user USER_ID] INTENT"); 1180 pw.println(" Prints the activity that resolves to the given Intent."); 1181 pw.println(" query-activities [--user USER_ID] INTENT"); 1182 pw.println(" Prints all activities that can handle the given Intent."); 1183 pw.println(" query-services [--user USER_ID] INTENT"); 1184 pw.println(" Prints all services that can handle the given Intent."); 1185 pw.println(" query-receivers [--user USER_ID] INTENT"); 1186 pw.println(" Prints all broadcast receivers that can handle the given Intent."); 1187 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE"); 1188 pw.println(" Suspends the specified package (as user)."); 1189 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE"); 1190 pw.println(" Unsuspends the specified package (as user)."); 1191 pw.println(); 1192 Intent.printIntentArgsHelp(pw , ""); 1193 } 1194 1195 private static class LocalIntentReceiver { 1196 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>(); 1197 1198 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 1199 @Override 1200 public int send(int code, Intent intent, String resolvedType, 1201 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 1202 try { 1203 mResult.offer(intent, 5, TimeUnit.SECONDS); 1204 } catch (InterruptedException e) { 1205 throw new RuntimeException(e); 1206 } 1207 return 0; 1208 } 1209 }; 1210 1211 public IntentSender getIntentSender() { 1212 return new IntentSender((IIntentSender) mLocalSender); 1213 } 1214 1215 public Intent getResult() { 1216 try { 1217 return mResult.take(); 1218 } catch (InterruptedException e) { 1219 throw new RuntimeException(e); 1220 } 1221 } 1222 } 1223} 1224