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