You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
CameraView/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java

278 lines
7.9 KiB

package com.otaliastudios.cameraview;
import android.graphics.PointF;
import android.location.Location;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import java.io.File;
abstract class CameraController implements Preview.SurfaceCallback {
private static final String TAG = CameraController.class.getSimpleName();
private static final CameraLogger LOG = CameraLogger.create(TAG);
static final int STATE_STOPPING = -1; // Camera is about to be stopped.
static final int STATE_STOPPED = 0; // Camera is stopped.
static final int STATE_STARTING = 1; // Camera is about to start.
static final int STATE_STARTED = 2; // Camera is available and we can set parameters.
protected final CameraView.CameraCallbacks mCameraCallbacks;
protected final Preview mPreview;
protected Facing mFacing;
protected Flash mFlash;
protected WhiteBalance mWhiteBalance;
protected VideoQuality mVideoQuality;
protected SessionType mSessionType;
protected Hdr mHdr;
protected Location mLocation;
protected Size mCaptureSize;
protected Size mPreviewSize;
protected ExtraProperties mExtraProperties;
protected CameraOptions mOptions;
protected int mDisplayOffset;
protected int mDeviceOrientation;
protected int mState = STATE_STOPPED;
protected WorkerHandler mHandler;
CameraController(CameraView.CameraCallbacks callback, Preview preview) {
mCameraCallbacks = callback;
mPreview = preview;
mPreview.setSurfaceCallback(this);
mHandler = WorkerHandler.get("CameraViewController");
mHandler.getThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
// Something went wrong. Thread is terminated (about to?).
// Move to other thread and stop resources.
WorkerHandler.clearCache();
mHandler = WorkerHandler.get("CameraViewController");
mHandler.post(new Runnable() {
@Override
public void run() {
stopImmediately();
}
});
}
});
}
//region Start&Stop
// Starts the preview asynchronously.
final void start() {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
int a = mState;
if (mState >= STATE_STARTING) return;
mState = STATE_STARTING;
onStart();
mState = STATE_STARTED;
mCameraCallbacks.dispatchOnCameraOpened(mOptions);
} catch (Exception e) {
LOG.e("Error while starting the camera engine.", e);
throw new RuntimeException(e);
}
}
});
}
// Stops the preview asynchronously.
final void stop() {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
int a = mState;
if (mState <= STATE_STOPPED) return;
mState = STATE_STOPPING;
onStop();
mState = STATE_STOPPED;
mCameraCallbacks.dispatchOnCameraClosed();
} catch (Exception e) {
LOG.e("Error while stopping the camera engine.", e);
throw new RuntimeException(e);
}
}
});
}
// Stops the preview synchronously, ensuring no exceptions are thrown.
void stopImmediately() {
try {
// Don't check, try stop again.
mState = STATE_STOPPING;
onStop();
mState = STATE_STOPPED;
} catch (Exception e) {
// Do nothing.
mState = STATE_STOPPED;
}
}
// Forces a restart.
protected final void restart() {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
// Don't stop if stopped.
if (mState > STATE_STOPPED) {
mState = STATE_STOPPING;
onStop();
mState = STATE_STOPPED;
mCameraCallbacks.dispatchOnCameraClosed();
}
mState = STATE_STARTING;
onStart();
mState = STATE_STARTED;
mCameraCallbacks.dispatchOnCameraOpened(mOptions);
} catch (Exception e) {
LOG.e("Error while restarting the camera engine.", e);
throw new RuntimeException(e);
}
}
});
}
// Starts the preview.
// At the end of this method camera must be available, e.g. for setting parameters.
@WorkerThread
abstract void onStart() throws Exception;
// Stops the preview.
@WorkerThread
abstract void onStop() throws Exception;
// Returns current state.
final int getState() {
return mState;
}
//endregion
//region Rotation callbacks
void onDisplayOffset(int displayOrientation) {
// I doubt this will ever change.
mDisplayOffset = displayOrientation;
}
void onDeviceOrientation(int deviceOrientation) {
mDeviceOrientation = deviceOrientation;
}
//endregion
//region Abstract setParameters
// Should restart the session if active.
abstract void setSessionType(SessionType sessionType);
// Should restart the session if active.
abstract void setFacing(Facing facing);
// If opened and supported, apply and return true.
abstract boolean setZoom(float zoom);
// If opened and supported, apply and return true.
abstract boolean setExposureCorrection(float EVvalue);
// If closed, keep. If opened, check supported and apply.
abstract void setFlash(Flash flash);
// If closed, keep. If opened, check supported and apply.
abstract void setWhiteBalance(WhiteBalance whiteBalance);
// If closed, keep. If opened, check supported and apply.
abstract void setHdr(Hdr hdr);
// If closed, keep. If opened, check supported and apply.
abstract void setLocation(Location location);
// Throw if capturing. If in video session, recompute capture size, and, if needed, preview size.
abstract void setVideoQuality(VideoQuality videoQuality);
//endregion
//region APIs
abstract boolean capturePicture();
abstract boolean captureSnapshot();
abstract boolean startVideo(@NonNull File file);
abstract boolean endVideo();
abstract boolean shouldFlipSizes(); // Wheter the Sizes should be flipped to match the view orientation.
abstract boolean startAutoFocus(@Nullable Gesture gesture, PointF point);
//endregion
//region final getters
@Nullable
final ExtraProperties getExtraProperties() {
return mExtraProperties;
}
@Nullable
final CameraOptions getCameraOptions() {
return mOptions;
}
final Facing getFacing() {
return mFacing;
}
final Flash getFlash() {
return mFlash;
}
final WhiteBalance getWhiteBalance() {
return mWhiteBalance;
}
final VideoQuality getVideoQuality() {
return mVideoQuality;
}
final SessionType getSessionType() {
return mSessionType;
}
final Hdr getHdr() {
return mHdr;
}
final Location getLocation() {
return mLocation;
}
final Size getCaptureSize() {
return mCaptureSize;
}
final Size getPreviewSize() {
return mPreviewSize;
}
//endregion
}