blob: 9be6b43f21c6e1a65d013272f5f8d3d931ff5641 [file] [log] [blame]
Dianne Hackborn2e441072015-10-28 18:00:57 -07001/*
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.am;
18
Felipe Leme2f1b2272016-03-25 16:15:02 -070019import android.app.ActivityManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070020import android.app.IActivityManager;
21import android.os.RemoteException;
22import android.os.ShellCommand;
23import android.os.UserHandle;
Felipe Leme2f1b2272016-03-25 16:15:02 -070024import android.util.DebugUtils;
Dianne Hackborn2e441072015-10-28 18:00:57 -070025
26import java.io.PrintWriter;
27
28class ActivityManagerShellCommand extends ShellCommand {
29 // IPC interface to activity manager -- don't need to do additional security checks.
30 final IActivityManager mInterface;
31
32 // Internal service impl -- must perform security checks before touching.
33 final ActivityManagerService mInternal;
34
35 final boolean mDumping;
36
37 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
38 mInterface = service;
39 mInternal = service;
40 mDumping = dumping;
41 }
42
43 @Override
44 public int onCommand(String cmd) {
45 if (cmd == null) {
46 return handleDefaultCommands(cmd);
47 }
48 PrintWriter pw = getOutPrintWriter();
49 try {
50 switch (cmd) {
51 case "force-stop":
52 return runForceStop(pw);
53 case "kill":
54 return runKill(pw);
55 case "kill-all":
56 return runKillAll(pw);
57 case "write":
58 return runWrite(pw);
59 case "track-associations":
60 return runTrackAssociations(pw);
61 case "untrack-associations":
62 return runUntrackAssociations(pw);
Suprabh Shukla09a88f52015-12-02 14:36:31 -080063 case "is-user-stopped":
64 return runIsUserStopped(pw);
Dianne Hackbornb2117d12016-02-16 18:26:35 -080065 case "lenient-background-check":
66 return runLenientBackgroundCheck(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -070067 case "get-uid-state":
68 return getUidState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -070069 default:
70 return handleDefaultCommands(cmd);
71 }
72 } catch (RemoteException e) {
73 pw.println("Remote exception: " + e);
74 }
75 return -1;
76 }
77
Suprabh Shukla09a88f52015-12-02 14:36:31 -080078 int runIsUserStopped(PrintWriter pw) {
79 int userId = UserHandle.parseUserArg(getNextArgRequired());
80 boolean stopped = mInternal.isUserStopped(userId);
81 pw.println(stopped);
82 return 0;
83 }
84
Dianne Hackborn2e441072015-10-28 18:00:57 -070085 int runForceStop(PrintWriter pw) throws RemoteException {
86 int userId = UserHandle.USER_ALL;
87
88 String opt;
89 while ((opt = getNextOption()) != null) {
90 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080091 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -070092 } else {
93 pw.println("Error: Unknown option: " + opt);
94 return -1;
95 }
96 }
97 mInterface.forceStopPackage(getNextArgRequired(), userId);
98 return 0;
99 }
100
101 int runKill(PrintWriter pw) throws RemoteException {
102 int userId = UserHandle.USER_ALL;
103
104 String opt;
105 while ((opt=getNextOption()) != null) {
106 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800107 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700108 } else {
109 pw.println("Error: Unknown option: " + opt);
110 return -1;
111 }
112 }
113 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
114 return 0;
115 }
116
117 int runKillAll(PrintWriter pw) throws RemoteException {
118 mInterface.killAllBackgroundProcesses();
119 return 0;
120 }
121
122 int runWrite(PrintWriter pw) {
123 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
124 "registerUidObserver()");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800125 mInternal.mRecentTasks.flush();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700126 pw.println("All tasks persisted.");
127 return 0;
128 }
129
130 int runTrackAssociations(PrintWriter pw) {
131 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
132 "registerUidObserver()");
133 synchronized (mInternal) {
134 if (!mInternal.mTrackingAssociations) {
135 mInternal.mTrackingAssociations = true;
136 pw.println("Association tracking started.");
137 } else {
138 pw.println("Association tracking already enabled.");
139 }
140 }
141 return 0;
142 }
143
144 int runUntrackAssociations(PrintWriter pw) {
145 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
146 "registerUidObserver()");
147 synchronized (mInternal) {
148 if (mInternal.mTrackingAssociations) {
149 mInternal.mTrackingAssociations = false;
150 mInternal.mAssociations.clear();
151 pw.println("Association tracking stopped.");
152 } else {
153 pw.println("Association tracking not running.");
154 }
155 }
156 return 0;
157 }
158
Dianne Hackbornb2117d12016-02-16 18:26:35 -0800159 int runLenientBackgroundCheck(PrintWriter pw) throws RemoteException {
160 String arg = getNextArg();
161 if (arg != null) {
162 boolean state = Boolean.valueOf(arg) || "1".equals(arg);
163 mInterface.setLenientBackgroundCheck(state);
164 }
165 synchronized (mInternal) {
166 if (mInternal.mLenientBackgroundCheck) {
167 pw.println("Lenient background check enabled");
168 } else {
169 pw.println("Lenient background check disabled");
170 }
171 }
172 return 0;
173 }
174
Felipe Leme2f1b2272016-03-25 16:15:02 -0700175 int getUidState(PrintWriter pw) throws RemoteException {
176 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
177 "getUidState()");
178 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
179 pw.print(state);
180 pw.print(" (");
181 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
182 pw.println(")");
183 return 0;
184 }
185
Dianne Hackborn2e441072015-10-28 18:00:57 -0700186 @Override
187 public void onHelp() {
188 PrintWriter pw = getOutPrintWriter();
189 dumpHelp(pw, mDumping);
190 }
191
192 static void dumpHelp(PrintWriter pw, boolean dumping) {
193 if (dumping) {
194 pw.println("Activity manager dump options:");
195 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
196 pw.println(" WHAT may be one of:");
197 pw.println(" a[ctivities]: activity stack state");
198 pw.println(" r[recents]: recent activities state");
199 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
200 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
201 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
202 pw.println(" o[om]: out of memory management");
203 pw.println(" perm[issions]: URI permission grant state");
204 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
205 pw.println(" provider [COMP_SPEC]: provider client-side state");
206 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
207 pw.println(" as[sociations]: tracked app associations");
208 pw.println(" service [COMP_SPEC]: service client-side state");
209 pw.println(" package [PACKAGE_NAME]: all state related to given package");
210 pw.println(" all: dump all activities");
211 pw.println(" top: dump the top activity");
212 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
213 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
214 pw.println(" a partial substring in a component name, a");
215 pw.println(" hex object identifier.");
216 pw.println(" -a: include all available server state.");
217 pw.println(" -c: include client state.");
218 pw.println(" -p: limit output to given package.");
219 } else {
220 pw.println("Activity manager (activity) commands:");
221 pw.println(" help");
222 pw.println(" Print this help text.");
223 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
224 pw.println(" Complete stop the given application package.");
225 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
226 pw.println(" Kill all processes associated with the given application.");
227 pw.println(" kill-all");
Felipe Leme2f1b2272016-03-25 16:15:02 -0700228 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn2e441072015-10-28 18:00:57 -0700229 pw.println(" write");
230 pw.println(" Write all pending state to storage.");
231 pw.println(" track-associations");
232 pw.println(" Enable association tracking.");
233 pw.println(" untrack-associations");
234 pw.println(" Disable and clear association tracking.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800235 pw.println(" is-user-stopped <USER_ID>");
Felipe Leme2f1b2272016-03-25 16:15:02 -0700236 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Dianne Hackbornb2117d12016-02-16 18:26:35 -0800237 pw.println(" lenient-background-check [<true|false>]");
Felipe Leme2f1b2272016-03-25 16:15:02 -0700238 pw.println(" Optionally controls lenient background check mode, returns current mode.");
239 pw.println(" get-uid-state <UID>");
240 pw.println(" Gets the process state of an app given its <UID>.");
Dianne Hackborn2e441072015-10-28 18:00:57 -0700241 }
242 }
243}