FileDocCategorySizeDatePackage
CameraDeviceState.javaAPI DocAndroid 5.1 API12774Thu Mar 12 22:22:10 GMT 2015android.hardware.camera2.legacy

CameraDeviceState

public class CameraDeviceState extends Object
Emulates a the state of a single Camera2 device.

This class acts as the state machine for a camera device. Valid state transitions are given in the table below:

  • {@code UNCONFIGURED -> CONFIGURING}
  • {@code CONFIGURING -> IDLE}
  • {@code IDLE -> CONFIGURING}
  • {@code IDLE -> CAPTURING}
  • {@code IDLE -> IDLE}
  • {@code CAPTURING -> IDLE}
  • {@code ANY -> ERROR}

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final int
STATE_ERROR
private static final int
STATE_UNCONFIGURED
private static final int
STATE_CONFIGURING
private static final int
STATE_IDLE
private static final int
STATE_CAPTURING
private static final String[]
sStateNames
private int
mCurrentState
private int
mCurrentError
private RequestHolder
mCurrentRequest
private android.os.Handler
mCurrentHandler
private CameraDeviceStateListener
mCurrentListener
public static final int
NO_CAPTURE_ERROR
Error code used by {@link #setCaptureStart} and {@link #setCaptureResult} to indicate that no error has occurred.
Constructors Summary
Methods Summary
private voiddoStateTransition(int newState)

        doStateTransition(newState, /*timestamp*/0, NO_CAPTURE_ERROR);
    
private voiddoStateTransition(int newState, long timestamp, int error)

        if (newState != mCurrentState) {
            String stateName = "UNKNOWN";
            if (newState >= 0 && newState < sStateNames.length) {
                stateName = sStateNames[newState];
            }
            Log.i(TAG, "Legacy camera service transitioning to state " + stateName);
        }

        // If we transitioned into a non-IDLE/non-ERROR state then mark the device as busy
        if(newState != STATE_ERROR && newState != STATE_IDLE) {
            if (mCurrentState != newState && mCurrentHandler != null &&
                    mCurrentListener != null) {
                mCurrentHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mCurrentListener.onBusy();
                    }
                });
            }
        }

        switch(newState) {
            case STATE_ERROR:
                if (mCurrentState != STATE_ERROR && mCurrentHandler != null &&
                        mCurrentListener != null) {
                    mCurrentHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mCurrentListener.onError(mCurrentError, mCurrentRequest);
                        }
                    });
                }
                mCurrentState = STATE_ERROR;
                break;
            case STATE_CONFIGURING:
                if (mCurrentState != STATE_UNCONFIGURED && mCurrentState != STATE_IDLE) {
                    Log.e(TAG, "Cannot call configure while in state: " + mCurrentState);
                    mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
                    doStateTransition(STATE_ERROR);
                    break;
                }
                if (mCurrentState != STATE_CONFIGURING && mCurrentHandler != null &&
                        mCurrentListener != null) {
                    mCurrentHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mCurrentListener.onConfiguring();
                        }
                    });
                }
                mCurrentState = STATE_CONFIGURING;
                break;
            case STATE_IDLE:
                if (mCurrentState == STATE_IDLE) {
                    break;
                }

                if (mCurrentState != STATE_CONFIGURING && mCurrentState != STATE_CAPTURING) {
                    Log.e(TAG, "Cannot call idle while in state: " + mCurrentState);
                    mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
                    doStateTransition(STATE_ERROR);
                    break;
                }

                if (mCurrentState != STATE_IDLE && mCurrentHandler != null &&
                        mCurrentListener != null) {
                    mCurrentHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mCurrentListener.onIdle();
                        }
                    });
                }
                mCurrentState = STATE_IDLE;
                break;
            case STATE_CAPTURING:
                if (mCurrentState != STATE_IDLE && mCurrentState != STATE_CAPTURING) {
                    Log.e(TAG, "Cannot call capture while in state: " + mCurrentState);
                    mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
                    doStateTransition(STATE_ERROR);
                    break;
                }

                if (mCurrentHandler != null && mCurrentListener != null) {
                    if (error != NO_CAPTURE_ERROR) {
                        mCurrentHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mCurrentListener.onError(error, mCurrentRequest);
                            }
                        });
                    } else {
                        mCurrentHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mCurrentListener.onCaptureStarted(mCurrentRequest, timestamp);
                            }
                        });
                    }
                }
                mCurrentState = STATE_CAPTURING;
                break;
            default:
                throw new IllegalStateException("Transition to unknown state: " + newState);
        }
    
