Merge change I50a321c9 into eclair

* changes:
  LocationManagerService: Fix race when removing LocationListener
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 8279914..b63e97f 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -563,7 +563,19 @@
     status_t ret = NO_ERROR;
     if (mSurface != 0) {
         if (mOverlayRef.get() == NULL) {
-            mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT);
+
+            // FIXME:
+            // Surfaceflinger may hold onto the previous overlay reference for some
+            // time after we try to destroy it. retry a few times. In the future, we
+            // should make the destroy call block, or possibly specify that we can
+            // wait in the createOverlay call if the previous overlay is in the 
+            // process of being destroyed.
+            for (int retry = 0; retry < 50; ++retry) {
+                mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT);
+                if (mOverlayRef != NULL) break;
+                LOGD("Overlay create failed - retrying");
+                usleep(20000);
+            }
             if ( mOverlayRef.get() == NULL )
             {
                 LOGE("Overlay Creation Failed!");
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 4a71dc6..9c2becf 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -110,7 +110,7 @@
         PRINT("------ PACKAGE UID ERRORS ------");
         DUMP("/data/system/uiderrors.txt");
 
-        dump_kernel_log("/data/dontpanic/last_kmsg", "RAMCONSOLE");
+        dump_kernel_log("/data/dontpanic/last_kmsg", "LAST KMSG");
         dump_kernel_log("/data/dontpanic/apanic_console",
                         "PANIC CONSOLE");
         dump_kernel_log("/data/dontpanic/apanic_threads",
diff --git a/core/java/android/accounts/AuthenticatorBindHelper.java b/core/java/android/accounts/AuthenticatorBindHelper.java
index 91e23ab..2ca1f0e 100644
--- a/core/java/android/accounts/AuthenticatorBindHelper.java
+++ b/core/java/android/accounts/AuthenticatorBindHelper.java
@@ -146,7 +146,7 @@
                                 Log.v(TAG, "there are no more callbacks for service "
                                         + authenticatorType + ", unbinding service");
                             }
-                            unbindFromService(authenticatorType);
+                            unbindFromServiceLocked(authenticatorType);
                         } else {
                             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Log.v(TAG, "leaving service " + authenticatorType
@@ -161,7 +161,10 @@
         }
     }
 
-    private void unbindFromService(String authenticatorType) {
+    /**
+     * You must synchronized on mServiceConnections before calling this
+     */
+    private void unbindFromServiceLocked(String authenticatorType) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "unbindService from " + authenticatorType);
         }
@@ -217,15 +220,18 @@
             // post a message for each service user to tell them that the service is disconnected,
             // and unbind from the service.
             synchronized (mServiceConnections) {
-                for (Callback callback : mServiceUsers.get(mAuthenticatorType)) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "the service became disconnected, scheduling a "
-                                + "disconnected message for "
-                                + mAuthenticatorType);
+                final ArrayList<Callback> callbackList = mServiceUsers.get(mAuthenticatorType);
+                if (callbackList != null) {
+                    for (Callback callback : callbackList) {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "the service became disconnected, scheduling a "
+                                    + "disconnected message for "
+                                    + mAuthenticatorType);
+                        }
+                        mHandler.obtainMessage(mMessageWhatDisconnected, callback).sendToTarget();
                     }
-                    mHandler.obtainMessage(mMessageWhatDisconnected, callback).sendToTarget();
+                    unbindFromServiceLocked(mAuthenticatorType);
                 }
-                unbindFromService(mAuthenticatorType);
             }
         }
     }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 933c2fc..697ac76 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1314,13 +1314,13 @@
             // source. this is because GlobalSearch may not have permission to launch the
             // intent, and to avoid the extra step of going through GlobalSearch.
             if (mGlobalSearchMode) {
+                launchGlobalSearchIntent(intent);
                 if (mStoredComponentName != null) {
                     // If we're embedded in an application, dismiss the dialog.
                     // This ensures that if the intent is handled by the current
                     // activity, it's not obscured by the dialog.
                     dismiss();
                 }
-                launchGlobalSearchIntent(intent);
             } else {
                 // If the intent was created from a suggestion, it will always have an explicit
                 // component here.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 78999fa..916fc2d 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -263,6 +263,13 @@
         boolean isVisibleLw();
         
         /**
+         * Like {@link #isVisibleLw}, but also counts a window that is currently
+         * "hidden" behind the keyguard as visible.  This allows us to apply
+         * things like window flags that impact the keyguard.
+         */
+        boolean isVisibleOrBehindKeyguardLw();
+        
+        /**
          * Is this window currently visible to the user on-screen?  It is 
          * displayed either if it is visible or it is currently running an 
          * animation before no longer being visible.  Must be called with the
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 67b8a85..00636c4 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7574,6 +7574,21 @@
         }
 
         /**
+         * Like {@link #isVisibleLw}, but also counts a window that is currently
+         * "hidden" behind the keyguard as visible.  This allows us to apply
+         * things like window flags that impact the keyguard.
+         * XXX I am starting to think we need to have ANOTHER visibility flag
+         * for this "hidden behind keyguard" state rather than overloading
+         * mPolicyVisibility.  Ungh.
+         */
+        public boolean isVisibleOrBehindKeyguardLw() {
+            final AppWindowToken atoken = mAppToken;
+            return mSurface != null && !mAttachedHidden
+                    && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
+                    && !mExiting && !mDestroying;
+        }
+
+        /**
          * Is this window visible, ignoring its app token?  It is not visible
          * if there is no surface, or we are in the process of running an exit animation
          * that will remove the surface.