Loading core/java/android/hardware/camera2/legacy/CameraDeviceState.java +21 −21 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package android.hardware.camera2.legacy; import android.hardware.camera2.impl.CameraDeviceImpl; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.utils.CameraBinderDecorator; import android.os.Handler; import android.util.Log; Loading Loading @@ -53,7 +53,7 @@ public class CameraDeviceState { "CAPTURING"}; private int mCurrentState = STATE_UNCONFIGURED; private int mCurrentError = CameraBinderDecorator.NO_ERROR; private int mCurrentError = NO_CAPTURE_ERROR; private RequestHolder mCurrentRequest = null; Loading Loading @@ -87,7 +87,7 @@ public class CameraDeviceState { * </p> * * @param error the error to set. Should be one of the error codes defined in * {@link android.hardware.camera2.utils.CameraBinderDecorator}. * {@link CameraDeviceImpl.CameraDeviceCallbacks}. */ public synchronized void setError(int error) { mCurrentError = error; Loading @@ -102,11 +102,11 @@ public class CameraDeviceState { * {@link CameraDeviceStateListener#onConfiguring()} will be called. * </p> * * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setConfiguring() { public synchronized boolean setConfiguring() { doStateTransition(STATE_CONFIGURING); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -117,11 +117,11 @@ public class CameraDeviceState { * {@link CameraDeviceStateListener#onIdle()} will be called. * </p> * * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setIdle() { public synchronized boolean setIdle() { doStateTransition(STATE_IDLE); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -137,13 +137,13 @@ public class CameraDeviceState { * @param captureError Report a recoverable error for a single request using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR} * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setCaptureStart(final RequestHolder request, long timestamp, public synchronized boolean setCaptureStart(final RequestHolder request, long timestamp, int captureError) { mCurrentRequest = request; doStateTransition(STATE_CAPTURING, timestamp, captureError); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -161,16 +161,16 @@ public class CameraDeviceState { * @param captureError Report a recoverable error for a single buffer or result using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR}. * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setCaptureResult(final RequestHolder request, public synchronized boolean setCaptureResult(final RequestHolder request, final CameraMetadataNative result, final int captureError) { if (mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot receive result while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } if (mCurrentHandler != null && mCurrentListener != null) { Loading @@ -190,7 +190,7 @@ public class CameraDeviceState { }); } } return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -206,7 +206,7 @@ public class CameraDeviceState { } private void doStateTransition(int newState) { doStateTransition(newState, /*timestamp*/0, CameraBinderDecorator.NO_ERROR); doStateTransition(newState, /*timestamp*/0, NO_CAPTURE_ERROR); } private void doStateTransition(int newState, final long timestamp, final int error) { Loading @@ -233,7 +233,7 @@ public class CameraDeviceState { case STATE_CONFIGURING: if (mCurrentState != STATE_UNCONFIGURED && mCurrentState != STATE_IDLE) { Log.e(TAG, "Cannot call configure while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); break; } Loading @@ -255,7 +255,7 @@ public class CameraDeviceState { if (mCurrentState != STATE_CONFIGURING && mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot call idle while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); break; } Loading @@ -274,7 +274,7 @@ public class CameraDeviceState { case STATE_CAPTURING: if (mCurrentState != STATE_IDLE && mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot call capture while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); break; } Loading core/java/android/hardware/camera2/legacy/GLThreadManager.java +46 −36 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.hardware.camera2.legacy; import android.graphics.SurfaceTexture; import android.hardware.camera2.impl.CameraDeviceImpl; import android.os.ConditionVariable; import android.os.Handler; import android.os.Message; Loading @@ -42,6 +43,8 @@ public class GLThreadManager { private CaptureCollector mCaptureCollector; private final CameraDeviceState mDeviceState; private final SurfaceTextureRenderer mTextureRenderer; private final RequestHandlerThread mGLHandlerThread; Loading Loading @@ -76,6 +79,7 @@ public class GLThreadManager { if (mCleanup) { return true; } try { switch (msg.what) { case MSG_NEW_CONFIGURATION: ConfigureHolder configure = (ConfigureHolder) msg.obj; Loading Loading @@ -113,6 +117,10 @@ public class GLThreadManager { Log.e(TAG, "Unhandled message " + msg.what + " on GLThread."); break; } } catch (Exception e) { Log.e(TAG, "Received exception on GL render thread: ", e); mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); } return true; } }; Loading @@ -122,11 +130,13 @@ public class GLThreadManager { * * @param cameraId the camera id for this thread. * @param facing direction the camera is facing. * @param state {@link CameraDeviceState} to use for error handling. */ public GLThreadManager(int cameraId, int facing) { public GLThreadManager(int cameraId, int facing, CameraDeviceState state) { mTextureRenderer = new SurfaceTextureRenderer(facing); TAG = String.format("CameraDeviceGLThread-%d", cameraId); mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb); mDeviceState = state; } /** Loading core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +8 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.hardware.camera2.ICameraDeviceCallbacks; import android.hardware.camera2.params.StreamConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.ArrayUtils; import android.hardware.camera2.utils.CameraBinderDecorator; import android.hardware.camera2.utils.LongParcelable; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.utils.CameraRuntimeException; Loading Loading @@ -288,17 +289,18 @@ public class LegacyCameraDevice implements AutoCloseable { } } int error = mDeviceState.setConfiguring(); if (error == NO_ERROR) { boolean success = false; if (mDeviceState.setConfiguring()) { mRequestThreadManager.configure(outputs); error = mDeviceState.setIdle(); success = mDeviceState.setIdle(); } if (error == NO_ERROR) { if (success) { mConfiguredSurfaces = outputs != null ? new ArrayList<>(outputs) : null; } else { return CameraBinderDecorator.INVALID_OPERATION; } return error; return CameraBinderDecorator.NO_ERROR; } /** Loading core/java/android/hardware/camera2/legacy/RequestThreadManager.java +30 −6 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class RequestThreadManager { private SurfaceTexture mDummyTexture; private Surface mDummySurface; private final Object mIdleLock = new Object(); private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview"); private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests"); Loading Loading @@ -173,6 +174,14 @@ public class RequestThreadManager { } } private final Camera.ErrorCallback mErrorCallback = new Camera.ErrorCallback() { @Override public void onError(int i, Camera camera) { Log.e(TAG, "Received error " + i + " from the Camera1 ErrorCallback"); mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); } }; private final ConditionVariable mReceivedJpeg = new ConditionVariable(false); private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() { Loading Loading @@ -405,7 +414,7 @@ public class RequestThreadManager { // TODO: Detect and optimize single-output paths here to skip stream teeing. if (mGLThreadManager == null) { mGLThreadManager = new GLThreadManager(mCameraId, facing); mGLThreadManager = new GLThreadManager(mCameraId, facing, mDeviceState); mGLThreadManager.start(); } mGLThreadManager.waitUntilStarted(); Loading Loading @@ -617,9 +626,20 @@ public class RequestThreadManager { CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); break; } synchronized (mIdleLock) { // Retry the the request queue. nextBurst = mRequestQueue.getNext(); // If we still have no queued requests, go idle. if (nextBurst == null) { mDeviceState.setIdle(); break; } else { } } } if (nextBurst != null) { // Queue another capture if we did not get the last burst. handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST); } Loading Loading @@ -831,6 +851,7 @@ public class RequestThreadManager { mFaceDetectMapper = new LegacyFaceDetectMapper(mCamera, mCharacteristics); mCaptureCollector = new CaptureCollector(MAX_IN_FLIGHT_REQUESTS, mDeviceState); mRequestThread = new RequestHandlerThread(name, mRequestHandlerCb); mCamera.setErrorCallback(mErrorCallback); } /** Loading Loading @@ -883,8 +904,11 @@ public class RequestThreadManager { public int submitCaptureRequests(List<CaptureRequest> requests, boolean repeating, /*out*/LongParcelable frameNumber) { Handler handler = mRequestThread.waitAndGetHandler(); int ret = mRequestQueue.submit(requests, repeating, frameNumber); int ret; synchronized (mIdleLock) { ret = mRequestQueue.submit(requests, repeating, frameNumber); handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST); } return ret; } Loading Loading
core/java/android/hardware/camera2/legacy/CameraDeviceState.java +21 −21 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package android.hardware.camera2.legacy; import android.hardware.camera2.impl.CameraDeviceImpl; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.utils.CameraBinderDecorator; import android.os.Handler; import android.util.Log; Loading Loading @@ -53,7 +53,7 @@ public class CameraDeviceState { "CAPTURING"}; private int mCurrentState = STATE_UNCONFIGURED; private int mCurrentError = CameraBinderDecorator.NO_ERROR; private int mCurrentError = NO_CAPTURE_ERROR; private RequestHolder mCurrentRequest = null; Loading Loading @@ -87,7 +87,7 @@ public class CameraDeviceState { * </p> * * @param error the error to set. Should be one of the error codes defined in * {@link android.hardware.camera2.utils.CameraBinderDecorator}. * {@link CameraDeviceImpl.CameraDeviceCallbacks}. */ public synchronized void setError(int error) { mCurrentError = error; Loading @@ -102,11 +102,11 @@ public class CameraDeviceState { * {@link CameraDeviceStateListener#onConfiguring()} will be called. * </p> * * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setConfiguring() { public synchronized boolean setConfiguring() { doStateTransition(STATE_CONFIGURING); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -117,11 +117,11 @@ public class CameraDeviceState { * {@link CameraDeviceStateListener#onIdle()} will be called. * </p> * * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setIdle() { public synchronized boolean setIdle() { doStateTransition(STATE_IDLE); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -137,13 +137,13 @@ public class CameraDeviceState { * @param captureError Report a recoverable error for a single request using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR} * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setCaptureStart(final RequestHolder request, long timestamp, public synchronized boolean setCaptureStart(final RequestHolder request, long timestamp, int captureError) { mCurrentRequest = request; doStateTransition(STATE_CAPTURING, timestamp, captureError); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -161,16 +161,16 @@ public class CameraDeviceState { * @param captureError Report a recoverable error for a single buffer or result using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR}. * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. * @return {@code false} if an error has occurred. */ public synchronized int setCaptureResult(final RequestHolder request, public synchronized boolean setCaptureResult(final RequestHolder request, final CameraMetadataNative result, final int captureError) { if (mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot receive result while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } if (mCurrentHandler != null && mCurrentListener != null) { Loading @@ -190,7 +190,7 @@ public class CameraDeviceState { }); } } return mCurrentError; return mCurrentError == NO_CAPTURE_ERROR; } /** Loading @@ -206,7 +206,7 @@ public class CameraDeviceState { } private void doStateTransition(int newState) { doStateTransition(newState, /*timestamp*/0, CameraBinderDecorator.NO_ERROR); doStateTransition(newState, /*timestamp*/0, NO_CAPTURE_ERROR); } private void doStateTransition(int newState, final long timestamp, final int error) { Loading @@ -233,7 +233,7 @@ public class CameraDeviceState { case STATE_CONFIGURING: if (mCurrentState != STATE_UNCONFIGURED && mCurrentState != STATE_IDLE) { Log.e(TAG, "Cannot call configure while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); break; } Loading @@ -255,7 +255,7 @@ public class CameraDeviceState { if (mCurrentState != STATE_CONFIGURING && mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot call idle while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); break; } Loading @@ -274,7 +274,7 @@ public class CameraDeviceState { case STATE_CAPTURING: if (mCurrentState != STATE_IDLE && mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot call capture while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; doStateTransition(STATE_ERROR); break; } Loading
core/java/android/hardware/camera2/legacy/GLThreadManager.java +46 −36 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.hardware.camera2.legacy; import android.graphics.SurfaceTexture; import android.hardware.camera2.impl.CameraDeviceImpl; import android.os.ConditionVariable; import android.os.Handler; import android.os.Message; Loading @@ -42,6 +43,8 @@ public class GLThreadManager { private CaptureCollector mCaptureCollector; private final CameraDeviceState mDeviceState; private final SurfaceTextureRenderer mTextureRenderer; private final RequestHandlerThread mGLHandlerThread; Loading Loading @@ -76,6 +79,7 @@ public class GLThreadManager { if (mCleanup) { return true; } try { switch (msg.what) { case MSG_NEW_CONFIGURATION: ConfigureHolder configure = (ConfigureHolder) msg.obj; Loading Loading @@ -113,6 +117,10 @@ public class GLThreadManager { Log.e(TAG, "Unhandled message " + msg.what + " on GLThread."); break; } } catch (Exception e) { Log.e(TAG, "Received exception on GL render thread: ", e); mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); } return true; } }; Loading @@ -122,11 +130,13 @@ public class GLThreadManager { * * @param cameraId the camera id for this thread. * @param facing direction the camera is facing. * @param state {@link CameraDeviceState} to use for error handling. */ public GLThreadManager(int cameraId, int facing) { public GLThreadManager(int cameraId, int facing, CameraDeviceState state) { mTextureRenderer = new SurfaceTextureRenderer(facing); TAG = String.format("CameraDeviceGLThread-%d", cameraId); mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb); mDeviceState = state; } /** Loading
core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +8 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.hardware.camera2.ICameraDeviceCallbacks; import android.hardware.camera2.params.StreamConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.ArrayUtils; import android.hardware.camera2.utils.CameraBinderDecorator; import android.hardware.camera2.utils.LongParcelable; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.utils.CameraRuntimeException; Loading Loading @@ -288,17 +289,18 @@ public class LegacyCameraDevice implements AutoCloseable { } } int error = mDeviceState.setConfiguring(); if (error == NO_ERROR) { boolean success = false; if (mDeviceState.setConfiguring()) { mRequestThreadManager.configure(outputs); error = mDeviceState.setIdle(); success = mDeviceState.setIdle(); } if (error == NO_ERROR) { if (success) { mConfiguredSurfaces = outputs != null ? new ArrayList<>(outputs) : null; } else { return CameraBinderDecorator.INVALID_OPERATION; } return error; return CameraBinderDecorator.NO_ERROR; } /** Loading
core/java/android/hardware/camera2/legacy/RequestThreadManager.java +30 −6 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class RequestThreadManager { private SurfaceTexture mDummyTexture; private Surface mDummySurface; private final Object mIdleLock = new Object(); private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview"); private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests"); Loading Loading @@ -173,6 +174,14 @@ public class RequestThreadManager { } } private final Camera.ErrorCallback mErrorCallback = new Camera.ErrorCallback() { @Override public void onError(int i, Camera camera) { Log.e(TAG, "Received error " + i + " from the Camera1 ErrorCallback"); mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); } }; private final ConditionVariable mReceivedJpeg = new ConditionVariable(false); private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() { Loading Loading @@ -405,7 +414,7 @@ public class RequestThreadManager { // TODO: Detect and optimize single-output paths here to skip stream teeing. if (mGLThreadManager == null) { mGLThreadManager = new GLThreadManager(mCameraId, facing); mGLThreadManager = new GLThreadManager(mCameraId, facing, mDeviceState); mGLThreadManager.start(); } mGLThreadManager.waitUntilStarted(); Loading Loading @@ -617,9 +626,20 @@ public class RequestThreadManager { CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); break; } synchronized (mIdleLock) { // Retry the the request queue. nextBurst = mRequestQueue.getNext(); // If we still have no queued requests, go idle. if (nextBurst == null) { mDeviceState.setIdle(); break; } else { } } } if (nextBurst != null) { // Queue another capture if we did not get the last burst. handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST); } Loading Loading @@ -831,6 +851,7 @@ public class RequestThreadManager { mFaceDetectMapper = new LegacyFaceDetectMapper(mCamera, mCharacteristics); mCaptureCollector = new CaptureCollector(MAX_IN_FLIGHT_REQUESTS, mDeviceState); mRequestThread = new RequestHandlerThread(name, mRequestHandlerCb); mCamera.setErrorCallback(mErrorCallback); } /** Loading Loading @@ -883,8 +904,11 @@ public class RequestThreadManager { public int submitCaptureRequests(List<CaptureRequest> requests, boolean repeating, /*out*/LongParcelable frameNumber) { Handler handler = mRequestThread.waitAndGetHandler(); int ret = mRequestQueue.submit(requests, repeating, frameNumber); int ret; synchronized (mIdleLock) { ret = mRequestQueue.submit(requests, repeating, frameNumber); handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST); } return ret; } Loading