143143import java .io .PrintWriter ;
144144import java .io .StringWriter ;
145145import java .net .Socket ;
146+ import java .text .DateFormat ;
146147import java .util .ArrayList ;
148+ import java .util .Date ;
147149import java .util .HashMap ;
148150import java .util .HashSet ;
149151import java .util .Iterator ;
@@ -458,6 +460,8 @@ public void onReceive(Context context, Intent intent) {
458460 boolean mForceDisplayEnabled = false ;
459461 boolean mShowingBootMessages = false ;
460462
463+ String mLastANRState ;
464+
461465 // This protects the following display size properties, so that
462466 // getDisplaySize() doesn't need to acquire the global lock. This is
463467 // needed because the window manager sometimes needs to use ActivityThread
@@ -9429,12 +9433,12 @@ public void lockNow() {
94299433 mPolicy .lockNow ();
94309434 }
94319435
9432- void dumpPolicyLocked (FileDescriptor fd , PrintWriter pw , String [] args , boolean dumpAll ) {
9436+ void dumpPolicyLocked (PrintWriter pw , String [] args , boolean dumpAll ) {
94339437 pw .println ("WINDOW MANAGER POLICY STATE (dumpsys window policy)" );
9434- mPolicy .dump (" " , fd , pw , args );
9438+ mPolicy .dump (" " , pw , args );
94359439 }
94369440
9437- void dumpTokensLocked (FileDescriptor fd , PrintWriter pw , boolean dumpAll ) {
9441+ void dumpTokensLocked (PrintWriter pw , boolean dumpAll ) {
94389442 pw .println ("WINDOW MANAGER TOKENS (dumpsys window tokens)" );
94399443 if (mTokenMap .size () > 0 ) {
94409444 pw .println (" All tokens:" );
@@ -9542,7 +9546,7 @@ void dumpTokensLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
95429546 }
95439547 }
95449548
9545- void dumpSessionsLocked (FileDescriptor fd , PrintWriter pw , boolean dumpAll ) {
9549+ void dumpSessionsLocked (PrintWriter pw , boolean dumpAll ) {
95469550 pw .println ("WINDOW MANAGER SESSIONS (dumpsys window sessions)" );
95479551 if (mSessions .size () > 0 ) {
95489552 Iterator <Session > it = mSessions .iterator ();
@@ -9554,9 +9558,14 @@ void dumpSessionsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
95549558 }
95559559 }
95569560
9557- void dumpWindowsLocked (FileDescriptor fd , PrintWriter pw , boolean dumpAll ,
9561+ void dumpWindowsLocked (PrintWriter pw , boolean dumpAll ,
95589562 ArrayList <WindowState > windows ) {
95599563 pw .println ("WINDOW MANAGER WINDOWS (dumpsys window windows)" );
9564+ dumpWindowsNoHeaderLocked (pw , dumpAll , windows );
9565+ }
9566+
9567+ void dumpWindowsNoHeaderLocked (PrintWriter pw , boolean dumpAll ,
9568+ ArrayList <WindowState > windows ) {
95609569 for (int i =mWindows .size ()-1 ; i >=0 ; i --) {
95619570 WindowState w = mWindows .get (i );
95629571 if (windows == null || windows .contains (w )) {
@@ -9793,7 +9802,7 @@ void dumpWindowsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
97939802 }
97949803 }
97959804
9796- boolean dumpWindows (FileDescriptor fd , PrintWriter pw , String name , String [] args ,
9805+ boolean dumpWindows (PrintWriter pw , String name , String [] args ,
97979806 int opti , boolean dumpAll ) {
97989807 ArrayList <WindowState > windows = new ArrayList <WindowState >();
97999808 if ("visible" .equals (name )) {
@@ -9832,11 +9841,42 @@ boolean dumpWindows(FileDescriptor fd, PrintWriter pw, String name, String[] arg
98329841 }
98339842
98349843 synchronized (mWindowMap ) {
9835- dumpWindowsLocked (fd , pw , dumpAll , windows );
9844+ dumpWindowsLocked (pw , dumpAll , windows );
98369845 }
98379846 return true ;
98389847 }
98399848
9849+ void dumpLastANRLocked (PrintWriter pw ) {
9850+ pw .println ("WINDOW MANAGER LAST ANR (dumpsys window lastanr)" );
9851+ if (mLastANRState == null ) {
9852+ pw .println (" <no ANR has occurred since boot>" );
9853+ } else {
9854+ pw .println (mLastANRState );
9855+ }
9856+ }
9857+
9858+ /**
9859+ * Saves information about the state of the window manager at
9860+ * the time an ANR occurred before anything else in the system changes
9861+ * in response.
9862+ *
9863+ * @param appWindowToken The application that ANR'd, never null.
9864+ * @param windowState The window that ANR'd, may be null.
9865+ */
9866+ public void saveANRStateLocked (AppWindowToken appWindowToken , WindowState windowState ) {
9867+ StringWriter sw = new StringWriter ();
9868+ PrintWriter pw = new PrintWriter (sw );
9869+ pw .println (" ANR time: " + DateFormat .getInstance ().format (new Date ()));
9870+ pw .println (" Application at fault: " + appWindowToken .stringName );
9871+ if (windowState != null ) {
9872+ pw .println (" Window at fault: " + windowState .mAttrs .getTitle ());
9873+ }
9874+ pw .println ();
9875+ dumpWindowsNoHeaderLocked (pw , true , null );
9876+ pw .close ();
9877+ mLastANRState = sw .toString ();
9878+ }
9879+
98409880 @ Override
98419881 public void dump (FileDescriptor fd , PrintWriter pw , String [] args ) {
98429882 if (mContext .checkCallingOrSelfPermission ("android.permission.DUMP" )
@@ -9862,6 +9902,7 @@ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
98629902 pw .println ("Window manager dump options:" );
98639903 pw .println (" [-a] [-h] [cmd] ..." );
98649904 pw .println (" cmd may be one of:" );
9905+ pw .println (" l[astanr]: last ANR information" );
98659906 pw .println (" p[policy]: policy state" );
98669907 pw .println (" s[essions]: active sessions" );
98679908 pw .println (" t[okens]: token list" );
@@ -9882,34 +9923,39 @@ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
98829923 if (opti < args .length ) {
98839924 String cmd = args [opti ];
98849925 opti ++;
9885- if ("policy " .equals (cmd ) || "p " .equals (cmd )) {
9926+ if ("lastanr " .equals (cmd ) || "l " .equals (cmd )) {
98869927 synchronized (mWindowMap ) {
9887- dumpPolicyLocked (fd , pw , args , true );
9928+ dumpLastANRLocked (pw );
9929+ }
9930+ return ;
9931+ } else if ("policy" .equals (cmd ) || "p" .equals (cmd )) {
9932+ synchronized (mWindowMap ) {
9933+ dumpPolicyLocked (pw , args , true );
98889934 }
98899935 return ;
98909936 } else if ("sessions" .equals (cmd ) || "s" .equals (cmd )) {
98919937 synchronized (mWindowMap ) {
9892- dumpSessionsLocked (fd , pw , true );
9938+ dumpSessionsLocked (pw , true );
98939939 }
98949940 return ;
98959941 } else if ("tokens" .equals (cmd ) || "t" .equals (cmd )) {
98969942 synchronized (mWindowMap ) {
9897- dumpTokensLocked (fd , pw , true );
9943+ dumpTokensLocked (pw , true );
98989944 }
98999945 return ;
99009946 } else if ("windows" .equals (cmd ) || "w" .equals (cmd )) {
99019947 synchronized (mWindowMap ) {
9902- dumpWindowsLocked (fd , pw , true , null );
9948+ dumpWindowsLocked (pw , true , null );
99039949 }
99049950 return ;
99059951 } else if ("all" .equals (cmd ) || "a" .equals (cmd )) {
99069952 synchronized (mWindowMap ) {
9907- dumpWindowsLocked (fd , pw , true , null );
9953+ dumpWindowsLocked (pw , true , null );
99089954 }
99099955 return ;
99109956 } else {
99119957 // Dumping a single name?
9912- if (!dumpWindows (fd , pw , cmd , args , opti , dumpAll )) {
9958+ if (!dumpWindows (pw , cmd , args , opti , dumpAll )) {
99139959 pw .println ("Bad window command, or no windows match: " + cmd );
99149960 pw .println ("Use -h for help." );
99159961 }
@@ -9921,22 +9967,27 @@ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
99219967 if (dumpAll ) {
99229968 pw .println ("-------------------------------------------------------------------------------" );
99239969 }
9924- dumpPolicyLocked (fd , pw , args , dumpAll );
9970+ dumpPolicyLocked (pw , args , dumpAll );
9971+ pw .println ();
9972+ if (dumpAll ) {
9973+ pw .println ("-------------------------------------------------------------------------------" );
9974+ }
9975+ dumpSessionsLocked (pw , dumpAll );
99259976 pw .println ();
99269977 if (dumpAll ) {
99279978 pw .println ("-------------------------------------------------------------------------------" );
99289979 }
9929- dumpSessionsLocked ( fd , pw , dumpAll );
9980+ dumpTokensLocked ( pw , dumpAll );
99309981 pw .println ();
99319982 if (dumpAll ) {
99329983 pw .println ("-------------------------------------------------------------------------------" );
99339984 }
9934- dumpTokensLocked ( fd , pw , dumpAll );
9985+ dumpWindowsLocked ( pw , dumpAll , null );
99359986 pw .println ();
99369987 if (dumpAll ) {
99379988 pw .println ("-------------------------------------------------------------------------------" );
99389989 }
9939- dumpWindowsLocked ( fd , pw , dumpAll , null );
9990+ dumpLastANRLocked ( pw );
99409991 }
99419992 }
99429993
0 commit comments