summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/ShellCommand.java3
-rw-r--r--services/core/java/com/android/server/BatteryService.java190
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java97
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java211
4 files changed, 377 insertions, 124 deletions
diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java
index d64273a36eac..73c2c804bdf1 100644
--- a/core/java/android/os/ShellCommand.java
+++ b/core/java/android/os/ShellCommand.java
@@ -44,7 +44,7 @@ public abstract class ShellCommand {
private FastPrintWriter mOutPrintWriter;
private FastPrintWriter mErrPrintWriter;
- public void exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
+ public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ResultReceiver resultReceiver) {
mTarget = target;
mIn = in;
@@ -89,6 +89,7 @@ public abstract class ShellCommand {
mResultReceiver.send(res, null);
}
if (DEBUG) Slog.d(TAG, "Finished command " + mCmd + " on " + mTarget);
+ return res;
}
public PrintWriter getOutPrintWriter() {
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 2eeaec96b581..61fe62fb88a4 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -19,6 +19,8 @@ package com.android.server;
import android.database.ContentObserver;
import android.os.BatteryStats;
+import android.os.ResultReceiver;
+import android.os.ShellCommand;
import com.android.internal.app.IBatteryStats;
import com.android.server.am.BatteryStatsService;
import com.android.server.lights.Light;
@@ -96,7 +98,6 @@ public final class BatteryService extends SystemService {
// discharge stats before the device dies.
private int mCriticalBatteryLevel;
- private static final int DUMP_MAX_LENGTH = 24 * 1024;
private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "--unplugged" };
private static final String DUMPSYS_DATA_PATH = "/data/system/";
@@ -106,6 +107,7 @@ public final class BatteryService extends SystemService {
private final Context mContext;
private final IBatteryStats mBatteryStats;
+ BinderService mBinderService;
private final Handler mHandler;
private final Object mLock = new Object();
@@ -162,7 +164,18 @@ public final class BatteryService extends SystemService {
// watch for invalid charger messages if the invalid_charger switch exists
if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
- mInvalidChargerObserver.startObserving(
+ UEventObserver invalidChargerObserver = new UEventObserver() {
+ @Override
+ public void onUEvent(UEvent event) {
+ final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;
+ synchronized (mLock) {
+ if (mInvalidCharger != invalidCharger) {
+ mInvalidCharger = invalidCharger;
+ }
+ }
+ }
+ };
+ invalidChargerObserver.startObserving(
"DEVPATH=/devices/virtual/switch/invalid_charger");
}
}
@@ -178,7 +191,8 @@ public final class BatteryService extends SystemService {
// Should never happen.
}
- publishBinderService("battery", new BinderService());
+ mBinderService = new BinderService();
+ publishBinderService("battery", mBinderService);
publishLocalService(BatteryManagerInternal.class, new LocalService());
}
@@ -593,7 +607,6 @@ public final class BatteryService extends SystemService {
} catch (NumberFormatException e) {
Slog.e(TAG, "Invalid DischargeThresholds GService string: " +
durationThresholdString + " or " + dischargeThresholdString);
- return;
}
}
}
@@ -616,27 +629,40 @@ public final class BatteryService extends SystemService {
}
}
- private void dumpInternal(PrintWriter pw, String[] args) {
- synchronized (mLock) {
- if (args == null || args.length == 0 || "-a".equals(args[0])) {
- pw.println("Current Battery Service state:");
- if (mUpdatesStopped) {
- pw.println(" (UPDATES STOPPED -- use 'reset' to restart)");
- }
- pw.println(" AC powered: " + mBatteryProps.chargerAcOnline);
- pw.println(" USB powered: " + mBatteryProps.chargerUsbOnline);
- pw.println(" Wireless powered: " + mBatteryProps.chargerWirelessOnline);
- pw.println(" Max charging current: " + mBatteryProps.maxChargingCurrent);
- pw.println(" status: " + mBatteryProps.batteryStatus);
- pw.println(" health: " + mBatteryProps.batteryHealth);
- pw.println(" present: " + mBatteryProps.batteryPresent);
- pw.println(" level: " + mBatteryProps.batteryLevel);
- pw.println(" scale: " + BATTERY_SCALE);
- pw.println(" voltage: " + mBatteryProps.batteryVoltage);
- pw.println(" temperature: " + mBatteryProps.batteryTemperature);
- pw.println(" technology: " + mBatteryProps.batteryTechnology);
+ class Shell extends ShellCommand {
+ @Override
+ public int onCommand(String cmd) {
+ return onShellCommand(this, cmd);
+ }
+
+ @Override
+ public void onHelp() {
+ PrintWriter pw = getOutPrintWriter();
+ dumpHelp(pw);
+ }
+ }
+
+ static void dumpHelp(PrintWriter pw) {
+ pw.println("Battery service (battery) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println(" set [ac|usb|wireless|status|level|invalid] <value>");
+ pw.println(" Force a battery property value, freezing battery state.");
+ pw.println(" unplug");
+ pw.println(" Force battery unplugged, freezing battery state.");
+ pw.println(" reset");
+ pw.println(" Unfreeze battery state, returning to current hardware values.");
+ }
- } else if ("unplug".equals(args[0])) {
+ int onShellCommand(Shell shell, String cmd) {
+ if (cmd == null) {
+ return shell.handleDefaultCommands(cmd);
+ }
+ PrintWriter pw = shell.getOutPrintWriter();
+ switch (cmd) {
+ case "unplug": {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
if (!mUpdatesStopped) {
mLastBatteryProps.set(mBatteryProps);
}
@@ -650,30 +676,50 @@ public final class BatteryService extends SystemService {
} finally {
Binder.restoreCallingIdentity(ident);
}
+ } break;
+ case "set": {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
+ final String key = shell.getNextArg();
+ if (key == null) {
+ pw.println("No property specified");
+ return -1;
- } else if (args.length == 3 && "set".equals(args[0])) {
- String key = args[1];
- String value = args[2];
+ }
+ final String value = shell.getNextArg();
+ if (value == null) {
+ pw.println("No value specified");
+ return -1;
+
+ }
try {
if (!mUpdatesStopped) {
mLastBatteryProps.set(mBatteryProps);
}
boolean update = true;
- if ("ac".equals(key)) {
- mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
- } else if ("usb".equals(key)) {
- mBatteryProps.chargerUsbOnline = Integer.parseInt(value) != 0;
- } else if ("wireless".equals(key)) {
- mBatteryProps.chargerWirelessOnline = Integer.parseInt(value) != 0;
- } else if ("status".equals(key)) {
- mBatteryProps.batteryStatus = Integer.parseInt(value);
- } else if ("level".equals(key)) {
- mBatteryProps.batteryLevel = Integer.parseInt(value);
- } else if ("invalid".equals(key)) {
- mInvalidCharger = Integer.parseInt(value);
- } else {
- pw.println("Unknown set option: " + key);
- update = false;
+ switch (key) {
+ case "ac":
+ mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
+ break;
+ case "usb":
+ mBatteryProps.chargerUsbOnline = Integer.parseInt(value) != 0;
+ break;
+ case "wireless":
+ mBatteryProps.chargerWirelessOnline = Integer.parseInt(value) != 0;
+ break;
+ case "status":
+ mBatteryProps.batteryStatus = Integer.parseInt(value);
+ break;
+ case "level":
+ mBatteryProps.batteryLevel = Integer.parseInt(value);
+ break;
+ case "invalid":
+ mInvalidCharger = Integer.parseInt(value);
+ break;
+ default:
+ pw.println("Unknown set option: " + key);
+ update = false;
+ break;
}
if (update) {
long ident = Binder.clearCallingIdentity();
@@ -686,9 +732,12 @@ public final class BatteryService extends SystemService {
}
} catch (NumberFormatException ex) {
pw.println("Bad value: " + value);
+ return -1;
}
-
- } else if (args.length == 1 && "reset".equals(args[0])) {
+ } break;
+ case "reset": {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
long ident = Binder.clearCallingIdentity();
try {
if (mUpdatesStopped) {
@@ -699,26 +748,38 @@ public final class BatteryService extends SystemService {
} finally {
Binder.restoreCallingIdentity(ident);
}
- } else {
- pw.println("Dump current battery state, or:");
- pw.println(" set [ac|usb|wireless|status|level|invalid] <value>");
- pw.println(" unplug");
- pw.println(" reset");
- }
+ } break;
+ default:
+ return shell.handleDefaultCommands(cmd);
}
+ return 0;
}
- private final UEventObserver mInvalidChargerObserver = new UEventObserver() {
- @Override
- public void onUEvent(UEventObserver.UEvent event) {
- final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;
- synchronized (mLock) {
- if (mInvalidCharger != invalidCharger) {
- mInvalidCharger = invalidCharger;
+ private void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
+ synchronized (mLock) {
+ if (args == null || args.length == 0 || "-a".equals(args[0])) {
+ pw.println("Current Battery Service state:");
+ if (mUpdatesStopped) {
+ pw.println(" (UPDATES STOPPED -- use 'reset' to restart)");
}
+ pw.println(" AC powered: " + mBatteryProps.chargerAcOnline);
+ pw.println(" USB powered: " + mBatteryProps.chargerUsbOnline);
+ pw.println(" Wireless powered: " + mBatteryProps.chargerWirelessOnline);
+ pw.println(" Max charging current: " + mBatteryProps.maxChargingCurrent);
+ pw.println(" status: " + mBatteryProps.batteryStatus);
+ pw.println(" health: " + mBatteryProps.batteryHealth);
+ pw.println(" present: " + mBatteryProps.batteryPresent);
+ pw.println(" level: " + mBatteryProps.batteryLevel);
+ pw.println(" scale: " + BATTERY_SCALE);
+ pw.println(" voltage: " + mBatteryProps.batteryVoltage);
+ pw.println(" temperature: " + mBatteryProps.batteryTemperature);
+ pw.println(" technology: " + mBatteryProps.batteryTechnology);
+ } else {
+ Shell shell = new Shell();
+ shell.exec(mBinderService, null, fd, null, args, new ResultReceiver(null));
}
}
- };
+ }
private final class Led {
private final Light mBatteryLight;
@@ -776,8 +837,7 @@ public final class BatteryService extends SystemService {
}
private final class BatteryListener extends IBatteryPropertiesListener.Stub {
- @Override
- public void batteryPropertiesChanged(BatteryProperties props) {
+ @Override public void batteryPropertiesChanged(BatteryProperties props) {
final long identity = Binder.clearCallingIdentity();
try {
BatteryService.this.update(props);
@@ -788,8 +848,7 @@ public final class BatteryService extends SystemService {
}
private final class BinderService extends Binder {
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -799,7 +858,12 @@ public final class BatteryService extends SystemService {
return;
}
- dumpInternal(pw, args);
+ dumpInternal(fd, pw, args);
+ }
+
+ @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
+ (new Shell()).exec(this, in, out, err, args, resultReceiver);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index dfe5751267fd..d5ee5e846277 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -69,6 +69,7 @@ import android.graphics.Rect;
import android.os.BatteryStats;
import android.os.PersistableBundle;
import android.os.PowerManager;
+import android.os.ResultReceiver;
import android.os.Trace;
import android.os.TransactionTooLargeException;
import android.os.WorkSource;
@@ -13083,6 +13084,13 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
+ (new ActivityManagerShellCommand(this, false)).exec(
+ this, in, out, err, args, resultReceiver);
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (checkCallingPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -13119,34 +13127,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
dumpClient = true;
} else if ("-h".equals(opt)) {
- pw.println("Activity manager dump options:");
- pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
- pw.println(" cmd may be one of:");
- pw.println(" a[ctivities]: activity stack state");
- pw.println(" r[recents]: recent activities state");
- pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
- pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
- pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
- pw.println(" o[om]: out of memory management");
- pw.println(" perm[issions]: URI permission grant state");
- pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
- pw.println(" provider [COMP_SPEC]: provider client-side state");
- pw.println(" s[ervices] [COMP_SPEC ...]: service state");
- pw.println(" as[sociations]: tracked app associations");
- pw.println(" service [COMP_SPEC]: service client-side state");
- pw.println(" package [PACKAGE_NAME]: all state related to given package");
- pw.println(" all: dump all activities");
- pw.println(" top: dump the top activity");
- pw.println(" write: write all pending state to storage");
- pw.println(" track-associations: enable association tracking");
- pw.println(" untrack-associations: disable and clear association tracking");
- pw.println(" cmd may also be a COMP_SPEC to dump activities.");
- pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
- pw.println(" a partial substring in a component name, a");
- pw.println(" hex object identifier.");
- pw.println(" -a: include all available server state.");
- pw.println(" -c: include client state.");
- pw.println(" -p: limit output to given package.");
+ ActivityManagerShellCommand.dumpHelp(pw, true);
return;
} else {
pw.println("Unknown argument: " + opt + "; use -h for help");
@@ -13283,36 +13264,15 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
}
- } else if ("write".equals(cmd)) {
- mTaskPersister.flush();
- pw.println("All tasks persisted.");
- return;
- } else if ("track-associations".equals(cmd)) {
- synchronized (this) {
- if (!mTrackingAssociations) {
- mTrackingAssociations = true;
- pw.println("Association tracking started.");
- } else {
- pw.println("Association tracking already enabled.");
- }
- }
- return;
- } else if ("untrack-associations".equals(cmd)) {
- synchronized (this) {
- if (mTrackingAssociations) {
- mTrackingAssociations = false;
- mAssociations.clear();
- pw.println("Association tracking stopped.");
- } else {
- pw.println("Association tracking not running.");
- }
- }
- return;
} else {
// Dumping a single activity?
if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
- pw.println("Bad activity command, or no activities match: " + cmd);
- pw.println("Use -h for help.");
+ ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
+ int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
+ if (res < 0) {
+ pw.println("Bad activity command, or no activities match: " + cmd);
+ pw.println("Use -h for help.");
+ }
}
}
if (!more) {
@@ -13563,17 +13523,34 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (mActiveUids.size() > 0) {
- if (needSep) {
- pw.println();
+ boolean printed = false;
+ int whichAppId = -1;
+ if (dumpPackage != null) {
+ try {
+ ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
+ dumpPackage, 0);
+ whichAppId = UserHandle.getAppId(info.uid);
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ }
}
- pw.println(" UID states:");
for (int i=0; i<mActiveUids.size(); i++) {
UidRecord uidRec = mActiveUids.valueAt(i);
+ if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
+ continue;
+ }
+ if (!printed) {
+ printed = true;
+ if (needSep) {
+ pw.println();
+ }
+ pw.println(" UID states:");
+ needSep = true;
+ printedAnything = true;
+ }
pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
pw.print(": "); pw.println(uidRec);
}
- needSep = true;
- printedAnything = true;
}
if (mLruProcesses.size() > 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
new file mode 100644
index 000000000000..d1e7e85b6d51
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.IActivityManager;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+
+import java.io.PrintWriter;
+
+class ActivityManagerShellCommand extends ShellCommand {
+ // IPC interface to activity manager -- don't need to do additional security checks.
+ final IActivityManager mInterface;
+
+ // Internal service impl -- must perform security checks before touching.
+ final ActivityManagerService mInternal;
+
+ final boolean mDumping;
+
+ ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
+ mInterface = service;
+ mInternal = service;
+ mDumping = dumping;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ PrintWriter pw = getOutPrintWriter();
+ try {
+ switch (cmd) {
+ case "force-stop":
+ return runForceStop(pw);
+ case "kill":
+ return runKill(pw);
+ case "kill-all":
+ return runKillAll(pw);
+ case "write":
+ return runWrite(pw);
+ case "track-associations":
+ return runTrackAssociations(pw);
+ case "untrack-associations":
+ return runUntrackAssociations(pw);
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ } catch (RemoteException e) {
+ pw.println("Remote exception: " + e);
+ }
+ return -1;
+ }
+
+ int runForceStop(PrintWriter pw) throws RemoteException {
+ int userId = UserHandle.USER_ALL;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = parseUserArg(getNextArgRequired());
+ } else {
+ pw.println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ mInterface.forceStopPackage(getNextArgRequired(), userId);
+ return 0;
+ }
+
+ int runKill(PrintWriter pw) throws RemoteException {
+ int userId = UserHandle.USER_ALL;
+
+ String opt;
+ while ((opt=getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = parseUserArg(getNextArgRequired());
+ } else {
+ pw.println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
+ return 0;
+ }
+
+ int runKillAll(PrintWriter pw) throws RemoteException {
+ mInterface.killAllBackgroundProcesses();
+ return 0;
+ }
+
+ int runWrite(PrintWriter pw) {
+ mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
+ "registerUidObserver()");
+ mInternal.mTaskPersister.flush();
+ pw.println("All tasks persisted.");
+ return 0;
+ }
+
+ int runTrackAssociations(PrintWriter pw) {
+ mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
+ "registerUidObserver()");
+ synchronized (mInternal) {
+ if (!mInternal.mTrackingAssociations) {
+ mInternal.mTrackingAssociations = true;
+ pw.println("Association tracking started.");
+ } else {
+ pw.println("Association tracking already enabled.");
+ }
+ }
+ return 0;
+ }
+
+ int runUntrackAssociations(PrintWriter pw) {
+ mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
+ "registerUidObserver()");
+ synchronized (mInternal) {
+ if (mInternal.mTrackingAssociations) {
+ mInternal.mTrackingAssociations = false;
+ mInternal.mAssociations.clear();
+ pw.println("Association tracking stopped.");
+ } else {
+ pw.println("Association tracking not running.");
+ }
+ }
+ return 0;
+ }
+
+ int parseUserArg(String arg) {
+ int userId;
+ if ("all".equals(arg)) {
+ userId = UserHandle.USER_ALL;
+ } else if ("current".equals(arg) || "cur".equals(arg)) {
+ userId = UserHandle.USER_CURRENT;
+ } else {
+ try {
+ userId = Integer.parseInt(arg);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Bad user number: " + arg);
+ }
+ }
+ return userId;
+ }
+
+ @Override
+ public void onHelp() {
+ PrintWriter pw = getOutPrintWriter();
+ dumpHelp(pw, mDumping);
+ }
+
+ static void dumpHelp(PrintWriter pw, boolean dumping) {
+ if (dumping) {
+ pw.println("Activity manager dump options:");
+ pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
+ pw.println(" WHAT may be one of:");
+ pw.println(" a[ctivities]: activity stack state");
+ pw.println(" r[recents]: recent activities state");
+ pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
+ pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
+ pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
+ pw.println(" o[om]: out of memory management");
+ pw.println(" perm[issions]: URI permission grant state");
+ pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
+ pw.println(" provider [COMP_SPEC]: provider client-side state");
+ pw.println(" s[ervices] [COMP_SPEC ...]: service state");
+ pw.println(" as[sociations]: tracked app associations");
+ pw.println(" service [COMP_SPEC]: service client-side state");
+ pw.println(" package [PACKAGE_NAME]: all state related to given package");
+ pw.println(" all: dump all activities");
+ pw.println(" top: dump the top activity");
+ pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
+ pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
+ pw.println(" a partial substring in a component name, a");
+ pw.println(" hex object identifier.");
+ pw.println(" -a: include all available server state.");
+ pw.println(" -c: include client state.");
+ pw.println(" -p: limit output to given package.");
+ } else {
+ pw.println("Activity manager (activity) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
+ pw.println(" Complete stop the given application package.");
+ pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
+ pw.println(" Kill all processes associated with the given application.");
+ pw.println(" kill-all");
+ pw.println(" Kill all processes that are safe to kill (cached, etc)");
+ pw.println(" write");
+ pw.println(" Write all pending state to storage.");
+ pw.println(" track-associations");
+ pw.println(" Enable association tracking.");
+ pw.println(" untrack-associations");
+ pw.println(" Disable and clear association tracking.");
+ }
+ }
+}