Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd7236db authored by Jeff Brown's avatar Jeff Brown Committed by The Android Automerger
Browse files

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
parent e182d890
Loading
Loading
Loading
Loading
+1 −3
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ import android.os.LocalPowerManager;
import android.os.Looper;
import android.os.Looper;
import android.view.animation.Animation;
import android.view.animation.Animation;


import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.PrintWriter;


/**
/**
@@ -1122,10 +1121,9 @@ public interface WindowManagerPolicy {
     * Print the WindowManagerPolicy's state into the given stream.
     * Print the WindowManagerPolicy's state into the given stream.
     *
     *
     * @param prefix Text to print at the front of each line.
     * @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
     * @param writer The PrintWriter to which you should dump your state.  This will be
     * closed for you after you return.
     * closed for you after you return.
     * @param args additional arguments to the dump request.
     * @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);
}
}
+1 −2
Original line number Original line Diff line number Diff line
@@ -143,7 +143,6 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AnimationUtils;


import java.io.File;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.PrintWriter;
@@ -4371,7 +4370,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mLastInputMethodTargetWindow = target;
        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(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
                pw.print(" mSystemReady="); pw.print(mSystemReady);
                pw.print(" mSystemReady="); pw.print(mSystemReady);
                pw.print(" mSystemBooted="); pw.println(mSystemBooted);
                pw.print(" mSystemBooted="); pw.println(mSystemBooted);
+2 −0
Original line number Original line Diff line number Diff line
@@ -94,6 +94,7 @@ final class InputMonitor implements InputManagerService.Callbacks {
                    Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
                    Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
                            + windowState.mAttrs.getTitle());
                            + windowState.mAttrs.getTitle());
                    appWindowToken = windowState.mAppToken;
                    appWindowToken = windowState.mAppToken;
                    mService.saveANRStateLocked(appWindowToken, windowState);
                }
                }
            }
            }
        }
        }
@@ -104,6 +105,7 @@ final class InputMonitor implements InputManagerService.Callbacks {
                Slog.i(WindowManagerService.TAG,
                Slog.i(WindowManagerService.TAG,
                        "Input event dispatching timed out sending to application "
                        "Input event dispatching timed out sending to application "
                                + appWindowToken.stringName);
                                + appWindowToken.stringName);
                mService.saveANRStateLocked(appWindowToken, null);
            }
            }
        }
        }


+69 −18
Original line number Original line Diff line number Diff line
@@ -143,7 +143,9 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.net.Socket;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Iterator;
@@ -458,6 +460,8 @@ public class WindowManagerService extends IWindowManager.Stub
    boolean mForceDisplayEnabled = false;
    boolean mForceDisplayEnabled = false;
    boolean mShowingBootMessages = false;
    boolean mShowingBootMessages = false;


    String mLastANRState;

    // This protects the following display size properties, so that
    // This protects the following display size properties, so that
    // getDisplaySize() doesn't need to acquire the global lock.  This is
    // getDisplaySize() doesn't need to acquire the global lock.  This is
    // needed because the window manager sometimes needs to use ActivityThread
    // needed because the window manager sometimes needs to use ActivityThread
@@ -9429,12 +9433,12 @@ public class WindowManagerService extends IWindowManager.Stub
        mPolicy.lockNow();
        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)");
        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)");
        pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
        if (mTokenMap.size() > 0) {
        if (mTokenMap.size() > 0) {
            pw.println("  All tokens:");
            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)");
        pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
        if (mSessions.size() > 0) {
        if (mSessions.size() > 0) {
            Iterator<Session> it = mSessions.iterator();
            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) {
            ArrayList<WindowState> windows) {
        pw.println("WINDOW MANAGER WINDOWS (dumpsys window 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--) {
        for (int i=mWindows.size()-1; i>=0; i--) {
            WindowState w = mWindows.get(i);
            WindowState w = mWindows.get(i);
            if (windows == null || windows.contains(w)) {
            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) {
            int opti, boolean dumpAll) {
        ArrayList<WindowState> windows = new ArrayList<WindowState>();
        ArrayList<WindowState> windows = new ArrayList<WindowState>();
        if ("visible".equals(name)) {
        if ("visible".equals(name)) {
@@ -9832,11 +9841,42 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        }


        synchronized(mWindowMap) {
        synchronized(mWindowMap) {
            dumpWindowsLocked(fd, pw, dumpAll, windows);
            dumpWindowsLocked(pw, dumpAll, windows);
        }
        }
        return true;
        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
    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -9862,6 +9902,7 @@ public class WindowManagerService extends IWindowManager.Stub
                pw.println("Window manager dump options:");
                pw.println("Window manager dump options:");
                pw.println("  [-a] [-h] [cmd] ...");
                pw.println("  [-a] [-h] [cmd] ...");
                pw.println("  cmd may be one of:");
                pw.println("  cmd may be one of:");
                pw.println("    l[astanr]: last ANR information");
                pw.println("    p[policy]: policy state");
                pw.println("    p[policy]: policy state");
                pw.println("    s[essions]: active sessions");
                pw.println("    s[essions]: active sessions");
                pw.println("    t[okens]: token list");
                pw.println("    t[okens]: token list");
@@ -9882,34 +9923,39 @@ public class WindowManagerService extends IWindowManager.Stub
        if (opti < args.length) {
        if (opti < args.length) {
            String cmd = args[opti];
            String cmd = args[opti];
            opti++;
            opti++;
            if ("policy".equals(cmd) || "p".equals(cmd)) {
            if ("lastanr".equals(cmd) || "l".equals(cmd)) {
                synchronized(mWindowMap) {
                    dumpLastANRLocked(pw);
                }
                return;
            } else if ("policy".equals(cmd) || "p".equals(cmd)) {
                synchronized(mWindowMap) {
                synchronized(mWindowMap) {
                    dumpPolicyLocked(fd, pw, args, true);
                    dumpPolicyLocked(pw, args, true);
                }
                }
                return;
                return;
            } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
            } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
                synchronized(mWindowMap) {
                synchronized(mWindowMap) {
                    dumpSessionsLocked(fd, pw, true);
                    dumpSessionsLocked(pw, true);
                }
                }
                return;
                return;
            } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
            } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
                synchronized(mWindowMap) {
                synchronized(mWindowMap) {
                    dumpTokensLocked(fd, pw, true);
                    dumpTokensLocked(pw, true);
                }
                }
                return;
                return;
            } else if ("windows".equals(cmd) || "w".equals(cmd)) {
            } else if ("windows".equals(cmd) || "w".equals(cmd)) {
                synchronized(mWindowMap) {
                synchronized(mWindowMap) {
                    dumpWindowsLocked(fd, pw, true, null);
                    dumpWindowsLocked(pw, true, null);
                }
                }
                return;
                return;
            } else if ("all".equals(cmd) || "a".equals(cmd)) {
            } else if ("all".equals(cmd) || "a".equals(cmd)) {
                synchronized(mWindowMap) {
                synchronized(mWindowMap) {
                    dumpWindowsLocked(fd, pw, true, null);
                    dumpWindowsLocked(pw, true, null);
                }
                }
                return;
                return;
            } else {
            } else {
                // Dumping a single name?
                // 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("Bad window command, or no windows match: " + cmd);
                    pw.println("Use -h for help.");
                    pw.println("Use -h for help.");
                }
                }
@@ -9921,22 +9967,27 @@ public class WindowManagerService extends IWindowManager.Stub
            if (dumpAll) {
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("-------------------------------------------------------------------------------");
            }
            }
            dumpPolicyLocked(fd, pw, args, dumpAll);
            dumpPolicyLocked(pw, args, dumpAll);
            pw.println();
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
            }
            dumpSessionsLocked(pw, dumpAll);
            pw.println();
            pw.println();
            if (dumpAll) {
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("-------------------------------------------------------------------------------");
            }
            }
            dumpSessionsLocked(fd, pw, dumpAll);
            dumpTokensLocked(pw, dumpAll);
            pw.println();
            pw.println();
            if (dumpAll) {
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("-------------------------------------------------------------------------------");
            }
            }
            dumpTokensLocked(fd, pw, dumpAll);
            dumpWindowsLocked(pw, dumpAll, null);
            pw.println();
            pw.println();
            if (dumpAll) {
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("-------------------------------------------------------------------------------");
            }
            }
            dumpWindowsLocked(fd, pw, dumpAll, null);
            dumpLastANRLocked(pw);
        }
        }
    }
    }