Skip to content
Snippets Groups Projects
Commit 3197dcf9 authored by Torsten Grote's avatar Torsten Grote
Browse files

Merge branch 'checked-camera-exceptions' into 'master'

Throw checked exceptions for camera errors

See merge request !580
parents 35aad409 0d6983b4
No related branches found
No related tags found
No related merge requests found
package org.briarproject.briar.android.keyagreement;
import java.io.IOException;
class CameraException extends IOException {
CameraException(String message) {
super(message);
}
CameraException(Throwable cause) {
super(cause);
}
}
...@@ -84,16 +84,14 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -84,16 +84,14 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} }
@UiThread @UiThread
public void start() { public void start() throws CameraException {
LOG.info("Opening camera");
try { try {
LOG.info("Opening camera");
camera = Camera.open(); camera = Camera.open();
if (camera == null)
throw new RuntimeException("No back-facing camera.");
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.log(WARNING, "Error opening camera", e); throw new CameraException(e);
return;
} }
if (camera == null) throw new CameraException("No back-facing camera");
setDisplayOrientation(0); setDisplayOrientation(0);
// Use barcode scene mode if it's available // Use barcode scene mode if it's available
Parameters params = camera.getParameters(); Parameters params = camera.getParameters();
...@@ -117,64 +115,81 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -117,64 +115,81 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} }
@UiThread @UiThread
public void stop() { public void stop() throws CameraException {
if (camera == null) return; if (camera == null) return;
stopPreview(); stopPreview();
LOG.info("Releasing camera");
try { try {
LOG.info("Releasing camera");
camera.release(); camera.release();
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.log(WARNING, "Error releasing camera", e); throw new CameraException(e);
} }
camera = null; camera = null;
} }
@UiThread @UiThread
private void startPreview(SurfaceHolder holder) { private void startPreview(SurfaceHolder holder) throws CameraException {
LOG.info("Starting preview"); LOG.info("Starting preview");
if (camera == null) throw new CameraException("Camera is null");
try { try {
if (camera == null) throw new IOException("Camera is null.");
camera.setPreviewDisplay(holder); camera.setPreviewDisplay(holder);
camera.startPreview(); camera.startPreview();
previewStarted = true; previewStarted = true;
startConsumer(); startConsumer();
} catch (IOException | RuntimeException e) { } catch (IOException | RuntimeException e) {
LOG.log(WARNING, "Error starting camera preview", e); throw new CameraException(e);
} }
} }
@UiThread @UiThread
private void stopPreview() { private void stopPreview() throws CameraException {
LOG.info("Stopping preview"); LOG.info("Stopping preview");
if (camera == null) throw new CameraException("Camera is null");
try { try {
if (camera == null) throw new RuntimeException("Camera is null.");
stopConsumer(); stopConsumer();
camera.stopPreview(); camera.stopPreview();
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.log(WARNING, "Error stopping camera preview", e); throw new CameraException(e);
} }
previewStarted = false; previewStarted = false;
} }
@UiThread @UiThread
private void startConsumer() { private void startConsumer() throws CameraException {
if (camera == null) throw new RuntimeException("Camera is null"); if (camera == null) throw new CameraException("Camera is null");
if (autoFocus) camera.autoFocus(this); if (autoFocus) {
try {
camera.autoFocus(this);
} catch (RuntimeException e) {
throw new CameraException(e);
}
}
previewConsumer.start(camera); previewConsumer.start(camera);
} }
@UiThread @UiThread
private void stopConsumer() { private void stopConsumer() throws CameraException {
if (camera == null) throw new RuntimeException("Camera is null"); if (camera == null) throw new CameraException("Camera is null");
if (autoFocus) camera.cancelAutoFocus(); if (autoFocus) {
try {
camera.cancelAutoFocus();
} catch (RuntimeException e) {
throw new CameraException(e);
}
}
previewConsumer.stop(); previewConsumer.stop();
} }
@UiThread @UiThread
private void setDisplayOrientation(int rotationDegrees) { private void setDisplayOrientation(int rotationDegrees)
throws CameraException {
int orientation; int orientation;
CameraInfo info = new CameraInfo(); CameraInfo info = new CameraInfo();
Camera.getCameraInfo(0, info); try {
Camera.getCameraInfo(0, info);
} catch (RuntimeException e) {
throw new CameraException(e);
}
if (info.facing == CAMERA_FACING_FRONT) { if (info.facing == CAMERA_FACING_FRONT) {
orientation = (info.orientation + rotationDegrees) % 360; orientation = (info.orientation + rotationDegrees) % 360;
orientation = (360 - orientation) % 360; orientation = (360 - orientation) % 360;
...@@ -183,54 +198,70 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -183,54 +198,70 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} }
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Display orientation " + orientation + " degrees"); LOG.info("Display orientation " + orientation + " degrees");
if (camera == null) throw new CameraException("Camera is null");
try { try {
if (camera == null) throw new RuntimeException("Camera is null");
camera.setDisplayOrientation(orientation); camera.setDisplayOrientation(orientation);
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.log(WARNING, "Error setting display orientation", e); throw new CameraException(e);
} }
displayOrientation = orientation; displayOrientation = orientation;
} }
@UiThread @UiThread
private Parameters setSceneMode(Camera camera, Parameters params) { private Parameters setSceneMode(Camera camera, Parameters params)
throws CameraException {
List<String> sceneModes = params.getSupportedSceneModes(); List<String> sceneModes = params.getSupportedSceneModes();
if (sceneModes == null) return params; if (sceneModes == null) return params;
if (LOG.isLoggable(INFO)) LOG.info("Scene modes: " + sceneModes); if (LOG.isLoggable(INFO)) LOG.info("Scene modes: " + sceneModes);
if (sceneModes.contains(SCENE_MODE_BARCODE)) { if (sceneModes.contains(SCENE_MODE_BARCODE)) {
params.setSceneMode(SCENE_MODE_BARCODE); params.setSceneMode(SCENE_MODE_BARCODE);
camera.setParameters(params); try {
return camera.getParameters(); camera.setParameters(params);
return camera.getParameters();
} catch (RuntimeException e) {
throw new CameraException(e);
}
} }
return params; return params;
} }
@UiThread @UiThread
private Parameters disableFlash(Camera camera, Parameters params) { private Parameters disableFlash(Camera camera, Parameters params)
throws CameraException {
params.setFlashMode(FLASH_MODE_OFF); params.setFlashMode(FLASH_MODE_OFF);
camera.setParameters(params); try {
return camera.getParameters(); camera.setParameters(params);
return camera.getParameters();
} catch (RuntimeException e) {
throw new CameraException(e);
}
} }
@UiThread @UiThread
private Parameters disableSceneMode(Camera camera, Parameters params) { private Parameters disableSceneMode(Camera camera, Parameters params)
throws CameraException {
params.setSceneMode(SCENE_MODE_AUTO); params.setSceneMode(SCENE_MODE_AUTO);
camera.setParameters(params); try {
return camera.getParameters(); camera.setParameters(params);
return camera.getParameters();
} catch (RuntimeException e) {
throw new CameraException(e);
}
} }
@UiThread @UiThread
private Parameters setBestParameters(Camera camera, Parameters params) { private Parameters setBestParameters(Camera camera, Parameters params)
throws CameraException {
setVideoStabilisation(params); setVideoStabilisation(params);
setFocusMode(params); setFocusMode(params);
params.setFlashMode(FLASH_MODE_OFF); params.setFlashMode(FLASH_MODE_OFF);
setPreviewSize(params); setPreviewSize(params);
try { try {
camera.setParameters(params); camera.setParameters(params);
return camera.getParameters();
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.log(WARNING, "Error setting best camera parameters", e); throw new CameraException(e);
} }
return camera.getParameters();
} }
@UiThread @UiThread
...@@ -299,9 +330,15 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -299,9 +330,15 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} }
@UiThread @UiThread
private void logCameraParameters() { private void logCameraParameters() throws CameraException {
if (camera != null && LOG.isLoggable(INFO)) { if (camera == null) throw new AssertionError();
Parameters params = camera.getParameters(); if (LOG.isLoggable(INFO)) {
Parameters params;
try {
params = camera.getParameters();
} catch (RuntimeException e) {
throw new CameraException(e);
}
if (Build.VERSION.SDK_INT >= 15) { if (Build.VERSION.SDK_INT >= 15) {
LOG.info("Video stabilisation enabled: " LOG.info("Video stabilisation enabled: "
+ params.getVideoStabilization()); + params.getVideoStabilization());
...@@ -319,13 +356,18 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -319,13 +356,18 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
post(new Runnable() { post(new Runnable() {
@Override @Override
public void run() { public void run() {
surfaceCreatedUi(holder); try {
surfaceCreatedUi(holder);
} catch (CameraException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@UiThread @UiThread
private void surfaceCreatedUi(SurfaceHolder holder) { private void surfaceCreatedUi(SurfaceHolder holder) throws CameraException {
LOG.info("Surface created"); LOG.info("Surface created");
if (surface != null && surface != holder.getSurface()) { if (surface != null && surface != holder.getSurface()) {
LOG.info("Releasing old surface"); LOG.info("Releasing old surface");
...@@ -342,13 +384,19 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -342,13 +384,19 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
post(new Runnable() { post(new Runnable() {
@Override @Override
public void run() { public void run() {
surfaceChangedUi(holder, w, h); try {
surfaceChangedUi(holder, w, h);
} catch (CameraException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@UiThread @UiThread
private void surfaceChangedUi(SurfaceHolder holder, int w, int h) { private void surfaceChangedUi(SurfaceHolder holder, int w, int h)
throws CameraException {
if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h); if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h);
if (surface != null && surface != holder.getSurface()) { if (surface != null && surface != holder.getSurface()) {
LOG.info("Releasing old surface"); LOG.info("Releasing old surface");
...@@ -365,7 +413,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -365,7 +413,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
camera.setParameters(params); camera.setParameters(params);
logCameraParameters(); logCameraParameters();
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.log(WARNING, "Error setting preview size", e); throw new CameraException(e);
} }
startPreview(holder); startPreview(holder);
} }
......
...@@ -56,6 +56,7 @@ import static android.view.View.INVISIBLE; ...@@ -56,6 +56,7 @@ import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.widget.Toast.LENGTH_LONG; import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
...@@ -143,6 +144,12 @@ public class ShowQrCodeFragment extends BaseEventFragment ...@@ -143,6 +144,12 @@ public class ShowQrCodeFragment extends BaseEventFragment
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
try {
cameraView.start();
} catch (CameraException e) {
logCameraExceptionAndFinish(e);
}
// Listen for changes to the Bluetooth state // Listen for changes to the Bluetooth state
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_STATE_CHANGED); filter.addAction(ACTION_STATE_CHANGED);
...@@ -162,7 +169,6 @@ public class ShowQrCodeFragment extends BaseEventFragment ...@@ -162,7 +169,6 @@ public class ShowQrCodeFragment extends BaseEventFragment
} else { } else {
startListening(); startListening();
} }
cameraView.start();
} }
@Override @Override
...@@ -170,7 +176,19 @@ public class ShowQrCodeFragment extends BaseEventFragment ...@@ -170,7 +176,19 @@ public class ShowQrCodeFragment extends BaseEventFragment
super.onStop(); super.onStop();
stopListening(); stopListening();
if (receiver != null) getActivity().unregisterReceiver(receiver); if (receiver != null) getActivity().unregisterReceiver(receiver);
cameraView.stop(); try {
cameraView.stop();
} catch (CameraException e) {
logCameraExceptionAndFinish(e);
}
}
@UiThread
private void logCameraExceptionAndFinish(CameraException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
Toast.makeText(getActivity(), R.string.camera_error,
LENGTH_LONG).show();
finish();
} }
@UiThread @UiThread
......
...@@ -121,6 +121,7 @@ ...@@ -121,6 +121,7 @@
<string name="contact_already_exists">Contact %s already exists</string> <string name="contact_already_exists">Contact %s already exists</string>
<string name="contact_exchange_failed">Contact exchange failed</string> <string name="contact_exchange_failed">Contact exchange failed</string>
<string name="qr_code_invalid">The QR code is invalid</string> <string name="qr_code_invalid">The QR code is invalid</string>
<string name="camera_error">Camera error</string>
<string name="connecting_to_device">Connecting to device\u2026</string> <string name="connecting_to_device">Connecting to device\u2026</string>
<string name="authenticating_with_device">Authenticating with device\u2026</string> <string name="authenticating_with_device">Authenticating with device\u2026</string>
<string name="connection_aborted_local">Connection aborted by us! This could mean that someone is trying to interfere with your connection</string> <string name="connection_aborted_local">Connection aborted by us! This could mean that someone is trying to interfere with your connection</string>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment