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