run Camera.startPreview() off main thread

Closes #4620
// FREEBIE
pull/1/head
Jake McGinty 9 years ago committed by Moxie Marlinspike
parent d9467ef3c5
commit 4fe6256967

@ -55,13 +55,13 @@ public class CameraView extends FrameLayout {
private final CameraSurfaceView surface; private final CameraSurfaceView surface;
private final OnOrientationChange onOrientationChange; private final OnOrientationChange onOrientationChange;
private @NonNull volatile Optional<Camera> camera = Optional.absent(); private volatile Optional<Camera> camera = Optional.absent();
private volatile int cameraId = CameraInfo.CAMERA_FACING_BACK; private volatile int cameraId = CameraInfo.CAMERA_FACING_BACK;
private volatile int displayOrientation = -1;
private @NonNull State state = State.PAUSED; private @NonNull State state = State.PAUSED;
private @Nullable Size previewSize; private @Nullable Size previewSize;
private @Nullable CameraViewListener listener; private @Nullable CameraViewListener listener;
private int displayOrientation = -1;
private int outputOrientation = -1; private int outputOrientation = -1;
public CameraView(Context context) { public CameraView(Context context) {
@ -96,41 +96,35 @@ public class CameraView extends FrameLayout {
if (state != State.PAUSED) return; if (state != State.PAUSED) return;
state = State.RESUMED; state = State.RESUMED;
Log.w(TAG, "onResume() queued"); Log.w(TAG, "onResume() queued");
enqueueTask(new SerialAsyncTask<Camera>() { enqueueTask(new SerialAsyncTask<Void>() {
@Override @Override
protected protected
@Nullable @Nullable
Camera onRunBackground() { Void onRunBackground() {
try { try {
return Camera.open(cameraId); camera = Optional.fromNullable(Camera.open(cameraId));
synchronized (CameraView.this) {
CameraView.this.notifyAll();
}
if (camera.isPresent()) onCameraReady(camera.get());
} catch (Exception e) { } catch (Exception e) {
Log.w(TAG, e); Log.w(TAG, e);
return null;
} }
return null;
} }
@Override @Override
protected void onPostMain(@Nullable Camera camera) { protected void onPostMain(Void avoid) {
if (camera == null) { if (!camera.isPresent()) {
Log.w(TAG, "tried to open camera but got null"); Log.w(TAG, "tried to open camera but got null");
if (listener != null) listener.onCameraFail(); if (listener != null) listener.onCameraFail();
return; return;
} }
CameraView.this.camera = Optional.of(camera); if (getActivity().getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
try { onOrientationChange.enable();
if (getActivity().getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
onOrientationChange.enable();
}
onCameraReady();
synchronized (CameraView.this) {
CameraView.this.notifyAll();
}
Log.w(TAG, "onResume() completed");
} catch (RuntimeException e) {
Log.w(TAG, "exception when starting camera preview", e);
onPause();
} }
Log.w(TAG, "onResume() completed");
} }
}); });
} }
@ -267,10 +261,8 @@ public class CameraView extends FrameLayout {
} }
@TargetApi(14) @TargetApi(14)
private void onCameraReady() { private void onCameraReady(final @NonNull Camera camera) {
if (!camera.isPresent()) return; final Parameters parameters = camera.getParameters();
final Parameters parameters = camera.get().getParameters();
if (VERSION.SDK_INT >= 14) { if (VERSION.SDK_INT >= 14) {
parameters.setRecordingHint(true); parameters.setRecordingHint(true);
@ -283,20 +275,18 @@ public class CameraView extends FrameLayout {
} }
displayOrientation = CameraUtils.getCameraDisplayOrientation(getActivity(), getCameraInfo()); displayOrientation = CameraUtils.getCameraDisplayOrientation(getActivity(), getCameraInfo());
camera.get().setDisplayOrientation(displayOrientation); camera.setDisplayOrientation(displayOrientation);
camera.get().setParameters(parameters); camera.setParameters(parameters);
enqueueTask(new PostInitializationTask<Void>() { enqueueTask(new PostInitializationTask<Void>() {
@Override protected void onPostMain(Void avoid) { @Override
if (camera.isPresent()) { protected Void onRunBackground() {
try { try {
camera.get().setPreviewDisplay(surface.getHolder()); camera.setPreviewDisplay(surface.getHolder());
startPreview(parameters); startPreview(parameters);
requestLayout(); } catch (Exception e) {
} catch (Exception e) { Log.w(TAG, "couldn't set preview display");
Log.w(TAG, e);
}
} }
return null;
} }
}); });
} }
@ -317,7 +307,7 @@ public class CameraView extends FrameLayout {
previewSize = parameters.getPreviewSize(); previewSize = parameters.getPreviewSize();
} }
camera.startPreview(); camera.startPreview();
requestLayout(); postRequestLayout();
state = State.ACTIVE; state = State.ACTIVE;
} catch (Exception e) { } catch (Exception e) {
Log.w(TAG, e); Log.w(TAG, e);
@ -357,6 +347,15 @@ public class CameraView extends FrameLayout {
return outputOrientation; return outputOrientation;
} }
private void postRequestLayout() {
post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
private @NonNull CameraInfo getCameraInfo() { private @NonNull CameraInfo getCameraInfo() {
final CameraInfo info = new Camera.CameraInfo(); final CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info); Camera.getCameraInfo(cameraId, info);

Loading…
Cancel
Save