mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Merge branch 'checked-camera-exceptions' into 'master'
Throw checked exceptions for camera errors See merge request !580
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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,
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
|||||||
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
|
|||||||
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
|
|||||||
} else {
|
} else {
|
||||||
startListening();
|
startListening();
|
||||||
}
|
}
|
||||||
cameraView.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -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 @@
|
|||||||
<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>
|
||||||
|
|||||||
Reference in New Issue
Block a user