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. 18
      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()) { if (hasFrameProcessors()) {
getFrameManager().release(); 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) { if (false) {
try { try {
// Preferring this over stopRepeating() so we're sure that all in-flights operations // Preferring abortCaptures() over stopRepeating(): it makes sure that all
// are discarded as fast as possible, which is exactly what we want. // 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. // 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()."); LOG.i("onStopPreview:", "calling abortCaptures().");
mSession.abortCaptures(); mSession.abortCaptures();
LOG.i("onStopPreview:", "called abortCaptures()."); LOG.i("onStopPreview:", "called abortCaptures().");
} catch (CameraAccessException e) { } catch (CameraAccessException e) {
// This tells us that we should stop everything. It's better to throw an unrecoverable // This tells us that we should stop everything. It's better to throw an
// exception rather than just swallow this, so everything gets stopped. // unrecoverable exception rather than just swallow, so everything gets stopped.
LOG.w("onStopPreview:", "abortCaptures failed!", e); LOG.w("onStopPreview:", "abortCaptures failed!", e);
throw createCameraException(e); throw createCameraException(e);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {

@ -137,6 +137,9 @@ public abstract class CameraEngine implements
protected static final String TAG = CameraEngine.class.getSimpleName(); protected static final String TAG = CameraEngine.class.getSimpleName();
protected static final CameraLogger LOG = CameraLogger.create(TAG); 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 // Need to be protected
@SuppressWarnings("WeakerAccess") protected final Callback mCallback; @SuppressWarnings("WeakerAccess") protected final Callback mCallback;
@SuppressWarnings("WeakerAccess") protected CameraPreview mPreview; @SuppressWarnings("WeakerAccess") protected CameraPreview mPreview;
@ -350,8 +353,13 @@ public abstract class CameraEngine implements
* awaiting for {@link #stop(boolean)} to return. * awaiting for {@link #stop(boolean)} to return.
*/ */
public void destroy(boolean unrecoverably) { public void destroy(boolean unrecoverably) {
destroy(unrecoverably, 0);
}
private void destroy(boolean unrecoverably, int depth) {
LOG.i("DESTROY:", "state:", getState(), LOG.i("DESTROY:", "state:", getState(),
"thread:", Thread.currentThread(), "thread:", Thread.currentThread(),
"depth:", depth,
"unrecoverably:", unrecoverably); "unrecoverably:", unrecoverably);
if (unrecoverably) { if (unrecoverably) {
// Prevent CameraEngine leaks. Don't set to null, or exceptions // Prevent CameraEngine leaks. Don't set to null, or exceptions
@ -377,10 +385,14 @@ public abstract class CameraEngine implements
LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.", LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.",
"Current thread:", Thread.currentThread(), "Current thread:", Thread.currentThread(),
"Handler thread:", mHandler.getThread()); "Handler thread:", mHandler.getThread());
depth++;
if (depth < DESTROY_RETRIES) {
recreateHandler(true); recreateHandler(true);
LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.", LOG.e("DESTROY: Trying again on thread:", mHandler.getThread());
"Trying again on thread:", mHandler.getThread()); destroy(unrecoverably, depth);
destroy(unrecoverably); } else {
LOG.w("DESTROY: Giving up because DESTROY_RETRIES was reached.");
}
} }
} catch (InterruptedException ignore) {} } catch (InterruptedException ignore) {}
} }

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

Loading…
Cancel
Save