Add destroy depth

pull/696/head
Mattia Iavarone 6 years ago
parent 84967019c4
commit f518156848
  1. 13
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  2. 30
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
  3. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java

@ -638,20 +638,19 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
if (hasFrameProcessors()) {
getFrameManager().release();
}
// Removing the part below for now. It hangs on emulators and can take a lot of time
// in real devices, for benefits that I'm not 100% sure about.
if (false) {
try {
// Preferring this over stopRepeating() so we're sure that all in-flights operations
// are discarded as fast as possible, which is exactly what we want.
// Preferring abortCaptures() over stopRepeating(): it makes sure that all
// in-flight operations are discarded as fast as possible, which is what we want.
// NOTE: this call is asynchronous. Should find a good way to wait for the outcome.
LOG.i("onStopPreview:", "calling stopRepeating().");
// TODO HANGS (rare, emulator only)
mSession.stopRepeating();
LOG.i("onStopPreview:", "calling abortCaptures().");
mSession.abortCaptures();
LOG.i("onStopPreview:", "called abortCaptures().");
} catch (CameraAccessException e) {
// This tells us that we should stop everything. It's better to throw an unrecoverable
// exception rather than just swallow this, so everything gets stopped.
// This tells us that we should stop everything. It's better to throw an
// unrecoverable exception rather than just swallow, so everything gets stopped.
LOG.w("onStopPreview:", "abortCaptures failed!", e);
throw createCameraException(e);
} catch (IllegalStateException e) {

@ -137,6 +137,9 @@ public abstract class CameraEngine implements
protected static final String TAG = CameraEngine.class.getSimpleName();
protected static final CameraLogger LOG = CameraLogger.create(TAG);
// If this is 2, this means we'll try to run destroy() twice.
private static final int DESTROY_RETRIES = 2;
// Need to be protected
@SuppressWarnings("WeakerAccess") protected final Callback mCallback;
@SuppressWarnings("WeakerAccess") protected CameraPreview mPreview;
@ -350,8 +353,13 @@ public abstract class CameraEngine implements
* awaiting for {@link #stop(boolean)} to return.
*/
public void destroy(boolean unrecoverably) {
destroy(unrecoverably, 0);
}
private void destroy(boolean unrecoverably, int depth) {
LOG.i("DESTROY:", "state:", getState(),
"thread:", Thread.currentThread(),
"depth:", depth,
"unrecoverably:", unrecoverably);
if (unrecoverably) {
// Prevent CameraEngine leaks. Don't set to null, or exceptions
@ -363,11 +371,11 @@ public abstract class CameraEngine implements
stop(true).addOnCompleteListener(
mHandler.getExecutor(),
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
latch.countDown();
}
});
@Override
public void onComplete(@NonNull Task<Void> task) {
latch.countDown();
}
});
try {
boolean success = latch.await(6, TimeUnit.SECONDS);
if (!success) {
@ -377,10 +385,14 @@ public abstract class CameraEngine implements
LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.",
"Current thread:", Thread.currentThread(),
"Handler thread:", mHandler.getThread());
recreateHandler(true);
LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.",
"Trying again on thread:", mHandler.getThread());
destroy(unrecoverably);
depth++;
if (depth < DESTROY_RETRIES) {
recreateHandler(true);
LOG.e("DESTROY: Trying again on thread:", mHandler.getThread());
destroy(unrecoverably, depth);
} else {
LOG.w("DESTROY: Giving up because DESTROY_RETRIES was reached.");
}
}
} catch (InterruptedException ignore) {}
}

@ -38,8 +38,8 @@ public class Full1PictureRecorder extends FullPictureRecorder {
@Override
public void take() {
LOG.i("take() called.");
// TODO HANGS (rare, emulator only)
// Trying to fix by stopping preview callback before.
// Stopping the preview callback is important on older APIs / emulators,
// or takePicture can hang and leave the camera in a bad state.
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.takePicture(
new Camera.ShutterCallback() {

Loading…
Cancel
Save