mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
[plugins/tor/TorPlugin] Adds tor-over-wifi setting
Provides a checkbox in the settings view, as well as an event handler to disable/enable the tor network if the device is not on using the wifi connection. Refactors network-enabling code to a separate function. This function is ran after the network state changes, or the settings change and will update the status accordingly.
This commit is contained in:
@@ -102,6 +102,8 @@
|
|||||||
<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_wifi_setting_title">TOR</string>
|
||||||
|
<string name="tor_wifi_setting"> Use Tor over WiFi Only</string>
|
||||||
<string name="notification_settings_title">NOTIFICATIONS</string>
|
<string name="notification_settings_title">NOTIFICATIONS</string>
|
||||||
<string name="notify_private_messages_setting">Show alerts for private messages</string>
|
<string name="notify_private_messages_setting">Show alerts for private messages</string>
|
||||||
<string name="notify_group_posts_setting">Show alerts for forum posts</string>
|
<string name="notify_group_posts_setting">Show alerts for forum posts</string>
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ OnClickListener {
|
|||||||
private TextView enableBluetooth = null, enableBluetoothHint = null;
|
private TextView enableBluetooth = null, enableBluetoothHint = null;
|
||||||
private CheckBox notifyPrivateMessages = null, notifyGroupPosts = null;
|
private CheckBox notifyPrivateMessages = null, notifyGroupPosts = null;
|
||||||
private CheckBox notifyVibration = null;
|
private CheckBox notifyVibration = null;
|
||||||
|
private CheckBox torOverWifi = null;
|
||||||
private TextView notifySound = null, notifySoundHint = null;
|
private TextView notifySound = null, notifySoundHint = null;
|
||||||
private ListLoadingProgressBar progress = null;
|
private ListLoadingProgressBar progress = null;
|
||||||
private ImageButton testingButton = null;
|
private ImageButton testingButton = null;
|
||||||
@@ -117,6 +118,23 @@ OnClickListener {
|
|||||||
enableBluetoothHint.setOnClickListener(this);
|
enableBluetoothHint.setOnClickListener(this);
|
||||||
settings.addView(enableBluetoothHint);
|
settings.addView(enableBluetoothHint);
|
||||||
|
|
||||||
|
TextView torTitle = new TextView(this);
|
||||||
|
torTitle.setPadding(pad, 0, pad, 0);
|
||||||
|
torTitle.setTypeface(DEFAULT_BOLD);
|
||||||
|
torTitle.setTextColor(titleText);
|
||||||
|
torTitle.setText(R.string.tor_wifi_setting_title);
|
||||||
|
settings.addView(torTitle);
|
||||||
|
|
||||||
|
underline = new HorizontalBorder(this);
|
||||||
|
underline.setBackgroundColor(titleUnderline);
|
||||||
|
settings.addView(underline);
|
||||||
|
|
||||||
|
torOverWifi = new CheckBox(this);
|
||||||
|
torOverWifi.setTextSize(18);
|
||||||
|
torOverWifi.setText(R.string.tor_wifi_setting);
|
||||||
|
torOverWifi.setOnClickListener(this);
|
||||||
|
settings.addView(torOverWifi);
|
||||||
|
|
||||||
TextView notificationsTitle = new TextView(this);
|
TextView notificationsTitle = new TextView(this);
|
||||||
notificationsTitle.setPadding(pad, 0, pad, 0);
|
notificationsTitle.setPadding(pad, 0, pad, 0);
|
||||||
notificationsTitle.setTypeface(DEFAULT_BOLD);
|
notificationsTitle.setTypeface(DEFAULT_BOLD);
|
||||||
@@ -280,6 +298,8 @@ OnClickListener {
|
|||||||
}
|
}
|
||||||
storeBluetoothSetting();
|
storeBluetoothSetting();
|
||||||
displaySettings();
|
displaySettings();
|
||||||
|
} else if (view == torOverWifi) {
|
||||||
|
storeTorSettings();
|
||||||
} else if (view == notifyPrivateMessages) {
|
} else if (view == notifyPrivateMessages) {
|
||||||
Settings s = new Settings();
|
Settings s = new Settings();
|
||||||
s.putBoolean("notifyPrivateMessages",
|
s.putBoolean("notifyPrivateMessages",
|
||||||
@@ -312,6 +332,24 @@ OnClickListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeTorSettings() {
|
||||||
|
runOnDbThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Settings s = new Settings();
|
||||||
|
s.putBoolean("torOverWifi", torOverWifi.isChecked());
|
||||||
|
TransportConfig c = new TransportConfig();
|
||||||
|
c.putBoolean("torOverWifi", torOverWifi.isChecked());
|
||||||
|
storeSettings(s);
|
||||||
|
try {
|
||||||
|
db.mergeConfig(new TransportId("tor"), c);
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void storeBluetoothSetting() {
|
private void storeBluetoothSetting() {
|
||||||
runOnDbThread(new Runnable() {
|
runOnDbThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
|
|||||||
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
|
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
|
||||||
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
|
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
|
||||||
import org.briarproject.api.system.LocationUtils;
|
import org.briarproject.api.system.LocationUtils;
|
||||||
|
import org.briarproject.api.event.EventBus;
|
||||||
import org.briarproject.plugins.droidtooth.DroidtoothPluginFactory;
|
import org.briarproject.plugins.droidtooth.DroidtoothPluginFactory;
|
||||||
import org.briarproject.plugins.tcp.AndroidLanTcpPluginFactory;
|
import org.briarproject.plugins.tcp.AndroidLanTcpPluginFactory;
|
||||||
import org.briarproject.plugins.tor.TorPluginFactory;
|
import org.briarproject.plugins.tor.TorPluginFactory;
|
||||||
@@ -36,12 +37,13 @@ public class AndroidPluginsModule extends PluginsModule {
|
|||||||
@Provides
|
@Provides
|
||||||
DuplexPluginConfig getDuplexPluginConfig(@IoExecutor Executor ioExecutor,
|
DuplexPluginConfig getDuplexPluginConfig(@IoExecutor Executor ioExecutor,
|
||||||
AndroidExecutor androidExecutor, Application app,
|
AndroidExecutor androidExecutor, Application app,
|
||||||
CryptoComponent crypto, LocationUtils locationUtils) {
|
CryptoComponent crypto, LocationUtils locationUtils,
|
||||||
|
EventBus eventBus) {
|
||||||
Context appContext = app.getApplicationContext();
|
Context appContext = app.getApplicationContext();
|
||||||
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(ioExecutor,
|
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(ioExecutor,
|
||||||
androidExecutor, appContext, crypto.getSecureRandom());
|
androidExecutor, appContext, crypto.getSecureRandom());
|
||||||
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext,
|
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext,
|
||||||
locationUtils);
|
locationUtils, eventBus);
|
||||||
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
||||||
appContext);
|
appContext);
|
||||||
final Collection<DuplexPluginFactory> factories =
|
final Collection<DuplexPluginFactory> factories =
|
||||||
|
|||||||
@@ -50,11 +50,18 @@ import static android.content.Context.CONNECTIVITY_SERVICE;
|
|||||||
import static android.content.Context.MODE_PRIVATE;
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||||
import static android.net.ConnectivityManager.EXTRA_NO_CONNECTIVITY;
|
import static android.net.ConnectivityManager.EXTRA_NO_CONNECTIVITY;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
|
|
||||||
|
import org.briarproject.api.event.EventListener;
|
||||||
|
import org.briarproject.api.event.Event;
|
||||||
|
import org.briarproject.api.event.SettingsUpdatedEvent;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
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;
|
||||||
|
|
||||||
class TorPlugin implements DuplexPlugin, EventHandler {
|
class TorPlugin implements DuplexPlugin, EventHandler,
|
||||||
|
EventListener {
|
||||||
|
|
||||||
static final TransportId ID = new TransportId("tor");
|
static final TransportId ID = new TransportId("tor");
|
||||||
|
|
||||||
@@ -82,6 +89,9 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
|||||||
|
|
||||||
private volatile boolean running = false, networkEnabled = false;
|
private volatile boolean running = false, networkEnabled = false;
|
||||||
private volatile boolean bootstrapped = false;
|
private volatile boolean bootstrapped = false;
|
||||||
|
private volatile boolean connectedToWifi = false;
|
||||||
|
private volatile boolean online = false;
|
||||||
|
|
||||||
private volatile ServerSocket socket = null;
|
private volatile ServerSocket socket = null;
|
||||||
private volatile Socket controlSocket = null;
|
private volatile Socket controlSocket = null;
|
||||||
private volatile TorControlConnection controlConnection = null;
|
private volatile TorControlConnection controlConnection = null;
|
||||||
@@ -585,27 +595,94 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context ctx, Intent i) {
|
public void onReceive(Context ctx, Intent i) {
|
||||||
|
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
boolean online = !i.getBooleanExtra(EXTRA_NO_CONNECTIVITY, false);
|
|
||||||
|
Object o = ctx.getSystemService(CONNECTIVITY_SERVICE);
|
||||||
|
ConnectivityManager cm = (ConnectivityManager) o;
|
||||||
|
NetworkInfo net = cm.getActiveNetworkInfo();
|
||||||
|
|
||||||
|
/* Some devices fail to set EXTRA_NO_CONNECTIVITY, double check */
|
||||||
|
online = !i.getBooleanExtra(EXTRA_NO_CONNECTIVITY, false);
|
||||||
if (online) {
|
if (online) {
|
||||||
// Some devices fail to set EXTRA_NO_CONNECTIVITY, double check
|
|
||||||
Object o = ctx.getSystemService(CONNECTIVITY_SERVICE);
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) o;
|
|
||||||
NetworkInfo net = cm.getActiveNetworkInfo();
|
|
||||||
if (net == null || !net.isConnected()) online = false;
|
if (net == null || !net.isConnected()) online = false;
|
||||||
}
|
}
|
||||||
String country = locationUtils.getCurrentCountry();
|
|
||||||
if (LOG.isLoggable(INFO)) {
|
connectedToWifi = (net != null && net.getType() == TYPE_WIFI
|
||||||
LOG.info("Online: " + online);
|
&& net.isConnected());
|
||||||
if ("".equals(country)) LOG.info("Country code unknown");
|
|
||||||
else LOG.info("Country code: " + country);
|
updateConnectionStatus();
|
||||||
}
|
|
||||||
boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(country);
|
|
||||||
try {
|
|
||||||
enableNetwork(online && !blocked);
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof SettingsUpdatedEvent) {
|
||||||
|
if (!running) return;
|
||||||
|
|
||||||
|
updateConnectionStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConnectionStatus() {
|
||||||
|
|
||||||
|
ioExecutor.execute(new Runnable() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
boolean wifiOnly = false;
|
||||||
|
boolean blocked = false;
|
||||||
|
|
||||||
|
String country = locationUtils.getCurrentCountry();
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("Online: " + online);
|
||||||
|
if ("".equals(country)) LOG.info("Country code unknown");
|
||||||
|
else LOG.info("Country code: " + country);
|
||||||
|
}
|
||||||
|
blocked = TorNetworkMetadata.isTorProbablyBlocked(country);
|
||||||
|
TransportConfig c = callback.getConfig();
|
||||||
|
wifiOnly = c.getBoolean("torOverWifi", false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
/*
|
||||||
|
1) Disable network if offline
|
||||||
|
*/
|
||||||
|
if (!online) {
|
||||||
|
LOG.log(WARNING, "Disabling network, network is offline");
|
||||||
|
enableNetwork(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
2) Disable network if blocked
|
||||||
|
*/
|
||||||
|
if (blocked) {
|
||||||
|
LOG.log(WARNING, "Disabling network, country is blocked");
|
||||||
|
enableNetwork(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
3) Disable network if wifiOnly and not connected to
|
||||||
|
wifi
|
||||||
|
*/
|
||||||
|
if (wifiOnly & !connectedToWifi){
|
||||||
|
LOG.log(WARNING, "Disabling network due to wifi only setting");
|
||||||
|
enableNetwork(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
4) Otherwise enable network
|
||||||
|
*/
|
||||||
|
enableNetwork(true);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.briarproject.plugins.tor;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.briarproject.api.event.EventBus;
|
||||||
|
|
||||||
import org.briarproject.android.util.AndroidUtils;
|
import org.briarproject.android.util.AndroidUtils;
|
||||||
import org.briarproject.api.TransportId;
|
import org.briarproject.api.TransportId;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||||
@@ -25,12 +27,14 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
|
private final EventBus eventBus;
|
||||||
|
|
||||||
public TorPluginFactory(Executor ioExecutor, Context appContext,
|
public TorPluginFactory(Executor ioExecutor, Context appContext,
|
||||||
LocationUtils locationUtils) {
|
LocationUtils locationUtils, EventBus eventBus) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
this.locationUtils = locationUtils;
|
this.locationUtils = locationUtils;
|
||||||
|
this.eventBus = eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportId getId() {
|
public TransportId getId() {
|
||||||
@@ -38,6 +42,9 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
|
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
|
||||||
|
|
||||||
|
TorPlugin thisPlugin = null;
|
||||||
|
|
||||||
// Check that we have a Tor binary for this architecture
|
// Check that we have a Tor binary for this architecture
|
||||||
String architecture = null;
|
String architecture = null;
|
||||||
for (String abi : AndroidUtils.getSupportedArchitectures()) {
|
for (String abi : AndroidUtils.getSupportedArchitectures()) {
|
||||||
@@ -55,7 +62,13 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
}
|
}
|
||||||
// Use position-independent executable for SDK >= 16
|
// Use position-independent executable for SDK >= 16
|
||||||
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
|
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
|
||||||
return new TorPlugin(ioExecutor,appContext, locationUtils, callback,
|
|
||||||
architecture, MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL);
|
thisPlugin = new TorPlugin(ioExecutor,appContext, locationUtils,
|
||||||
|
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
|
||||||
|
POLLING_INTERVAL);
|
||||||
|
this.eventBus.addListener(thisPlugin);
|
||||||
|
|
||||||
|
return thisPlugin;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user