Fix issue #5446988: WindowManager warns BOOT TIMEOUT,...

...dev.bootcomplete flags is set before boot animation is out

Also:

- Fix crash in recent apps if the intent for an old app didn't
happen to have the new task flag set.
- Fix issue where a crash in system UI would cause the crash
dialog to be displayed below it, effectively locking the UI.  Now
the crash dialog for persistent processes is shown above everything
else.

Change-Id: I0312001a92beeae5f644c7c3e5c5e19f6716df36
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 5b4c33e..d3c4a61 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -483,7 +483,8 @@
         } else {
             Intent intent = ad.intent;
             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-                    | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+                    | Intent.FLAG_ACTIVITY_TASK_ON_HOME
+                    | Intent.FLAG_ACTIVITY_NEW_TASK);
             if (DEBUG) Log.v(TAG, "Starting activity " + intent);
             context.startActivity(intent);
         }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3eb04cb..aac3209 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -128,7 +128,6 @@
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
 import android.view.KeyCharacterMap.FallbackAction;
-import android.view.WindowManagerPolicy.WindowManagerFuncs;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -180,26 +179,26 @@
     static final int PRIORITY_PHONE_LAYER = 7;
     // like the ANR / app crashed dialogs
     static final int SYSTEM_ALERT_LAYER = 8;
-    // system-level error dialogs
-    static final int SYSTEM_ERROR_LAYER = 9;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_LAYER = 10;
+    static final int INPUT_METHOD_LAYER = 9;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_DIALOG_LAYER = 11;
+    static final int INPUT_METHOD_DIALOG_LAYER = 10;
     // the keyguard; nothing on top of these can take focus, since they are
     // responsible for power management when displayed.
-    static final int KEYGUARD_LAYER = 12;
-    static final int KEYGUARD_DIALOG_LAYER = 13;
-    static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
-    static final int STATUS_BAR_LAYER = 15;
-    static final int STATUS_BAR_PANEL_LAYER = 16;
+    static final int KEYGUARD_LAYER = 11;
+    static final int KEYGUARD_DIALOG_LAYER = 12;
+    static final int STATUS_BAR_SUB_PANEL_LAYER = 13;
+    static final int STATUS_BAR_LAYER = 14;
+    static final int STATUS_BAR_PANEL_LAYER = 15;
     // the on-screen volume indicator and controller shown when the user
     // changes the device volume
-    static final int VOLUME_OVERLAY_LAYER = 17;
+    static final int VOLUME_OVERLAY_LAYER = 16;
     // things in here CAN NOT take focus, but are shown on top of everything else.
-    static final int SYSTEM_OVERLAY_LAYER = 18;
+    static final int SYSTEM_OVERLAY_LAYER = 17;
     // the navigation bar, if available, shows atop most things
-    static final int NAVIGATION_BAR_LAYER = 19;
+    static final int NAVIGATION_BAR_LAYER = 18;
+    // system-level error dialogs
+    static final int SYSTEM_ERROR_LAYER = 19;
     // the drag layer: input for drag-and-drop is associated with this window,
     // which sits above all other focusable windows
     static final int DRAG_LAYER = 20;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d038d76..55fb371 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3427,8 +3427,10 @@
                     ac.removePackage(name);
                 }
             }
-            mMainStack.resumeTopActivityLocked(null);
-            mMainStack.scheduleIdleLocked();
+            if (mBooted) {
+                mMainStack.resumeTopActivityLocked(null);
+                mMainStack.scheduleIdleLocked();
+            }
         }
         
         return didSomething;
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index a769c05..57e11cf 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -24,6 +24,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.Slog;
+import android.view.WindowManager;
 
 class AppErrorDialog extends BaseErrorDialog {
     private final static String TAG = "AppErrorDialog";
@@ -73,6 +74,9 @@
         setTitle(res.getText(com.android.internal.R.string.aerr_title));
         getWindow().addFlags(FLAG_SYSTEM_ERROR);
         getWindow().setTitle("Application Error: " + app.info.processName);
+        if (app.persistent) {
+            getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        }
 
         // After the timeout, pretend the user clicked the quit button
         mHandler.sendMessageDelayed(
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0a9ef3d..68f0e66 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -167,6 +167,7 @@
     static final boolean DEBUG_DRAG = false;
     static final boolean DEBUG_SCREEN_ON = false;
     static final boolean DEBUG_SCREENSHOT = false;
+    static final boolean DEBUG_BOOT = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -4728,6 +4729,14 @@
 
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
+                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (mSystemBooted) {
                 return;
             }
@@ -4745,6 +4754,14 @@
     }
 
     void enableScreenIfNeededLocked() {
+        if (DEBUG_BOOT) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
+                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                    + " mShowingBootMessages=" + mShowingBootMessages
+                    + " mSystemBooted=" + mSystemBooted, here);
+        }
         if (mDisplayEnabled) {
             return;
         }
@@ -4767,6 +4784,14 @@
 
     public void performEnableScreen() {
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (mDisplayEnabled) {
                 return;
             }
@@ -4780,10 +4805,22 @@
                 boolean haveBootMsg = false;
                 boolean haveApp = false;
                 boolean haveWallpaper = false;
-                boolean haveKeyguard = false;
+                boolean haveKeyguard = true;
                 final int N = mWindows.size();
                 for (int i=0; i<N; i++) {
                     WindowState w = mWindows.get(i);
+                    if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+                        // Only if there is a keyguard attached to the window manager
+                        // will we consider ourselves as having a keyguard.  If it
+                        // isn't attached, we don't know if it wants to be shown or
+                        // hidden.  If it is attached, we will say we have a keyguard
+                        // if the window doesn't want to be visible, because in that
+                        // case it explicitly doesn't want to be shown so we should
+                        // not delay turning the screen on for it.
+                        boolean vis = w.mViewVisibility == View.VISIBLE
+                                && w.mPolicyVisibility;
+                        haveKeyguard = !vis;
+                    }
                     if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
                         return;
                     }
@@ -4800,7 +4837,7 @@
                     }
                 }
 
-                if (DEBUG_SCREEN_ON) {
+                if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
                     Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
                             + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
                             + " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
@@ -4821,7 +4858,7 @@
             }
 
             mDisplayEnabled = true;
-            if (DEBUG_SCREEN_ON) Slog.i(TAG, "******************** ENABLING SCREEN!");
+            if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
             if (false) {
                 StringWriter sw = new StringWriter();
                 PrintWriter pw = new PrintWriter(sw);
@@ -4852,6 +4889,14 @@
     public void showBootMessage(final CharSequence msg, final boolean always) {
         boolean first = false;
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
+                        + " mAllowBootMessages=" + mAllowBootMessages
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (!mAllowBootMessages) {
                 return;
             }
@@ -4873,6 +4918,14 @@
     }
 
     public void hideBootMessagesLocked() {
+        if (DEBUG_BOOT) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
+                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                    + " mShowingBootMessages=" + mShowingBootMessages
+                    + " mSystemBooted=" + mSystemBooted, here);
+        }
         if (mShowingBootMessages) {
             mShowingBootMessages = false;
             mPolicy.hideBootMessages();