summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Wale Ogunwale <ogunwale@google.com> 2017-06-10 16:13:51 +0000
committer android-build-merger <android-build-merger@google.com> 2017-06-10 16:13:51 +0000
commitce777c67e75f89a7c15734da75d6a26831f39640 (patch)
treea70a02879c1687d3a747c0798ac3b6f2e1275ee2
parente637937af7f9b220167f65d23c2ffbc7661b99ee (diff)
parentba16911723bef4d406f2a51f30ffebad892db532 (diff)
Merge "Added 'dumpsys activity lastanr'" into oc-dev am: b32fecd6e0
am: ba16911723 Change-Id: I12ba7aeeba10410b2b9291d6b8627bee539ba4df
-rw-r--r--core/java/android/app/ActivityManagerInternal.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java68
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java3
4 files changed, 82 insertions, 3 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index e9ee13866b1a..d3b4b403e1ac 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -249,4 +249,15 @@ public abstract class ActivityManagerInternal {
* {@param vr2dDisplayId}.
*/
public abstract void setVr2dDisplayId(int vr2dDisplayId);
+
+ /**
+ * Saves the current activity manager state and includes the saved state in the next dump of
+ * activity manager.
+ */
+ public abstract void saveANRState(String reason);
+
+ /**
+ * Clears the previously saved activity manager ANR state.
+ */
+ public abstract void clearSavedANRState();
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f80dd6204d13..76456f3edccc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -430,10 +430,12 @@ import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -703,6 +705,12 @@ public class ActivityManagerService extends IActivityManager.Stub
final AppErrors mAppErrors;
/**
+ * Dump of the activity state at the time of the last ANR. Cleared after
+ * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
+ */
+ String mLastANRState;
+
+ /**
* Indicates the maximum time spent waiting for the network rules to get updated.
*/
@VisibleForTesting
@@ -14992,6 +15000,10 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
}
+ } else if ("lastanr".equals(cmd)) {
+ synchronized (this) {
+ dumpLastANRLocked(pw);
+ }
} else if ("recents".equals(cmd) || "r".equals(cmd)) {
synchronized (this) {
dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
@@ -15220,6 +15232,11 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
+ dumpLastANRLocked(pw);
+ pw.println();
+ if (dumpAll) {
+ pw.println("-------------------------------------------------------------------------------");
+ }
dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
if (mAssociations.size() > 0) {
pw.println();
@@ -15280,6 +15297,11 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
+ dumpLastANRLocked(pw);
+ pw.println();
+ if (dumpAll) {
+ pw.println("-------------------------------------------------------------------------------");
+ }
dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
if (mAssociations.size() > 0) {
pw.println();
@@ -15298,9 +15320,24 @@ public class ActivityManagerService extends IActivityManager.Stub
Binder.restoreCallingIdentity(origId);
}
+ private void dumpLastANRLocked(PrintWriter pw) {
+ if (mLastANRState == null) {
+ pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
+ pw.println(" <no ANR has occurred since boot>");
+ } else {
+ pw.println(mLastANRState);
+ }
+ }
+
void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
- pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
+ dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
+ "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
+ }
+
+ void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
+ pw.println(header);
boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
dumpPackage);
@@ -24030,10 +24067,37 @@ public class ActivityManagerService extends IActivityManager.Stub
mVr2dDisplayId = vr2dDisplayId;
}
}
+
+ @Override
+ public void saveANRState(String reason) {
+ synchronized (ActivityManagerService.this) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
+ pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
+ if (reason != null) {
+ pw.println(" Reason: " + reason);
+ }
+ pw.println();
+ dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
+ true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
+ "ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
+ pw.println();
+ pw.close();
+
+ mLastANRState = sw.toString();
+ }
+ }
+
+ @Override
+ public void clearSavedANRState() {
+ synchronized (ActivityManagerService.this) {
+ mLastANRState = null;
+ }
+ }
}
/**
- * Called by app main thread to wait for the network policy rules to get udpated.
+ * Called by app main thread to wait for the network policy rules to get updated.
*
* @param procStateSeq The sequence number indicating the process state change that the main
* thread is interested in.
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 3caf89d750c8..5057f632461c 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -254,6 +254,9 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
mService.saveANRStateLocked(appWindowToken, windowState, reason);
}
+ // All the calls below need to happen without the WM lock held since they call into AM.
+ mService.mAmInternal.saveANRState(reason);
+
if (appWindowToken != null && appWindowToken.appToken != null) {
// Notify the activity manager about the timeout and let it decide whether
// to abort dispatching or keep waiting.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7ef1bd5e0515..f8ede6cee9e3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5116,6 +5116,7 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mWindowMap) {
mLastANRState = null;
}
+ mAmInternal.clearSavedANRState();
}
break;
case WALLPAPER_DRAW_PENDING_TIMEOUT: {
@@ -6583,7 +6584,7 @@ public class WindowManagerService extends IWindowManager.Stub
void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, String reason) {
StringWriter sw = new StringWriter();
PrintWriter pw = new FastPrintWriter(sw, false, 1024);
- pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
+ pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
if (appWindowToken != null) {
pw.println(" Application at fault: " + appWindowToken.stringName);
}