OSDN Git Service

Camera2: Fix null-listener capture for CameraCaptureSession
authorEino-Ville Talvala <etalvala@google.com>
Thu, 31 Jul 2014 19:47:07 +0000 (12:47 -0700)
committerEino-Ville Talvala <etalvala@google.com>
Thu, 7 Aug 2014 20:16:22 +0000 (13:16 -0700)
Correctly allow null listener/handler when invoked on a thread with no
looper; otherwise all capture/repeating requests will fail even if listener
is null.

Change-Id: I4c64c81ad7f14b5cb309b4f92822cb50dbd74ba6

core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
core/java/android/hardware/camera2/impl/CameraDeviceImpl.java

index f829f5e..690093b 100644 (file)
@@ -141,7 +141,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
         checkNotClosed();
         checkLegalToCapture();
 
-        handler = checkHandler(handler);
+        handler = checkHandler(handler, listener);
 
         if (VERBOSE) {
             Log.v(TAG, "capture - request " + request + ", listener " + listener + " handler" +
@@ -164,7 +164,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
         checkNotClosed();
         checkLegalToCapture();
 
-        handler = checkHandler(handler);
+        handler = checkHandler(handler, listener);
 
         if (VERBOSE) {
             CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
@@ -186,7 +186,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
         checkNotClosed();
         checkLegalToCapture();
 
-        handler = checkHandler(handler);
+        handler = checkHandler(handler, listener);
 
         if (VERBOSE) {
             Log.v(TAG, "setRepeatingRequest - request " + request + ", listener " + listener +
@@ -209,7 +209,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
         checkNotClosed();
         checkLegalToCapture();
 
-        handler = checkHandler(handler);
+        handler = checkHandler(handler, listener);
 
         if (VERBOSE) {
             CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
@@ -379,15 +379,18 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
          * - then forward the call to a handler
          * - then finally invoke the destination method on the session listener object
          */
-        Dispatchable<CaptureListener> userListenerSink;
-        if (listener == null) { // OK: API allows the user to not specify a listener
-            userListenerSink = new NullDispatcher<>();
-        } else {
-            userListenerSink = new InvokeDispatcher<>(listener);
+        if (listener == null) {
+            // OK: API allows the user to not specify a listener, and the handler may
+            // also be null in that case. Collapse whole dispatch chain to only call the local
+            // listener
+            return localListener;
         }
 
         InvokeDispatcher<CameraDevice.CaptureListener> localSink =
                 new InvokeDispatcher<>(localListener);
+
+        InvokeDispatcher<CaptureListener> userListenerSink =
+                new InvokeDispatcher<>(listener);
         HandlerDispatcher<CaptureListener> handlerPassthrough =
                 new HandlerDispatcher<>(userListenerSink, handler);
         DuckTypingDispatcher<CameraDevice.CaptureListener, CaptureListener> duckToSession
index 18b1202..3a94e02 100644 (file)
@@ -543,9 +543,7 @@ public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
 
         // Need a valid handler, or current thread needs to have a looper, if
         // listener is valid
-        if (listener != null) {
-            handler = checkHandler(handler);
-        }
+        handler = checkHandler(handler, listener);
 
         // Make sure that there all requests have at least 1 surface; all surfaces are non-null
         for (CaptureRequest request : requestList) {
@@ -1155,6 +1153,18 @@ public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
         return handler;
     }
 
+    /**
+     * Default handler management, conditional on there being a listener.
+     *
+     * <p>If the listener isn't null, check the handler, otherwise pass it through.</p>
+     */
+    static <T> Handler checkHandler(Handler handler, T listener) {
+        if (listener != null) {
+            return checkHandler(handler);
+        }
+        return handler;
+    }
+
     private void checkIfCameraClosedOrInError() throws CameraAccessException {
         if (mInError) {
             throw new CameraAccessException(CameraAccessException.CAMERA_ERROR,