Capture window manager's last ANR state in bug report.
Currently just grabbing the window state but we could grab other things as part of the last ANR report. Bug: 6680398 Change-Id: I23aa70907b1bdcb21c8acc556fde196ca790ef6a
This commit is contained in:
@@ -26,7 +26,6 @@ import android.os.LocalPowerManager;
|
||||
import android.os.Looper;
|
||||
import android.view.animation.Animation;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
@@ -1122,10 +1121,9 @@ public interface WindowManagerPolicy {
|
||||
* Print the WindowManagerPolicy's state into the given stream.
|
||||
*
|
||||
* @param prefix Text to print at the front of each line.
|
||||
* @param fd The raw file descriptor that the dump is being sent to.
|
||||
* @param writer The PrintWriter to which you should dump your state. This will be
|
||||
* closed for you after you return.
|
||||
* @param args additional arguments to the dump request.
|
||||
*/
|
||||
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
|
||||
public void dump(String prefix, PrintWriter writer, String[] args);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,6 @@ import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
@@ -4371,7 +4370,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mLastInputMethodTargetWindow = target;
|
||||
}
|
||||
|
||||
public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
public void dump(String prefix, PrintWriter pw, String[] args) {
|
||||
pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
|
||||
pw.print(" mSystemReady="); pw.print(mSystemReady);
|
||||
pw.print(" mSystemBooted="); pw.println(mSystemBooted);
|
||||
|
||||
@@ -94,6 +94,7 @@ final class InputMonitor implements InputManagerService.Callbacks {
|
||||
Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
|
||||
+ windowState.mAttrs.getTitle());
|
||||
appWindowToken = windowState.mAppToken;
|
||||
mService.saveANRStateLocked(appWindowToken, windowState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +105,7 @@ final class InputMonitor implements InputManagerService.Callbacks {
|
||||
Slog.i(WindowManagerService.TAG,
|
||||
"Input event dispatching timed out sending to application "
|
||||
+ appWindowToken.stringName);
|
||||
mService.saveANRStateLocked(appWindowToken, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,9 @@ import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.Socket;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -458,6 +460,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
boolean mForceDisplayEnabled = false;
|
||||
boolean mShowingBootMessages = false;
|
||||
|
||||
String mLastANRState;
|
||||
|
||||
// This protects the following display size properties, so that
|
||||
// getDisplaySize() doesn't need to acquire the global lock. This is
|
||||
// needed because the window manager sometimes needs to use ActivityThread
|
||||
@@ -9429,12 +9433,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mPolicy.lockNow();
|
||||
}
|
||||
|
||||
void dumpPolicyLocked(FileDescriptor fd, PrintWriter pw, String[] args, boolean dumpAll) {
|
||||
void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
|
||||
pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
|
||||
mPolicy.dump(" ", fd, pw, args);
|
||||
mPolicy.dump(" ", pw, args);
|
||||
}
|
||||
|
||||
void dumpTokensLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
|
||||
void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
|
||||
pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
|
||||
if (mTokenMap.size() > 0) {
|
||||
pw.println(" All tokens:");
|
||||
@@ -9542,7 +9546,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
void dumpSessionsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
|
||||
void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
|
||||
pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
|
||||
if (mSessions.size() > 0) {
|
||||
Iterator<Session> it = mSessions.iterator();
|
||||
@@ -9554,9 +9558,14 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
void dumpWindowsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
|
||||
void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
|
||||
ArrayList<WindowState> windows) {
|
||||
pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
|
||||
dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
|
||||
}
|
||||
|
||||
void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
|
||||
ArrayList<WindowState> windows) {
|
||||
for (int i=mWindows.size()-1; i>=0; i--) {
|
||||
WindowState w = mWindows.get(i);
|
||||
if (windows == null || windows.contains(w)) {
|
||||
@@ -9793,7 +9802,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
boolean dumpWindows(FileDescriptor fd, PrintWriter pw, String name, String[] args,
|
||||
boolean dumpWindows(PrintWriter pw, String name, String[] args,
|
||||
int opti, boolean dumpAll) {
|
||||
ArrayList<WindowState> windows = new ArrayList<WindowState>();
|
||||
if ("visible".equals(name)) {
|
||||
@@ -9832,11 +9841,42 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
synchronized(mWindowMap) {
|
||||
dumpWindowsLocked(fd, pw, dumpAll, windows);
|
||||
dumpWindowsLocked(pw, dumpAll, windows);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void dumpLastANRLocked(PrintWriter pw) {
|
||||
pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
|
||||
if (mLastANRState == null) {
|
||||
pw.println(" <no ANR has occurred since boot>");
|
||||
} else {
|
||||
pw.println(mLastANRState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves information about the state of the window manager at
|
||||
* the time an ANR occurred before anything else in the system changes
|
||||
* in response.
|
||||
*
|
||||
* @param appWindowToken The application that ANR'd, never null.
|
||||
* @param windowState The window that ANR'd, may be null.
|
||||
*/
|
||||
public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
|
||||
pw.println(" Application at fault: " + appWindowToken.stringName);
|
||||
if (windowState != null) {
|
||||
pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
|
||||
}
|
||||
pw.println();
|
||||
dumpWindowsNoHeaderLocked(pw, true, null);
|
||||
pw.close();
|
||||
mLastANRState = sw.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
|
||||
@@ -9862,6 +9902,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
pw.println("Window manager dump options:");
|
||||
pw.println(" [-a] [-h] [cmd] ...");
|
||||
pw.println(" cmd may be one of:");
|
||||
pw.println(" l[astanr]: last ANR information");
|
||||
pw.println(" p[policy]: policy state");
|
||||
pw.println(" s[essions]: active sessions");
|
||||
pw.println(" t[okens]: token list");
|
||||
@@ -9882,34 +9923,39 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (opti < args.length) {
|
||||
String cmd = args[opti];
|
||||
opti++;
|
||||
if ("policy".equals(cmd) || "p".equals(cmd)) {
|
||||
if ("lastanr".equals(cmd) || "l".equals(cmd)) {
|
||||
synchronized(mWindowMap) {
|
||||
dumpPolicyLocked(fd, pw, args, true);
|
||||
dumpLastANRLocked(pw);
|
||||
}
|
||||
return;
|
||||
} else if ("policy".equals(cmd) || "p".equals(cmd)) {
|
||||
synchronized(mWindowMap) {
|
||||
dumpPolicyLocked(pw, args, true);
|
||||
}
|
||||
return;
|
||||
} else if ("sessions".equals(cmd) || "s".equals(cmd)) {
|
||||
synchronized(mWindowMap) {
|
||||
dumpSessionsLocked(fd, pw, true);
|
||||
dumpSessionsLocked(pw, true);
|
||||
}
|
||||
return;
|
||||
} else if ("tokens".equals(cmd) || "t".equals(cmd)) {
|
||||
synchronized(mWindowMap) {
|
||||
dumpTokensLocked(fd, pw, true);
|
||||
dumpTokensLocked(pw, true);
|
||||
}
|
||||
return;
|
||||
} else if ("windows".equals(cmd) || "w".equals(cmd)) {
|
||||
synchronized(mWindowMap) {
|
||||
dumpWindowsLocked(fd, pw, true, null);
|
||||
dumpWindowsLocked(pw, true, null);
|
||||
}
|
||||
return;
|
||||
} else if ("all".equals(cmd) || "a".equals(cmd)) {
|
||||
synchronized(mWindowMap) {
|
||||
dumpWindowsLocked(fd, pw, true, null);
|
||||
dumpWindowsLocked(pw, true, null);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Dumping a single name?
|
||||
if (!dumpWindows(fd, pw, cmd, args, opti, dumpAll)) {
|
||||
if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
|
||||
pw.println("Bad window command, or no windows match: " + cmd);
|
||||
pw.println("Use -h for help.");
|
||||
}
|
||||
@@ -9921,22 +9967,27 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (dumpAll) {
|
||||
pw.println("-------------------------------------------------------------------------------");
|
||||
}
|
||||
dumpPolicyLocked(fd, pw, args, dumpAll);
|
||||
dumpPolicyLocked(pw, args, dumpAll);
|
||||
pw.println();
|
||||
if (dumpAll) {
|
||||
pw.println("-------------------------------------------------------------------------------");
|
||||
}
|
||||
dumpSessionsLocked(fd, pw, dumpAll);
|
||||
dumpSessionsLocked(pw, dumpAll);
|
||||
pw.println();
|
||||
if (dumpAll) {
|
||||
pw.println("-------------------------------------------------------------------------------");
|
||||
}
|
||||
dumpTokensLocked(fd, pw, dumpAll);
|
||||
dumpTokensLocked(pw, dumpAll);
|
||||
pw.println();
|
||||
if (dumpAll) {
|
||||
pw.println("-------------------------------------------------------------------------------");
|
||||
}
|
||||
dumpWindowsLocked(fd, pw, dumpAll, null);
|
||||
dumpWindowsLocked(pw, dumpAll, null);
|
||||
pw.println();
|
||||
if (dumpAll) {
|
||||
pw.println("-------------------------------------------------------------------------------");
|
||||
}
|
||||
dumpLastANRLocked(pw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user