From b04bde4f4180f6087c3ab4bead1101f0c9029744 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Thu, 4 Aug 2016 16:44:28 -0300
Subject: [PATCH] Fix crashes when no Bluetooth or no Camera is available

Briar crashed when run in a device without bluetooth or without camera
such as an emulator.

Closes #514
---
 .../android/keyagreement/ShowQrCodeFragment.java       |  1 +
 .../src/org/briarproject/android/util/CameraView.java  | 10 +++++++---
 .../plugins/droidtooth/DroidtoothPlugin.java           |  5 +++--
 .../keyagreement/KeyAgreementConnector.java            |  4 ++--
 .../plugins/bluetooth/BluetoothPlugin.java             |  3 ++-
 5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
index dacca905bf..8f508b33c5 100644
--- a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
+++ b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
@@ -225,6 +225,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 					protected void onPostExecute(Camera camera) {
 						if (camera == null) {
 							// TODO better solution?
+							LOG.info("No Camera found, finishing...");
 							getActivity().finish();
 						} else {
 							cameraView.start(camera, decoder, 0);
diff --git a/briar-android/src/org/briarproject/android/util/CameraView.java b/briar-android/src/org/briarproject/android/util/CameraView.java
index 52bea8fb8b..9d5295b236 100644
--- a/briar-android/src/org/briarproject/android/util/CameraView.java
+++ b/briar-android/src/org/briarproject/android/util/CameraView.java
@@ -86,7 +86,8 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	public void stop() {
 		stopPreview();
 		try {
-			camera.release();
+			if (camera != null)
+				camera.release();
 		} catch (RuntimeException e) {
 			LOG.log(WARNING, "Error releasing camera", e);
 		}
@@ -106,7 +107,8 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	private void stopPreview() {
 		try {
 			stopConsumer();
-			camera.stopPreview();
+			if (camera != null)
+				camera.stopPreview();
 		} catch (RuntimeException e) {
 			LOG.log(WARNING, "Error stopping camera preview", e);
 		}
@@ -118,7 +120,9 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	}
 
 	public void stopConsumer() {
-		previewConsumer.stop();
+		if (previewConsumer != null) {
+			previewConsumer.stop();
+		}
 		if (autoFocus) camera.cancelAutoFocus();
 	}
 
diff --git a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
index a89216505b..8c26d4518e 100644
--- a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
@@ -261,7 +261,7 @@ class DroidtoothPlugin implements DuplexPlugin {
 
 	@Override
 	public boolean isRunning() {
-		return running && adapter.isEnabled();
+		return running && adapter != null && adapter.isEnabled();
 	}
 
 	@Override
@@ -446,6 +446,7 @@ class DroidtoothPlugin implements DuplexPlugin {
 
 	@Override
 	public KeyAgreementListener createKeyAgreementListener(byte[] commitment) {
+		if (!isRunning()) return null;
 		// No truncation necessary because COMMIT_LENGTH = 16
 		UUID uuid = UUID.nameUUIDFromBytes(commitment);
 		if (LOG.isLoggable(INFO)) LOG.info("Key agreement UUID " + uuid);
@@ -616,7 +617,7 @@ class DroidtoothPlugin implements DuplexPlugin {
 
 		private final BluetoothServerSocket ss;
 
-		public BluetoothKeyAgreementListener(TransportDescriptor descriptor,
+		BluetoothKeyAgreementListener(TransportDescriptor descriptor,
 				BluetoothServerSocket ss) {
 			super(descriptor);
 			this.ss = ss;
diff --git a/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java b/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java
index e87297af63..190a138502 100644
--- a/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java
+++ b/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java
@@ -51,7 +51,7 @@ class KeyAgreementConnector {
 	private volatile boolean connecting = false;
 	private volatile boolean alice = false;
 
-	public KeyAgreementConnector(Callbacks callbacks, Clock clock,
+	KeyAgreementConnector(Callbacks callbacks, Clock clock,
 			CryptoComponent crypto, PluginManager pluginManager,
 			Executor ioExecutor) {
 		this.callbacks = callbacks;
@@ -83,7 +83,7 @@ class KeyAgreementConnector {
 		return new Payload(commitment, descriptors);
 	}
 
-	public void stopListening() {
+	void stopListening() {
 		LOG.info("Stopping BQP listeners");
 		for (KeyAgreementListener l : listeners) {
 			l.close();
diff --git a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
index b8a0418c07..f7b639bba9 100644
--- a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
+++ b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
@@ -363,6 +363,7 @@ class BluetoothPlugin implements DuplexPlugin {
 
 	@Override
 	public KeyAgreementListener createKeyAgreementListener(byte[] commitment) {
+		if (!running) return null;
 		// No truncation necessary because COMMIT_LENGTH = 16
 		String uuid = UUID.nameUUIDFromBytes(commitment).toString();
 		if (LOG.isLoggable(INFO)) LOG.info("Key agreement UUID " + uuid);
@@ -490,7 +491,7 @@ class BluetoothPlugin implements DuplexPlugin {
 
 		private final StreamConnectionNotifier ss;
 
-		public BluetoothKeyAgreementListener(TransportDescriptor descriptor,
+		BluetoothKeyAgreementListener(TransportDescriptor descriptor,
 				StreamConnectionNotifier ss) {
 			super(descriptor);
 			this.ss = ss;
-- 
GitLab