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