public synchronized voidsetCameraDeviceCallbacks(android.os.Handler handler, android.hardware.camera2.legacy.CameraDeviceState$CameraDeviceStateListener listener)
Set the listener for state transition callbacks.

param
handler handler on which to call the callbacks.
param
listener the {@link CameraDeviceStateListener} callbacks to call.

        mCurrentHandler = handler;
        mCurrentListener = listener;
    
public synchronized booleansetCaptureResult(RequestHolder request, android.hardware.camera2.impl.CameraMetadataNative result, int captureError)
Set the result for a capture.

If the device was in the {@code CAPTURING} state, {@link CameraDeviceStateListener#onCaptureResult(CameraMetadataNative, RequestHolder)} will be called with the given result, otherwise this will result in the device transitioning to the {@code ERROR} state,

param
request The {@link RequestHolder} request that created this result.
param
result The {@link CameraMetadataNative} result to set.
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
{@code false} if an error has occurred.

        if (mCurrentState != STATE_CAPTURING) {
            Log.e(TAG, "Cannot receive result while in state: " + mCurrentState);
            mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
            doStateTransition(STATE_ERROR);
            return mCurrentError == NO_CAPTURE_ERROR;
        }

        if (mCurrentHandler != null && mCurrentListener != null) {
            if (captureError != NO_CAPTURE_ERROR) {
                mCurrentHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mCurrentListener.onError(captureError, request);
                    }
                });
            } else {
                mCurrentHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mCurrentListener.onCaptureResult(result, request);
                    }
                });
            }
        }
        return mCurrentError == NO_CAPTURE_ERROR;
    
public synchronized booleansetCaptureStart(RequestHolder request, long timestamp, int captureError)
Transition to the {@code CAPTURING} state, or {@code ERROR} if in an invalid state.

If the device was not already in the {@code CAPTURING} state, {@link CameraDeviceStateListener#onCaptureStarted(RequestHolder)} will be called.

param
request A {@link RequestHolder} containing the request for the current capture.
param
timestamp The timestamp of the capture start in nanoseconds.
param
captureError Report a recoverable error for a single request using a valid error code for {@code ICameraDeviceCallbacks}, or {@link #NO_CAPTURE_ERROR}
return
{@code false} if an error has occurred.

        mCurrentRequest = request;
        doStateTransition(STATE_CAPTURING, timestamp, captureError);
        return mCurrentError == NO_CAPTURE_ERROR;
    
public synchronized booleansetConfiguring()
Transition to the {@code CONFIGURING} state, or {@code ERROR} if in an invalid state.

If the device was not already in the {@code CONFIGURING} state, {@link CameraDeviceStateListener#onConfiguring()} will be called.

return
{@code false} if an error has occurred.

        doStateTransition(STATE_CONFIGURING);
        return mCurrentError == NO_CAPTURE_ERROR;
    
public synchronized voidsetError(int error)
Transition to the {@code ERROR} state.

The device cannot exit the {@code ERROR} state. If the device was not already in the {@code ERROR} state, {@link CameraDeviceStateListener#onError(int, RequestHolder)} will be called.

param
error the error to set. Should be one of the error codes defined in {@link CameraDeviceImpl.CameraDeviceCallbacks}.


                 
       
            
         
         
         
            
            
    

                                                                  
         
        mCurrentError = error;
        doStateTransition(STATE_ERROR);
    
public synchronized booleansetIdle()
Transition to the {@code IDLE} state, or {@code ERROR} if in an invalid state.

If the device was not already in the {@code IDLE} state, {@link CameraDeviceStateListener#onIdle()} will be called.

return
{@code false} if an error has occurred.

        doStateTransition(STATE_IDLE);
        return mCurrentError == NO_CAPTURE_ERROR;