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 17 package com.android.server.am; 18 19 import android.app.ActivityManager; 20 import android.app.IActivityManager; 21 import android.os.RemoteException; 22 import android.os.ShellCommand; 23 import android.os.UserHandle; 24 import android.util.DebugUtils; 25 26 import java.io.PrintWriter; 27 28 class 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); 63 case "is-user-stopped": 64 return runIsUserStopped(pw); 65 case "lenient-background-check": 66 return runLenientBackgroundCheck(pw); 67 case "get-uid-state": 68 return getUidState(pw); 69 default: 70 return handleDefaultCommands(cmd); 71 } 72 } catch (RemoteException e) { 73 pw.println("Remote exception: " + e); 74 } 75 return -1; 76 } 77 78 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 85 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")) { 91 userId = UserHandle.parseUserArg(getNextArgRequired()); 92 } 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")) { 107 userId = UserHandle.parseUserArg(getNextArgRequired()); 108 } 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()"); 125 mInternal.mRecentTasks.flush(); 126 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 159 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 175 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 186 @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(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics"); 201 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 202 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 203 pw.println(" o[om]: out of memory management"); 204 pw.println(" perm[issions]: URI permission grant state"); 205 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 206 pw.println(" provider [COMP_SPEC]: provider client-side state"); 207 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 208 pw.println(" as[sociations]: tracked app associations"); 209 pw.println(" service [COMP_SPEC]: service client-side state"); 210 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 211 pw.println(" all: dump all activities"); 212 pw.println(" top: dump the top activity"); 213 pw.println(" WHAT may also be a COMP_SPEC to dump activities."); 214 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 215 pw.println(" a partial substring in a component name, a"); 216 pw.println(" hex object identifier."); 217 pw.println(" -a: include all available server state."); 218 pw.println(" -c: include client state."); 219 pw.println(" -p: limit output to given package."); 220 pw.println(" --checkin: output checkin format, resetting data."); 221 pw.println(" --C: output checkin format, not resetting data."); 222 } else { 223 pw.println("Activity manager (activity) commands:"); 224 pw.println(" help"); 225 pw.println(" Print this help text."); 226 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>"); 227 pw.println(" Completely stop the given application package."); 228 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>"); 229 pw.println(" Kill all processes associated with the given application."); 230 pw.println(" kill-all"); 231 pw.println(" Kill all processes that are safe to kill (cached, etc)."); 232 pw.println(" write"); 233 pw.println(" Write all pending state to storage."); 234 pw.println(" track-associations"); 235 pw.println(" Enable association tracking."); 236 pw.println(" untrack-associations"); 237 pw.println(" Disable and clear association tracking."); 238 pw.println(" is-user-stopped <USER_ID>"); 239 pw.println(" Returns whether <USER_ID> has been stopped or not."); 240 pw.println(" lenient-background-check [<true|false>]"); 241 pw.println(" Optionally controls lenient background check mode, returns current mode."); 242 pw.println(" get-uid-state <UID>"); 243 pw.println(" Gets the process state of an app given its <UID>."); 244 } 245 } 246 } 247