From 03811f78fa321530f8a3600e352907d0f2b5cb3b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 16 Jan 2020 17:51:49 +0000 Subject: [PATCH] Add toggle setting for LAN plugin. --- .../plugin/tcp/AndroidLanTcpPlugin.java | 9 ++- .../bramble/api/plugin/TcpConstants.java | 8 +++ .../bramble/plugin/tcp/LanTcpPlugin.java | 3 +- .../plugin/tcp/LanTcpPluginFactory.java | 9 ++- .../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 +++ 10 files changed, 128 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 f269d3406..ffbeab9d3 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()); @@ -72,7 +73,8 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { public void start() { if (used.getAndSet(true)) throw new IllegalStateException(); initialisePortProperty(); - state.setStarted(); + Settings settings = callback.getSettings(); + state.setStarted(settings.getBoolean(PREF_TCP_ENABLE, false)); updateConnectionStatus(); } @@ -128,6 +130,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/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java index bd980cff6..1200b10b1 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java @@ -91,7 +91,8 @@ class LanTcpPlugin extends TcpPlugin { public void start() { if (used.getAndSet(true)) throw new IllegalStateException(); initialisePortProperty(); - running = true; + Settings settings = callback.getSettings(); + state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE, false)); bind(); } 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 cfbdcea80..6528a6571 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; @@ -26,11 +27,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; } @@ -48,7 +51,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, + LanTcpPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, MAX_LATENCY, MAX_IDLE_TIME, CONNECTION_TIMEOUT); + 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 35f291633..c8c650af6 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()); @@ -122,7 +129,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(); } @@ -200,7 +208,7 @@ abstract class TcpPlugin implements DuplexPlugin { @Override public int getReasonDisabled() { - return getState() == DISABLED ? REASON_STARTING_STOPPING : -1; + return state.getReasonDisabled(); } @Override @@ -370,18 +378,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()); } @@ -394,6 +428,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; @@ -412,8 +458,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 079697319..db0f2c2a8 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; @@ -27,12 +28,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; } @@ -51,8 +54,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, CONNECTION_TIMEOUT); + 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 53578ccc4..f7a5168b9 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 @@ -45,9 +45,9 @@ public class DesktopPluginModule extends PluginModule { ioExecutor, random, eventBus, timeoutMonitor, 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 dea0d1b98..a6c6094b0 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -446,6 +446,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"/> + +