diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index c62ecb854e1352b19e9f2c60b72db88f62065cef..ee732b7b737437d7ac6ef6c902897d090e09c34a 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -76,6 +76,7 @@ import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS; import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY; 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_DISABLE_BLOCKED; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER; @@ -128,8 +129,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { LocationUtils locationUtils, SocketFactory torSocketFactory, Clock clock, CircumventionProvider circumventionProvider, Backoff backoff, DuplexPluginCallback callback, - String architecture, - int maxLatency, int maxIdleTime) { + String architecture, int maxLatency, int maxIdleTime) { this.ioExecutor = ioExecutor; this.appContext = appContext; this.networkManager = networkManager; @@ -661,6 +661,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { circumventionProvider.isTorProbablyBlocked(country); Settings s = callback.getSettings(); int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); + boolean disableWhenBlocked = + s.getBoolean(PREF_TOR_DISABLE_BLOCKED, true); if (LOG.isLoggable(INFO)) { LOG.info("Online: " + online + ", wifi: " + wifi); @@ -681,9 +683,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { LOG.info("Enabling network, using bridges"); enableBridges(true); enableNetwork(true); - } else { + } else if (disableWhenBlocked) { LOG.info("Disabling network, country is blocked"); enableNetwork(false); + } else { + LOG.info("Enabling network but country is blocked"); + enableNetwork(true); } } else { LOG.info("Enabling network"); 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 8f265a95ed6a839a2c5c1d560c80b5ee4877650b..6e9f712f9485bb5f2cca638bd4b9112e72456a67 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 @@ -14,6 +14,7 @@ public interface TorConstants { String PREF_TOR_NETWORK = "network"; String PREF_TOR_PORT = "port"; + String PREF_TOR_DISABLE_BLOCKED = "disableWhenBlocked"; int PREF_TOR_NETWORK_NEVER = 0; int PREF_TOR_NETWORK_WIFI = 1; 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 f5c38f23cc92d71d43a2ef6eb4b02ba5e2015329..fbd69b7f89021a7e984780c4c5fe54d936894ac1 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 @@ -70,6 +70,7 @@ import static android.widget.Toast.LENGTH_SHORT; 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_DISABLE_BLOCKED; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS; import static org.briarproject.bramble.util.LogUtils.logDuration; @@ -104,6 +105,7 @@ public class SettingsFragment extends PreferenceFragmentCompat public static final String TOR_NAMESPACE = TorConstants.ID.getString(); public static final String LANGUAGE = "pref_key_language"; public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in"; + public static final String TOR_LOCATION = "pref_key_tor_location"; private static final Logger LOG = Logger.getLogger(SettingsFragment.class.getName()); @@ -112,6 +114,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private ListPreference language; private ListPreference enableBluetooth; private ListPreference torNetwork; + private CheckBoxPreference torBlocked; private CheckBoxPreference notifyPrivateMessages; private CheckBoxPreference notifyGroupMessages; private CheckBoxPreference notifyForumPosts; @@ -150,6 +153,7 @@ public class SettingsFragment extends PreferenceFragmentCompat (ListPreference) findPreference("pref_key_theme"); enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth"); torNetwork = (ListPreference) findPreference("pref_key_tor_network"); + torBlocked = (CheckBoxPreference) findPreference(TOR_LOCATION); CheckBoxPreference notifySignIn = (CheckBoxPreference) findPreference(NOTIFY_SIGN_IN); notifyPrivateMessages = (CheckBoxPreference) findPreference( @@ -189,6 +193,7 @@ public class SettingsFragment extends PreferenceFragmentCompat }); enableBluetooth.setOnPreferenceChangeListener(this); torNetwork.setOnPreferenceChangeListener(this); + torBlocked.setOnPreferenceChangeListener(this); if (SDK_INT >= 21) { notifyLockscreen.setVisible(true); notifyLockscreen.setOnPreferenceChangeListener(this); @@ -299,19 +304,24 @@ public class SettingsFragment extends PreferenceFragmentCompat logDuration(LOG, "Loading settings", start); boolean btSetting = btSettings.getBoolean(PREF_BT_ENABLE, false); - int torSetting = torSettings.getInt(PREF_TOR_NETWORK, + int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); - displaySettings(btSetting, torSetting); + boolean torBlockedSetting = + torSettings.getBoolean(PREF_TOR_DISABLE_BLOCKED, true); + displaySettings(btSetting, torNetworkSetting, + torBlockedSetting); } catch (DbException e) { logException(LOG, WARNING, e); } }); } - private void displaySettings(boolean btSetting, int torSetting) { + private void displaySettings(boolean btSetting, int torNetworkSetting, + boolean torBlockedSetting) { listener.runOnUiThreadUnlessDestroyed(() -> { enableBluetooth.setValue(Boolean.toString(btSetting)); - torNetwork.setValue(Integer.toString(torSetting)); + torNetwork.setValue(Integer.toString(torNetworkSetting)); + torBlocked.setChecked(torBlockedSetting); if (SDK_INT < 26) { notifyPrivateMessages.setChecked(settings.getBoolean( @@ -371,6 +381,7 @@ public class SettingsFragment extends PreferenceFragmentCompat // - pref_key_notify_sign_in enableBluetooth.setEnabled(enabled); torNetwork.setEnabled(enabled); + torBlocked.setEnabled(enabled); notifyPrivateMessages.setEnabled(enabled); notifyGroupMessages.setEnabled(enabled); notifyForumPosts.setEnabled(enabled); @@ -430,8 +441,11 @@ public class SettingsFragment extends PreferenceFragmentCompat boolean btSetting = Boolean.valueOf((String) newValue); storeBluetoothSettings(btSetting); } else if (preference == torNetwork) { - int torSetting = Integer.valueOf((String) newValue); - storeTorSettings(torSetting); + int torNetworkSetting = Integer.valueOf((String) newValue); + storeTorNetworkSetting(torNetworkSetting); + } else if (preference == torBlocked) { + boolean torBlockedSetting = (Boolean) newValue; + storeTorBlockedSetting(torBlockedSetting); } else if (preference == notifyPrivateMessages) { Settings s = new Settings(); s.putBoolean(PREF_NOTIFY_PRIVATE, (Boolean) newValue); @@ -480,39 +494,33 @@ public class SettingsFragment extends PreferenceFragmentCompat builder.show(); } - private void storeTorSettings(int torSetting) { - listener.runOnDbThread(() -> { - try { - Settings s = new Settings(); - s.putInt(PREF_TOR_NETWORK, torSetting); - long start = now(); - settingsManager.mergeSettings(s, TOR_NAMESPACE); - logDuration(LOG, "Merging settings", start); - } catch (DbException e) { - logException(LOG, WARNING, e); - } - }); + private void storeTorNetworkSetting(int torNetworkSetting) { + Settings s = new Settings(); + s.putInt(PREF_TOR_NETWORK, torNetworkSetting); + mergeSettings(s, TOR_NAMESPACE); + } + + private void storeTorBlockedSetting(boolean torBlockedSetting) { + Settings s = new Settings(); + s.putBoolean(PREF_TOR_DISABLE_BLOCKED, torBlockedSetting); + mergeSettings(s, TOR_NAMESPACE); } private void storeBluetoothSettings(boolean btSetting) { - listener.runOnDbThread(() -> { - try { - Settings s = new Settings(); - s.putBoolean(PREF_BT_ENABLE, btSetting); - long start = now(); - settingsManager.mergeSettings(s, BT_NAMESPACE); - logDuration(LOG, "Merging settings", start); - } catch (DbException e) { - logException(LOG, WARNING, e); - } - }); + Settings s = new Settings(); + s.putBoolean(PREF_BT_ENABLE, btSetting); + mergeSettings(s, BT_NAMESPACE); + } + + private void storeSettings(Settings s) { + mergeSettings(s, SETTINGS_NAMESPACE); } - private void storeSettings(Settings settings) { + private void mergeSettings(Settings s, String namespace) { listener.runOnDbThread(() -> { try { long start = now(); - settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); + settingsManager.mergeSettings(s, namespace); logDuration(LOG, "Merging settings", start); } catch (DbException e) { logException(LOG, WARNING, e); diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 06a09ddce823d4463d6cdaba9e12a12216e86e2d..d51576c290589a2db7582f72caf3962893531a8c 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -348,6 +348,8 @@ <string name="tor_network_setting_never">Never</string> <string name="tor_network_setting_wifi">Only when using Wi-Fi</string> <string name="tor_network_setting_always">When using Wi-Fi or mobile data</string> + <string name="tor_location_setting_title">Disable Tor based on location</string> + <string name="tor_location_setting_hint">Disable Tor in countries where it is likely to be blocked</string> <!-- Settings Security and Panic --> <string name="security_settings_title">Security</string> diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index c81fbb2ad497c3493f7e3766678f3b4aeef7dfdd..6d78bbc69725b86633c6853002762db7732efa44 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -44,6 +44,13 @@ android:summary="%s" android:title="@string/tor_network_setting"/> + <CheckBoxPreference + android:defaultValue="true" + android:key="pref_key_tor_location" + android:persistent="false" + android:summary="@string/tor_location_setting_hint" + android:title="@string/tor_location_setting_title"/> + </PreferenceCategory> <PreferenceCategory