OSDN Git Service

Not calling startUi() if no longer bound
authorBrian Colonna <bcolonna@google.com>
Thu, 17 May 2012 02:11:30 +0000 (22:11 -0400)
committerBrian Colonna <bcolonna@google.com>
Thu, 17 May 2012 02:11:30 +0000 (22:11 -0400)
After the bind to the FUL service is complete, an
onServiceConnected() callback is received.  This callback is
asynchronous - bindService() does not block while we are waiting for
the service to finish binding.  Therefore, when rapidly turning the
screen on and off, it is possible to call bindService() and then call
unbindService() before the onServiceConnected() callback is received.
When onServiceConnected() is received, startUi() is called.  If the
service is no longer bound, a runtime restart occurs when calling
startUi().

Note that onServiceConnected() actually has its work done via a
handler.  The delay of calling the handler increases the possibility
of unbindService() being called before trying to call startUi().  But
since this problem still happens without using the handler,
eliminating using the handler would not solve the problem and would
just create the problems that come with performing operations on
different threads since onServiceConnected() is not called on the main
thread.

Also note that a new instance of FaceUnlock is created in
LockPatternKeyguardView with each iteration.  So, if we bind/stop/bind
before getting onServiceConnected(), the second bind happens in a new
instance of FaceUnlock and therefore does not lead to a problem when
onServiceConnected() returns as a result of the first bind.

This fixes some occurrences of bug 6409767.  However, this fixes the
problem when turned the device on and off rapidly.  It seems there
are some reports of bug 6409767 where this is not the case, so I
can't be sure this has any affect on those cases.

This change also cleans up some debugging and modifies other
debugging to try to get just the information that is useful for
tracking down the bug.

Change-Id: Ifa59107b9974acaa8a18b74b5d47e4cf3a794b8e

policy/src/com/android/internal/policy/impl/FaceUnlock.java

index c46b94a..737ea47 100644 (file)
@@ -300,7 +300,18 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
      * onServiceConnected() callback is received.
      */
     void handleServiceConnected() {
-        if (DEBUG) Log.d(TAG, "handleServiceConnected()");
+        Log.d(TAG, "handleServiceConnected()");
+
+        // It is possible that an unbind has occurred in the time between the bind and when this
+        // function is reached.  If an unbind has already occurred, proceeding on to call startUi()
+        // can result in a fatal error.  Note that the onServiceConnected() callback is
+        // asynchronous, so this possibility would still exist if we executed this directly in
+        // onServiceConnected() rather than using a handler.
+        if (!mBoundToService) {
+            Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound");
+            return;
+        }
+
         try {
             mService.registerCallback(mFaceUnlockCallback);
         } catch (RemoteException e) {
@@ -452,25 +463,12 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
      * Tells the Face Unlock service to start displaying its UI and start processing.
      */
     private void startUi(IBinder windowToken, int x, int y, int w, int h) {
-        Log.d(TAG, "startUi()");
+        if (DEBUG) Log.d(TAG, "startUi()");
         synchronized (mServiceRunningLock) {
             if (!mServiceRunning) {
-                if (DEBUG) Log.d(TAG, "Starting Face Unlock");
+                Log.d(TAG, "Starting Face Unlock");
                 try {
-                    // TODO: these checks and logs are for tracking down bug 6409767 and can be
-                    // removed when that bug is fixed.
-                    if (mService == null) {
-                        Log.d(TAG, "mService is null");
-                    }
-                    if (windowToken == null) {
-                        Log.d(TAG, "windowToken is null");
-                    }
-                    if (mLockPatternUtils == null) {
-                        Log.d(TAG, "mLockPatternUtils is null");
-                    }
-                    Log.d(TAG, "x,y,w,h,live: " + x + "," + y + "," + w + "," + h + ", no");
                     mService.startUi(windowToken, x, y, w, h, false);
-                    Log.d(TAG, "mService.startUi() called");
                 } catch (RemoteException e) {
                     Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
                     return;
@@ -492,7 +490,7 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
         // screen is turned off.  That's why we check.
         synchronized (mServiceRunningLock) {
             if (mServiceRunning) {
-                if (DEBUG) Log.d(TAG, "Stopping Face Unlock");
+                Log.d(TAG, "Stopping Face Unlock");
                 try {
                     mService.stopUi();
                 } catch (RemoteException e) {