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