ActivityManagerShellCommand.java revision 2e44107bf7d9ad97833933422ccd241bf53ff50c
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.am;
18
19import android.app.IActivityManager;
20import android.os.RemoteException;
21import android.os.ShellCommand;
22import android.os.UserHandle;
23
24import java.io.PrintWriter;
25
26class ActivityManagerShellCommand extends ShellCommand {
27    // IPC interface to activity manager -- don't need to do additional security checks.
28    final IActivityManager mInterface;
29
30    // Internal service impl -- must perform security checks before touching.
31    final ActivityManagerService mInternal;
32
33    final boolean mDumping;
34
35    ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
36        mInterface = service;
37        mInternal = service;
38        mDumping = dumping;
39    }
40
41    @Override
42    public int onCommand(String cmd) {
43        if (cmd == null) {
44            return handleDefaultCommands(cmd);
45        }
46        PrintWriter pw = getOutPrintWriter();
47        try {
48            switch (cmd) {
49                case "force-stop":
50                    return runForceStop(pw);
51                case "kill":
52                    return runKill(pw);
53                case "kill-all":
54                    return runKillAll(pw);
55                case "write":
56                    return runWrite(pw);
57                case "track-associations":
58                    return runTrackAssociations(pw);
59                case "untrack-associations":
60                    return runUntrackAssociations(pw);
61                default:
62                    return handleDefaultCommands(cmd);
63            }
64        } catch (RemoteException e) {
65            pw.println("Remote exception: " + e);
66        }
67        return -1;
68    }
69
70    int runForceStop(PrintWriter pw) throws RemoteException {
71        int userId = UserHandle.USER_ALL;
72
73        String opt;
74        while ((opt = getNextOption()) != null) {
75            if (opt.equals("--user")) {
76                userId = parseUserArg(getNextArgRequired());
77            } else {
78                pw.println("Error: Unknown option: " + opt);
79                return -1;
80            }
81        }
82        mInterface.forceStopPackage(getNextArgRequired(), userId);
83        return 0;
84    }
85
86    int runKill(PrintWriter pw) throws RemoteException {
87        int userId = UserHandle.USER_ALL;
88
89        String opt;
90        while ((opt=getNextOption()) != null) {
91            if (opt.equals("--user")) {
92                userId = parseUserArg(getNextArgRequired());
93            } else {
94                pw.println("Error: Unknown option: " + opt);
95                return -1;
96            }
97        }
98        mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
99        return 0;
100    }
101
102    int runKillAll(PrintWriter pw) throws RemoteException {
103        mInterface.killAllBackgroundProcesses();
104        return 0;
105    }
106
107    int runWrite(PrintWriter pw) {
108        mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
109                "registerUidObserver()");
110        mInternal.mTaskPersister.flush();
111        pw.println("All tasks persisted.");
112        return 0;
113    }
114
115    int runTrackAssociations(PrintWriter pw) {
116        mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
117                "registerUidObserver()");
118        synchronized (mInternal) {
119            if (!mInternal.mTrackingAssociations) {
120                mInternal.mTrackingAssociations = true;
121                pw.println("Association tracking started.");
122            } else {
123                pw.println("Association tracking already enabled.");
124            }
125        }
126        return 0;
127    }
128
129    int runUntrackAssociations(PrintWriter pw) {
130        mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
131                "registerUidObserver()");
132        synchronized (mInternal) {
133            if (mInternal.mTrackingAssociations) {
134                mInternal.mTrackingAssociations = false;
135                mInternal.mAssociations.clear();
136                pw.println("Association tracking stopped.");
137            } else {
138                pw.println("Association tracking not running.");
139            }
140        }
141        return 0;
142    }
143
144    int parseUserArg(String arg) {
145        int userId;
146        if ("all".equals(arg)) {
147            userId = UserHandle.USER_ALL;
148        } else if ("current".equals(arg) || "cur".equals(arg)) {
149            userId = UserHandle.USER_CURRENT;
150        } else {
151            try {
152                userId = Integer.parseInt(arg);
153            } catch (NumberFormatException e) {
154                throw new IllegalArgumentException("Bad user number: " + arg);
155            }
156        }
157        return userId;
158    }
159
160    @Override
161    public void onHelp() {
162        PrintWriter pw = getOutPrintWriter();
163        dumpHelp(pw, mDumping);
164    }
165
166    static void dumpHelp(PrintWriter pw, boolean dumping) {
167        if (dumping) {
168            pw.println("Activity manager dump options:");
169            pw.println("  [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
170            pw.println("  WHAT may be one of:");
171            pw.println("    a[ctivities]: activity stack state");
172            pw.println("    r[recents]: recent activities state");
173            pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
174            pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
175            pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
176            pw.println("    o[om]: out of memory management");
177            pw.println("    perm[issions]: URI permission grant state");
178            pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
179            pw.println("    provider [COMP_SPEC]: provider client-side state");
180            pw.println("    s[ervices] [COMP_SPEC ...]: service state");
181            pw.println("    as[sociations]: tracked app associations");
182            pw.println("    service [COMP_SPEC]: service client-side state");
183            pw.println("    package [PACKAGE_NAME]: all state related to given package");
184            pw.println("    all: dump all activities");
185            pw.println("    top: dump the top activity");
186            pw.println("  WHAT may also be a COMP_SPEC to dump activities.");
187            pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
188            pw.println("    a partial substring in a component name, a");
189            pw.println("    hex object identifier.");
190            pw.println("  -a: include all available server state.");
191            pw.println("  -c: include client state.");
192            pw.println("  -p: limit output to given package.");
193        } else {
194            pw.println("Activity manager (activity) commands:");
195            pw.println("  help");
196            pw.println("    Print this help text.");
197            pw.println("  force-stop [--user <USER_ID> | all | current] <PACKAGE>");
198            pw.println("    Complete stop the given application package.");
199            pw.println("  kill [--user <USER_ID> | all | current] <PACKAGE>");
200            pw.println("    Kill all processes associated with the given application.");
201            pw.println("  kill-all");
202            pw.println("    Kill all processes that are safe to kill (cached, etc)");
203            pw.println("  write");
204            pw.println("    Write all pending state to storage.");
205            pw.println("  track-associations");
206            pw.println("    Enable association tracking.");
207            pw.println("  untrack-associations");
208            pw.println("    Disable and clear association tracking.");
209        }
210    }
211}
212