diff options
| author | 2017-07-10 17:22:32 +0100 | |
|---|---|---|
| committer | 2017-07-14 16:05:48 +0100 | |
| commit | ffae1cb401aab3737c3546e564d9e8d28b01ad51 (patch) | |
| tree | 2692e19e4e278dd7bcf8c5dc90953f100d0bf524 | |
| parent | d8aad5ac388340512a628bb5820d45afa6709ee5 (diff) | |
Add activity manager command to watch uid state changes.
Also fix a few issues in uid reporting: active was being
reported multiple times when a process started, and idle
could be reported before the idle delay actually happened.
Test: manual, will be adding cts using the new cmd
Change-Id: I051b54145f3cabf72e757b0dcb1f0ef2e979b34e
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 8 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerShellCommand.java | 140 |
2 files changed, 144 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 04df10442aa6..9ed1c36c7907 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6715,7 +6715,6 @@ public class ActivityManagerService extends IActivityManager.Stub mActiveUids.put(proc.uid, uidRec); EventLogTags.writeAmUidRunning(uidRec.uid); noteUidProcessState(uidRec.uid, uidRec.curProcState); - enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE); } proc.uidRecord = uidRec; @@ -22807,8 +22806,9 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i=mActiveUids.size()-1; i>=0; i--) { final UidRecord uidRec = mActiveUids.valueAt(i); int uidChange = UidRecord.CHANGE_PROCSTATE; - if (uidRec.setProcState != uidRec.curProcState - || uidRec.setWhitelist != uidRec.curWhitelist) { + if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT + && (uidRec.setProcState != uidRec.curProcState + || uidRec.setWhitelist != uidRec.curWhitelist)) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec + ": proc state from " + uidRec.setProcState + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist @@ -22829,7 +22829,7 @@ public class ActivityManagerService extends IActivityManager.Stub mConstants.BACKGROUND_SETTLE_TIME); } } - if (!uidRec.setIdle) { + if (uidRec.idle && !uidRec.setIdle) { uidChange = UidRecord.CHANGE_IDLE; } } else { diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 5d242963dfb4..40196e85ef87 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -23,6 +23,7 @@ import android.app.IActivityContainer; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IStopUserCallback; +import android.app.IUidObserver; import android.app.ProfilerInfo; import android.app.WaitResult; import android.app.usage.ConfigurationStats; @@ -184,6 +185,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return runMakeIdle(pw); case "monitor": return runMonitor(pw); + case "watch-uids": + return runWatchUids(pw); case "hang": return runHang(pw); case "restart": @@ -1290,6 +1293,141 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } + static final class MyUidObserver extends IUidObserver.Stub { + final IActivityManager mInterface; + final PrintWriter mPw; + final InputStream mInput; + + static final int STATE_NORMAL = 0; + + int mState; + + MyUidObserver(IActivityManager iam, PrintWriter pw, InputStream input) { + mInterface = iam; + mPw = pw; + mInput = input; + } + + @Override + public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException { + synchronized (this) { + mPw.print(uid); + mPw.print(" procstate "); + mPw.print(ProcessList.makeProcStateString(procState)); + mPw.print(" seq "); + mPw.println(procStateSeq); + mPw.flush(); + } + } + + @Override + public void onUidGone(int uid, boolean disabled) throws RemoteException { + synchronized (this) { + mPw.print(uid); + mPw.print(" gone"); + if (disabled) { + mPw.print(" disabled"); + } + mPw.println(); + mPw.flush(); + } + } + + @Override + public void onUidActive(int uid) throws RemoteException { + synchronized (this) { + mPw.print(uid); + mPw.println(" active"); + mPw.flush(); + } + } + + @Override + public void onUidIdle(int uid, boolean disabled) throws RemoteException { + synchronized (this) { + mPw.print(uid); + mPw.print(" idle"); + if (disabled) { + mPw.print(" disabled"); + } + mPw.println(); + mPw.flush(); + } + } + + @Override + public void onUidCachedChanged(int uid, boolean cached) throws RemoteException { + synchronized (this) { + mPw.print(uid); + mPw.println(cached ? " cached" : " uncached"); + mPw.flush(); + } + } + + void printMessageForState() { + switch (mState) { + case STATE_NORMAL: + mPw.println("Watching uid states... available commands:"); + break; + } + mPw.println("(q)uit: finish watching"); + } + + void run() throws RemoteException { + try { + printMessageForState(); + mPw.flush(); + + mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE + | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE + | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED, + ActivityManager.PROCESS_STATE_UNKNOWN, null); + mState = STATE_NORMAL; + + InputStreamReader converter = new InputStreamReader(mInput); + BufferedReader in = new BufferedReader(converter); + String line; + + while ((line = in.readLine()) != null) { + boolean addNewline = true; + if (line.length() <= 0) { + addNewline = false; + } else if ("q".equals(line) || "quit".equals(line)) { + break; + } else { + mPw.println("Invalid command: " + line); + } + + synchronized (this) { + if (addNewline) { + mPw.println(""); + } + printMessageForState(); + mPw.flush(); + } + } + + } catch (IOException e) { + e.printStackTrace(mPw); + mPw.flush(); + } finally { + mInterface.unregisterUidObserver(this); + } + } + } + + int runWatchUids(PrintWriter pw) throws RemoteException { + String opt; + while ((opt=getNextOption()) != null) { + getErrPrintWriter().println("Error: Unknown option: " + opt); + return -1; + } + + MyUidObserver controller = new MyUidObserver(mInterface, pw, getRawInputStream()); + controller.run(); + return 0; + } + int runHang(PrintWriter pw) throws RemoteException { String opt; boolean allowRestart = false; @@ -2595,6 +2733,8 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" monitor [--gdb <port>]"); pw.println(" Start monitoring for crashes or ANRs."); pw.println(" --gdb: start gdbserv on the given port at crash/ANR"); + pw.println(" watch-uids [--gdb <port>]"); + pw.println(" Start watching for and reporting uid state changes."); pw.println(" hang [--allow-restart]"); pw.println(" Hang the system."); pw.println(" --allow-restart: allow watchdog to perform normal system restart"); |