pull/696/head
Mattia Iavarone 6 years ago
parent 959516222b
commit c7028fde9b
  1. 1
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java
  2. 14
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
  3. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/orchestrator/CameraOrchestrator.java
  4. 8
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/utils/WorkerHandler.java

@ -563,6 +563,7 @@ public abstract class CameraIntegrationTest<E extends CameraEngine> extends Base
@Test
@Retry(emulatorOnly = true)
@SdkExclude(maxSdkVersion = 22, emulatorOnly = true)
public void testSetPreviewFrameRate() {
CameraOptions options = openSync(true);
camera.setPreviewFrameRate(30);

@ -216,7 +216,7 @@ public abstract class CameraEngine implements
mCrashHandler = new Handler(Looper.getMainLooper());
mFrameManager = instantiateFrameManager();
mAngles = new Angles();
recreateHandler();
recreateHandler(false);
}
public void setPreview(@NonNull CameraPreview cameraPreview) {
@ -276,7 +276,7 @@ public abstract class CameraEngine implements
// (at least in Camera1, e.g. onError).
if (fromExceptionHandler) {
LOG.e("EXCEPTION:", "Handler thread is gone. Replacing.");
recreateHandler();
recreateHandler(false);
}
// 2. Depending on the exception, we must destroy(false|true) to release resources, and
@ -308,7 +308,13 @@ public abstract class CameraEngine implements
});
}
private void recreateHandler() {
/**
* Recreates the handler, to ensure we use a fresh one from now on.
* If we suspect that handler is currently stuck, the orchestrator should be reset
* because it hosts a chain of tasks and the last one will never complete.
* @param resetOrchestrator true to reset
*/
private void recreateHandler(boolean resetOrchestrator) {
if (mHandler != null) mHandler.destroy();
mHandler = WorkerHandler.get("CameraViewEngine");
mHandler.getThread().setUncaughtExceptionHandler(new CrashExceptionHandler());
@ -370,7 +376,7 @@ public abstract class CameraEngine implements
LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.",
"Current thread:", Thread.currentThread(),
"Handler thread:", mHandler.getThread());
recreateHandler();
recreateHandler(true);
LOG.e("DESTROY: Could not destroy synchronously after 6 seconds.",
"Trying again on thread:", mHandler.getThread());
destroy(unrecoverably);

@ -11,7 +11,9 @@ import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.internal.utils.WorkerHandler;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
@ -161,6 +163,20 @@ public class CameraOrchestrator {
}
}
public void reset() {
synchronized (mLock) {
List<String> all = new ArrayList<>();
//noinspection CollectionAddAllCanBeReplacedWithConstructor
all.addAll(mDelayedJobs.keySet());
for (Token token : mJobs) {
all.add(token.name);
}
for (String job : all) {
remove(job);
}
}
}
private void ensureToken() {
synchronized (mLock) {
if (mJobs.isEmpty()) {

@ -96,7 +96,13 @@ public class WorkerHandler {
private WorkerHandler(@NonNull String name) {
mName = name;
mThread = new HandlerThread(name);
mThread = new HandlerThread(name) {
@NonNull
@Override
public String toString() {
return super.toString() + "[" + getThreadId() + "]";
}
};
mThread.setDaemon(true);
mThread.start();
mHandler = new Handler(mThread.getLooper());

Loading…
Cancel
Save