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