Start removing remaining pm code to package manager

Everything is now moved out of the pm command except for
the various install commands.  I am going to hold of on
those since they require doing some resolution with the
current implementations in the package manager to make
sure they match and behave identically to the implementations
currently in the pm command.  But other than that, everything
in pm is now just redirecting over to "cmd package".

Also fix up some of the dumpsys output of a few other sevices
when asking to print the data for a particular package, so
the "pm dump" command gives a little more sane result.

Test: manual

Change-Id: I139e06e560203b72243d7eea9543c2240db0f8f8
This commit is contained in:
Dianne Hackborn
2017-10-20 16:16:32 -07:00
parent 8664028d4f
commit c81983a0c3
11 changed files with 1534 additions and 1478 deletions

View File

@@ -116,9 +116,8 @@ public final class Pm {
}
public int run(String[] args) throws RemoteException {
boolean validCommand = false;
if (args.length < 1) {
return showUsage();
return runShellCommand("package", mArgs);
}
mAm = IAccountManager.Stub.asInterface(ServiceManager.getService(Context.ACCOUNT_SERVICE));
mUm = IUserManager.Stub.asInterface(ServiceManager.getService(Context.USER_SERVICE));
@@ -134,18 +133,6 @@ public final class Pm {
String op = args[0];
mNextArg = 1;
if ("list".equals(op)) {
return runList();
}
if ("path".equals(op)) {
return runPath();
}
if ("dump".equals(op)) {
return runDump();
}
if ("install".equals(op)) {
return runInstall();
}
@@ -166,134 +153,7 @@ public final class Pm {
return runInstallAbandon();
}
if ("set-installer".equals(op)) {
return runSetInstaller();
}
if ("uninstall".equals(op)) {
return runUninstall();
}
if ("clear".equals(op)) {
return runClear();
}
if ("enable".equals(op)) {
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}
if ("disable".equals(op)) {
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
}
if ("disable-user".equals(op)) {
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
}
if ("disable-until-used".equals(op)) {
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
}
if ("default-state".equals(op)) {
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
}
if ("hide".equals(op)) {
return runSetHiddenSetting(true);
}
if ("unhide".equals(op)) {
return runSetHiddenSetting(false);
}
if ("grant".equals(op)) {
return runGrantRevokePermission(true);
}
if ("revoke".equals(op)) {
return runGrantRevokePermission(false);
}
if ("reset-permissions".equals(op)) {
return runResetPermissions();
}
if ("set-permission-enforced".equals(op)) {
return runSetPermissionEnforced();
}
if ("set-app-link".equals(op)) {
return runSetAppLink();
}
if ("get-app-link".equals(op)) {
return runGetAppLink();
}
if ("set-install-location".equals(op)) {
return runSetInstallLocation();
}
if ("get-install-location".equals(op)) {
return runGetInstallLocation();
}
if ("trim-caches".equals(op)) {
return runTrimCaches();
}
if ("create-user".equals(op)) {
return runCreateUser();
}
if ("remove-user".equals(op)) {
return runRemoveUser();
}
if ("get-max-users".equals(op)) {
return runGetMaxUsers();
}
if ("force-dex-opt".equals(op)) {
return runForceDexOpt();
}
if ("move-package".equals(op)) {
return runMovePackage();
}
if ("move-primary-storage".equals(op)) {
return runMovePrimaryStorage();
}
if ("set-user-restriction".equals(op)) {
return runSetUserRestriction();
}
try {
if (args.length == 1) {
if (args[0].equalsIgnoreCase("-l")) {
validCommand = true;
return runShellCommand("package", new String[] { "list", "package" });
} else if (args[0].equalsIgnoreCase("-lf")) {
validCommand = true;
return runShellCommand("package", new String[] { "list", "package", "-f" });
}
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("-p")) {
validCommand = true;
return displayPackageFilePath(args[1], UserHandle.USER_SYSTEM);
}
}
return 1;
} finally {
if (validCommand == false) {
if (op != null) {
System.err.println("Error: unknown command '" + op + "'");
}
showUsage();
}
}
return runShellCommand("package", mArgs);
}
static final class MyShellCallback extends ShellCallback {
@@ -704,59 +564,6 @@ public final class Pm {
}
}
/**
* Execute the list sub-command.
*
* pm list [package | packages]
* pm list permission-groups
* pm list permissions
* pm list features
* pm list libraries
* pm list instrumentation
*/
private int runList() {
final String type = nextArg();
if ("users".equals(type)) {
return runShellCommand("user", new String[] { "list" });
}
return runShellCommand("package", mArgs);
}
private int runUninstall() {
return runShellCommand("package", mArgs);
}
private int runPath() {
int userId = UserHandle.USER_SYSTEM;
String option = nextOption();
if (option != null && option.equals("--user")) {
String optionData = nextOptionData();
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
return showUsage();
} else {
userId = Integer.parseInt(optionData);
}
}
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
return 1;
}
return displayPackageFilePath(pkg, userId);
}
private int runDump() {
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
return 1;
}
ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
return 0;
}
class LocalPackageInstallObserver extends PackageInstallObserver {
boolean finished;
int result;
@@ -779,477 +586,6 @@ public final class Pm {
}
}
// pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
private int runSetAppLink() {
int userId = UserHandle.USER_SYSTEM;
String opt;
while ((opt = nextOption()) != null) {
if (opt.equals("--user")) {
userId = Integer.parseInt(nextOptionData());
if (userId < 0) {
System.err.println("Error: user must be >= 0");
return 1;
}
} else {
System.err.println("Error: unknown option: " + opt);
return showUsage();
}
}
// Package name to act on; required
final String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified.");
return showUsage();
}
// State to apply; {always|ask|never|undefined}, required
final String modeString = nextArg();
if (modeString == null) {
System.err.println("Error: no app link state specified.");
return showUsage();
}
final int newMode;
switch (modeString.toLowerCase()) {
case "undefined":
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
break;
case "always":
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
break;
case "ask":
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
break;
case "always-ask":
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
break;
case "never":
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
break;
default:
System.err.println("Error: unknown app link state '" + modeString + "'");
return 1;
}
try {
final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId);
if (info == null) {
System.err.println("Error: package " + pkg + " not found.");
return 1;
}
if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
System.err.println("Error: package " + pkg + " does not handle web links.");
return 1;
}
if (!mPm.updateIntentVerificationStatus(pkg, newMode, userId)) {
System.err.println("Error: unable to update app link status for " + pkg);
return 1;
}
} catch (Exception e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
return 0;
}
// pm get-app-link [--user USER_ID] PACKAGE
private int runGetAppLink() {
int userId = UserHandle.USER_SYSTEM;
String opt;
while ((opt = nextOption()) != null) {
if (opt.equals("--user")) {
userId = Integer.parseInt(nextOptionData());
if (userId < 0) {
System.err.println("Error: user must be >= 0");
return 1;
}
} else {
System.err.println("Error: unknown option: " + opt);
return showUsage();
}
}
// Package name to act on; required
final String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified.");
return showUsage();
}
try {
final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId);
if (info == null) {
System.err.println("Error: package " + pkg + " not found.");
return 1;
}
if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
System.err.println("Error: package " + pkg + " does not handle web links.");
return 1;
}
System.out.println(linkStateToString(mPm.getIntentVerificationStatus(pkg, userId)));
} catch (Exception e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
return 0;
}
private String linkStateToString(int state) {
switch (state) {
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
}
return "Unknown link state: " + state;
}
private int runSetInstallLocation() {
int loc;
String arg = nextArg();
if (arg == null) {
System.err.println("Error: no install location specified.");
return 1;
}
try {
loc = Integer.parseInt(arg);
} catch (NumberFormatException e) {
System.err.println("Error: install location has to be a number.");
return 1;
}
try {
if (!mPm.setInstallLocation(loc)) {
System.err.println("Error: install location has to be a number.");
return 1;
}
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
private int runGetInstallLocation() {
try {
int loc = mPm.getInstallLocation();
String locStr = "invalid";
if (loc == PackageHelper.APP_INSTALL_AUTO) {
locStr = "auto";
} else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
locStr = "internal";
} else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
locStr = "external";
}
System.out.println(loc + "[" + locStr + "]");
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
private int runSetInstaller() throws RemoteException {
final String targetPackage = nextArg();
final String installerPackageName = nextArg();
if (targetPackage == null || installerPackageName == null) {
throw new IllegalArgumentException(
"must provide both target and installer package names");
}
mPm.setInstallerPackageName(targetPackage, installerPackageName);
System.out.println("Success");
return 0;
}
public int runCreateUser() {
String name;
int userId = -1;
int flags = 0;
String opt;
while ((opt = nextOption()) != null) {
if ("--profileOf".equals(opt)) {
String optionData = nextOptionData();
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
return showUsage();
} else {
userId = Integer.parseInt(optionData);
}
} else if ("--managed".equals(opt)) {
flags |= UserInfo.FLAG_MANAGED_PROFILE;
} else if ("--restricted".equals(opt)) {
flags |= UserInfo.FLAG_RESTRICTED;
} else if ("--ephemeral".equals(opt)) {
flags |= UserInfo.FLAG_EPHEMERAL;
} else if ("--guest".equals(opt)) {
flags |= UserInfo.FLAG_GUEST;
} else if ("--demo".equals(opt)) {
flags |= UserInfo.FLAG_DEMO;
} else {
System.err.println("Error: unknown option " + opt);
return showUsage();
}
}
String arg = nextArg();
if (arg == null) {
System.err.println("Error: no user name specified.");
return 1;
}
name = arg;
try {
UserInfo info;
if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
// In non-split user mode, userId can only be SYSTEM
int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
info = mUm.createRestrictedProfile(name, parentUserId);
mAm.addSharedAccountsFromParentUser(parentUserId, userId,
(Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
} else if (userId < 0) {
info = mUm.createUser(name, flags);
} else {
info = mUm.createProfileForUser(name, flags, userId, null);
}
if (info != null) {
System.out.println("Success: created user id " + info.id);
return 0;
} else {
System.err.println("Error: couldn't create User.");
return 1;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
public int runRemoveUser() {
int userId;
String arg = nextArg();
if (arg == null) {
System.err.println("Error: no user id specified.");
return 1;
}
try {
userId = Integer.parseInt(arg);
} catch (NumberFormatException e) {
System.err.println("Error: user id '" + arg + "' is not a number.");
return 1;
}
try {
if (mUm.removeUser(userId)) {
System.out.println("Success: removed user");
return 0;
} else {
System.err.println("Error: couldn't remove user id " + userId);
return 1;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
public int runGetMaxUsers() {
System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers());
return 0;
}
public int runForceDexOpt() {
final String packageName = nextArg();
try {
mPm.forceDexOpt(packageName);
return 0;
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
public int runMovePackage() {
final String packageName = nextArg();
String volumeUuid = nextArg();
if ("internal".equals(volumeUuid)) {
volumeUuid = null;
}
try {
final int moveId = mPm.movePackage(packageName, volumeUuid);
int status = mPm.getMoveStatus(moveId);
while (!PackageManager.isMoveStatusFinished(status)) {
SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
status = mPm.getMoveStatus(moveId);
}
if (status == PackageManager.MOVE_SUCCEEDED) {
System.out.println("Success");
return 0;
} else {
System.err.println("Failure [" + status + "]");
return 1;
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
public int runMovePrimaryStorage() {
String volumeUuid = nextArg();
if ("internal".equals(volumeUuid)) {
volumeUuid = null;
}
try {
final int moveId = mPm.movePrimaryStorage(volumeUuid);
int status = mPm.getMoveStatus(moveId);
while (!PackageManager.isMoveStatusFinished(status)) {
SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
status = mPm.getMoveStatus(moveId);
}
if (status == PackageManager.MOVE_SUCCEEDED) {
System.out.println("Success");
return 0;
} else {
System.err.println("Failure [" + status + "]");
return 1;
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
public int runSetUserRestriction() {
int userId = UserHandle.USER_SYSTEM;
String opt = nextOption();
if (opt != null && "--user".equals(opt)) {
String arg = nextArg();
if (arg == null || !isNumber(arg)) {
System.err.println("Error: valid userId not specified");
return 1;
}
userId = Integer.parseInt(arg);
}
String restriction = nextArg();
String arg = nextArg();
boolean value;
if ("1".equals(arg)) {
value = true;
} else if ("0".equals(arg)) {
value = false;
} else {
System.err.println("Error: valid value not specified");
return 1;
}
try {
mUm.setUserRestriction(restriction, value, userId);
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
return 1;
}
}
static class ClearDataObserver extends IPackageDataObserver.Stub {
boolean finished;
boolean result;
@Override
public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
synchronized (this) {
finished = true;
result = succeeded;
notifyAll();
}
}
}
private int runClear() {
int userId = UserHandle.USER_SYSTEM;
String option = nextOption();
if (option != null && option.equals("--user")) {
String optionData = nextOptionData();
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
return showUsage();
} else {
userId = Integer.parseInt(optionData);
}
}
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
return showUsage();
}
ClearDataObserver obs = new ClearDataObserver();
try {
ActivityManager.getService().clearApplicationUserData(pkg, obs, userId);
synchronized (obs) {
while (!obs.finished) {
try {
obs.wait();
} catch (InterruptedException e) {
}
}
}
if (obs.result) {
System.out.println("Success");
return 0;
} else {
System.err.println("Failed");
return 1;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
private static String enabledSettingToString(int state) {
switch (state) {
case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
return "default";
case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
return "enabled";
case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
return "disabled";
case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
return "disabled-user";
case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
return "disabled-until-used";
}
return "unknown";
}
private static boolean isNumber(String s) {
try {
Integer.parseInt(s);
@@ -1259,169 +595,6 @@ public final class Pm {
return true;
}
private int runSetEnabledSetting(int state) {
int userId = UserHandle.USER_SYSTEM;
String option = nextOption();
if (option != null && option.equals("--user")) {
String optionData = nextOptionData();
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
return showUsage();
} else {
userId = Integer.parseInt(optionData);
}
}
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package or component specified");
return showUsage();
}
ComponentName cn = ComponentName.unflattenFromString(pkg);
if (cn == null) {
try {
mPm.setApplicationEnabledSetting(pkg, state, 0, userId,
"shell:" + android.os.Process.myUid());
System.out.println("Package " + pkg + " new state: "
+ enabledSettingToString(
mPm.getApplicationEnabledSetting(pkg, userId)));
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
} else {
try {
mPm.setComponentEnabledSetting(cn, state, 0, userId);
System.out.println("Component " + cn.toShortString() + " new state: "
+ enabledSettingToString(
mPm.getComponentEnabledSetting(cn, userId)));
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
}
private int runSetHiddenSetting(boolean state) {
int userId = UserHandle.USER_SYSTEM;
String option = nextOption();
if (option != null && option.equals("--user")) {
String optionData = nextOptionData();
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
return showUsage();
} else {
userId = Integer.parseInt(optionData);
}
}
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package or component specified");
return showUsage();
}
try {
mPm.setApplicationHiddenSettingAsUser(pkg, state, userId);
System.out.println("Package " + pkg + " new hidden state: "
+ mPm.getApplicationHiddenSettingAsUser(pkg, userId));
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
}
}
private int runGrantRevokePermission(boolean grant) {
int userId = UserHandle.USER_SYSTEM;
String opt = null;
while ((opt = nextOption()) != null) {
if (opt.equals("--user")) {
userId = Integer.parseInt(nextArg());
}
}
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
return showUsage();
}
String perm = nextArg();
if (perm == null) {
System.err.println("Error: no permission specified");
return showUsage();
}
try {
if (grant) {
mPm.grantRuntimePermission(pkg, perm, userId);
} else {
mPm.revokeRuntimePermission(pkg, perm, userId);
}
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
return showUsage();
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
return 1;
}
}
private int runResetPermissions() {
try {
mPm.resetRuntimePermissions();
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
return showUsage();
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
return 1;
}
}
private int runSetPermissionEnforced() {
final String permission = nextArg();
if (permission == null) {
System.err.println("Error: no permission specified");
return showUsage();
}
final String enforcedRaw = nextArg();
if (enforcedRaw == null) {
System.err.println("Error: no enforcement specified");
return showUsage();
}
final boolean enforced = Boolean.parseBoolean(enforcedRaw);
try {
mPm.setPermissionEnforced(permission, enforced);
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
return showUsage();
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
return 1;
}
}
static class ClearCacheObserver extends IPackageDataObserver.Stub {
boolean finished;
boolean result;
@@ -1437,62 +610,17 @@ public final class Pm {
}
private int runTrimCaches() {
String size = nextArg();
if (size == null) {
System.err.println("Error: no size specified");
return showUsage();
}
long multiplier = 1;
int len = size.length();
char c = size.charAt(len - 1);
if (c < '0' || c > '9') {
if (c == 'K' || c == 'k') {
multiplier = 1024L;
} else if (c == 'M' || c == 'm') {
multiplier = 1024L*1024L;
} else if (c == 'G' || c == 'g') {
multiplier = 1024L*1024L*1024L;
} else {
System.err.println("Invalid suffix: " + c);
return showUsage();
static class ClearDataObserver extends IPackageDataObserver.Stub {
boolean finished;
boolean result;
@Override
public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
synchronized (this) {
finished = true;
result = succeeded;
notifyAll();
}
size = size.substring(0, len-1);
}
long sizeVal;
try {
sizeVal = Long.parseLong(size) * multiplier;
} catch (NumberFormatException e) {
System.err.println("Error: expected number at: " + size);
return showUsage();
}
String volumeUuid = nextArg();
if ("internal".equals(volumeUuid)) {
volumeUuid = null;
}
ClearDataObserver obs = new ClearDataObserver();
try {
mPm.freeStorageAndNotify(volumeUuid, sizeVal,
StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
synchronized (obs) {
while (!obs.finished) {
try {
obs.wait();
} catch (InterruptedException e) {
}
}
}
return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
return showUsage();
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
return 1;
}
}

View File

@@ -46,6 +46,7 @@ import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
@@ -3885,21 +3886,36 @@ public class ActivityManager {
IBinder service = ServiceManager.checkService(name);
if (service == null) {
pw.println(" (Service not found)");
pw.flush();
return;
}
TransferPipe tp = null;
try {
pw.flush();
tp = new TransferPipe();
tp.setBufferPrefix(" ");
service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
tp.go(fd, 10000);
} catch (Throwable e) {
if (tp != null) {
tp.kill();
pw.flush();
if (service instanceof Binder) {
// If this is a local object, it doesn't make sense to do an async dump with it,
// just directly dump.
try {
service.dump(fd, args);
} catch (Throwable e) {
pw.println("Failure dumping service:");
e.printStackTrace(pw);
pw.flush();
}
} else {
// Otherwise, it is remote, do the dump asynchronously to avoid blocking.
TransferPipe tp = null;
try {
pw.flush();
tp = new TransferPipe();
tp.setBufferPrefix(" ");
service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
tp.go(fd, 10000);
} catch (Throwable e) {
if (tp != null) {
tp.kill();
}
pw.println("Failure dumping service:");
e.printStackTrace(pw);
}
pw.println("Failure dumping service:");
e.printStackTrace(pw);
}
}

View File

@@ -6453,7 +6453,7 @@ public abstract class BatteryStats implements Parcelable {
pw.println();
}
}
if (!filtering || (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0) {
if (!filtering || (flags & DUMP_DAILY_ONLY) != 0) {
pw.println("Daily stats:");
pw.print(" Current start time: ");
pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",

View File

@@ -167,7 +167,7 @@ public class Binder implements IBinder {
try {
if (binder instanceof BinderProxy) {
((BinderProxy) binder).mWarnOnBlocking = false;
} else if (binder != null
} else if (binder != null && binder.getInterfaceDescriptor() != null
&& binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
Log.w(TAG, "Unable to allow blocking on interface " + binder);
}
@@ -414,7 +414,7 @@ public class Binder implements IBinder {
* descriptor.
*/
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
if (mDescriptor.equals(descriptor)) {
if (mDescriptor != null && mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;

View File

@@ -17,6 +17,7 @@
package android.os;
import android.util.Slog;
import com.android.internal.util.FastPrintWriter;
import java.io.BufferedInputStream;
@@ -118,12 +119,32 @@ public abstract class ShellCommand {
mErrPrintWriter.flush();
}
if (DEBUG) Slog.d(TAG, "Sending command result on " + mTarget);
mResultReceiver.send(res, null);
if (mResultReceiver != null) {
mResultReceiver.send(res, null);
}
}
if (DEBUG) Slog.d(TAG, "Finished command " + mCmd + " on " + mTarget);
return res;
}
/**
* Adopt the ResultReceiver that was given to this shell command from it, taking
* it over. Primarily used to dispatch to another shell command. Once called,
* this shell command will no longer return its own result when done.
*/
public ResultReceiver adoptResultReceiver() {
ResultReceiver rr = mResultReceiver;
mResultReceiver = null;
return rr;
}
/**
* Return the raw FileDescriptor for the output stream.
*/
public FileDescriptor getOutFileDescriptor() {
return mOut;
}
/**
* Return direct raw access (not buffered) to the command's output data stream.
*/
@@ -144,6 +165,13 @@ public abstract class ShellCommand {
return mOutPrintWriter;
}
/**
* Return the raw FileDescriptor for the error stream.
*/
public FileDescriptor getErrFileDescriptor() {
return mErr;
}
/**
* Return direct raw access (not buffered) to the command's error output data stream.
*/
@@ -167,6 +195,13 @@ public abstract class ShellCommand {
return mErrPrintWriter;
}
/**
* Return the raw FileDescriptor for the input stream.
*/
public FileDescriptor getInFileDescriptor() {
return mIn;
}
/**
* Return direct raw access (not buffered) to the command's input data stream.
*/

View File

@@ -15626,7 +15626,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
pw.println(" mPreviousProcess: " + mPreviousProcess);
}
if (dumpAll) {
if (dumpAll && (mPreviousProcess == null || dumpPackage == null
|| mPreviousProcess.pkgList.containsKey(dumpPackage))) {
StringBuilder sb = new StringBuilder(128);
sb.append(" mPreviousProcessVisibleTime: ");
TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
@@ -15645,7 +15646,9 @@ public class ActivityManagerService extends IActivityManager.Stub
mStackSupervisor.dumpDisplayConfigs(pw, " ");
}
if (dumpAll) {
pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
if (dumpPackage == null) {
pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
}
if (mCompatModePackages.getPackages().size() > 0) {
boolean printed = false;
for (Map.Entry<String, Integer> entry
@@ -15725,8 +15728,8 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.println(" mRunningVoice=" + mRunningVoice);
pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
}
pw.println(" mVrController=" + mVrController);
}
pw.println(" mVrController=" + mVrController);
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
|| mOrigWaitForDebugger) {
if (dumpPackage == null || dumpPackage.equals(mDebugApp)

View File

@@ -478,7 +478,7 @@ public class AppIdleHistory {
}
}
public void dump(IndentingPrintWriter idpw, int userId) {
public void dump(IndentingPrintWriter idpw, int userId, String pkg) {
idpw.println("Package idle stats:");
idpw.increaseIndent();
ArrayMap<String, AppUsageHistory> userHistory = mIdleHistory.get(userId);
@@ -490,6 +490,9 @@ public class AppIdleHistory {
for (int p = 0; p < P; p++) {
final String packageName = userHistory.keyAt(p);
final AppUsageHistory appUsageHistory = userHistory.valueAt(p);
if (pkg != null && !pkg.equals(packageName)) {
continue;
}
idpw.print("package=" + packageName);
idpw.print(" lastUsedElapsed=");
TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastUsedElapsedTime, idpw);

View File

@@ -873,9 +873,9 @@ public class AppStandbyController {
}
}
void dumpUser(IndentingPrintWriter idpw, int userId) {
void dumpUser(IndentingPrintWriter idpw, int userId, String pkg) {
synchronized (mAppIdleLock) {
mAppIdleHistory.dump(idpw, userId);
mAppIdleHistory.dump(idpw, userId, pkg);
}
}

View File

@@ -470,8 +470,32 @@ public class UsageStatsService extends SystemService implements
void dump(String[] args, PrintWriter pw) {
synchronized (mLock) {
IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
ArraySet<String> argSet = new ArraySet<>();
argSet.addAll(Arrays.asList(args));
boolean checkin = false;
boolean history = false;
String pkg = null;
if (args != null) {
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if ("--checkin".equals(arg)) {
checkin = true;
} else if ("--history".equals(arg)) {
history = true;
} else if ("history".equals(arg)) {
history = true;
break;
} else if ("flush".equals(arg)) {
flushToDiskLocked();
pw.println("Flushed stats to disk");
return;
} else {
// Anything else is a pkg to filter
pkg = arg;
break;
}
}
}
final int userCount = mUserState.size();
for (int i = 0; i < userCount; i++) {
@@ -479,26 +503,23 @@ public class UsageStatsService extends SystemService implements
idpw.printPair("user", userId);
idpw.println();
idpw.increaseIndent();
if (argSet.contains("--checkin")) {
if (checkin) {
mUserState.valueAt(i).checkin(idpw);
} else {
mUserState.valueAt(i).dump(idpw);
mUserState.valueAt(i).dump(idpw, pkg);
idpw.println();
if (args.length > 0) {
if ("history".equals(args[0])) {
mAppStandby.dumpHistory(idpw, userId);
} else if ("flush".equals(args[0])) {
flushToDiskLocked();
pw.println("Flushed stats to disk");
}
if (history) {
mAppStandby.dumpHistory(idpw, userId);
}
}
mAppStandby.dumpUser(idpw, userId);
mAppStandby.dumpUser(idpw, userId, pkg);
idpw.decreaseIndent();
}
pw.println();
mAppStandby.dumpState(args, pw);
if (pkg == null) {
pw.println();
mAppStandby.dumpState(args, pw);
}
}
}

View File

@@ -474,19 +474,19 @@ class UserUsageStatsService {
mDatabase.checkinDailyFiles(new UsageStatsDatabase.CheckinAction() {
@Override
public boolean checkin(IntervalStats stats) {
printIntervalStats(pw, stats, false);
printIntervalStats(pw, stats, false, null);
return true;
}
});
}
void dump(IndentingPrintWriter pw) {
void dump(IndentingPrintWriter pw, String pkg) {
// This is not a check-in, only dump in-memory stats.
for (int interval = 0; interval < mCurrentStats.length; interval++) {
pw.print("In-memory ");
pw.print(intervalToString(interval));
pw.println(" stats");
printIntervalStats(pw, mCurrentStats[interval], true);
printIntervalStats(pw, mCurrentStats[interval], true, pkg);
}
}
@@ -505,7 +505,7 @@ class UserUsageStatsService {
}
void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats,
boolean prettyDates) {
boolean prettyDates, String pkg) {
if (prettyDates) {
pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
stats.beginTime, stats.endTime, sDateFormatFlags) + "\"");
@@ -521,6 +521,9 @@ class UserUsageStatsService {
final int pkgCount = pkgStats.size();
for (int i = 0; i < pkgCount; i++) {
final UsageStats usageStats = pkgStats.valueAt(i);
if (pkg != null && !pkg.equals(usageStats.mPackageName)) {
continue;
}
pw.printPair("package", usageStats.mPackageName);
pw.printPair("totalTime",
formatElapsedTime(usageStats.mTotalTimeInForeground, prettyDates));
@@ -533,6 +536,9 @@ class UserUsageStatsService {
pw.println("ChooserCounts");
pw.increaseIndent();
for (UsageStats usageStats : pkgStats.values()) {
if (pkg != null && !pkg.equals(usageStats.mPackageName)) {
continue;
}
pw.printPair("package", usageStats.mPackageName);
if (usageStats.mChooserCounts != null) {
final int chooserCountSize = usageStats.mChooserCounts.size();
@@ -555,19 +561,22 @@ class UserUsageStatsService {
}
pw.decreaseIndent();
pw.println("configurations");
pw.increaseIndent();
final ArrayMap<Configuration, ConfigurationStats> configStats = stats.configurations;
final int configCount = configStats.size();
for (int i = 0; i < configCount; i++) {
final ConfigurationStats config = configStats.valueAt(i);
pw.printPair("config", Configuration.resourceQualifierString(config.mConfiguration));
pw.printPair("totalTime", formatElapsedTime(config.mTotalTimeActive, prettyDates));
pw.printPair("lastTime", formatDateTime(config.mLastTimeActive, prettyDates));
pw.printPair("count", config.mActivationCount);
pw.println();
if (pkg == null) {
pw.println("configurations");
pw.increaseIndent();
final ArrayMap<Configuration, ConfigurationStats> configStats = stats.configurations;
final int configCount = configStats.size();
for (int i = 0; i < configCount; i++) {
final ConfigurationStats config = configStats.valueAt(i);
pw.printPair("config", Configuration.resourceQualifierString(
config.mConfiguration));
pw.printPair("totalTime", formatElapsedTime(config.mTotalTimeActive, prettyDates));
pw.printPair("lastTime", formatDateTime(config.mLastTimeActive, prettyDates));
pw.printPair("count", config.mActivationCount);
pw.println();
}
pw.decreaseIndent();
}
pw.decreaseIndent();
pw.println("events");
pw.increaseIndent();
@@ -575,6 +584,9 @@ class UserUsageStatsService {
final int eventCount = events != null ? events.size() : 0;
for (int i = 0; i < eventCount; i++) {
final UsageEvents.Event event = events.valueAt(i);
if (pkg != null && !pkg.equals(event.mPackage)) {
continue;
}
pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates));
pw.printPair("type", eventToString(event.mEventType));
pw.printPair("package", event.mPackage);