Merge topic 'camera2-remove-hidden' into lmp-dev
* changes:
Camera2: Fix session shutdown race, frequent warning log
Camera2: Remove hidden parts of public CameraDevice
Camera2: Fix null-listener capture for CameraCaptureSession
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index c461511..6a9d565 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -130,15 +130,6 @@
public abstract String getId();
/**
- * <p>Set up a new output set of Surfaces for the camera device.</p>
- *
- * @deprecated Use {@link #createCaptureSession} instead
- * @hide
- */
- @Deprecated
- public abstract void configureOutputs(List<Surface> outputs) throws CameraAccessException;
-
- /**
* <p>Create a new camera capture session by providing the target output set of Surfaces to the
* camera device.</p>
*
@@ -276,68 +267,6 @@
throws CameraAccessException;
/**
- * <p>Submit a request for an image to be captured by this CameraDevice.</p>
- *
- * @deprecated Use {@link CameraCaptureSession#capture} instead
- * @hide
- */
- @Deprecated
- public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler)
- throws CameraAccessException;
-
- /**
- * Submit a list of requests to be captured in sequence as a burst.
- *
- * @deprecated Use {@link CameraCaptureSession#captureBurst} instead
- * @hide
- */
- @Deprecated
- public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
- Handler handler) throws CameraAccessException;
-
- /**
- * Request endlessly repeating capture of images by this CameraDevice.
- *
- * @deprecated Use {@link CameraCaptureSession#setRepeatingRequest} instead
- * @hide
- */
- @Deprecated
- public abstract int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
- Handler handler) throws CameraAccessException;
-
- /**
- * <p>Request endlessly repeating capture of a sequence of images by this
- * CameraDevice.</p>
- *
- * @deprecated Use {@link CameraCaptureSession#setRepeatingBurst} instead
- * @hide
- */
- @Deprecated
- public abstract int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
- Handler handler) throws CameraAccessException;
-
- /**
- * <p>Cancel any ongoing repeating capture set by either
- * {@link #setRepeatingRequest setRepeatingRequest} or
- * {@link #setRepeatingBurst}.
- *
- * @deprecated Use {@link CameraCaptureSession#stopRepeating} instead
- * @hide
- */
- @Deprecated
- public abstract void stopRepeating() throws CameraAccessException;
-
- /**
- * Flush all captures currently pending and in-progress as fast as
- * possible.
- *
- * @deprecated Use {@link CameraCaptureSession#abortCaptures} instead
- * @hide
- */
- @Deprecated
- public abstract void flush() throws CameraAccessException;
-
- /**
* Close the connection to this camera device as quickly as possible.
*
* <p>Immediately after this call, all calls to the camera device or active session interface
@@ -356,96 +285,6 @@
public abstract void close();
/**
- * <p>A listener for tracking the progress of a {@link CaptureRequest}
- * submitted to the camera device.</p>
- *
- * @deprecated Use {@link CameraCaptureSession.CaptureListener} instead
- * @hide
- */
- @Deprecated
- public static abstract class CaptureListener {
-
- /**
- * This constant is used to indicate that no images were captured for
- * the request.
- *
- * @hide
- */
- public static final int NO_FRAMES_CAPTURED = -1;
-
- /**
- * This method is called when the camera device has started capturing
- * the output image for the request, at the beginning of image exposure.
- *
- * @see android.media.MediaActionSound
- */
- public void onCaptureStarted(CameraDevice camera,
- CaptureRequest request, long timestamp) {
- // default empty implementation
- }
-
- /**
- * This method is called when some results from an image capture are
- * available.
- *
- * @hide
- */
- public void onCapturePartial(CameraDevice camera,
- CaptureRequest request, CaptureResult result) {
- // default empty implementation
- }
-
- /**
- * This method is called when an image capture makes partial forward progress; some
- * (but not all) results from an image capture are available.
- *
- */
- public void onCaptureProgressed(CameraDevice camera,
- CaptureRequest request, CaptureResult partialResult) {
- // default empty implementation
- }
-
- /**
- * This method is called when an image capture has fully completed and all the
- * result metadata is available.
- */
- public void onCaptureCompleted(CameraDevice camera,
- CaptureRequest request, TotalCaptureResult result) {
- // default empty implementation
- }
-
- /**
- * This method is called instead of {@link #onCaptureCompleted} when the
- * camera device failed to produce a {@link CaptureResult} for the
- * request.
- */
- public void onCaptureFailed(CameraDevice camera,
- CaptureRequest request, CaptureFailure failure) {
- // default empty implementation
- }
-
- /**
- * This method is called independently of the others in CaptureListener,
- * when a capture sequence finishes and all {@link CaptureResult}
- * or {@link CaptureFailure} for it have been returned via this listener.
- */
- public void onCaptureSequenceCompleted(CameraDevice camera,
- int sequenceId, long frameNumber) {
- // default empty implementation
- }
-
- /**
- * This method is called independently of the others in CaptureListener,
- * when a capture sequence aborts before any {@link CaptureResult}
- * or {@link CaptureFailure} for it have been returned via this listener.
- */
- public void onCaptureSequenceAborted(CameraDevice camera,
- int sequenceId) {
- // default empty implementation
- }
- }
-
- /**
* A listener for notifications about the state of a camera
* device.
*
@@ -542,40 +381,6 @@
public abstract void onOpened(CameraDevice camera); // Must implement
/**
- * The method called when a camera device has no outputs configured.
- *
- * @deprecated Use {@link #onOpened} instead.
- * @hide
- */
- @Deprecated
- public void onUnconfigured(CameraDevice camera) {
- // Default empty implementation
- }
-
- /**
- * The method called when a camera device begins processing
- * {@link CaptureRequest capture requests}.
- *
- * @deprecated Use {@link CameraCaptureSession.StateListener#onActive} instead.
- * @hide
- */
- @Deprecated
- public void onActive(CameraDevice camera) {
- // Default empty implementation
- }
-
- /**
- * The method called when a camera device is busy.
- *
- * @deprecated Use {@link CameraCaptureSession.StateListener#onConfigured} instead.
- * @hide
- */
- @Deprecated
- public void onBusy(CameraDevice camera) {
- // Default empty implementation
- }
-
- /**
* The method called when a camera device has been closed with
* {@link CameraDevice#close}.
*
@@ -591,18 +396,6 @@
}
/**
- * The method called when a camera device has finished processing all
- * submitted capture requests and has reached an idle state.
- *
- * @deprecated Use {@link CameraCaptureSession.StateListener#onReady} instead.
- * @hide
- */
- @Deprecated
- public void onIdle(CameraDevice camera) {
- // Default empty implementation
- }
-
- /**
* The method called when a camera device is no longer available for
* use.
*
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index f829f5e..a15028c 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -103,7 +103,7 @@
* Use the same handler as the device's StateListener for all the internal coming events
*
* This ensures total ordering between CameraDevice.StateListener and
- * CameraDevice.CaptureListener events.
+ * CameraDeviceImpl.CaptureListener events.
*/
mSequenceDrainer = new TaskDrainer<>(mDeviceHandler, new SequenceDrainListener(),
/*name*/"seq");
@@ -141,7 +141,7 @@
checkNotClosed();
checkLegalToCapture();
- handler = checkHandler(handler);
+ handler = checkHandler(handler, listener);
if (VERBOSE) {
Log.v(TAG, "capture - request " + request + ", listener " + listener + " handler" +
@@ -164,7 +164,7 @@
checkNotClosed();
checkLegalToCapture();
- handler = checkHandler(handler);
+ handler = checkHandler(handler, listener);
if (VERBOSE) {
CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
@@ -186,7 +186,7 @@
checkNotClosed();
checkLegalToCapture();
- handler = checkHandler(handler);
+ handler = checkHandler(handler, listener);
if (VERBOSE) {
Log.v(TAG, "setRepeatingRequest - request " + request + ", listener " + listener +
@@ -209,7 +209,7 @@
checkNotClosed();
checkLegalToCapture();
- handler = checkHandler(handler);
+ handler = checkHandler(handler, listener);
if (VERBOSE) {
CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
@@ -261,9 +261,12 @@
* <p>The semantics are identical to {@link #close}, except that unconfiguring will be skipped.
* <p>
*
+ * <p>After this call completes, the session will not call any further methods on the camera
+ * device.</p>
+ *
* @see CameraCaptureSession#close
*/
- synchronized void replaceSessionClose(CameraCaptureSession other) {
+ synchronized void replaceSessionClose() {
/*
* In order for creating new sessions to be fast, the new session should be created
* before the old session is closed.
@@ -278,13 +281,17 @@
if (VERBOSE) Log.v(TAG, "replaceSessionClose");
- // #close was already called explicitly, keep going the slow route
- if (mClosed) {
- if (VERBOSE) Log.v(TAG, "replaceSessionClose - close was already called");
- return;
- }
-
+ // Set up fast shutdown. Possible alternative paths:
+ // - This session is active, so close() below starts the shutdown drain
+ // - This session is mid-shutdown drain, and hasn't yet reached the idle drain listener.
+ // - This session is already closed and has executed the idle drain listener, and
+ // configureOutputs(null) has already been called.
+ //
+ // Do not call configureOutputs(null) going forward, since it would race with the
+ // configuration for the new session. If it was already called, then we don't care, since it
+ // won't get called again.
mSkipUnconfigure = true;
+
close();
}
@@ -347,7 +354,7 @@
/**
* Forward callbacks from
- * CameraDevice.CaptureListener to the CameraCaptureSession.CaptureListener.
+ * CameraDeviceImpl.CaptureListener to the CameraCaptureSession.CaptureListener.
*
* <p>In particular, all calls are automatically split to go both to our own
* internal listener, and to the user-specified listener (by transparently posting
@@ -356,9 +363,9 @@
* <p>When a capture sequence finishes, update the pending checked sequences set.</p>
*/
@SuppressWarnings("deprecation")
- private CameraDevice.CaptureListener createCaptureListenerProxy(
+ private CameraDeviceImpl.CaptureListener createCaptureListenerProxy(
Handler handler, CaptureListener listener) {
- CameraDevice.CaptureListener localListener = new CameraDevice.CaptureListener() {
+ CameraDeviceImpl.CaptureListener localListener = new CameraDeviceImpl.CaptureListener() {
@Override
public void onCaptureSequenceCompleted(CameraDevice camera,
int sequenceId, long frameNumber) {
@@ -379,27 +386,30 @@
* - 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 =
+ InvokeDispatcher<CameraDeviceImpl.CaptureListener> localSink =
new InvokeDispatcher<>(localListener);
+
+ InvokeDispatcher<CaptureListener> userListenerSink =
+ new InvokeDispatcher<>(listener);
HandlerDispatcher<CaptureListener> handlerPassthrough =
new HandlerDispatcher<>(userListenerSink, handler);
- DuckTypingDispatcher<CameraDevice.CaptureListener, CaptureListener> duckToSession
+ DuckTypingDispatcher<CameraDeviceImpl.CaptureListener, CaptureListener> duckToSession
= new DuckTypingDispatcher<>(handlerPassthrough, CaptureListener.class);
- ArgumentReplacingDispatcher<CameraDevice.CaptureListener, CameraCaptureSessionImpl>
- replaceDeviceWithSession = new ArgumentReplacingDispatcher<>(duckToSession,
- /*argumentIndex*/0, this);
+ ArgumentReplacingDispatcher<CameraDeviceImpl.CaptureListener, CameraCaptureSessionImpl>
+ replaceDeviceWithSession = new ArgumentReplacingDispatcher<>(duckToSession,
+ /*argumentIndex*/0, this);
- BroadcastDispatcher<CameraDevice.CaptureListener> broadcaster =
- new BroadcastDispatcher<CameraDevice.CaptureListener>(
- replaceDeviceWithSession,
- localSink);
+ BroadcastDispatcher<CameraDeviceImpl.CaptureListener> broadcaster =
+ new BroadcastDispatcher<CameraDeviceImpl.CaptureListener>(
+ replaceDeviceWithSession,
+ localSink);
return new ListenerProxies.DeviceCaptureListenerProxy(broadcaster);
}
@@ -415,10 +425,10 @@
* </ul>
* </p>
* */
- CameraDevice.StateListener getDeviceStateListener() {
+ CameraDeviceImpl.StateListenerKK getDeviceStateListener() {
final CameraCaptureSession session = this;
- return new CameraDevice.StateListener() {
+ return new CameraDeviceImpl.StateListenerKK() {
private boolean mBusy = false;
private boolean mActive = false;
@@ -596,6 +606,8 @@
*
* This operation is idempotent; a session will not be closed twice.
*/
+ if (VERBOSE) Log.v(TAG, "Session drain complete, skip unconfigure: " +
+ mSkipUnconfigure);
// Fast path: A new capture session has replaced this one; don't unconfigure.
if (mSkipUnconfigure) {
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 18b1202..71eb0e9 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -21,8 +21,10 @@
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.TotalCaptureResult;
@@ -47,7 +49,7 @@
/**
* HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate
*/
-public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
+public class CameraDeviceImpl extends CameraDevice {
private final String TAG;
private final boolean DEBUG;
@@ -62,7 +64,7 @@
private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
private final StateListener mDeviceListener;
- private volatile StateListener mSessionStateListener;
+ private volatile StateListenerKK mSessionStateListener;
private final Handler mDeviceHandler;
private volatile boolean mClosing = false;
@@ -103,7 +105,7 @@
private final Runnable mCallOnOpened = new Runnable() {
@Override
public void run() {
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
@@ -119,7 +121,7 @@
private final Runnable mCallOnUnconfigured = new Runnable() {
@Override
public void run() {
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
@@ -128,14 +130,13 @@
if (sessionListener != null) {
sessionListener.onUnconfigured(CameraDeviceImpl.this);
}
- mDeviceListener.onUnconfigured(CameraDeviceImpl.this);
}
};
private final Runnable mCallOnActive = new Runnable() {
@Override
public void run() {
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
@@ -144,14 +145,13 @@
if (sessionListener != null) {
sessionListener.onActive(CameraDeviceImpl.this);
}
- mDeviceListener.onActive(CameraDeviceImpl.this);
}
};
private final Runnable mCallOnBusy = new Runnable() {
@Override
public void run() {
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
@@ -160,7 +160,6 @@
if (sessionListener != null) {
sessionListener.onBusy(CameraDeviceImpl.this);
}
- mDeviceListener.onBusy(CameraDeviceImpl.this);
}
};
@@ -172,7 +171,7 @@
if (mClosedOnce) {
throw new AssertionError("Don't post #onClosed more than once");
}
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
sessionListener = mSessionStateListener;
}
@@ -187,7 +186,7 @@
private final Runnable mCallOnIdle = new Runnable() {
@Override
public void run() {
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
@@ -196,14 +195,13 @@
if (sessionListener != null) {
sessionListener.onIdle(CameraDeviceImpl.this);
}
- mDeviceListener.onIdle(CameraDeviceImpl.this);
}
};
private final Runnable mCallOnDisconnected = new Runnable() {
@Override
public void run() {
- StateListener sessionListener = null;
+ StateListenerKK sessionListener = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
@@ -313,7 +311,6 @@
return mCameraId;
}
- @Override
public void configureOutputs(List<Surface> outputs) throws CameraAccessException {
// Treat a null input the same an empty list
if (outputs == null) {
@@ -390,7 +387,11 @@
checkIfCameraClosedOrInError();
- // TODO: we must be in UNCONFIGURED mode to begin with, or using another session
+ // Notify current session that it's going away, before starting camera operations
+ // After this call completes, the session is not allowed to call into CameraDeviceImpl
+ if (mCurrentSession != null) {
+ mCurrentSession.replaceSessionClose();
+ }
// TODO: dont block for this
boolean configureSuccess = true;
@@ -410,10 +411,6 @@
new CameraCaptureSessionImpl(outputs, listener, handler, this, mDeviceHandler,
configureSuccess);
- if (mCurrentSession != null) {
- mCurrentSession.replaceSessionClose(newSession);
- }
-
// TODO: wait until current session closes, then create the new session
mCurrentSession = newSession;
@@ -425,6 +422,15 @@
}
}
+ /**
+ * For use by backwards-compatibility code only.
+ */
+ public void setSessionListener(StateListenerKK sessionListener) {
+ synchronized(mInterfaceLock) {
+ mSessionStateListener = sessionListener;
+ }
+ }
+
@Override
public CaptureRequest.Builder createCaptureRequest(int templateType)
throws CameraAccessException {
@@ -449,7 +455,6 @@
}
}
- @Override
public int capture(CaptureRequest request, CaptureListener listener, Handler handler)
throws CameraAccessException {
if (DEBUG) {
@@ -460,7 +465,6 @@
return submitCaptureRequest(requestList, listener, handler, /*streaming*/false);
}
- @Override
public int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
Handler handler) throws CameraAccessException {
if (requests == null || requests.isEmpty()) {
@@ -543,9 +547,7 @@
// 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) {
@@ -613,7 +615,6 @@
}
}
- @Override
public int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
Handler handler) throws CameraAccessException {
List<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
@@ -621,7 +622,6 @@
return submitCaptureRequest(requestList, listener, handler, /*streaming*/true);
}
- @Override
public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
Handler handler) throws CameraAccessException {
if (requests == null || requests.isEmpty()) {
@@ -630,7 +630,6 @@
return submitCaptureRequest(requests, listener, handler, /*streaming*/true);
}
- @Override
public void stopRepeating() throws CameraAccessException {
synchronized(mInterfaceLock) {
@@ -681,7 +680,6 @@
}
}
- @Override
public void flush() throws CameraAccessException {
synchronized(mInterfaceLock) {
checkIfCameraClosedOrInError();
@@ -739,6 +737,133 @@
}
}
+ /**
+ * <p>A listener for tracking the progress of a {@link CaptureRequest}
+ * submitted to the camera device.</p>
+ *
+ */
+ public static abstract class CaptureListener {
+
+ /**
+ * This constant is used to indicate that no images were captured for
+ * the request.
+ *
+ * @hide
+ */
+ public static final int NO_FRAMES_CAPTURED = -1;
+
+ /**
+ * This method is called when the camera device has started capturing
+ * the output image for the request, at the beginning of image exposure.
+ *
+ * @see android.media.MediaActionSound
+ */
+ public void onCaptureStarted(CameraDevice camera,
+ CaptureRequest request, long timestamp) {
+ // default empty implementation
+ }
+
+ /**
+ * This method is called when some results from an image capture are
+ * available.
+ *
+ * @hide
+ */
+ public void onCapturePartial(CameraDevice camera,
+ CaptureRequest request, CaptureResult result) {
+ // default empty implementation
+ }
+
+ /**
+ * This method is called when an image capture makes partial forward progress; some
+ * (but not all) results from an image capture are available.
+ *
+ */
+ public void onCaptureProgressed(CameraDevice camera,
+ CaptureRequest request, CaptureResult partialResult) {
+ // default empty implementation
+ }
+
+ /**
+ * This method is called when an image capture has fully completed and all the
+ * result metadata is available.
+ */
+ public void onCaptureCompleted(CameraDevice camera,
+ CaptureRequest request, TotalCaptureResult result) {
+ // default empty implementation
+ }
+
+ /**
+ * This method is called instead of {@link #onCaptureCompleted} when the
+ * camera device failed to produce a {@link CaptureResult} for the
+ * request.
+ */
+ public void onCaptureFailed(CameraDevice camera,
+ CaptureRequest request, CaptureFailure failure) {
+ // default empty implementation
+ }
+
+ /**
+ * This method is called independently of the others in CaptureListener,
+ * when a capture sequence finishes and all {@link CaptureResult}
+ * or {@link CaptureFailure} for it have been returned via this listener.
+ */
+ public void onCaptureSequenceCompleted(CameraDevice camera,
+ int sequenceId, long frameNumber) {
+ // default empty implementation
+ }
+
+ /**
+ * This method is called independently of the others in CaptureListener,
+ * when a capture sequence aborts before any {@link CaptureResult}
+ * or {@link CaptureFailure} for it have been returned via this listener.
+ */
+ public void onCaptureSequenceAborted(CameraDevice camera,
+ int sequenceId) {
+ // default empty implementation
+ }
+ }
+
+ /**
+ * A listener for notifications about the state of a camera device, adding in the callbacks that
+ * were part of the earlier KK API design, but now only used internally.
+ */
+ public static abstract class StateListenerKK extends StateListener {
+ /**
+ * The method called when a camera device has no outputs configured.
+ *
+ */
+ public void onUnconfigured(CameraDevice camera) {
+ // Default empty implementation
+ }
+
+ /**
+ * The method called when a camera device begins processing
+ * {@link CaptureRequest capture requests}.
+ *
+ */
+ public void onActive(CameraDevice camera) {
+ // Default empty implementation
+ }
+
+ /**
+ * The method called when a camera device is busy.
+ *
+ */
+ public void onBusy(CameraDevice camera) {
+ // Default empty implementation
+ }
+
+ /**
+ * The method called when a camera device has finished processing all
+ * submitted capture requests and has reached an idle state.
+ *
+ */
+ public void onIdle(CameraDevice camera) {
+ // Default empty implementation
+ }
+ }
+
static class CaptureListenerHolder {
private final boolean mRepeating;
@@ -1155,6 +1280,18 @@
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,
diff --git a/core/java/android/hardware/camera2/impl/ListenerProxies.java b/core/java/android/hardware/camera2/impl/ListenerProxies.java
index ab9a4d5..f44f9ad 100644
--- a/core/java/android/hardware/camera2/impl/ListenerProxies.java
+++ b/core/java/android/hardware/camera2/impl/ListenerProxies.java
@@ -36,13 +36,13 @@
// TODO: replace with codegen
- public static class DeviceStateListenerProxy extends CameraDevice.StateListener {
- private final MethodNameInvoker<CameraDevice.StateListener> mProxy;
+ public static class DeviceStateListenerProxy extends CameraDeviceImpl.StateListenerKK {
+ private final MethodNameInvoker<CameraDeviceImpl.StateListenerKK> mProxy;
public DeviceStateListenerProxy(
- Dispatchable<CameraDevice.StateListener> dispatchTarget) {
+ Dispatchable<CameraDeviceImpl.StateListenerKK> dispatchTarget) {
dispatchTarget = checkNotNull(dispatchTarget, "dispatchTarget must not be null");
- mProxy = new MethodNameInvoker<>(dispatchTarget, CameraDevice.StateListener.class);
+ mProxy = new MethodNameInvoker<>(dispatchTarget, CameraDeviceImpl.StateListenerKK.class);
}
@Override
@@ -87,13 +87,13 @@
}
@SuppressWarnings("deprecation")
- public static class DeviceCaptureListenerProxy extends CameraDevice.CaptureListener {
- private final MethodNameInvoker<CameraDevice.CaptureListener> mProxy;
+ public static class DeviceCaptureListenerProxy extends CameraDeviceImpl.CaptureListener {
+ private final MethodNameInvoker<CameraDeviceImpl.CaptureListener> mProxy;
public DeviceCaptureListenerProxy(
- Dispatchable<CameraDevice.CaptureListener> dispatchTarget) {
+ Dispatchable<CameraDeviceImpl.CaptureListener> dispatchTarget) {
dispatchTarget = checkNotNull(dispatchTarget, "dispatchTarget must not be null");
- mProxy = new MethodNameInvoker<>(dispatchTarget, CameraDevice.CaptureListener.class);
+ mProxy = new MethodNameInvoker<>(dispatchTarget, CameraDeviceImpl.CaptureListener.class);
}
@Override
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 1efabb1..2e6b9ae 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -813,6 +813,7 @@
switch (format) {
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_BLOB:
+ case HAL_PIXEL_FORMAT_RAW_OPAQUE:
return format;
case ImageFormat.JPEG:
throw new IllegalArgumentException(
@@ -843,12 +844,6 @@
* @throws IllegalArgumentException if the format was not user-defined
*/
static int checkArgumentFormat(int format) {
- // TODO: remove this hack , CTS shouldn't have been using internal constants
- if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
- Log.w(TAG, "RAW_OPAQUE is not yet a published format; allowing it anyway");
- return format;
- }
-
if (!ImageFormat.isPublicFormat(format) && !PixelFormat.isPublicFormat(format)) {
throw new IllegalArgumentException(String.format(
"format 0x%x was not defined in either ImageFormat or PixelFormat", format));