From dac21cb3a040ed9a8c02b137c17daf181238a519 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 16 Jan 2020 14:09:22 +0000 Subject: [PATCH 01/15] Remove redundant casts. --- .../android/settings/SettingsFragment.java | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) 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 dc7096db0..ed071d8ec 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 @@ -163,28 +163,21 @@ public class SettingsFragment extends PreferenceFragmentCompat public void onCreatePreferences(Bundle bundle, String s) { addPreferencesFromResource(R.xml.settings); - language = (ListPreference) findPreference(LANGUAGE); + language = findPreference(LANGUAGE); setLanguageEntries(); - ListPreference theme = - (ListPreference) findPreference("pref_key_theme"); - enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth"); - torNetwork = (ListPreference) findPreference(TOR_NETWORK); - torMobile = (SwitchPreference) findPreference(TOR_MOBILE); - torOnlyWhenCharging = - (SwitchPreference) findPreference(TOR_ONLY_WHEN_CHARGING); - screenLock = (SwitchPreference) findPreference(PREF_SCREEN_LOCK); - screenLockTimeout = - (ListPreference) findPreference(PREF_SCREEN_LOCK_TIMEOUT); - notifyPrivateMessages = (SwitchPreference) findPreference( - "pref_key_notify_private_messages"); - notifyGroupMessages = (SwitchPreference) findPreference( - "pref_key_notify_group_messages"); - notifyForumPosts = (SwitchPreference) findPreference( - "pref_key_notify_forum_posts"); - notifyBlogPosts = (SwitchPreference) findPreference( - "pref_key_notify_blog_posts"); - notifyVibration = (SwitchPreference) findPreference( - "pref_key_notify_vibration"); + ListPreference theme = findPreference("pref_key_theme"); + enableBluetooth = findPreference("pref_key_bluetooth"); + torNetwork = findPreference(TOR_NETWORK); + torMobile = findPreference(TOR_MOBILE); + torOnlyWhenCharging = findPreference(TOR_ONLY_WHEN_CHARGING); + screenLock = findPreference(PREF_SCREEN_LOCK); + screenLockTimeout = findPreference(PREF_SCREEN_LOCK_TIMEOUT); + notifyPrivateMessages = + findPreference("pref_key_notify_private_messages"); + notifyGroupMessages = findPreference("pref_key_notify_group_messages"); + notifyForumPosts = findPreference("pref_key_notify_forum_posts"); + notifyBlogPosts = findPreference("pref_key_notify_blog_posts"); + notifyVibration = findPreference("pref_key_notify_vibration"); notifySound = findPreference("pref_key_notify_sound"); language.setOnPreferenceChangeListener(this); @@ -335,7 +328,8 @@ public class SettingsFragment extends PreferenceFragmentCompat boolean blocked = circumventionProvider.isTorProbablyBlocked(country); boolean useBridges = circumventionProvider.doBridgesWork(country); - String setting = getString(R.string.tor_network_setting_without_bridges); + String setting = + getString(R.string.tor_network_setting_without_bridges); if (blocked && useBridges) { setting = getString(R.string.tor_network_setting_with_bridges); } else if (blocked) { From 0940b8d5b99cb774ebaf77c7007faaee2dccf960 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 16 Jan 2020 14:41:03 +0000 Subject: [PATCH 02/15] Add toggle setting for Tor plugin. --- .../bramble/api/plugin/TorConstants.java | 1 + .../bramble/plugin/tor/TorPlugin.java | 22 ++++++++-- .../android/settings/SettingsFragment.java | 44 ++++++++++++++----- briar-android/src/main/res/values/arrays.xml | 2 - briar-android/src/main/res/values/strings.xml | 7 +-- briar-android/src/main/res/xml/settings.xml | 8 ++++ 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java index 2d808eaa9..6199ddd35 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java @@ -13,6 +13,7 @@ public interface TorConstants { int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds + String PREF_TOR_ENABLE = "enable"; String PREF_TOR_NETWORK = "network2"; String PREF_TOR_PORT = "port"; String PREF_TOR_MOBILE = "useMobileData"; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index f284999dd..01adb72e6 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -75,6 +75,7 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.ID; +import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ENABLE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC; @@ -200,7 +201,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } } // Load the settings - settings = callback.getSettings(); + settings = migrateSettings(callback.getSettings()); // Install or update the assets if necessary if (!assetsAreUpToDate()) installAssets(); if (cookieFile.exists() && !cookieFile.delete()) @@ -288,6 +289,18 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { bind(); } + // TODO: Remove after a reasonable migration period (added 2020-01-16) + private Settings migrateSettings(Settings settings) { + int network = settings.getInt(PREF_TOR_NETWORK, + PREF_TOR_NETWORK_AUTOMATIC); + if (network == PREF_TOR_NETWORK_NEVER) { + settings.putInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC); + settings.putBoolean(PREF_TOR_ENABLE, false); + callback.mergeSettings(settings); + } + return settings; + } + private boolean assetsAreUpToDate() { return doneFile.lastModified() > getLastUpdateTime(); } @@ -763,6 +776,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { String country = locationUtils.getCurrentCountry(); boolean blocked = circumventionProvider.isTorProbablyBlocked(country); + boolean enabledByUser = settings.getBoolean(PREF_TOR_ENABLE, true); int network = settings.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC); boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true); @@ -785,7 +799,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (!online) { LOG.info("Disabling network, device is offline"); - } else if (network == PREF_TOR_NETWORK_NEVER) { + } else if (!enabledByUser) { LOG.info("Disabling network, user has disabled Tor"); disabledBySettings = true; reasonDisabled = REASON_USER; @@ -866,11 +880,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { callback.pluginStateChanged(getState()); } + // Doesn't affect getState() synchronized void setTorStarted() { torStarted = true; } - @SuppressWarnings("BooleanMethodIsAlwaysInverted") synchronized boolean isTorRunning() { return torStarted && !stopped; } @@ -910,12 +924,14 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { callback.pluginStateChanged(getState()); } + // Doesn't affect getState() synchronized boolean setServerSocket(ServerSocket ss) { if (stopped || serverSocket != null) return false; serverSocket = ss; return true; } + // Doesn't affect getState() synchronized void clearServerSocket(ServerSocket ss) { if (serverSocket == ss) serverSocket = null; } 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 ed071d8ec..00c3ef84f 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 @@ -73,6 +73,7 @@ import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; +import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ENABLE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC; @@ -105,16 +106,19 @@ public class SettingsFragment extends PreferenceFragmentCompat implements EventListener, OnPreferenceChangeListener { public static final String SETTINGS_NAMESPACE = "android-ui"; - public static final String BT_NAMESPACE = BluetoothConstants.ID.getString(); - public static final String TOR_NAMESPACE = TorConstants.ID.getString(); public static final String LANGUAGE = "pref_key_language"; public static final String PREF_SCREEN_LOCK = "pref_key_lock"; public static final String PREF_SCREEN_LOCK_TIMEOUT = "pref_key_lock_timeout"; public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in"; - public static final String TOR_NETWORK = "pref_key_tor_network"; - public static final String TOR_MOBILE = "pref_key_tor_mobile_data"; - public static final String TOR_ONLY_WHEN_CHARGING = + + private static final String BT_NAMESPACE = + BluetoothConstants.ID.getString(); + private static final String TOR_NAMESPACE = TorConstants.ID.getString(); + private static final String TOR_ENABLE = "pref_key_tor_enable"; + private static final String TOR_NETWORK = "pref_key_tor_network"; + private static final String TOR_MOBILE = "pref_key_tor_mobile_data"; + private static final String TOR_ONLY_WHEN_CHARGING = "pref_key_tor_only_when_charging"; private static final Logger LOG = @@ -123,6 +127,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private SettingsActivity listener; private ListPreference language; private ListPreference enableBluetooth; + private SwitchPreference enableTor; private ListPreference torNetwork; private SwitchPreference torMobile; private SwitchPreference torOnlyWhenCharging; @@ -167,6 +172,7 @@ public class SettingsFragment extends PreferenceFragmentCompat setLanguageEntries(); ListPreference theme = findPreference("pref_key_theme"); enableBluetooth = findPreference("pref_key_bluetooth"); + enableTor = findPreference(TOR_ENABLE); torNetwork = findPreference(TOR_NETWORK); torMobile = findPreference(TOR_MOBILE); torOnlyWhenCharging = findPreference(TOR_ONLY_WHEN_CHARGING); @@ -187,8 +193,7 @@ public class SettingsFragment extends PreferenceFragmentCompat UiUtils.setTheme(getActivity(), (String) newValue); // bring up parent activity, so it can change its theme as well // upstream bug: https://issuetracker.google.com/issues/38352704 - Intent intent = - new Intent(getActivity(), ENTRY_ACTIVITY); + Intent intent = new Intent(getActivity(), ENTRY_ACTIVITY); intent.setFlags( FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK); startActivity(intent); @@ -200,6 +205,7 @@ public class SettingsFragment extends PreferenceFragmentCompat return true; }); enableBluetooth.setOnPreferenceChangeListener(this); + enableTor.setOnPreferenceChangeListener(this); torNetwork.setOnPreferenceChangeListener(this); torMobile.setOnPreferenceChangeListener(this); torOnlyWhenCharging.setOnPreferenceChangeListener(this); @@ -365,6 +371,10 @@ public class SettingsFragment extends PreferenceFragmentCompat btSettings.getBoolean(PREF_BT_ENABLE, false); enableBluetooth.setValue(Boolean.toString(btEnabledSetting)); + boolean torEnabledSetting = + torSettings.getBoolean(PREF_TOR_ENABLE, true); + enableTor.setChecked(torEnabledSetting); + int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC); torNetwork.setValue(Integer.toString(torNetworkSetting)); @@ -437,9 +447,10 @@ public class SettingsFragment extends PreferenceFragmentCompat // - pref_key_lock (screenLock -> displayScreenLockSetting()) // - pref_key_lock_timeout (screenLockTimeout) enableBluetooth.setEnabled(enabled); - torNetwork.setEnabled(enabled); - torMobile.setEnabled(enabled); - torOnlyWhenCharging.setEnabled(enabled); + enableTor.setEnabled(enabled); + torNetwork.setEnabled(enabled && enableTor.isChecked()); + torMobile.setEnabled(enabled && enableTor.isChecked()); + torOnlyWhenCharging.setEnabled(enabled && enableTor.isChecked()); if (!enabled) screenLock.setEnabled(false); notifyPrivateMessages.setEnabled(enabled); notifyGroupMessages.setEnabled(enabled); @@ -541,6 +552,13 @@ public class SettingsFragment extends PreferenceFragmentCompat } else if (preference == enableBluetooth) { boolean btSetting = Boolean.valueOf((String) newValue); storeBluetoothSettings(btSetting); + } else if (preference == enableTor) { + boolean torEnabledSetting = (Boolean) newValue; + torNetwork.setEnabled(torNetwork.isEnabled() && torEnabledSetting); + torMobile.setEnabled(torMobile.isEnabled() && torEnabledSetting); + torOnlyWhenCharging.setEnabled(torOnlyWhenCharging.isEnabled() && + torEnabledSetting); + storeTorEnabledSetting(torEnabledSetting); } else if (preference == torNetwork) { int torNetworkSetting = Integer.valueOf((String) newValue); storeTorNetworkSetting(torNetworkSetting); @@ -604,6 +622,12 @@ public class SettingsFragment extends PreferenceFragmentCompat builder.show(); } + private void storeTorEnabledSetting(boolean torEnabledSetting) { + Settings s = new Settings(); + s.putBoolean(PREF_TOR_ENABLE, torEnabledSetting); + mergeSettings(s, TOR_NAMESPACE); + } + private void storeTorNetworkSetting(int torNetworkSetting) { Settings s = new Settings(); s.putInt(PREF_TOR_NETWORK, torNetworkSetting); diff --git a/briar-android/src/main/res/values/arrays.xml b/briar-android/src/main/res/values/arrays.xml index a7a950e78..3ed985eec 100644 --- a/briar-android/src/main/res/values/arrays.xml +++ b/briar-android/src/main/res/values/arrays.xml @@ -13,13 +13,11 @@ @string/tor_network_setting_automatic @string/tor_network_setting_without_bridges @string/tor_network_setting_with_bridges - @string/tor_network_setting_never 0 1 2 - 3 diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index d7e5d7090..9294223f7 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -441,12 +441,13 @@ Automatic (Daytime) System Default - - Networks + + Connections Connect via Bluetooth Whenever contacts are nearby Only when adding contacts - Connect via Internet (Tor) + Connect to contacts via Internet (Tor) + Connection method for Internet (Tor) Automatic based on location Use Tor without bridges Use Tor with bridges diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index d45a80f86..b6c0b86ce 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -39,6 +39,14 @@ android:title="@string/bluetooth_setting" app:iconSpaceReserved="false"/> + + Date: Thu, 16 Jan 2020 14:51:32 +0000 Subject: [PATCH 03/15] Convert Bluetooth setting to a switch. --- .../briar/android/settings/SettingsFragment.java | 10 ++++++---- briar-android/src/main/res/values/arrays.xml | 10 +--------- briar-android/src/main/res/values/strings.xml | 4 +--- briar-android/src/main/res/xml/settings.xml | 6 ++---- 4 files changed, 10 insertions(+), 20 deletions(-) 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 00c3ef84f..2d469d5ce 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 @@ -114,6 +114,8 @@ public class SettingsFragment extends PreferenceFragmentCompat private static final String BT_NAMESPACE = BluetoothConstants.ID.getString(); + private static final String BT_ENABLE = "pref_key_bluetooth"; + private static final String TOR_NAMESPACE = TorConstants.ID.getString(); private static final String TOR_ENABLE = "pref_key_tor_enable"; private static final String TOR_NETWORK = "pref_key_tor_network"; @@ -126,7 +128,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private SettingsActivity listener; private ListPreference language; - private ListPreference enableBluetooth; + private SwitchPreference enableBluetooth; private SwitchPreference enableTor; private ListPreference torNetwork; private SwitchPreference torMobile; @@ -171,7 +173,7 @@ public class SettingsFragment extends PreferenceFragmentCompat language = findPreference(LANGUAGE); setLanguageEntries(); ListPreference theme = findPreference("pref_key_theme"); - enableBluetooth = findPreference("pref_key_bluetooth"); + enableBluetooth = findPreference(BT_ENABLE); enableTor = findPreference(TOR_ENABLE); torNetwork = findPreference(TOR_NETWORK); torMobile = findPreference(TOR_MOBILE); @@ -369,7 +371,7 @@ public class SettingsFragment extends PreferenceFragmentCompat boolean btEnabledSetting = btSettings.getBoolean(PREF_BT_ENABLE, false); - enableBluetooth.setValue(Boolean.toString(btEnabledSetting)); + enableBluetooth.setChecked(btEnabledSetting); boolean torEnabledSetting = torSettings.getBoolean(PREF_TOR_ENABLE, true); @@ -550,7 +552,7 @@ public class SettingsFragment extends PreferenceFragmentCompat languageChanged((String) newValue); return false; } else if (preference == enableBluetooth) { - boolean btSetting = Boolean.valueOf((String) newValue); + boolean btSetting = (Boolean) newValue; storeBluetoothSettings(btSetting); } else if (preference == enableTor) { boolean torEnabledSetting = (Boolean) newValue; diff --git a/briar-android/src/main/res/values/arrays.xml b/briar-android/src/main/res/values/arrays.xml index 3ed985eec..8a7313b73 100644 --- a/briar-android/src/main/res/values/arrays.xml +++ b/briar-android/src/main/res/values/arrays.xml @@ -1,14 +1,5 @@ - - true - false - - - @string/bluetooth_setting_enabled - @string/bluetooth_setting_disabled - - @string/tor_network_setting_automatic @string/tor_network_setting_without_bridges @@ -64,6 +55,7 @@ zh-CN zh-TW + @string/pref_theme_light @string/pref_theme_dark diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 9294223f7..ea4617969 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -443,9 +443,7 @@ Connections - Connect via Bluetooth - Whenever contacts are nearby - Only when adding contacts + Connect to contacts via Bluetooth Connect to contacts via Internet (Tor) Connection method for Internet (Tor) Automatic based on location diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index b6c0b86ce..f06bd78d7 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -29,14 +29,12 @@ android:layout="@layout/preferences_category" android:title="@string/network_settings_title"> - Date: Thu, 16 Jan 2020 15:50:44 +0000 Subject: [PATCH 04/15] Update semantics of Bluetooth setting. The setting now enables/disables the plugin, not just contact connections. The key agreement UI will need to be updated to change the setting if the user agrees to use Bluetooth. --- .../api/plugin/BluetoothConstants.java | 3 + .../plugin/bluetooth/BluetoothPlugin.java | 100 +++++++++++------- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java index 785aee2b3..9176bdeb4 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java @@ -10,4 +10,7 @@ public interface BluetoothConstants { String PROP_UUID = "uuid"; String PREF_BT_ENABLE = "enable"; + + int REASON_USER = 1; + int REASON_NO_BT_ADAPTER = 2; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index e15a3e623..f2ceb2afc 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -9,6 +9,7 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.keyagreement.event.KeyAgreementListeningEvent; import org.briarproject.bramble.api.keyagreement.event.KeyAgreementStoppedListeningEvent; +import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; @@ -48,6 +49,7 @@ import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID; +import static org.briarproject.bramble.api.plugin.BluetoothConstants.REASON_NO_BT_ADAPTER; import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; @@ -76,7 +78,6 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { protected final PluginState state = new PluginState(); - private volatile boolean contactConnections = false; private volatile String contactConnectionsUuid = null; abstract void initialiseAdapter() throws IOException; @@ -126,16 +127,18 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { LOG.info("Bluetooth enabled"); // We may not have been able to get the local address before ioExecutor.execute(this::updateProperties); - if (shouldAllowContactConnections()) bind(); - callback.pluginStateChanged(getState()); + if (getState() == INACTIVE) bind(); } void onAdapterDisabled() { LOG.info("Bluetooth disabled"); connectionLimiter.allConnectionsClosed(); // The server socket may not have been closed automatically - tryToClose(state.clearServerSocket()); - callback.pluginStateChanged(getState()); + SS ss = state.clearServerSocket(); + if (ss != null) { + LOG.info("Closing server socket"); + tryToClose(ss); + } } @Override @@ -160,29 +163,22 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { try { initialiseAdapter(); } catch (IOException e) { + state.setNoAdapter(); throw new PluginException(e); } updateProperties(); - state.setStarted(); - loadSettings(callback.getSettings()); - if (shouldAllowContactConnections()) { + Settings settings = callback.getSettings(); + boolean enabledByUser = settings.getBoolean(PREF_BT_ENABLE, false); + state.setStarted(enabledByUser); + if (enabledByUser) { if (isAdapterEnabled()) bind(); else enableAdapter(); } } - private void loadSettings(Settings settings) { - contactConnections = settings.getBoolean(PREF_BT_ENABLE, false); - } - - private boolean shouldAllowContactConnections() { - return contactConnections; - } - private void bind() { ioExecutor.execute(() -> { - if (!shouldAllowContactConnections() || getState() != ACTIVE) - return; + if (getState() != INACTIVE) return; // Bind a server socket to accept connections from contacts SS ss; try { @@ -191,8 +187,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { logException(LOG, WARNING, e); return; } - if (!shouldAllowContactConnections() || - !state.setServerSocket(ss)) { + if (!state.setServerSocket(ss)) { LOG.info("Closing redundant server socket"); tryToClose(ss); return; @@ -259,7 +254,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { @Override public int getReasonDisabled() { - return getState() == DISABLED ? REASON_STARTING_STOPPING : -1; + return state.getReasonDisabled(); } @Override @@ -275,7 +270,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { @Override public void poll(Collection> properties) { - if (!shouldAllowContactConnections() || getState() != ACTIVE) return; + if (getState() != ACTIVE) return; backoff.increment(); for (Pair p : properties) { connect(p.getFirst(), p.getSecond()); @@ -288,8 +283,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { String uuid = p.get(PROP_UUID); if (isNullOrEmpty(uuid)) return; ioExecutor.execute(() -> { - if (!shouldAllowContactConnections() || getState() != ACTIVE) - return; + if (getState() != ACTIVE) return; if (!connectionLimiter.canOpenContactConnection()) return; DuplexTransportConnection d = createConnection(p); if (d != null) { @@ -333,8 +327,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { @Override public DuplexTransportConnection createConnection(TransportProperties p) { - if (!shouldAllowContactConnections() || getState() != ACTIVE) - return null; + if (getState() != ACTIVE) return null; if (!connectionLimiter.canOpenContactConnection()) return null; String address = p.get(PROP_ADDRESS); if (isNullOrEmpty(address)) return null; @@ -439,16 +432,18 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { } } + @IoExecutor private void onSettingsUpdated(Settings settings) { - boolean wasAllowed = shouldAllowContactConnections(); - loadSettings(settings); - boolean isAllowed = shouldAllowContactConnections(); - if (wasAllowed && !isAllowed) { - LOG.info("Contact connections disabled"); - tryToClose(state.clearServerSocket()); + boolean enabledByUser = settings.getBoolean(PREF_BT_ENABLE, false); + SS ss = state.setEnabledByUser(enabledByUser); + State s = getState(); + callback.pluginStateChanged(s); + if (ss != null) { + LOG.info("Disabled by user, closing server socket"); + tryToClose(ss); disableAdapterIfEnabledByUs(); - } else if (!wasAllowed && isAllowed) { - LOG.info("Contact connections enabled"); + } else if (s == INACTIVE) { + LOG.info("Enabled by user, opening server socket"); if (isAdapterEnabled()) bind(); else enableAdapter(); } @@ -482,13 +477,18 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { protected class PluginState { @GuardedBy("this") - private boolean started = false, stopped = false; + private boolean started = false, + stopped = false, + noAdapter = false, + enabledByUser = false; + @GuardedBy("this") @Nullable private SS serverSocket = null; - synchronized void setStarted() { + synchronized void setStarted(boolean enabledByUser) { started = true; + this.enabledByUser = enabledByUser; callback.pluginStateChanged(getState()); } @@ -501,6 +501,23 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { return ss; } + synchronized void setNoAdapter() { + noAdapter = true; + callback.pluginStateChanged(getState()); + } + + @Nullable + synchronized SS setEnabledByUser(boolean enabledByUser) { + this.enabledByUser = enabledByUser; + SS ss = null; + if (!enabledByUser) { + ss = serverSocket; + serverSocket = null; + } + callback.pluginStateChanged(getState()); + return ss; + } + synchronized boolean setServerSocket(SS ss) { if (stopped || serverSocket != null) return false; serverSocket = ss; @@ -512,12 +529,19 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { synchronized SS clearServerSocket() { SS ss = serverSocket; serverSocket = null; + callback.pluginStateChanged(getState()); return ss; } synchronized State getState() { - if (!started || stopped) return DISABLED; - return isAdapterEnabled() ? ACTIVE : INACTIVE; + if (!started || stopped || !enabledByUser) return DISABLED; + return serverSocket == null ? INACTIVE : ACTIVE; + } + + synchronized int getReasonDisabled() { + if (noAdapter && !stopped) return REASON_NO_BT_ADAPTER; + if (!started || stopped) return REASON_STARTING_STOPPING; + return enabledByUser ? -1 : REASON_USER; } } } From 9184bf6afc9280e98347de5696269f7c7c601ed0 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 16 Jan 2020 17:51:49 +0000 Subject: [PATCH 05/15] Add toggle setting for LAN plugin. --- .../plugin/tcp/AndroidLanTcpPlugin.java | 9 ++- .../bramble/api/plugin/TcpConstants.java | 8 +++ .../plugin/tcp/LanTcpPluginFactory.java | 11 +++- .../bramble/plugin/tcp/TcpPlugin.java | 63 +++++++++++++++++-- .../plugin/tcp/WanTcpPluginFactory.java | 9 ++- .../bramble/plugin/DesktopPluginModule.java | 4 +- .../android/settings/SettingsFragment.java | 33 +++++++++- briar-android/src/main/res/values/strings.xml | 1 + briar-android/src/main/res/xml/settings.xml | 8 +++ 9 files changed, 127 insertions(+), 19 deletions(-) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java index 577a773e7..d4a8a417b 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java @@ -9,11 +9,11 @@ import android.net.wifi.WifiManager; import org.briarproject.bramble.PoliteExecutor; import org.briarproject.bramble.api.event.Event; -import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.network.event.NetworkStatusEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.PluginCallback; +import org.briarproject.bramble.api.settings.Settings; import java.io.IOException; import java.net.InetAddress; @@ -36,10 +36,11 @@ import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; +import static org.briarproject.bramble.api.plugin.TcpConstants.PREF_TCP_ENABLE; import static org.briarproject.bramble.util.IoUtils.tryToClose; @NotNullByDefault -class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { +class AndroidLanTcpPlugin extends LanTcpPlugin { private static final Logger LOG = getLogger(AndroidLanTcpPlugin.class.getName()); @@ -83,7 +84,8 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { @Override public void start() { if (used.getAndSet(true)) throw new IllegalStateException(); - state.setStarted(); + Settings settings = callback.getSettings(); + state.setStarted(settings.getBoolean(PREF_TCP_ENABLE, false)); updateConnectionStatus(); } @@ -136,6 +138,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { @Override public void eventOccurred(Event e) { + super.eventOccurred(e); if (e instanceof NetworkStatusEvent) updateConnectionStatus(); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java new file mode 100644 index 000000000..8e008b0ae --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java @@ -0,0 +1,8 @@ +package org.briarproject.bramble.api.plugin; + +public interface TcpConstants { + + String PREF_TCP_ENABLE = "enable"; + + int REASON_USER = 1; +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java index caa4c6a2e..7b0d20463 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.plugin.tcp; +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; @@ -25,11 +26,13 @@ public class LanTcpPluginFactory implements DuplexPluginFactory { private static final double BACKOFF_BASE = 1.2; private final Executor ioExecutor; + private final EventBus eventBus; private final BackoffFactory backoffFactory; - public LanTcpPluginFactory(Executor ioExecutor, + public LanTcpPluginFactory(Executor ioExecutor, EventBus eventBus, BackoffFactory backoffFactory) { this.ioExecutor = ioExecutor; + this.eventBus = eventBus; this.backoffFactory = backoffFactory; } @@ -47,7 +50,9 @@ public class LanTcpPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(PluginCallback callback) { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); - return new LanTcpPlugin(ioExecutor, backoff, callback, MAX_LATENCY, - MAX_IDLE_TIME); + LanTcpPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, + MAX_LATENCY, MAX_IDLE_TIME); + eventBus.addListener(plugin); + return plugin; } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java index d4713fecf..1ac111bb0 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java @@ -3,7 +3,10 @@ package org.briarproject.bramble.plugin.tcp; import org.briarproject.bramble.PoliteExecutor; import org.briarproject.bramble.api.Pair; 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.KeyAgreementListener; +import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; @@ -15,6 +18,8 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; import org.briarproject.bramble.api.rendezvous.RendezvousEndpoint; +import org.briarproject.bramble.api.settings.Settings; +import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import java.io.IOException; import java.net.InetAddress; @@ -46,6 +51,8 @@ import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; +import static org.briarproject.bramble.api.plugin.TcpConstants.PREF_TCP_ENABLE; +import static org.briarproject.bramble.api.plugin.TcpConstants.REASON_USER; import static org.briarproject.bramble.util.IoUtils.tryToClose; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; @@ -53,7 +60,7 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @MethodsNotNullByDefault @ParametersNotNullByDefault -abstract class TcpPlugin implements DuplexPlugin { +abstract class TcpPlugin implements DuplexPlugin, EventListener { private static final Logger LOG = getLogger(TcpPlugin.class.getName()); @@ -119,7 +126,8 @@ abstract class TcpPlugin implements DuplexPlugin { @Override public void start() { if (used.getAndSet(true)) throw new IllegalStateException(); - state.setStarted(); + Settings settings = callback.getSettings(); + state.setStarted(settings.getBoolean(PREF_TCP_ENABLE, false)); bind(); } @@ -197,7 +205,7 @@ abstract class TcpPlugin implements DuplexPlugin { @Override public int getReasonDisabled() { - return getState() == DISABLED ? REASON_STARTING_STOPPING : -1; + return state.getReasonDisabled(); } @Override @@ -331,18 +339,44 @@ abstract class TcpPlugin implements DuplexPlugin { } } + @Override + public void eventOccurred(Event e) { + if (e instanceof SettingsUpdatedEvent) { + SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; + if (s.getNamespace().equals(getId().getString())) + ioExecutor.execute(() -> onSettingsUpdated(s.getSettings())); + } + } + + @IoExecutor + private void onSettingsUpdated(Settings settings) { + boolean enabledByUser = settings.getBoolean(PREF_TCP_ENABLE, false); + ServerSocket ss = state.setEnabledByUser(enabledByUser); + State s = getState(); + callback.pluginStateChanged(s); + if (ss != null) { + LOG.info("Disabled by user, closing server socket"); + tryToClose(ss, LOG, WARNING); + } else if (s == INACTIVE) { + LOG.info("Enabled by user, opening server socket"); + bind(); + } + } + @ThreadSafe @NotNullByDefault protected class PluginState { @GuardedBy("this") - private boolean started = false, stopped = false; + private boolean started = false, stopped = false, enabledByUser = false; + @GuardedBy("this") @Nullable private ServerSocket serverSocket = null; - synchronized void setStarted() { + synchronized void setStarted(boolean enabledByUser) { started = true; + this.enabledByUser = enabledByUser; callback.pluginStateChanged(getState()); } @@ -355,6 +389,18 @@ abstract class TcpPlugin implements DuplexPlugin { return ss; } + @Nullable + synchronized ServerSocket setEnabledByUser(boolean enabledByUser) { + this.enabledByUser = enabledByUser; + ServerSocket ss = null; + if (!enabledByUser) { + ss = serverSocket; + serverSocket = null; + } + callback.pluginStateChanged(getState()); + return ss; + } + @Nullable synchronized ServerSocket getServerSocket() { return serverSocket; @@ -373,8 +419,13 @@ abstract class TcpPlugin implements DuplexPlugin { } synchronized State getState() { - if (!started || stopped) return DISABLED; + if (!started || stopped || !enabledByUser) return DISABLED; return serverSocket == null ? INACTIVE : ACTIVE; } + + synchronized int getReasonDisabled() { + if (!started || stopped) return REASON_STARTING_STOPPING; + return enabledByUser ? -1 : REASON_USER; + } } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java index 440b208f1..7237f71e1 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.plugin.tcp; +import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.ShutdownManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; @@ -26,12 +27,14 @@ public class WanTcpPluginFactory implements DuplexPluginFactory { private static final double BACKOFF_BASE = 1.2; private final Executor ioExecutor; + private final EventBus eventBus; private final BackoffFactory backoffFactory; private final ShutdownManager shutdownManager; - public WanTcpPluginFactory(Executor ioExecutor, + public WanTcpPluginFactory(Executor ioExecutor, EventBus eventBus, BackoffFactory backoffFactory, ShutdownManager shutdownManager) { this.ioExecutor = ioExecutor; + this.eventBus = eventBus; this.backoffFactory = backoffFactory; this.shutdownManager = shutdownManager; } @@ -50,8 +53,10 @@ public class WanTcpPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(PluginCallback callback) { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); - return new WanTcpPlugin(ioExecutor, backoff, + WanTcpPlugin plugin = new WanTcpPlugin(ioExecutor, backoff, new PortMapperImpl(shutdownManager), callback, MAX_LATENCY, MAX_IDLE_TIME); + eventBus.addListener(plugin); + return plugin; } } diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java index 5b4cf7014..ce7ceb48b 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java @@ -37,9 +37,9 @@ public class DesktopPluginModule extends PluginModule { backoffFactory); DuplexPluginFactory modem = new ModemPluginFactory(ioExecutor, reliabilityFactory); - DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor, + DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor, eventBus, backoffFactory); - DuplexPluginFactory wan = new WanTcpPluginFactory(ioExecutor, + DuplexPluginFactory wan = new WanTcpPluginFactory(ioExecutor, eventBus, backoffFactory, shutdownManager); Collection duplex = asList(bluetooth, modem, lan, wan); 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 2d469d5ce..0cc96c6f8 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 @@ -21,6 +21,7 @@ import org.briarproject.bramble.api.event.EventListener; 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.LanTcpConstants; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.SettingsManager; @@ -73,6 +74,7 @@ import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; +import static org.briarproject.bramble.api.plugin.TcpConstants.PREF_TCP_ENABLE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ENABLE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; @@ -116,6 +118,9 @@ public class SettingsFragment extends PreferenceFragmentCompat BluetoothConstants.ID.getString(); private static final String BT_ENABLE = "pref_key_bluetooth"; + private static final String WIFI_NAMESPACE = LanTcpConstants.ID.getString(); + private static final String WIFI_ENABLE = "pref_key_wifi"; + private static final String TOR_NAMESPACE = TorConstants.ID.getString(); private static final String TOR_ENABLE = "pref_key_tor_enable"; private static final String TOR_NETWORK = "pref_key_tor_network"; @@ -129,6 +134,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private SettingsActivity listener; private ListPreference language; private SwitchPreference enableBluetooth; + private SwitchPreference enableWifi; private SwitchPreference enableTor; private ListPreference torNetwork; private SwitchPreference torMobile; @@ -144,7 +150,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private Preference notifySound; // Fields that are accessed from background threads must be volatile - private volatile Settings settings, btSettings, torSettings; + private volatile Settings settings, btSettings, wifiSettings, torSettings; private volatile boolean settingsLoaded = false; @Inject @@ -174,6 +180,7 @@ public class SettingsFragment extends PreferenceFragmentCompat setLanguageEntries(); ListPreference theme = findPreference("pref_key_theme"); enableBluetooth = findPreference(BT_ENABLE); + enableWifi = findPreference(WIFI_ENABLE); enableTor = findPreference(TOR_ENABLE); torNetwork = findPreference(TOR_NETWORK); torMobile = findPreference(TOR_MOBILE); @@ -207,6 +214,7 @@ public class SettingsFragment extends PreferenceFragmentCompat return true; }); enableBluetooth.setOnPreferenceChangeListener(this); + enableWifi.setOnPreferenceChangeListener(this); enableTor.setOnPreferenceChangeListener(this); torNetwork.setOnPreferenceChangeListener(this); torMobile.setOnPreferenceChangeListener(this); @@ -354,6 +362,7 @@ public class SettingsFragment extends PreferenceFragmentCompat long start = now(); settings = settingsManager.getSettings(SETTINGS_NAMESPACE); btSettings = settingsManager.getSettings(BT_NAMESPACE); + wifiSettings = settingsManager.getSettings(WIFI_NAMESPACE); torSettings = settingsManager.getSettings(TOR_NAMESPACE); settingsLoaded = true; logDuration(LOG, "Loading settings", start); @@ -373,6 +382,10 @@ public class SettingsFragment extends PreferenceFragmentCompat btSettings.getBoolean(PREF_BT_ENABLE, false); enableBluetooth.setChecked(btEnabledSetting); + boolean wifiEnabledSetting = + wifiSettings.getBoolean(PREF_TCP_ENABLE, false); + enableWifi.setChecked(wifiEnabledSetting); + boolean torEnabledSetting = torSettings.getBoolean(PREF_TOR_ENABLE, true); enableTor.setChecked(torEnabledSetting); @@ -449,6 +462,7 @@ public class SettingsFragment extends PreferenceFragmentCompat // - pref_key_lock (screenLock -> displayScreenLockSetting()) // - pref_key_lock_timeout (screenLockTimeout) enableBluetooth.setEnabled(enabled); + enableWifi.setEnabled(enabled); enableTor.setEnabled(enabled); torNetwork.setEnabled(enabled && enableTor.isChecked()); torMobile.setEnabled(enabled && enableTor.isChecked()); @@ -553,7 +567,10 @@ public class SettingsFragment extends PreferenceFragmentCompat return false; } else if (preference == enableBluetooth) { boolean btSetting = (Boolean) newValue; - storeBluetoothSettings(btSetting); + storeBluetoothSetting(btSetting); + } else if (preference == enableWifi) { + boolean wifiSetting = (Boolean) newValue; + storeWifiSetting(wifiSetting); } else if (preference == enableTor) { boolean torEnabledSetting = (Boolean) newValue; torNetwork.setEnabled(torNetwork.isEnabled() && torEnabledSetting); @@ -648,12 +665,18 @@ public class SettingsFragment extends PreferenceFragmentCompat mergeSettings(s, TOR_NAMESPACE); } - private void storeBluetoothSettings(boolean btSetting) { + private void storeBluetoothSetting(boolean btSetting) { Settings s = new Settings(); s.putBoolean(PREF_BT_ENABLE, btSetting); mergeSettings(s, BT_NAMESPACE); } + private void storeWifiSetting(boolean wifiSetting) { + Settings s = new Settings(); + s.putBoolean(PREF_TCP_ENABLE, wifiSetting); + mergeSettings(s, WIFI_NAMESPACE); + } + private void storeSettings(Settings s) { mergeSettings(s, SETTINGS_NAMESPACE); } @@ -716,6 +739,10 @@ public class SettingsFragment extends PreferenceFragmentCompat LOG.info("Bluetooth settings updated"); btSettings = s.getSettings(); displaySettings(); + } else if (namespace.equals(WIFI_NAMESPACE)) { + LOG.info("Wifi settings updated"); + wifiSettings = s.getSettings(); + displaySettings(); } else if (namespace.equals(TOR_NAMESPACE)) { LOG.info("Tor settings updated"); torSettings = s.getSettings(); diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index ea4617969..902a56c89 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -444,6 +444,7 @@ Connections Connect to contacts via Bluetooth + Connect to contacts on the same Wi-Fi network Connect to contacts via Internet (Tor) Connection method for Internet (Tor) Automatic based on location diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index f06bd78d7..b1b40552f 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -37,6 +37,14 @@ android:widgetLayout="@layout/preference_switch_compat" app:iconSpaceReserved="false"/> + + Date: Thu, 16 Jan 2020 17:56:31 +0000 Subject: [PATCH 06/15] Make REASON_USER into a generic reason code. --- .../bramble/api/plugin/BluetoothConstants.java | 2 +- .../briarproject/bramble/api/plugin/Plugin.java | 16 +++++++++++----- .../bramble/api/plugin/TcpConstants.java | 2 -- .../bramble/api/plugin/TorConstants.java | 2 +- .../bramble/plugin/tcp/TcpPlugin.java | 1 - .../bramble/plugin/tor/TorPlugin.java | 1 - 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java index 9176bdeb4..915dfbbab 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/BluetoothConstants.java @@ -11,6 +11,6 @@ public interface BluetoothConstants { String PREF_BT_ENABLE = "enable"; - int REASON_USER = 1; + // Reason code returned by Plugin#getReasonDisabled() int REASON_NO_BT_ADAPTER = 2; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java index b7247967c..ee26500f1 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java @@ -35,12 +35,18 @@ public interface Plugin { } /** - * Reason code returned by {@link #getReasonDisabled()} ()} to indicate - * that the plugin is disabled because it has not been started or has been + * Reason code returned by {@link #getReasonDisabled()} to indicate that + * the plugin is disabled because it has not been started or has been * stopped. */ int REASON_STARTING_STOPPING = 0; + /** + * Reason code returned by {@link #getReasonDisabled()} to indicate that + * the plugin has been disabled by the user. + */ + int REASON_USER = 1; + /** * Returns the plugin's transport identifier. */ @@ -75,9 +81,9 @@ public interface Plugin { * Returns an integer code indicating why the plugin is * {@link State#DISABLED disabled}, or -1 if the plugin is not disabled. *

- * The codes used are plugin-specific, except the generic code - * {@link #REASON_STARTING_STOPPING}, which may be used by - * any plugin. + * The codes used are plugin-specific, except the generic codes + * {@link #REASON_STARTING_STOPPING} and {@link #REASON_USER}, which may + * be used by any plugin. */ int getReasonDisabled(); diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java index 8e008b0ae..503f2cb88 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TcpConstants.java @@ -3,6 +3,4 @@ package org.briarproject.bramble.api.plugin; public interface TcpConstants { String PREF_TCP_ENABLE = "enable"; - - int REASON_USER = 1; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java index 6199ddd35..727dab4b4 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java @@ -24,7 +24,7 @@ public interface TorConstants { int PREF_TOR_NETWORK_WITH_BRIDGES = 2; int PREF_TOR_NETWORK_NEVER = 3; - int REASON_USER = 1; + // Reason codes returned by Plugin#getReasonDisabled() int REASON_BATTERY = 2; int REASON_MOBILE_DATA = 3; int REASON_COUNTRY_BLOCKED = 4; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java index 1ac111bb0..f1506ed5f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java @@ -52,7 +52,6 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.TcpConstants.PREF_TCP_ENABLE; -import static org.briarproject.bramble.api.plugin.TcpConstants.REASON_USER; import static org.briarproject.bramble.util.IoUtils.tryToClose; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 01adb72e6..c8c6a1512 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -88,7 +88,6 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3; import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY; import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED; import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA; -import static org.briarproject.bramble.api.plugin.TorConstants.REASON_USER; import static org.briarproject.bramble.plugin.tor.TorRendezvousCrypto.SEED_BYTES; import static org.briarproject.bramble.util.IoUtils.copyAndClose; import static org.briarproject.bramble.util.IoUtils.tryToClose; From b53319a7b0f9684ef26c06b61515860d3d50dad7 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 Jan 2020 10:22:12 +0000 Subject: [PATCH 07/15] Small code cleanups in key agreement UI. --- .../keyagreement/ContactExchangeActivity.java | 13 +++++++-- .../keyagreement/KeyAgreementActivity.java | 29 +++++++++---------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeActivity.java index 062f12059..f18c41f75 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeActivity.java @@ -9,6 +9,7 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; import javax.annotation.Nullable; import javax.inject.Inject; @@ -79,13 +80,13 @@ public class ContactExchangeActivity extends KeyAgreementActivity { @UiThread private void contactExchangeFailed() { - showErrorFragment(R.string.connection_error_explanation); + showErrorFragment(); } @UiThread @Override public void keyAgreementFailed() { - showErrorFragment(R.string.connection_error_explanation); + showErrorFragment(); } @UiThread @@ -103,7 +104,7 @@ public class ContactExchangeActivity extends KeyAgreementActivity { @UiThread @Override public void keyAgreementAborted(boolean remoteAborted) { - showErrorFragment(R.string.connection_error_explanation); + showErrorFragment(); } @UiThread @@ -112,4 +113,10 @@ public class ContactExchangeActivity extends KeyAgreementActivity { startContactExchange(result); return getString(R.string.exchanging_contact_details); } + + protected void showErrorFragment() { + String errorMsg = getString(R.string.connection_error_explanation); + BaseFragment f = ContactExchangeErrorFragment.newInstance(errorMsg); + showNextFragment(f); + } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java index 16d8e2a03..67e125020 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java @@ -44,6 +44,8 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION; @@ -62,7 +64,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements } private static final Logger LOG = - Logger.getLogger(KeyAgreementActivity.class.getName()); + getLogger(KeyAgreementActivity.class.getName()); @Inject EventBus eventBus; @@ -74,18 +76,21 @@ public abstract class KeyAgreementActivity extends BriarActivity implements * https://issuetracker.google.com/issues/37067655. */ private boolean isResumed = false; + /** * Set to true when the continue button is clicked, and false when the QR * code fragment is shown. This prevents the QR code fragment from being * shown automatically before the continue button has been clicked. */ private boolean continueClicked = false; + /** * Records whether the Bluetooth adapter was already enabled before we * asked for Bluetooth discoverability, so we know whether to broadcast a * {@link BluetoothEnabledEvent}. */ private boolean wasAdapterEnabled = false; + private Permission cameraPermission = Permission.UNKNOWN; private Permission locationPermission = Permission.UNKNOWN; private BluetoothState bluetoothState = BluetoothState.UNKNOWN; @@ -96,14 +101,13 @@ public abstract class KeyAgreementActivity extends BriarActivity implements component.inject(this); } - @SuppressWarnings("ConstantConditions") @Override public void onCreate(@Nullable Bundle state) { super.onCreate(state); setContentView(R.layout.activity_fragment_container_toolbar); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); + requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); if (state == null) { showInitialFragment(IntroFragment.newInstance()); } @@ -122,13 +126,11 @@ public abstract class KeyAgreementActivity extends BriarActivity implements @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - onBackPressed(); - return true; - default: - return super.onOptionsItemSelected(item); + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; } + return super.onOptionsItemSelected(item); } @Override @@ -206,7 +208,8 @@ public abstract class KeyAgreementActivity extends BriarActivity implements } @Override - public void onActivityResult(int request, int result, Intent data) { + public void onActivityResult(int request, int result, + @Nullable Intent data) { if (request == REQUEST_BLUETOOTH_DISCOVERABLE) { if (result == RESULT_CANCELED) { setBluetoothState(BluetoothState.REFUSED); @@ -239,12 +242,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements } } - protected void showErrorFragment(@StringRes int errorResId) { - String errorMsg = getString(errorResId); - BaseFragment f = ContactExchangeErrorFragment.newInstance(errorMsg); - showNextFragment(f); - } - private boolean checkPermissions() { if (areEssentialPermissionsGranted()) return true; // If the camera permission has been permanently denied, ask the From 628b69d4eb6da5047f87afeb225cd6e45be8104a Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 Jan 2020 10:32:01 +0000 Subject: [PATCH 08/15] Enable BT plugin before showing QR code. --- .../keyagreement/KeyAgreementActivity.java | 153 +++++++++++++++--- 1 file changed, 129 insertions(+), 24 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java index 67e125020..4f787598f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java @@ -8,10 +8,20 @@ import android.content.IntentFilter; import android.os.Bundle; import android.view.MenuItem; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.event.EventListener; +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.plugin.BluetoothConstants; +import org.briarproject.bramble.api.plugin.Plugin; +import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent; +import org.briarproject.bramble.api.plugin.event.TransportActiveEvent; +import org.briarproject.bramble.api.settings.Settings; +import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; @@ -21,6 +31,7 @@ import org.briarproject.briar.android.keyagreement.IntroFragment.IntroScreenSeen import org.briarproject.briar.android.keyagreement.KeyAgreementFragment.KeyAgreementEventListener; import org.briarproject.briar.android.util.UiUtils; +import java.util.concurrent.Executor; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -37,15 +48,15 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.CAMERA; import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE; import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED; -import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE; -import static android.bluetooth.BluetoothAdapter.EXTRA_STATE; -import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; -import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; +import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; +import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; +import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION; @@ -53,10 +64,41 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMI @ParametersNotNullByDefault public abstract class KeyAgreementActivity extends BriarActivity implements BaseFragmentListener, IntroScreenSeenListener, - KeyAgreementEventListener { + KeyAgreementEventListener, EventListener { private enum BluetoothState { - UNKNOWN, NO_ADAPTER, WAITING, REFUSED, ENABLED, DISCOVERABLE + /** + * We don't yet know the state of the Bluetooth adapter or plugin. + */ + UNKNOWN, + + /** + * The device doesn't have a Bluetooth adapter. + */ + NO_ADAPTER, + + /** + * We're waiting for the user to decide whether to allow + * discoverability, or the user has allowed discoverability and we're + * waiting for the adapter to become discoverable. + */ + WAITING, + + /** + * The user has refused discoverability. + */ + REFUSED, + + /** + * The Bluetooth adapter is discoverable. + */ + DISCOVERABLE, + + /** + * The Bluetooth adapter is discoverable and we're waiting for the + * Bluetooth plugin to become active. + */ + ACTIVATING_PLUGIN } private enum Permission { @@ -69,6 +111,16 @@ public abstract class KeyAgreementActivity extends BriarActivity implements @Inject EventBus eventBus; + @Inject + PluginManager pluginManager; + + @Inject + @IoExecutor + Executor ioExecutor; + + @Inject + SettingsManager settingsManager; + /** * Set to true in onPostResume() and false in onPause(). This prevents the * QR code fragment from being shown if onRequestPermissionsResult() is @@ -91,6 +143,13 @@ public abstract class KeyAgreementActivity extends BriarActivity implements */ private boolean wasAdapterEnabled = false; + /** + * Records whether the user accepted the most recent request (if any) to + * make the Bluetooth adapter discoverable, so we know whether to broadcast + * a {@link BluetoothEnabledEvent}. + */ + private boolean wasRequestAccepted = false; + private Permission cameraPermission = Permission.UNKNOWN; private Permission locationPermission = Permission.UNKNOWN; private BluetoothState bluetoothState = BluetoothState.UNKNOWN; @@ -111,9 +170,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements if (state == null) { showInitialFragment(IntroFragment.newInstance()); } - IntentFilter filter = new IntentFilter(); - filter.addAction(ACTION_STATE_CHANGED); - filter.addAction(ACTION_SCAN_MODE_CHANGED); + IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED); bluetoothReceiver = new BluetoothStateReceiver(); registerReceiver(bluetoothReceiver, filter); } @@ -136,6 +193,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements @Override public void onStart() { super.onStart(); + eventBus.addListener(this); // Permissions may have been granted manually while we were stopped cameraPermission = Permission.UNKNOWN; locationPermission = Permission.UNKNOWN; @@ -152,11 +210,22 @@ public abstract class KeyAgreementActivity extends BriarActivity implements private void showQrCodeFragmentIfAllowed() { if (isResumed && continueClicked && areEssentialPermissionsGranted()) { - if (bluetoothState == BluetoothState.UNKNOWN || - bluetoothState == BluetoothState.ENABLED) { + if (bluetoothState == BluetoothState.UNKNOWN) { requestBluetoothDiscoverable(); - } else if (bluetoothState != BluetoothState.WAITING) { + } else if (bluetoothState == BluetoothState.NO_ADAPTER || + bluetoothState == BluetoothState.REFUSED) { + LOG.info("Continuing without Bluetooth"); showQrCodeFragment(); + } else if (bluetoothState == BluetoothState.DISCOVERABLE || + bluetoothState == BluetoothState.ACTIVATING_PLUGIN) { + if (isBluetoothPluginActive()) { + LOG.info("Bluetooth plugin is active"); + showQrCodeFragment(); + } else { + LOG.info("Enabling Bluetooth plugin"); + bluetoothState = BluetoothState.ACTIVATING_PLUGIN; + enableBluetoothPlugin(); + } } } } @@ -169,12 +238,36 @@ public abstract class KeyAgreementActivity extends BriarActivity implements locationPermission == Permission.PERMANENTLY_DENIED); } + private boolean isBluetoothPluginActive() { + Plugin p = pluginManager.getPlugin(BluetoothConstants.ID); + return p != null && p.getState() == ACTIVE; + } + + private void enableBluetoothPlugin() { + ioExecutor.execute(() -> { + try { + Settings s = new Settings(); + s.putBoolean(PREF_BT_ENABLE, true); + String namespace = BluetoothConstants.ID.getString(); + settingsManager.mergeSettings(s, namespace); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } + @Override protected void onPause() { super.onPause(); isResumed = false; } + @Override + protected void onStop() { + super.onStop(); + eventBus.removeListener(this); + } + @Override public void showNextScreen() { continueClicked = true; @@ -200,8 +293,11 @@ public abstract class KeyAgreementActivity extends BriarActivity implements private void setBluetoothState(BluetoothState bluetoothState) { LOG.info("Setting Bluetooth state to " + bluetoothState); this.bluetoothState = bluetoothState; - if (!wasAdapterEnabled && bluetoothState == BluetoothState.ENABLED) { + if (!wasAdapterEnabled && wasRequestAccepted && + bluetoothState == BluetoothState.DISCOVERABLE) { + LOG.info("Bluetooth adapter was enabled by us"); eventBus.broadcast(new BluetoothEnabledEvent()); + wasRequestAccepted = false; wasAdapterEnabled = true; } showQrCodeFragmentIfAllowed(); @@ -214,12 +310,14 @@ public abstract class KeyAgreementActivity extends BriarActivity implements if (result == RESULT_CANCELED) { setBluetoothState(BluetoothState.REFUSED); } else { + wasRequestAccepted = true; // If Bluetooth is already discoverable, show the QR code - // otherwise wait for the state or scan mode to change BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); if (bt == null) throw new AssertionError(); - if (bt.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) + if (bt.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) { setBluetoothState(BluetoothState.DISCOVERABLE); + } } } else super.onActivityResult(request, result, data); } @@ -332,23 +430,30 @@ public abstract class KeyAgreementActivity extends BriarActivity implements permission); } + @Override + public void eventOccurred(Event e) { + if (e instanceof TransportActiveEvent) { + TransportActiveEvent t = (TransportActiveEvent) e; + if (t.getTransportId().equals(BluetoothConstants.ID)) { + showQrCodeFragmentIfAllowed(); + } + } + } + private class BluetoothStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (ACTION_STATE_CHANGED.equals(action)) { - int state = intent.getIntExtra(EXTRA_STATE, 0); - if (state == STATE_ON) - setBluetoothState(BluetoothState.ENABLED); - else setBluetoothState(BluetoothState.UNKNOWN); - } else if (ACTION_SCAN_MODE_CHANGED.equals(action)) { + if (ACTION_SCAN_MODE_CHANGED.equals(action)) { int scanMode = intent.getIntExtra(EXTRA_SCAN_MODE, 0); - if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) + if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + LOG.info("Bluetooth adapter is discoverable"); setBluetoothState(BluetoothState.DISCOVERABLE); - else if (scanMode == SCAN_MODE_CONNECTABLE) - setBluetoothState(BluetoothState.ENABLED); - else setBluetoothState(BluetoothState.UNKNOWN); + } else if (bluetoothState == BluetoothState.DISCOVERABLE) { + LOG.info("Bluetooth adapter is not discoverable"); + setBluetoothState(BluetoothState.UNKNOWN); + } } } } From 8622f663f697a59ea5758a73ed0c3dc1f1cef0ce Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 Jan 2020 11:57:18 +0000 Subject: [PATCH 09/15] Enable LAN plugin in unit test. --- .../briarproject/bramble/plugin/tcp/LanTcpPluginTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java index 7b175f805..af5f23da9 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java @@ -34,6 +34,7 @@ import static java.util.concurrent.Executors.newCachedThreadPool; import static java.util.concurrent.TimeUnit.SECONDS; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN; +import static org.briarproject.bramble.api.plugin.TcpConstants.PREF_TCP_ENABLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -345,10 +346,15 @@ public class LanTcpPluginTest extends BrambleTestCase { private final CountDownLatch propertiesLatch = new CountDownLatch(1); private final CountDownLatch connectionsLatch = new CountDownLatch(1); private final TransportProperties local = new TransportProperties(); + private final Settings settings = new Settings(); + + private Callback() { + settings.putBoolean(PREF_TCP_ENABLE, true); + } @Override public Settings getSettings() { - return new Settings(); + return settings; } @Override From 5e37b3da2258aa45d60b9460bce81bf17deefff2 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 Jan 2020 13:11:54 +0000 Subject: [PATCH 10/15] Don't remove old settings yet. This avoids an unlikely race condition at startup, where the user opens the settings screen before the Tor plugin has migrated the settings. --- briar-android/src/main/res/values/arrays.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/briar-android/src/main/res/values/arrays.xml b/briar-android/src/main/res/values/arrays.xml index 8a7313b73..a9dc6aed6 100644 --- a/briar-android/src/main/res/values/arrays.xml +++ b/briar-android/src/main/res/values/arrays.xml @@ -4,11 +4,13 @@ @string/tor_network_setting_automatic @string/tor_network_setting_without_bridges @string/tor_network_setting_with_bridges + @string/tor_network_setting_never 0 1 2 + 3 From c2dd61b00604ac4015f8c56c3d418cdb7eb9cc5c Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 Jan 2020 13:12:16 +0000 Subject: [PATCH 11/15] Clean up logic for enabling/disabling settings. --- .../briar/android/settings/SettingsFragment.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 0cc96c6f8..8ddba892f 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 @@ -573,10 +573,9 @@ public class SettingsFragment extends PreferenceFragmentCompat storeWifiSetting(wifiSetting); } else if (preference == enableTor) { boolean torEnabledSetting = (Boolean) newValue; - torNetwork.setEnabled(torNetwork.isEnabled() && torEnabledSetting); - torMobile.setEnabled(torMobile.isEnabled() && torEnabledSetting); - torOnlyWhenCharging.setEnabled(torOnlyWhenCharging.isEnabled() && - torEnabledSetting); + torNetwork.setEnabled(torEnabledSetting); + torMobile.setEnabled(torEnabledSetting); + torOnlyWhenCharging.setEnabled(torEnabledSetting); storeTorEnabledSetting(torEnabledSetting); } else if (preference == torNetwork) { int torNetworkSetting = Integer.valueOf((String) newValue); From 070be8621d39fb4854f7c7ef704a727a939b81df Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 20 Jan 2020 16:41:39 +0000 Subject: [PATCH 12/15] Use XML to specify dependencies between settings. --- .../briar/android/settings/SettingsFragment.java | 9 +++------ briar-android/src/main/res/xml/settings.xml | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) 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 8ddba892f..4e2ab8f83 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 @@ -464,9 +464,9 @@ public class SettingsFragment extends PreferenceFragmentCompat enableBluetooth.setEnabled(enabled); enableWifi.setEnabled(enabled); enableTor.setEnabled(enabled); - torNetwork.setEnabled(enabled && enableTor.isChecked()); - torMobile.setEnabled(enabled && enableTor.isChecked()); - torOnlyWhenCharging.setEnabled(enabled && enableTor.isChecked()); + torNetwork.setEnabled(enabled); + torMobile.setEnabled(enabled); + torOnlyWhenCharging.setEnabled(enabled); if (!enabled) screenLock.setEnabled(false); notifyPrivateMessages.setEnabled(enabled); notifyGroupMessages.setEnabled(enabled); @@ -573,9 +573,6 @@ public class SettingsFragment extends PreferenceFragmentCompat storeWifiSetting(wifiSetting); } else if (preference == enableTor) { boolean torEnabledSetting = (Boolean) newValue; - torNetwork.setEnabled(torEnabledSetting); - torMobile.setEnabled(torEnabledSetting); - torOnlyWhenCharging.setEnabled(torEnabledSetting); storeTorEnabledSetting(torEnabledSetting); } else if (preference == torNetwork) { int torNetworkSetting = Integer.valueOf((String) newValue); diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index b1b40552f..db50e4732 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -55,6 +55,7 @@ Date: Thu, 23 Jan 2020 12:51:41 +0000 Subject: [PATCH 13/15] Remove redundant call to pluginStateChanged(). --- .../main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java index f1506ed5f..215a47ea1 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java @@ -352,7 +352,6 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener { boolean enabledByUser = settings.getBoolean(PREF_TCP_ENABLE, false); ServerSocket ss = state.setEnabledByUser(enabledByUser); State s = getState(); - callback.pluginStateChanged(s); if (ss != null) { LOG.info("Disabled by user, closing server socket"); tryToClose(ss, LOG, WARNING); From dc64c4148d0e48d943c92ae70e6a839d6f86fd26 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 23 Jan 2020 13:18:38 +0000 Subject: [PATCH 14/15] Enable LAN plugin before showing QR code. --- .../keyagreement/KeyAgreementActivity.java | 226 ++++++++++-------- 1 file changed, 131 insertions(+), 95 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java index 4f787598f..771c17cdc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java @@ -16,10 +16,13 @@ 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.plugin.BluetoothConstants; +import org.briarproject.bramble.api.plugin.LanTcpConstants; import org.briarproject.bramble.api.plugin.Plugin; +import org.briarproject.bramble.api.plugin.Plugin.State; import org.briarproject.bramble.api.plugin.PluginManager; +import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent; -import org.briarproject.bramble.api.plugin.event.TransportActiveEvent; +import org.briarproject.bramble.api.plugin.event.TransportStateEvent; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.briar.R; @@ -48,14 +51,17 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.CAMERA; import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE; import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED; -import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; +import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; +import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; +import static org.briarproject.bramble.api.plugin.TcpConstants.PREF_TCP_ENABLE; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION; @@ -66,9 +72,9 @@ public abstract class KeyAgreementActivity extends BriarActivity implements BaseFragmentListener, IntroScreenSeenListener, KeyAgreementEventListener, EventListener { - private enum BluetoothState { + private enum BluetoothDecision { /** - * We don't yet know the state of the Bluetooth adapter or plugin. + * We haven't asked the user about Bluetooth discoverability. */ UNKNOWN, @@ -78,27 +84,19 @@ public abstract class KeyAgreementActivity extends BriarActivity implements NO_ADAPTER, /** - * We're waiting for the user to decide whether to allow - * discoverability, or the user has allowed discoverability and we're - * waiting for the adapter to become discoverable. + * We're waiting for the user to accept or refuse discoverability. */ WAITING, + /** + * The user has accepted discoverability. + */ + ACCEPTED, + /** * The user has refused discoverability. */ - REFUSED, - - /** - * The Bluetooth adapter is discoverable. - */ - DISCOVERABLE, - - /** - * The Bluetooth adapter is discoverable and we're waiting for the - * Bluetooth plugin to become active. - */ - ACTIVATING_PLUGIN + REFUSED } private enum Permission { @@ -144,15 +142,20 @@ public abstract class KeyAgreementActivity extends BriarActivity implements private boolean wasAdapterEnabled = false; /** - * Records whether the user accepted the most recent request (if any) to - * make the Bluetooth adapter discoverable, so we know whether to broadcast - * a {@link BluetoothEnabledEvent}. + * Records whether we've enabled the wifi plugin so we don't enable it more + * than once. */ - private boolean wasRequestAccepted = false; + private boolean hasEnabledWifi = false; + + /** + * Records whether we've enabled the Bluetooth plugin so we don't enable it + * more than once. + */ + private boolean hasEnabledBluetooth = false; private Permission cameraPermission = Permission.UNKNOWN; private Permission locationPermission = Permission.UNKNOWN; - private BluetoothState bluetoothState = BluetoothState.UNKNOWN; + private BluetoothDecision bluetoothDecision = BluetoothDecision.UNKNOWN; private BroadcastReceiver bluetoothReceiver = null; @Override @@ -210,21 +213,21 @@ public abstract class KeyAgreementActivity extends BriarActivity implements private void showQrCodeFragmentIfAllowed() { if (isResumed && continueClicked && areEssentialPermissionsGranted()) { - if (bluetoothState == BluetoothState.UNKNOWN) { - requestBluetoothDiscoverable(); - } else if (bluetoothState == BluetoothState.NO_ADAPTER || - bluetoothState == BluetoothState.REFUSED) { - LOG.info("Continuing without Bluetooth"); + if (isWifiReady() && isBluetoothReady()) { + LOG.info("Wifi and Bluetooth are ready"); showQrCodeFragment(); - } else if (bluetoothState == BluetoothState.DISCOVERABLE || - bluetoothState == BluetoothState.ACTIVATING_PLUGIN) { - if (isBluetoothPluginActive()) { - LOG.info("Bluetooth plugin is active"); - showQrCodeFragment(); - } else { + } else { + if (shouldEnableWifi()) { + LOG.info("Enabling wifi plugin"); + hasEnabledWifi = true; + enablePlugin(LanTcpConstants.ID, PREF_TCP_ENABLE); + } + if (bluetoothDecision == BluetoothDecision.UNKNOWN) { + requestBluetoothDiscoverable(); + } else if (shouldEnableBluetooth()) { LOG.info("Enabling Bluetooth plugin"); - bluetoothState = BluetoothState.ACTIVATING_PLUGIN; - enableBluetoothPlugin(); + hasEnabledBluetooth = true; + enablePlugin(BluetoothConstants.ID, PREF_BT_ENABLE); } } } @@ -238,24 +241,81 @@ public abstract class KeyAgreementActivity extends BriarActivity implements locationPermission == Permission.PERMANENTLY_DENIED); } - private boolean isBluetoothPluginActive() { - Plugin p = pluginManager.getPlugin(BluetoothConstants.ID); - return p != null && p.getState() == ACTIVE; + private boolean isWifiReady() { + Plugin p = pluginManager.getPlugin(LanTcpConstants.ID); + if (p == null) return true; // Continue without wifi + State state = p.getState(); + // Wait for plugin to become enabled + return state == ACTIVE || state == INACTIVE; } - private void enableBluetoothPlugin() { + private boolean isBluetoothReady() { + if (bluetoothDecision == BluetoothDecision.UNKNOWN || + bluetoothDecision == BluetoothDecision.WAITING) { + // Wait for decision + return false; + } + if (bluetoothDecision == BluetoothDecision.NO_ADAPTER + || bluetoothDecision == BluetoothDecision.REFUSED) { + // Continue without Bluetooth + return true; + } + BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); + if (bt == null) return true; // Continue without Bluetooth + if (bt.getScanMode() != SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + // Wait for adapter to become discoverable + return false; + } + Plugin p = pluginManager.getPlugin(BluetoothConstants.ID); + if (p == null) return true; // Continue without Bluetooth + // Wait for plugin to become active + return p.getState() == ACTIVE; + } + + private boolean shouldEnableWifi() { + if (hasEnabledWifi) return false; + Plugin p = pluginManager.getPlugin(LanTcpConstants.ID); + return p != null && p.getState() == DISABLED; + } + + private void enablePlugin(TransportId t, String settingKey) { ioExecutor.execute(() -> { try { Settings s = new Settings(); - s.putBoolean(PREF_BT_ENABLE, true); - String namespace = BluetoothConstants.ID.getString(); - settingsManager.mergeSettings(s, namespace); + s.putBoolean(settingKey, true); + settingsManager.mergeSettings(s, t.getString()); } catch (DbException e) { logException(LOG, WARNING, e); } }); } + private void requestBluetoothDiscoverable() { + BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); + if (bt == null) { + bluetoothDecision = BluetoothDecision.NO_ADAPTER; + showQrCodeFragmentIfAllowed(); + } else { + Intent i = new Intent(ACTION_REQUEST_DISCOVERABLE); + if (i.resolveActivity(getPackageManager()) != null) { + LOG.info("Asking for Bluetooth discoverability"); + bluetoothDecision = BluetoothDecision.WAITING; + wasAdapterEnabled = bt.isEnabled(); + startActivityForResult(i, REQUEST_BLUETOOTH_DISCOVERABLE); + } else { + bluetoothDecision = BluetoothDecision.NO_ADAPTER; + showQrCodeFragmentIfAllowed(); + } + } + } + + private boolean shouldEnableBluetooth() { + if (bluetoothDecision != BluetoothDecision.ACCEPTED) return false; + if (hasEnabledBluetooth) return false; + Plugin p = pluginManager.getPlugin(BluetoothConstants.ID); + return p != null && p.getState() == DISABLED; + } + @Override protected void onPause() { super.onPause(); @@ -274,51 +334,23 @@ public abstract class KeyAgreementActivity extends BriarActivity implements if (checkPermissions()) showQrCodeFragmentIfAllowed(); } - private void requestBluetoothDiscoverable() { - BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); - if (bt == null) { - setBluetoothState(BluetoothState.NO_ADAPTER); - } else { - Intent i = new Intent(ACTION_REQUEST_DISCOVERABLE); - if (i.resolveActivity(getPackageManager()) != null) { - setBluetoothState(BluetoothState.WAITING); - wasAdapterEnabled = bt.isEnabled(); - startActivityForResult(i, REQUEST_BLUETOOTH_DISCOVERABLE); - } else { - setBluetoothState(BluetoothState.NO_ADAPTER); - } - } - } - - private void setBluetoothState(BluetoothState bluetoothState) { - LOG.info("Setting Bluetooth state to " + bluetoothState); - this.bluetoothState = bluetoothState; - if (!wasAdapterEnabled && wasRequestAccepted && - bluetoothState == BluetoothState.DISCOVERABLE) { - LOG.info("Bluetooth adapter was enabled by us"); - eventBus.broadcast(new BluetoothEnabledEvent()); - wasRequestAccepted = false; - wasAdapterEnabled = true; - } - showQrCodeFragmentIfAllowed(); - } - @Override public void onActivityResult(int request, int result, @Nullable Intent data) { if (request == REQUEST_BLUETOOTH_DISCOVERABLE) { if (result == RESULT_CANCELED) { - setBluetoothState(BluetoothState.REFUSED); + LOG.info("Bluetooth discoverability was refused"); + bluetoothDecision = BluetoothDecision.REFUSED; } else { - wasRequestAccepted = true; - // If Bluetooth is already discoverable, show the QR code - - // otherwise wait for the state or scan mode to change - BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); - if (bt == null) throw new AssertionError(); - if (bt.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) { - setBluetoothState(BluetoothState.DISCOVERABLE); + LOG.info("Bluetooth discoverability was accepted"); + bluetoothDecision = BluetoothDecision.ACCEPTED; + if (!wasAdapterEnabled) { + LOG.info("Bluetooth adapter was enabled by us"); + eventBus.broadcast(new BluetoothEnabledEvent()); + wasAdapterEnabled = true; } } + showQrCodeFragmentIfAllowed(); } else super.onActivityResult(request, result, data); } @@ -328,7 +360,12 @@ public abstract class KeyAgreementActivity extends BriarActivity implements continueClicked = false; // If we return to the intro fragment, ask for Bluetooth // discoverability again before showing the QR code fragment - bluetoothState = BluetoothState.UNKNOWN; + bluetoothDecision = BluetoothDecision.UNKNOWN; + // If we return to the intro fragment, we may need to enable wifi and + // Bluetooth again + hasEnabledWifi = false; + hasEnabledBluetooth = false; + // FIXME #824 FragmentManager fm = getSupportFragmentManager(); if (fm.findFragmentByTag(KeyAgreementFragment.TAG) == null) { @@ -432,9 +469,17 @@ public abstract class KeyAgreementActivity extends BriarActivity implements @Override public void eventOccurred(Event e) { - if (e instanceof TransportActiveEvent) { - TransportActiveEvent t = (TransportActiveEvent) e; + if (e instanceof TransportStateEvent) { + TransportStateEvent t = (TransportStateEvent) e; if (t.getTransportId().equals(BluetoothConstants.ID)) { + if (LOG.isLoggable(INFO)) { + LOG.info("Bluetooth state changed to " + t.getState()); + } + showQrCodeFragmentIfAllowed(); + } else if (t.getTransportId().equals(LanTcpConstants.ID)) { + if (LOG.isLoggable(INFO)) { + LOG.info("Wifi state changed to " + t.getState()); + } showQrCodeFragmentIfAllowed(); } } @@ -444,17 +489,8 @@ public abstract class KeyAgreementActivity extends BriarActivity implements @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (ACTION_SCAN_MODE_CHANGED.equals(action)) { - int scanMode = intent.getIntExtra(EXTRA_SCAN_MODE, 0); - if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) { - LOG.info("Bluetooth adapter is discoverable"); - setBluetoothState(BluetoothState.DISCOVERABLE); - } else if (bluetoothState == BluetoothState.DISCOVERABLE) { - LOG.info("Bluetooth adapter is not discoverable"); - setBluetoothState(BluetoothState.UNKNOWN); - } - } + LOG.info("Bluetooth scan mode changed"); + showQrCodeFragmentIfAllowed(); } } } From cc7a19402ed8fd46c1f4ddb9f2ba067a5d4b31ff Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 23 Jan 2020 13:24:37 +0000 Subject: [PATCH 15/15] Remove another redundant call to pluginStateChanged(). --- .../briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index f2ceb2afc..a8c53b417 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -437,7 +437,6 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { boolean enabledByUser = settings.getBoolean(PREF_BT_ENABLE, false); SS ss = state.setEnabledByUser(enabledByUser); State s = getState(); - callback.pluginStateChanged(s); if (ss != null) { LOG.info("Disabled by user, closing server socket"); tryToClose(ss);