diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java index 1f0055ae71b3dc7d34ecf22f26b74cc392dec505..d070c90ea852f2cced900ab0317f239007634824 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java @@ -39,7 +39,7 @@ public class AndroidPluginModule { EventBus eventBus) { Context appContext = app.getApplicationContext(); DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(ioExecutor, - androidExecutor, appContext, random, backoffFactory); + androidExecutor, appContext, random, eventBus, backoffFactory); DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext, locationUtils, reporter, eventBus, torSocketFactory, backoffFactory); diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java index a5a28e005452d06230d34a04e27c25588bf7413d..4d0111652987c264ecbca9019fed24333ed4d5d8 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java @@ -12,6 +12,8 @@ import android.content.IntentFilter; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.data.BdfList; +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; @@ -22,6 +24,8 @@ import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent; +import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.util.AndroidUtils; @@ -63,7 +67,7 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; @MethodsNotNullByDefault @ParametersNotNullByDefault -class DroidtoothPlugin implements DuplexPlugin { +class DroidtoothPlugin implements DuplexPlugin, EventListener { private static final Logger LOG = Logger.getLogger(DroidtoothPlugin.class.getName()); @@ -150,9 +154,7 @@ class DroidtoothPlugin implements DuplexPlugin { } else { // Enable Bluetooth if settings allow if (callback.getSettings().getBoolean(PREF_BT_ENABLE, false)) { - wasEnabledByUs = true; - if (adapter.enable()) LOG.info("Enabling Bluetooth"); - else LOG.info("Could not enable Bluetooth"); + enableAdapter(); } else { LOG.info("Not enabling Bluetooth"); } @@ -243,13 +245,27 @@ class DroidtoothPlugin implements DuplexPlugin { return new DroidtoothTransportConnection(this, s); } + private void enableAdapter() { + if (adapter != null && !adapter.isEnabled()) { + if (adapter.enable()) { + LOG.info("Enabling Bluetooth"); + wasEnabledByUs = true; + } else { + LOG.info("Could not enable Bluetooth"); + } + } + } + @Override public void stop() { running = false; if (receiver != null) appContext.unregisterReceiver(receiver); tryToClose(socket); - // Disable Bluetooth if we enabled it and it's still enabled - if (wasEnabledByUs && adapter.isEnabled()) { + disableAdapter(); + } + + private void disableAdapter() { + if (adapter != null && adapter.isEnabled() && wasEnabledByUs) { if (adapter.disable()) LOG.info("Disabling Bluetooth"); else LOG.info("Could not disable Bluetooth"); } @@ -413,6 +429,33 @@ class DroidtoothPlugin implements DuplexPlugin { return StringUtils.macToString(mac); } + @Override + public void eventOccurred(Event e) { + if (e instanceof EnableBluetoothEvent) { + enableAdapterAsync(); + } else if (e instanceof DisableBluetoothEvent) { + disableAdapterAsync(); + } + } + + private void enableAdapterAsync() { + ioExecutor.execute(new Runnable() { + @Override + public void run() { + enableAdapter(); + } + }); + } + + private void disableAdapterAsync() { + ioExecutor.execute(new Runnable() { + @Override + public void run() { + disableAdapter(); + } + }); + } + private class BluetoothStateReceiver extends BroadcastReceiver { @Override diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPluginFactory.java index f612ad9e72cde1d0b4651bb18eb99b97af77edc4..38c95abefeb60008cee01d8a608fd8bf9ac62e9f 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPluginFactory.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.plugin.droidtooth; import android.content.Context; +import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; @@ -31,15 +32,18 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory { private final AndroidExecutor androidExecutor; private final Context appContext; private final SecureRandom secureRandom; + private final EventBus eventBus; private final BackoffFactory backoffFactory; public DroidtoothPluginFactory(Executor ioExecutor, AndroidExecutor androidExecutor, Context appContext, - SecureRandom secureRandom, BackoffFactory backoffFactory) { + SecureRandom secureRandom, EventBus eventBus, + BackoffFactory backoffFactory) { this.ioExecutor = ioExecutor; this.androidExecutor = androidExecutor; this.appContext = appContext; this.secureRandom = secureRandom; + this.eventBus = eventBus; this.backoffFactory = backoffFactory; } @@ -57,7 +61,10 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(DuplexPluginCallback callback) { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); - return new DroidtoothPlugin(ioExecutor, androidExecutor, appContext, - secureRandom, backoff, callback, MAX_LATENCY); + DroidtoothPlugin plugin = new DroidtoothPlugin(ioExecutor, + androidExecutor, appContext, secureRandom, backoff, callback, + MAX_LATENCY); + eventBus.addListener(plugin); + return plugin; } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/event/DisableBluetoothEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/event/DisableBluetoothEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..e9a53b27cd5ba0ff95f0cb0b0036a569a02567d5 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/event/DisableBluetoothEvent.java @@ -0,0 +1,15 @@ +package org.briarproject.bramble.api.plugin.event; + +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; + +/** + * An event that asks the Bluetooth plugin to disable the Bluetooth adapter if + * we previously enabled it. + */ +@Immutable +@NotNullByDefault +public class DisableBluetoothEvent extends Event { +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/event/EnableBluetoothEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/event/EnableBluetoothEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..148e55e6e3f2ddf57b40c8aa2f66b2a7bbf82e7c --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/event/EnableBluetoothEvent.java @@ -0,0 +1,14 @@ +package org.briarproject.bramble.api.plugin.event; + +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; + +/** + * An event asks the Bluetooth plugin to enable the Bluetooth adapter. + */ +@Immutable +@NotNullByDefault +public class EnableBluetoothEvent extends Event { +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java index 7a57a601b55f5efee400587dd605ea5485e9a1fe..c8e61ac655da4cce5bd648123924bd52249493a8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java @@ -22,6 +22,7 @@ import android.widget.Toast; import com.google.zxing.Result; import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.keyagreement.KeyAgreementTask; import org.briarproject.bramble.api.keyagreement.KeyAgreementTaskFactory; import org.briarproject.bramble.api.keyagreement.Payload; @@ -36,7 +37,7 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementWaitingEvent; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.bramble.api.system.AndroidExecutor; +import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.fragment.BaseEventFragment; @@ -73,10 +74,10 @@ public class ShowQrCodeFragment extends BaseEventFragment @Inject PayloadParser payloadParser; @Inject - AndroidExecutor androidExecutor; - @Inject @IoExecutor Executor ioExecutor; + @Inject + EventBus eventBus; private CameraView cameraView; private View statusView; @@ -160,12 +161,7 @@ public class ShowQrCodeFragment extends BaseEventFragment final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null && !adapter.isEnabled()) { waitingForBluetooth = true; - androidExecutor.runOnBackgroundThread(new Runnable() { - @Override - public void run() { - adapter.enable(); - } - }); + eventBus.broadcast(new EnableBluetoothEvent()); } else { startListening(); } @@ -385,7 +381,6 @@ public class ShowQrCodeFragment extends BaseEventFragment public void onReceive(Context ctx, Intent intent) { int state = intent.getIntExtra(EXTRA_STATE, 0); if (state == STATE_ON && waitingForBluetooth) { - LOG.info("Bluetooth enabled"); waitingForBluetooth = false; startListening(); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java index d149f15f0601c72488f3141cf1f1b338fd9fe157..12e64ea84eff3f56a1767e06baf46aa11924339a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java @@ -1,6 +1,5 @@ package org.briarproject.briar.android.settings; -import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Intent; import android.media.Ringtone; @@ -26,6 +25,8 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.BluetoothConstants; import org.briarproject.bramble.api.plugin.TorConstants; +import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent; +import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; @@ -338,17 +339,9 @@ public class SettingsFragment extends PreferenceFragmentCompat return true; } - private void enableOrDisableBluetooth(final boolean enable) { - final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - if (adapter != null) { - androidExecutor.runOnBackgroundThread(new Runnable() { - @Override - public void run() { - if (enable) adapter.enable(); - else adapter.disable(); - } - }); - } + private void enableOrDisableBluetooth(boolean enable) { + if (enable) eventBus.broadcast(new EnableBluetoothEvent()); + else eventBus.broadcast(new DisableBluetoothEvent()); } private void storeTorSettings(final int torSetting) {