summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Boucher <solb@google.com>2014-08-27 04:53:26 (GMT)
committerAndroid Git Automerger <android-git-automerger@android.com>2014-08-27 04:53:26 (GMT)
commit444909d9aff00d322b5a596e576175bcf1550504 (patch)
tree2f79b7886436c56a4ba619654ddfb4eba38493eb
parentc192e279acae7ce5b75e26c443bd53c33e9c667c (diff)
parent984a086412a94ebea1bd9af8cd8bbf4afab38034 (diff)
downloadandroid_frameworks_ex-444909d9aff00d322b5a596e576175bcf1550504.zip
android_frameworks_ex-444909d9aff00d322b5a596e576175bcf1550504.tar.gz
android_frameworks_ex-444909d9aff00d322b5a596e576175bcf1550504.tar.bz2
am 984a0864: camera2-portability: Optimize out some camera2 AE precaptures
* commit '984a086412a94ebea1bd9af8cd8bbf4afab38034': camera2-portability: Optimize out some camera2 AE precaptures
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java259
-rw-r--r--camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java17
-rw-r--r--camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java40
3 files changed, 241 insertions, 75 deletions
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
index d139c62..2a30063 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
@@ -198,6 +198,9 @@ class AndroidCamera2AgentImpl extends CameraAgent {
// Available whenever setAutoFocusMoveCallback() was last invoked with a non-null argument:
private CameraAFMoveCallback mPassiveAfCallback;
+ // Gets reset on every state change
+ private int mCurrentAeState = CaptureResult.CONTROL_AE_STATE_INACTIVE;
+
Camera2Handler(Looper looper) {
super(looper);
}
@@ -263,7 +266,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
mPhotoSize = null;
mCameraIndex = 0;
mCameraId = null;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_UNOPENED);
+ changeState(AndroidCamera2StateHolder.CAMERA_UNOPENED);
break;
}
@@ -289,15 +292,15 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}
mOneshotPreviewingCallback = (CameraStartPreviewCallback) msg.obj;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
try {
mSession.setRepeatingRequest(
mPersistentSettings.createRequest(mCamera,
CameraDevice.TEMPLATE_PREVIEW, mPreviewSurface),
- /*listener*/mCameraFocusStateListener, /*handler*/this);
+ /*listener*/mCameraResultStateListener, /*handler*/this);
} catch(CameraAccessException ex) {
Log.w(TAG, "Unable to start preview", ex);
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
}
break;
}
@@ -310,7 +313,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}
mSession.stopRepeating();
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
break;
}
@@ -368,19 +371,39 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}
// The earliest we can reliably tell whether the autofocus has locked in
- // response to our latest request is when our one-time capture completes.
+ // response to our latest request is when our one-time capture progresses.
// However, it will probably take longer than that, so once that happens,
// just start checking the repeating preview requests as they complete.
final CameraAFCallback callback = (CameraAFCallback) msg.obj;
CameraCaptureSession.CaptureListener deferredCallbackSetter =
new CameraCaptureSession.CaptureListener() {
+ private boolean mAlreadyDispatched = false;
+
+ @Override
+ public void onCaptureProgressed(CameraCaptureSession session,
+ CaptureRequest request,
+ CaptureResult result) {
+ checkAfState(result);
+ }
+
@Override
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request,
TotalCaptureResult result) {
- // Now our mCameraFocusStateListener will invoke the callback the
- // first time it finds the focus motor to be locked.
- mOneshotAfCallback = callback;
+ checkAfState(result);
+ }
+
+ private void checkAfState(CaptureResult result) {
+ if (result.get(CaptureResult.CONTROL_AF_STATE) != null &&
+ !mAlreadyDispatched) {
+ // Now our mCameraResultStateListener will invoke the callback
+ // the first time it finds the focus motor to be locked.
+ mAlreadyDispatched = true;
+ mOneshotAfCallback = callback;
+ // This is an optimization: check the AF state of this frame
+ // instead of simply waiting for the next.
+ mCameraResultStateListener.monitorControlStates(result);
+ }
}
@Override
@@ -392,7 +415,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}};
// Send a one-time capture to trigger the camera driver to lock focus.
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
+ changeState(AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
Camera2RequestSettingsSet trigger =
new Camera2RequestSettingsSet(mPersistentSettings);
trigger.set(CaptureRequest.CONTROL_AF_TRIGGER,
@@ -404,7 +427,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
/*listener*/deferredCallbackSetter, /*handler*/ this);
} catch(CameraAccessException ex) {
Log.e(TAG, "Unable to lock autofocus", ex);
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
}
break;
}
@@ -418,7 +441,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}
// Send a one-time capture to trigger the camera driver to resume scanning.
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
Camera2RequestSettingsSet cancel =
new Camera2RequestSettingsSet(mPersistentSettings);
cancel.set(CaptureRequest.CONTROL_AF_TRIGGER,
@@ -430,8 +453,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
/*listener*/null, /*handler*/this);
} catch(CameraAccessException ex) {
Log.e(TAG, "Unable to cancel autofocus", ex);
- mCameraState.setState(
- AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
+ changeState(AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
}
break;
}
@@ -486,8 +508,21 @@ class AndroidCamera2AgentImpl extends CameraAgent {
final CaptureAvailableListener listener =
(CaptureAvailableListener) msg.obj;
- if (mLegacyDevice) {
- // Just snap the shot
+ if (mLegacyDevice ||
+ (mCurrentAeState == CaptureResult.CONTROL_AE_STATE_CONVERGED &&
+ !mPersistentSettings.matches(CaptureRequest.CONTROL_AE_MODE,
+ CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH) &&
+ !mPersistentSettings.matches(CaptureRequest.FLASH_MODE,
+ CaptureRequest.FLASH_MODE_SINGLE)))
+ {
+ // Legacy devices don't support the precapture state keys and instead
+ // perform autoexposure convergence automatically upon capture.
+
+ // On other devices, as long as it has already converged, it determined
+ // that flash was not required, and we're not going to invalidate the
+ // current exposure levels by forcing the force on, we can save
+ // significant capture time by not forcing a recalculation.
+ Log.i(TAG, "Skipping pre-capture autoexposure convergence");
mCaptureReader.setOnImageAvailableListener(listener, /*handler*/this);
try {
mSession.capture(
@@ -496,17 +531,42 @@ class AndroidCamera2AgentImpl extends CameraAgent {
mCaptureReader.getSurface()),
listener, /*handler*/this);
} catch (CameraAccessException ex) {
- Log.e(TAG, "Unable to initiate legacy capture", ex);
+ Log.e(TAG, "Unable to initiate immediate capture", ex);
}
} else {
- // Not a legacy device, so we need to let AE converge before capturing
+ // We need to let AE converge before capturing. Once our one-time
+ // trigger capture has made it into the pipeline, we'll start checking
+ // for the completion of that convergence, capturing when that happens.
+ Log.i(TAG, "Forcing pre-capture autoexposure convergence");
CameraCaptureSession.CaptureListener deferredCallbackSetter =
new CameraCaptureSession.CaptureListener() {
+ private boolean mAlreadyDispatched = false;
+
+ @Override
+ public void onCaptureProgressed(CameraCaptureSession session,
+ CaptureRequest request,
+ CaptureResult result) {
+ checkAeState(result);
+ }
+
@Override
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request,
TotalCaptureResult result) {
- mOneshotCaptureCallback = listener;
+ checkAeState(result);
+ }
+
+ private void checkAeState(CaptureResult result) {
+ if (result.get(CaptureResult.CONTROL_AE_STATE) != null &&
+ !mAlreadyDispatched) {
+ // Now our mCameraResultStateListener will invoke the
+ // callback once the autoexposure routine has converged.
+ mAlreadyDispatched = true;
+ mOneshotCaptureCallback = listener;
+ // This is an optimization: check the AE state of this frame
+ // instead of simply waiting for the next.
+ mCameraResultStateListener.monitorControlStates(result);
+ }
}
@Override
@@ -599,13 +659,13 @@ class AndroidCamera2AgentImpl extends CameraAgent {
mSession.setRepeatingRequest(
mPersistentSettings.createRequest(mCamera,
CameraDevice.TEMPLATE_PREVIEW, mPreviewSurface),
- /*listener*/mCameraFocusStateListener, /*handler*/this);
+ /*listener*/mCameraResultStateListener, /*handler*/this);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to apply updated request settings", ex);
}
} else if (mCameraState.getState() < AndroidCamera2StateHolder.CAMERA_PREVIEW_READY) {
// If we're already ready to preview, this doesn't regress our state
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
+ changeState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
}
}
@@ -659,7 +719,17 @@ class AndroidCamera2AgentImpl extends CameraAgent {
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to close existing camera capture session", ex);
}
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
+ changeState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
+ }
+
+ private void changeState(int newState) {
+ if (mCameraState.getState() != newState) {
+ mCameraState.setState(newState);
+ if (newState < AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE) {
+ mCurrentAeState = CaptureResult.CONTROL_AE_STATE_INACTIVE;
+ mCameraResultStateListener.resetState();
+ }
+ }
}
// This listener monitors our connection to and disconnection from camera devices.
@@ -680,7 +750,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
mLegacyDevice =
props.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_UNCONFIGURED);
+ changeState(AndroidCamera2StateHolder.CAMERA_UNCONFIGURED);
mOpenCallback.onCameraOpened(mCameraProxy);
} catch (CameraAccessException ex) {
mOpenCallback.onDeviceOpenFailure(mCameraIndex,
@@ -710,7 +780,7 @@ class AndroidCamera2AgentImpl extends CameraAgent {
@Override
public void onConfigured(CameraCaptureSession session) {
mSession = session;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
}
@Override
@@ -728,49 +798,73 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}
}};
+ private abstract class CameraResultStateListener
+ extends CameraCaptureSession.CaptureListener {
+ public abstract void monitorControlStates(CaptureResult result);
+
+ public abstract void resetState();
+ }
+
// This listener monitors requested captures and notifies any relevant callbacks.
- private CameraCaptureSession.CaptureListener mCameraFocusStateListener =
- new CameraCaptureSession.CaptureListener() {
+ private CameraResultStateListener mCameraResultStateListener =
+ new CameraResultStateListener() {
private int mLastAfState = -1;
+ private long mLastAfFrameNumber = -1;
+ private long mLastAeFrameNumber = -1;
+
+ @Override
+ public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
+ CaptureResult result) {
+ monitorControlStates(result);
+ }
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
+ monitorControlStates(result);
+ }
+
+ @Override
+ public void monitorControlStates(CaptureResult result) {
Integer afStateMaybe = result.get(CaptureResult.CONTROL_AF_STATE);
if (afStateMaybe != null) {
int afState = afStateMaybe;
- boolean afStateChanged = false;
- if (afState != mLastAfState) {
+ // Since we handle both partial and total results for multiple frames here, we
+ // might get the final callbacks for an earlier frame after receiving one or
+ // more that correspond to the next one. To prevent our data from oscillating,
+ // we never consider AF states that are older than the last one we've seen.
+ if (result.getFrameNumber() > mLastAfFrameNumber) {
+ boolean afStateChanged = afState != mLastAfState;
mLastAfState = afState;
- afStateChanged = true;
- }
-
- switch (afState) {
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED: {
- if (afStateChanged && mPassiveAfCallback != null) {
- // A CameraAFMoveCallback is attached. If we just started to scan,
- // the motor is moving; otherwise, it has settled.
- mPassiveAfCallback.onAutoFocusMoving(
- afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN,
- mCameraProxy);
+ mLastAfFrameNumber = result.getFrameNumber();
+
+ switch (afState) {
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED: {
+ if (afStateChanged && mPassiveAfCallback != null) {
+ // A CameraAFMoveCallback is attached. If we just started to
+ // scan, the motor is moving; otherwise, it has settled.
+ mPassiveAfCallback.onAutoFocusMoving(
+ afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN,
+ mCameraProxy);
+ }
+ break;
}
- break;
- }
- case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
- case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: {
- if (mOneshotAfCallback != null) {
- // A call to autoFocus() was just made to request a focus lock.
- // Notify the caller that the lens is now indefinitely fixed, and
- // report whether the image we're now stuck with is in focus.
- mOneshotAfCallback.onAutoFocus(
- afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED,
- mCameraProxy);
- mOneshotAfCallback = null;
+ case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
+ case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: {
+ if (mOneshotAfCallback != null) {
+ // A call to autoFocus() was just made to request a focus lock.
+ // Notify the caller that the lens is now indefinitely fixed,
+ // and report whether the image we're stuck with is in focus.
+ mOneshotAfCallback.onAutoFocus(
+ afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED,
+ mCameraProxy);
+ mOneshotAfCallback = null;
+ }
+ break;
}
- break;
}
}
}
@@ -778,36 +872,53 @@ class AndroidCamera2AgentImpl extends CameraAgent {
Integer aeStateMaybe = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeStateMaybe != null) {
int aeState = aeStateMaybe;
-
- switch (aeState) {
- case CaptureResult.CONTROL_AE_STATE_CONVERGED:
- case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
- case CaptureResult.CONTROL_AE_STATE_LOCKED: {
- if (mOneshotCaptureCallback != null) {
- // A call to takePicture() was just made, and autoexposure converged
- // so it's time to initiate the capture!
- mCaptureReader.setOnImageAvailableListener(mOneshotCaptureCallback,
- /*handler*/Camera2Handler.this);
- try {
- mSession.capture(
- mPersistentSettings.createRequest(mCamera,
- CameraDevice.TEMPLATE_STILL_CAPTURE,
- mCaptureReader.getSurface()),
+ // Since we handle both partial and total results for multiple frames here, we
+ // might get the final callbacks for an earlier frame after receiving one or
+ // more that correspond to the next one. To prevent our data from oscillating,
+ // we never consider AE states that are older than the last one we've seen.
+ if (aeState != mCurrentAeState &&
+ result.getFrameNumber() > mLastAeFrameNumber) {
+ mCurrentAeState = aeStateMaybe;
+ mLastAeFrameNumber = result.getFrameNumber();
+
+ switch (aeState) {
+ case CaptureResult.CONTROL_AE_STATE_CONVERGED:
+ case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
+ case CaptureResult.CONTROL_AE_STATE_LOCKED: {
+ if (mOneshotCaptureCallback != null) {
+ // A call to takePicture() was just made, and autoexposure
+ // converged so it's time to initiate the capture!
+ mCaptureReader.setOnImageAvailableListener(
/*listener*/mOneshotCaptureCallback,
/*handler*/Camera2Handler.this);
- } catch (CameraAccessException ex) {
- Log.e(TAG, "Unable to initiate capture", ex);
- } finally {
- mOneshotCaptureCallback = null;
+ try {
+ mSession.capture(
+ mPersistentSettings.createRequest(mCamera,
+ CameraDevice.TEMPLATE_STILL_CAPTURE,
+ mCaptureReader.getSurface()),
+ /*listener*/mOneshotCaptureCallback,
+ /*handler*/Camera2Handler.this);
+ } catch (CameraAccessException ex) {
+ Log.e(TAG, "Unable to initiate capture", ex);
+ } finally {
+ mOneshotCaptureCallback = null;
+ }
}
+ break;
}
- break;
}
}
}
}
@Override
+ public void resetState() {
+ mLastAfState = -1;
+ mLastAfFrameNumber = -1;
+ mLastAeFrameNumber = -1;
+ }
+
+ @Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
CaptureFailure failure) {
Log.e(TAG, "Capture attempt failed with reason " + failure.getReason());
diff --git a/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java b/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java
index fac8f1a..6e1d825 100644
--- a/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java
+++ b/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java
@@ -146,7 +146,7 @@ public class Camera2RequestSettingsSet {
* to its default value or simply unset. While {@link #get} will return
* {@code null} in both these cases, this method will return {@code true}
* and {@code false}, respectively.</p>
-
+ *
* @param key Which setting to look for.
* @return Whether that setting has a value that will propagate with unions.
*
@@ -160,8 +160,23 @@ public class Camera2RequestSettingsSet {
}
/**
+ * Check whether the value of the specified setting matches the given one.
+ *
+ * <p>This method uses the {@code T} type's {@code equals} method, but is
+ * {@code null}-tolerant.</p>
+ *
+ * @param key Which of this class's settings to check.
+ * @param value Value to test for equality against.
+ * @return Whether they are the same.
+ */
+ public <T> boolean matches(Key<T> key, T value) {
+ return Objects.equals(get(key), value);
+ }
+
+ /**
* Get this set of settings's revision identifier, which can be compared
* against cached past values to determine whether it has been modified.
+ *
* <p>Distinct revisions across the same object do not necessarily indicate
* that the object's key/value pairs have changed at all, but the same
* revision on the same object does imply that they've stayed the same.</p>
diff --git a/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java b/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java
index 01eda8f..7847526 100644
--- a/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java
+++ b/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import android.graphics.Rect;
import android.hardware.camera2.CameraCaptureSession.CaptureListener;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
@@ -234,6 +235,45 @@ public class Camera2UtilsTest extends Camera2DeviceTester {
setUp.get(null);
}
+ @Test
+ public void requestSettingsSetMatchesPrimitives() {
+ Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+
+ setUp.set(CaptureRequest.CONTROL_AE_LOCK, null);
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+
+ setUp.set(CaptureRequest.CONTROL_AE_LOCK, false);
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+
+ setUp.set(CaptureRequest.CONTROL_AE_LOCK, true);
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+ }
+
+ @Test
+ public void requestSettingsSetMatchesReferences() {
+ Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
+ assertTrue(setUp.matches(CaptureRequest.SCALER_CROP_REGION, null));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0)));
+
+ setUp.set(CaptureRequest.SCALER_CROP_REGION, null);
+ assertTrue(setUp.matches(CaptureRequest.SCALER_CROP_REGION, null));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0)));
+
+ setUp.set(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, null));
+ assertTrue(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0)));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 1, 1)));
+ }
+
@Test(expected=NullPointerException.class)
public void requestSettingsSetNullArgToCreateRequest0() throws Exception {
Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();