OSDN Git Service

Add ability to include messages in oom reports.
authorDianne Hackborn <hackbod@google.com>
Tue, 8 Aug 2017 00:13:52 +0000 (17:13 -0700)
committerDianne Hackborn <hackbod@google.com>
Thu, 31 Aug 2017 23:41:39 +0000 (16:41 -0700)
Test: manual
Bug: 65248777
Merged-In: I1a6b3c02912224b830dbe5573f3b1edebe24c2b3

Change-Id: Ifef2c16f44925c1b7d4ace8435daea48890b238b

services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/ActivityManagerShellCommand.java

index 7356c93..e7d1ee8 100644 (file)
@@ -466,7 +466,6 @@ public class ActivityManagerService extends IActivityManager.Stub
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
-    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
     private static final String TAG_LRU = TAG + POSTFIX_LRU;
     private static final String TAG_MU = TAG + POSTFIX_MU;
@@ -484,7 +483,6 @@ public class ActivityManagerService extends IActivityManager.Stub
     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
-    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
 
     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
     // here so that while the job scheduler can depend on AMS, the other way around
@@ -1562,6 +1560,13 @@ public class ActivityManagerService extends IActivityManager.Stub
     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
 
+    OomAdjObserver mCurOomAdjObserver;
+    int mCurOomAdjUid;
+
+    interface OomAdjObserver {
+        void onOomAdjMessage(String msg);
+    }
+
     /**
      * Runtime CPU use collection thread.  This object's lock is used to
      * perform synchronization with the thread (notifying it to run).
@@ -1683,6 +1688,7 @@ public class ActivityManagerService extends IActivityManager.Stub
     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
+    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
     static final int START_USER_SWITCH_FG_MSG = 712;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -1918,6 +1924,9 @@ public class ActivityManagerService extends IActivityManager.Stub
             case DISPATCH_UIDS_CHANGED_UI_MSG: {
                 dispatchUidsChanged();
             } break;
+            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
+                dispatchOomAdjObserver((String)msg.obj);
+            } break;
             case PUSH_TEMP_WHITELIST_UI_MSG: {
                 pushTempWhitelist();
             } break;
@@ -4456,6 +4465,38 @@ public class ActivityManagerService extends IActivityManager.Stub
         }
     }
 
+    void dispatchOomAdjObserver(String msg) {
+        OomAdjObserver observer;
+        synchronized (this) {
+            observer = mCurOomAdjObserver;
+        }
+
+        if (observer != null) {
+            observer.onOomAdjMessage(msg);
+        }
+    }
+
+    void setOomAdjObserver(int uid, OomAdjObserver observer) {
+        synchronized (this) {
+            mCurOomAdjUid = uid;
+            mCurOomAdjObserver = observer;
+        }
+    }
+
+    void clearOomAdjObserver() {
+        synchronized (this) {
+            mCurOomAdjUid = -1;
+            mCurOomAdjObserver = null;
+        }
+    }
+
+    void reportOomAdjMessageLocked(String tag, String msg) {
+        Slog.d(tag, msg);
+        if (mCurOomAdjObserver != null) {
+            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
+        }
+    }
+
     @Override
     public final int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
@@ -21938,9 +21979,11 @@ public class ActivityManagerService extends IActivityManager.Stub
 
         if (app.curAdj != app.setAdj) {
             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
-            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
-                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
-                    + app.adjType);
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
+                String msg = "Set " + app.pid + " " + app.processName + " adj "
+                        + app.curAdj + ": " + app.adjType;
+                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
+            }
             app.setAdj = app.curAdj;
             app.verifiedAdj = ProcessList.INVALID_ADJ;
         }
@@ -21948,9 +21991,11 @@ public class ActivityManagerService extends IActivityManager.Stub
         if (app.setSchedGroup != app.curSchedGroup) {
             int oldSchedGroup = app.setSchedGroup;
             app.setSchedGroup = app.curSchedGroup;
-            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
-                    "Setting sched group of " + app.processName
-                    + " to " + app.curSchedGroup);
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
+                String msg = "Setting sched group of " + app.processName
+                        + " to " + app.curSchedGroup;
+                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
+            }
             if (app.waitingToKill != null && app.curReceivers.isEmpty()
                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
                 app.kill(app.waitingToKill, true);
@@ -22087,9 +22132,11 @@ public class ActivityManagerService extends IActivityManager.Stub
                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
         }
         if (app.setProcState != app.curProcState) {
-            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
-                    "Proc state change of " + app.processName
-                            + " to " + app.curProcState);
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
+                String msg = "Proc state change of " + app.processName
+                        + " to " + app.curProcState;
+                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
+            }
             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
             if (setImportant && !curImportant) {
index 45357cb..8488e52 100644 (file)
@@ -55,7 +55,6 @@ import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.DebugUtils;
 import android.util.DisplayMetrics;
-import android.view.IWindowManager;
 
 import com.android.internal.util.HexDump;
 import com.android.internal.util.Preconditions;
@@ -1296,19 +1295,24 @@ final class ActivityManagerShellCommand extends ShellCommand {
         return 0;
     }
 
-    static final class MyUidObserver extends IUidObserver.Stub {
+    static final class MyUidObserver extends IUidObserver.Stub
+            implements ActivityManagerService.OomAdjObserver {
         final IActivityManager mInterface;
+        final ActivityManagerService mInternal;
         final PrintWriter mPw;
         final InputStream mInput;
+        final int mUid;
 
         static final int STATE_NORMAL = 0;
 
         int mState;
 
-        MyUidObserver(IActivityManager iam, PrintWriter pw, InputStream input) {
-            mInterface = iam;
+        MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
+            mInterface = service;
+            mInternal = service;
             mPw = pw;
             mInput = input;
+            mUid = uid;
         }
 
         @Override
@@ -1367,6 +1371,15 @@ final class ActivityManagerShellCommand extends ShellCommand {
             }
         }
 
+        @Override
+        public void onOomAdjMessage(String msg) {
+            synchronized (this) {
+                mPw.print("# ");
+                mPw.println(msg);
+                mPw.flush();
+            }
+        }
+
         void printMessageForState() {
             switch (mState) {
                 case STATE_NORMAL:
@@ -1385,6 +1398,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
                         | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
                         | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
+                if (mUid >= 0) {
+                    mInternal.setOomAdjObserver(mUid, this);
+                }
                 mState = STATE_NORMAL;
 
                 InputStreamReader converter = new InputStreamReader(mInput);
@@ -1414,6 +1430,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
                 e.printStackTrace(mPw);
                 mPw.flush();
             } finally {
+                if (mUid >= 0) {
+                    mInternal.clearOomAdjObserver();
+                }
                 mInterface.unregisterUidObserver(this);
             }
         }
@@ -1421,12 +1440,18 @@ final class ActivityManagerShellCommand extends ShellCommand {
 
     int runWatchUids(PrintWriter pw) throws RemoteException {
         String opt;
+        int uid = -1;
         while ((opt=getNextOption()) != null) {
-            getErrPrintWriter().println("Error: Unknown option: " + opt);
-            return -1;
+            if (opt.equals("--oom")) {
+                uid = Integer.parseInt(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
+
+            }
         }
 
-        MyUidObserver controller = new MyUidObserver(mInterface, pw, getRawInputStream());
+        MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
         controller.run();
         return 0;
     }
@@ -1858,8 +1883,12 @@ final class ActivityManagerShellCommand extends ShellCommand {
                 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
                 break;
             default:
-                getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
-                return -1;
+                try {
+                    level = Integer.parseInt(levelArg);
+                } catch (NumberFormatException e) {
+                    getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
+                    return -1;
+                }
         }
         if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
             getErrPrintWriter().println("Unknown error: failed to set trim level");
@@ -2744,8 +2773,9 @@ 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("  watch-uids [--oom <uid>");
             pw.println("      Start watching for and reporting uid state changes.");
+            pw.println("      --oom: specify a uid for which to report detailed change messages.");
             pw.println("  hang [--allow-restart]");
             pw.println("      Hang the system.");
             pw.println("      --allow-restart: allow watchdog to perform normal system restart");
@@ -2804,7 +2834,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
             pw.println("      Returns the inactive state of an app.");
             pw.println("  send-trim-memory [--user <USER_ID>] <PROCESS>");
             pw.println("          [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
-            pw.println("      Send a memory trim event to a <PROCESS>.");
+            pw.println("      Send a memory trim event to a <PROCESS>.  May also supply a raw trim int level.");
             pw.println("  display [COMMAND] [...]: sub-commands for operating on displays.");
             pw.println("       move-stack <STACK_ID> <DISPLAY_ID>");
             pw.println("           Move <STACK_ID> from its current display to <DISPLAY_ID>.");