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"/> + +