Refactor Tor settings and add a setting for forcing to use bridges

This commit is contained in:
Torsten Grote
2018-08-13 17:57:44 -03:00
parent e5112ae9ee
commit 9b17836595
7 changed files with 121 additions and 86 deletions

View File

@@ -12,12 +12,13 @@ public interface TorConstants {
int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds
int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds
String PREF_TOR_NETWORK = "network"; String PREF_TOR_NETWORK = "network2";
String PREF_TOR_PORT = "port"; String PREF_TOR_PORT = "port";
String PREF_TOR_DISABLE_BLOCKED = "disableWhenBlocked"; String PREF_TOR_MOBILE = "useMobileData";
int PREF_TOR_NETWORK_NEVER = 0; int PREF_TOR_NETWORK_AUTOMATIC = 0;
int PREF_TOR_NETWORK_WIFI = 1; int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
int PREF_TOR_NETWORK_ALWAYS = 2; int PREF_TOR_NETWORK_WITH_BRIDGES = 2;
int PREF_TOR_NETWORK_NEVER = 3;
} }

View File

@@ -64,11 +64,11 @@ import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY; 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.CONTROL_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.ID; 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_MOBILE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; 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_AUTOMATIC;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
@@ -170,6 +170,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!assetsAreUpToDate()) installAssets(); if (!assetsAreUpToDate()) installAssets();
if (cookieFile.exists() && !cookieFile.delete()) if (cookieFile.exists() && !cookieFile.delete())
LOG.warning("Old auth cookie not deleted"); LOG.warning("Old auth cookie not deleted");
// Migrate old settings before having a chance to stop
migrateSettings();
// Start a new Tor process // Start a new Tor process
LOG.info("Starting Tor"); LOG.info("Starting Tor");
String torPath = torFile.getAbsolutePath(); String torPath = torFile.getAbsolutePath();
@@ -629,9 +631,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
boolean blocked = boolean blocked =
circumventionProvider.isTorProbablyBlocked(country); circumventionProvider.isTorProbablyBlocked(country);
Settings s = callback.getSettings(); Settings s = callback.getSettings();
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); int network =
boolean disableWhenBlocked = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC);
s.getBoolean(PREF_TOR_DISABLE_BLOCKED, true); boolean useMobile = s.getBoolean(PREF_TOR_MOBILE, true);
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Online: " + online + ", wifi: " + wifi); LOG.info("Online: " + online + ", wifi: " + wifi);
@@ -643,25 +647,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!online) { if (!online) {
LOG.info("Disabling network, device is offline"); LOG.info("Disabling network, device is offline");
enableNetwork(false); enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_NEVER } else if (network == PREF_TOR_NETWORK_NEVER ||
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) { (!useMobile && !wifi)) {
LOG.info("Disabling network due to data setting"); LOG.info("Disabling network due to data setting");
enableNetwork(false); enableNetwork(false);
} else if (blocked) { } else if (automatic && blocked && !bridgesWork) {
if (circumventionProvider.doBridgesWork(country)) { LOG.info("Disabling network, country is blocked");
LOG.info("Enabling network, using bridges"); enableNetwork(false);
enableBridges(true); } else if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
enableNetwork(true); (automatic && bridgesWork)) {
} else if (disableWhenBlocked) { LOG.info("Enabling network, using bridges");
LOG.info("Disabling network, country is blocked"); enableBridges(true);
enableNetwork(false); enableNetwork(true);
} else {
LOG.info("Enabling network but country is blocked");
enableBridges(false);
enableNetwork(true);
}
} else { } else {
LOG.info("Enabling network"); LOG.info("Enabling network, not using bridges");
enableBridges(false); enableBridges(false);
enableNetwork(true); enableNetwork(true);
} }
@@ -671,6 +670,21 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}); });
} }
// TODO remove when sufficient time has passed. Added 2018-08-15
private void migrateSettings() {
Settings sOld = callback.getSettings();
int oldNetwork = sOld.getInt("network", -1);
if (oldNetwork == -1) return;
Settings s = new Settings();
if (oldNetwork == 0) {
s.putInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_NEVER);
} else if (oldNetwork == 1) {
s.putBoolean(PREF_TOR_MOBILE, false);
}
s.putInt("network", -1);
callback.mergeSettings(s);
}
private static class ConnectionStatus { private static class ConnectionStatus {
// All of the following are locking: this // All of the following are locking: this

View File

@@ -22,6 +22,8 @@ import org.briarproject.bramble.api.plugin.PluginManager;
import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.bramble.api.settings.SettingsManager;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
import org.briarproject.briar.BriarCoreEagerSingletons; import org.briarproject.briar.BriarCoreEagerSingletons;
import org.briarproject.briar.BriarCoreModule; import org.briarproject.briar.BriarCoreModule;
import org.briarproject.briar.android.login.SignInReminderReceiver; import org.briarproject.briar.android.login.SignInReminderReceiver;
@@ -149,6 +151,10 @@ public interface AndroidComponent
LockManager lockManager(); LockManager lockManager();
LocationUtils locationUtils();
CircumventionProvider circumventionProvider();
void inject(SignInReminderReceiver briarService); void inject(SignInReminderReceiver briarService);
void inject(BriarService briarService); void inject(BriarService briarService);

View File

@@ -35,6 +35,8 @@ import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.bramble.api.settings.SettingsManager;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.Localizer; import org.briarproject.briar.android.Localizer;
@@ -43,7 +45,6 @@ import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.briar.android.util.UserFeedback; import org.briarproject.briar.android.util.UserFeedback;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -68,19 +69,15 @@ import static android.provider.Settings.EXTRA_CHANNEL_ID;
import static android.provider.Settings.System.DEFAULT_NOTIFICATION_URI; import static android.provider.Settings.System.DEFAULT_NOTIFICATION_URI;
import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_LTR; import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_LTR;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static java.util.Arrays.asList;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; 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.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_MOBILE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; 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_AUTOMATIC;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BLOCKED;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BRIDGES;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.bramble.util.StringUtils.join;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_PIN_LOCK; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_PIN_LOCK;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER;
@@ -113,7 +110,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
public static final String LANGUAGE = "pref_key_language"; 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 = "pref_key_lock";
public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in"; public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in";
public static final String TOR_LOCATION = "pref_key_tor_location"; public static final String TOR_NETWORK = "pref_key_tor_network";
public static final String TOR_MOBILE = "pref_key_tor_mobile_data";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(SettingsFragment.class.getName()); Logger.getLogger(SettingsFragment.class.getName());
@@ -122,7 +120,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
private ListPreference language; private ListPreference language;
private ListPreference enableBluetooth; private ListPreference enableBluetooth;
private ListPreference torNetwork; private ListPreference torNetwork;
private SwitchPreference torBlocked; private SwitchPreference torMobile;
private SwitchPreference screenLock; private SwitchPreference screenLock;
private SwitchPreference notifyPrivateMessages; private SwitchPreference notifyPrivateMessages;
private SwitchPreference notifyGroupMessages; private SwitchPreference notifyGroupMessages;
@@ -130,6 +128,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
private SwitchPreference notifyBlogPosts; private SwitchPreference notifyBlogPosts;
private SwitchPreference notifyVibration; private SwitchPreference notifyVibration;
private SwitchPreference notifyLockscreen; private SwitchPreference notifyLockscreen;
private Preference notifySound; private Preference notifySound;
// Fields that are accessed from background threads must be volatile // Fields that are accessed from background threads must be volatile
@@ -138,6 +137,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
volatile SettingsManager settingsManager; volatile SettingsManager settingsManager;
@Inject @Inject
volatile EventBus eventBus; volatile EventBus eventBus;
@Inject
LocationUtils locationUtils;
@Inject
CircumventionProvider circumventionProvider;
@Inject @Inject
AndroidExecutor androidExecutor; AndroidExecutor androidExecutor;
@@ -160,9 +163,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
ListPreference theme = ListPreference theme =
(ListPreference) findPreference("pref_key_theme"); (ListPreference) findPreference("pref_key_theme");
enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth"); enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth");
torNetwork = (ListPreference) findPreference("pref_key_tor_network"); torNetwork = (ListPreference) findPreference(TOR_NETWORK);
torBlocked = (SwitchPreference) findPreference(TOR_LOCATION); torMobile = (SwitchPreference) findPreference(TOR_MOBILE);
setBlockedCountries();
SwitchPreference notifySignIn = SwitchPreference notifySignIn =
(SwitchPreference) findPreference(NOTIFY_SIGN_IN); (SwitchPreference) findPreference(NOTIFY_SIGN_IN);
screenLock = (SwitchPreference) findPreference(PREF_SCREEN_LOCK); screenLock = (SwitchPreference) findPreference(PREF_SCREEN_LOCK);
@@ -201,7 +203,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
}); });
enableBluetooth.setOnPreferenceChangeListener(this); enableBluetooth.setOnPreferenceChangeListener(this);
torNetwork.setOnPreferenceChangeListener(this); torNetwork.setOnPreferenceChangeListener(this);
torBlocked.setOnPreferenceChangeListener(this); torMobile.setOnPreferenceChangeListener(this);
screenLock.setOnPreferenceChangeListener(this); screenLock.setOnPreferenceChangeListener(this);
if (SDK_INT >= 21) { if (SDK_INT >= 21) {
notifyLockscreen.setVisible(true); notifyLockscreen.setVisible(true);
@@ -304,30 +306,33 @@ public class SettingsFragment extends PreferenceFragmentCompat
return direction == LAYOUT_DIRECTION_LTR; return direction == LAYOUT_DIRECTION_LTR;
} }
private void setBlockedCountries() { private void setTorNetworkSummary(int torNetworkSetting) {
List<String> countryCodes = new ArrayList<>(asList(BLOCKED)); if (torNetworkSetting != PREF_TOR_NETWORK_AUTOMATIC) {
countryCodes.removeAll(asList(BRIDGES)); torNetwork.setSummary("%s"); // use setting value
// Look up country names in the user's chosen language if available return;
Locale[] locales = Locale.getAvailableLocales(); }
List<String> countries = new ArrayList<>(countryCodes.size());
for (String countryCode : countryCodes) { // Look up country name in the user's chosen language if available
boolean found = false; String country = locationUtils.getCurrentCountry();
for (Locale locale : locales) { String countryName = getString(R.string.tor_network_country_unknown);
if (locale.getCountry().equalsIgnoreCase(countryCode)) { for (Locale locale : Locale.getAvailableLocales()) {
countries.add(locale.getDisplayCountry()); if (locale.getCountry().equalsIgnoreCase(country)) {
found = true; countryName = locale.getDisplayCountry();
break; break;
}
}
if (!found) {
if (LOG.isLoggable(INFO))
LOG.info("No locale for " + countryCode);
countries.add(countryCode);
} }
} }
Collections.sort(countries); boolean blocked =
String format = getString(R.string.tor_location_setting_hint_format); circumventionProvider.isTorProbablyBlocked(country);
torBlocked.setSummary(String.format(format, join(countries, ", "))); boolean useBridges = circumventionProvider.doBridgesWork(country);
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) {
setting = getString(R.string.tor_network_setting_never);
}
torNetwork.setSummary(
getString(R.string.tor_network_setting_summary, setting,
countryName));
} }
private void loadSettings() { private void loadSettings() {
@@ -342,11 +347,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
boolean btSetting = boolean btSetting =
btSettings.getBoolean(PREF_BT_ENABLE, false); btSettings.getBoolean(PREF_BT_ENABLE, false);
int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK, int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK,
PREF_TOR_NETWORK_ALWAYS); PREF_TOR_NETWORK_AUTOMATIC);
boolean torBlockedSetting = boolean torMobileSetting =
torSettings.getBoolean(PREF_TOR_DISABLE_BLOCKED, true); torSettings.getBoolean(PREF_TOR_MOBILE, true);
displaySettings(btSetting, torNetworkSetting, displaySettings(btSetting, torNetworkSetting, torMobileSetting);
torBlockedSetting);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
} }
@@ -354,11 +358,12 @@ public class SettingsFragment extends PreferenceFragmentCompat
} }
private void displaySettings(boolean btSetting, int torNetworkSetting, private void displaySettings(boolean btSetting, int torNetworkSetting,
boolean torBlockedSetting) { boolean torMobileSetting) {
listener.runOnUiThreadUnlessDestroyed(() -> { listener.runOnUiThreadUnlessDestroyed(() -> {
enableBluetooth.setValue(Boolean.toString(btSetting)); enableBluetooth.setValue(Boolean.toString(btSetting));
torNetwork.setValue(Integer.toString(torNetworkSetting)); torNetwork.setValue(Integer.toString(torNetworkSetting));
torBlocked.setChecked(torBlockedSetting); setTorNetworkSummary(torNetworkSetting);
torMobile.setChecked(torMobileSetting);
displayScreenLockSetting(); displayScreenLockSetting();
if (SDK_INT < 26) { if (SDK_INT < 26) {
@@ -421,7 +426,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
// - pref_key_lock (screenLock -> displayScreenLockSetting()) // - pref_key_lock (screenLock -> displayScreenLockSetting())
enableBluetooth.setEnabled(enabled); enableBluetooth.setEnabled(enabled);
torNetwork.setEnabled(enabled); torNetwork.setEnabled(enabled);
torBlocked.setEnabled(enabled); torMobile.setEnabled(enabled);
if (!enabled) screenLock.setEnabled(false); if (!enabled) screenLock.setEnabled(false);
notifyPrivateMessages.setEnabled(enabled); notifyPrivateMessages.setEnabled(enabled);
notifyGroupMessages.setEnabled(enabled); notifyGroupMessages.setEnabled(enabled);
@@ -501,9 +506,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
} else if (preference == torNetwork) { } else if (preference == torNetwork) {
int torNetworkSetting = Integer.valueOf((String) newValue); int torNetworkSetting = Integer.valueOf((String) newValue);
storeTorNetworkSetting(torNetworkSetting); storeTorNetworkSetting(torNetworkSetting);
} else if (preference == torBlocked) { setTorNetworkSummary(torNetworkSetting);
boolean torBlockedSetting = (Boolean) newValue; } else if (preference == torMobile) {
storeTorBlockedSetting(torBlockedSetting); boolean torMobileSetting = (Boolean) newValue;
storeTorMobileSetting(torMobileSetting);
} else if (preference == screenLock) { } else if (preference == screenLock) {
Settings s = new Settings(); Settings s = new Settings();
s.putBoolean(PREF_SCREEN_LOCK, (Boolean) newValue); s.putBoolean(PREF_SCREEN_LOCK, (Boolean) newValue);
@@ -562,9 +568,9 @@ public class SettingsFragment extends PreferenceFragmentCompat
mergeSettings(s, TOR_NAMESPACE); mergeSettings(s, TOR_NAMESPACE);
} }
private void storeTorBlockedSetting(boolean torBlockedSetting) { private void storeTorMobileSetting(boolean torMobileSetting) {
Settings s = new Settings(); Settings s = new Settings();
s.putBoolean(PREF_TOR_DISABLE_BLOCKED, torBlockedSetting); s.putBoolean(PREF_TOR_MOBILE, torMobileSetting);
mergeSettings(s, TOR_NAMESPACE); mergeSettings(s, TOR_NAMESPACE);
} }

View File

@@ -8,16 +8,20 @@
<item>@string/bluetooth_setting_enabled</item> <item>@string/bluetooth_setting_enabled</item>
<item>@string/bluetooth_setting_disabled</item> <item>@string/bluetooth_setting_disabled</item>
</string-array> </string-array>
<string-array name="tor_network_setting_names"> <string-array name="tor_network_setting_names">
<item>@string/tor_network_setting_automatic</item>
<item>@string/tor_network_setting_without_bridges</item>
<item>@string/tor_network_setting_with_bridges</item>
<item>@string/tor_network_setting_never</item> <item>@string/tor_network_setting_never</item>
<item>@string/tor_network_setting_wifi</item>
<item>@string/tor_network_setting_always</item>
</string-array> </string-array>
<string-array name="tor_network_setting_values"> <string-array name="tor_network_setting_values">
<item>0</item> <item>0</item>
<item>1</item> <item>1</item>
<item>2</item> <item>2</item>
<item>3</item>
</string-array> </string-array>
<string-array name="pref_language_values"> <string-array name="pref_language_values">
<item>default</item> <item>default</item>
<item>en-US</item> <item>en-US</item>

View File

@@ -348,12 +348,16 @@
<string name="bluetooth_setting">Connect via Bluetooth</string> <string name="bluetooth_setting">Connect via Bluetooth</string>
<string name="bluetooth_setting_enabled">Whenever contacts are nearby</string> <string name="bluetooth_setting_enabled">Whenever contacts are nearby</string>
<string name="bluetooth_setting_disabled">Only when adding contacts</string> <string name="bluetooth_setting_disabled">Only when adding contacts</string>
<string name="tor_network_setting">Connect via Tor</string> <string name="tor_network_setting">Connect via Internet (Tor)</string>
<string name="tor_network_setting_never">Never</string> <string name="tor_network_setting_automatic">Automatic based on location</string>
<string name="tor_network_setting_wifi">Only when using Wi-Fi</string> <string name="tor_network_setting_without_bridges">Use Tor without bridges</string>
<string name="tor_network_setting_always">When using Wi-Fi or mobile data</string> <string name="tor_network_setting_with_bridges">Use Tor with bridges</string>
<string name="tor_location_setting_title">Disable Tor based on location</string> <string name="tor_network_setting_never">Don\'t connect</string>
<string name="tor_location_setting_hint_format">Disable Tor in countries where it is likely to be blocked (%1$s)</string> <!-- How and when Tor will connect after Automatic: E.g. Don't connect (in China) or Use Tor with bridges (in Belarus) -->
<string name="tor_network_setting_summary">Automatic: %1$s (in %2$s)</string>
<!-- The placeholder when we don't know the user's current country -->
<string name="tor_network_country_unknown">unknown</string>
<string name="tor_mobile_data_title">Use Mobile Data</string>
<!-- Settings Security and Panic --> <!-- Settings Security and Panic -->
<string name="security_settings_title">Security</string> <string name="security_settings_title">Security</string>

View File

@@ -36,7 +36,7 @@
android:title="@string/bluetooth_setting"/> android:title="@string/bluetooth_setting"/>
<ListPreference <ListPreference
android:defaultValue="2" android:defaultValue="0"
android:entries="@array/tor_network_setting_names" android:entries="@array/tor_network_setting_names"
android:entryValues="@array/tor_network_setting_values" android:entryValues="@array/tor_network_setting_values"
android:key="pref_key_tor_network" android:key="pref_key_tor_network"
@@ -46,9 +46,9 @@
<SwitchPreference <SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="pref_key_tor_location" android:key="pref_key_tor_mobile_data"
android:persistent="false" android:persistent="false"
android:title="@string/tor_location_setting_title"/> android:title="@string/tor_mobile_data_title"/>
</PreferenceCategory> </PreferenceCategory>