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