Skip to content

Commit dbc58af

Browse files
authored
Don't act on Camera if it is in the middle of a stop (#50)
* Don't act on Camera if it is in the middle of a stop * Ensure no issues if scheduled for stop
1 parent 98855d0 commit dbc58af

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ void onStop() throws Exception {
191191
Exception error = null;
192192
LOG.i("onStop:", "About to clean up.");
193193
mHandler.get().removeCallbacks(mPostFocusResetRunnable);
194-
if (isCameraAvailable()) {
194+
if (mCamera != null) {
195195
LOG.i("onStop:", "Clean up.", "Ending video?", mIsCapturingVideo);
196196
if (mIsCapturingVideo) endVideo();
197197

@@ -510,7 +510,20 @@ boolean shouldFlipSizes() {
510510
}
511511

512512
private boolean isCameraAvailable() {
513-
return mCamera != null;
513+
switch (mState) {
514+
// If we are stopped, don't.
515+
case STATE_STOPPED: return false;
516+
// If we are going to be closed, don't act on camera.
517+
// Even if mCamera != null, it might have been released.
518+
case STATE_STOPPING: return false;
519+
// If we are started, act as long as there is no stop/restart scheduled.
520+
// At this point mCamera should never be null.
521+
case STATE_STARTED: return !mScheduledForStop && !mScheduledForRestart;
522+
// If we are starting, theoretically we could act.
523+
// Just check that camera is available.
524+
case STATE_STARTING: return mCamera != null && !mScheduledForStop && !mScheduledForRestart;
525+
}
526+
return false;
514527
}
515528

516529

cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ abstract class CameraController implements CameraPreview.SurfaceCallback {
3838

3939
protected int mDisplayOffset;
4040
protected int mDeviceOrientation;
41+
42+
protected boolean mScheduledForStart = false;
43+
protected boolean mScheduledForStop = false;
44+
protected boolean mScheduledForRestart = false;
4145
protected int mState = STATE_STOPPED;
4246

4347
protected WorkerHandler mHandler;
@@ -84,11 +88,13 @@ private String ss() {
8488
// Starts the preview asynchronously.
8589
final void start() {
8690
LOG.i("Start:", "posting runnable. State:", ss());
91+
mScheduledForStart = true;
8792
mHandler.post(new Runnable() {
8893
@Override
8994
public void run() {
9095
try {
9196
LOG.i("Start:", "executing. State:", ss());
97+
mScheduledForStart = false;
9298
if (mState >= STATE_STARTING) return;
9399
mState = STATE_STARTING;
94100
LOG.i("Start:", "about to call onStart()", ss());
@@ -108,11 +114,13 @@ public void run() {
108114
// Stops the preview asynchronously.
109115
final void stop() {
110116
LOG.i("Stop:", "posting runnable. State:", ss());
117+
mScheduledForStop = true;
111118
mHandler.post(new Runnable() {
112119
@Override
113120
public void run() {
114121
try {
115122
LOG.i("Stop:", "executing. State:", ss());
123+
mScheduledForStop = false;
116124
if (mState <= STATE_STOPPED) return;
117125
mState = STATE_STOPPING;
118126
LOG.i("Stop:", "about to call onStop()");
@@ -148,11 +156,13 @@ void stopImmediately() {
148156
// Forces a restart.
149157
protected final void restart() {
150158
LOG.i("Restart:", "posting runnable");
159+
mScheduledForRestart = true;
151160
mHandler.post(new Runnable() {
152161
@Override
153162
public void run() {
154163
try {
155164
LOG.i("Restart:", "executing. Needs stopping:", mState > STATE_STOPPED, ss());
165+
mScheduledForRestart = false;
156166
// Don't stop if stopped.
157167
if (mState > STATE_STOPPED) {
158168
mState = STATE_STOPPING;

0 commit comments

Comments
 (0)