Home | History | Annotate | Download | only in am
      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