Merge "Fix issue #6381224: Initial emulator boot fails and shows a blank black screen." into jb-dev
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 41a6ae7..25da642 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -279,6 +279,7 @@
     WindowManagerFuncs mWindowManagerFuncs;
     LocalPowerManager mPowerManager;
     IStatusBarService mStatusBarService;
+    final Object mServiceAquireLock = new Object();
     Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
     SearchManager mSearchManager;
 
@@ -597,6 +598,16 @@
     }
     MyOrientationListener mOrientationListener;
 
+    IStatusBarService getStatusBarService() {
+        synchronized (mServiceAquireLock) {
+            if (mStatusBarService == null) {
+                mStatusBarService = IStatusBarService.Stub.asInterface(
+                        ServiceManager.getService("statusbar"));
+            }
+            return mStatusBarService;
+        }
+    }
+
     /*
      * We always let the sensor be switched on by default except when
      * the user has explicitly disabled sensor based rotation or when the
@@ -790,9 +801,14 @@
             showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
         } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
             try {
-                mStatusBarService.toggleRecentApps();
+                IStatusBarService statusbar = getStatusBarService();
+                if (statusbar != null) {
+                    statusbar.toggleRecentApps();
+                }
             } catch (RemoteException e) {
                 Slog.e(TAG, "RemoteException when showing recent apps", e);
+                // re-acquire status bar service next time it is needed.
+                mStatusBarService = null;
             }
         }
     }
@@ -1752,9 +1768,14 @@
                 mHomeLongPressed = false;
                 if (!homeWasLongPressed) {
                     try {
-                        mStatusBarService.cancelPreloadRecentApps();
+                        IStatusBarService statusbar = getStatusBarService();
+                        if (statusbar != null) {
+                            statusbar.cancelPreloadRecentApps();
+                        }
                     } catch (RemoteException e) {
                         Slog.e(TAG, "RemoteException when showing recent apps", e);
+                        // re-acquire status bar service next time it is needed.
+                        mStatusBarService = null;
                     }
 
                     mHomePressed = false;
@@ -1805,9 +1826,14 @@
             if (down) {
                 if (!mHomePressed && mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                     try {
-                        mStatusBarService.preloadRecentApps();
+                        IStatusBarService statusbar = getStatusBarService();
+                        if (statusbar != null) {
+                            statusbar.preloadRecentApps();
+                        }
                     } catch (RemoteException e) {
                         Slog.e(TAG, "RemoteException when preloading recent apps", e);
+                        // re-acquire status bar service next time it is needed.
+                        mStatusBarService = null;
                     }
                 }
                 if (repeatCount == 0) {
@@ -2902,10 +2928,14 @@
                         changes |= FINISH_LAYOUT_REDO_LAYOUT;
 
                         mHandler.post(new Runnable() { public void run() {
-                            if (mStatusBarService != null) {
-                                try {
-                                    mStatusBarService.collapse();
-                                } catch (RemoteException ex) {}
+                            try {
+                                IStatusBarService statusbar = getStatusBarService();
+                                if (statusbar != null) {
+                                    statusbar.collapse();
+                                }
+                            } catch (RemoteException ex) {
+                                // re-acquire status bar service next time it is needed.
+                                mStatusBarService = null;
                             }
                         }});
                     } else if (DEBUG_LAYOUT) {
@@ -4343,18 +4373,15 @@
         mFocusedApp = mFocusedWindow.getAppToken();
         mHandler.post(new Runnable() {
                 public void run() {
-                    if (mStatusBarService == null) {
-                        mStatusBarService = IStatusBarService.Stub.asInterface(
-                                ServiceManager.getService("statusbar"));
-                    }
-                    if (mStatusBarService != null) {
-                        try {
-                            mStatusBarService.setSystemUiVisibility(visibility, 0xffffffff);
-                            mStatusBarService.topAppWindowChanged(needsMenu);
-                        } catch (RemoteException e) {
-                            // not much to be done
-                            mStatusBarService = null;
+                    try {
+                        IStatusBarService statusbar = getStatusBarService();
+                        if (statusbar != null) {
+                            statusbar.setSystemUiVisibility(visibility, 0xffffffff);
+                            statusbar.topAppWindowChanged(needsMenu);
                         }
+                    } catch (RemoteException e) {
+                        // re-acquire status bar service next time it is needed.
+                        mStatusBarService = null;
                     }
                 }
             });
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index d954c6c..b276494 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1129,6 +1129,11 @@
             resumeTopActivityLocked(prev);
         } else {
             checkReadyForSleepLocked();
+            if (topRunningActivityLocked(null) == null) {
+                // If there are no more activities available to run, then
+                // do resume anyway to start something.
+                resumeTopActivityLocked(null);
+            }
         }
         
         if (prev != null) {
@@ -3409,6 +3414,7 @@
         IApplicationThread sendThumbnail = null;
         boolean booting = false;
         boolean enableScreen = false;
+        boolean activityRemoved = false;
 
         synchronized (mService) {
             ActivityRecord r = ActivityRecord.forToken(token);
@@ -3515,7 +3521,7 @@
         for (i=0; i<NF; i++) {
             ActivityRecord r = (ActivityRecord)finishes.get(i);
             synchronized (mService) {
-                destroyActivityLocked(r, true, false, "finish-idle");
+                activityRemoved = destroyActivityLocked(r, true, false, "finish-idle");
             }
         }
 
@@ -3537,6 +3543,10 @@
             mService.enableScreenAfterBoot();
         }
 
+        if (activityRemoved) {
+            resumeTopActivityLocked(null);
+        }
+
         return res;
     }
 
@@ -3776,7 +3786,11 @@
                 || prevState == ActivityState.INITIALIZING) {
             // If this activity is already stopped, we can just finish
             // it right now.
-            return destroyActivityLocked(r, true, true, "finish-imm") ? null : r;
+            boolean activityRemoved = destroyActivityLocked(r, true, true, "finish-imm");
+            if (activityRemoved) {
+                resumeTopActivityLocked(null);
+            }
+            return activityRemoved ? null : r;
         } else {
             // Need to go through the full pause cycle to get this
             // activity into the stopped state and then finish it.
@@ -3840,6 +3854,10 @@
         }
 
         // Get rid of any pending idle timeouts.
+        removeTimeoutsForActivityLocked(r);
+    }
+
+    private void removeTimeoutsForActivityLocked(ActivityRecord r) {
         mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
         mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
@@ -3893,6 +3911,7 @@
 
     final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) {
         boolean lastIsOpaque = false;
+        boolean activityRemoved = false;
         for (int i=mHistory.size()-1; i>=0; i--) {
             ActivityRecord r = mHistory.get(i);
             if (r.finishing) {
@@ -3916,9 +3935,14 @@
                 if (DEBUG_SWITCH) Slog.v(TAG, "Destroying " + r + " in state " + r.state
                         + " resumed=" + mResumedActivity
                         + " pausing=" + mPausingActivity);
-                destroyActivityLocked(r, true, oomAdj, reason);
+                if (destroyActivityLocked(r, true, oomAdj, reason)) {
+                    activityRemoved = true;
+                }
             }
         }
+        if (activityRemoved) {
+            resumeTopActivityLocked(null);
+        }
     }
 
     /**
@@ -4023,23 +4047,28 @@
 
     final void activityDestroyed(IBinder token) {
         synchronized (mService) {
-            ActivityRecord r = ActivityRecord.forToken(token);
-            if (r != null) {
-                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
-            }
-            
-            int index = indexOfActivityLocked(r);
-            if (index >= 0) {
-                if (r.state == ActivityState.DESTROYING) {
-                    final long origId = Binder.clearCallingIdentity();
-                    removeActivityFromHistoryLocked(r);
-                    Binder.restoreCallingIdentity(origId);
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                ActivityRecord r = ActivityRecord.forToken(token);
+                if (r != null) {
+                    mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
                 }
+
+                int index = indexOfActivityLocked(r);
+                if (index >= 0) {
+                    if (r.state == ActivityState.DESTROYING) {
+                        cleanUpActivityLocked(r, true, true);
+                        removeActivityFromHistoryLocked(r);
+                    }
+                }
+                resumeTopActivityLocked(null);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
             }
         }
     }
     
-    private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
+    private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
         int i = list.size();
         if (localLOGV) Slog.v(
             TAG, "Removing app " + app + " from list " + list
@@ -4052,6 +4081,7 @@
             if (r.app == app) {
                 if (localLOGV) Slog.v(TAG, "Removing this entry!");
                 list.remove(i);
+                removeTimeoutsForActivityLocked(r);
             }
         }
     }