mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
13 Commits
avoid-depr
...
remove-bac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98e5d892a4 | ||
|
|
94f8f68336 | ||
|
|
2f8dd51ef8 | ||
|
|
5dd1c28e77 | ||
|
|
c1d0936a1e | ||
|
|
717be0178a | ||
|
|
34677eb3a7 | ||
|
|
1dd15567de | ||
|
|
428f06abdd | ||
|
|
e1d1c62708 | ||
|
|
ae75090d23 | ||
|
|
fb85730b8e | ||
|
|
48b1e77065 |
@@ -12,7 +12,6 @@ import android.content.IntentFilter;
|
|||||||
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
import org.briarproject.bramble.api.plugin.PluginException;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
@@ -82,10 +81,10 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
|
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
|
||||||
SecureRandom secureRandom, ScheduledExecutorService scheduler,
|
SecureRandom secureRandom, ScheduledExecutorService scheduler,
|
||||||
AndroidExecutor androidExecutor, Context appContext, Clock clock,
|
AndroidExecutor androidExecutor, Context appContext, Clock clock,
|
||||||
Backoff backoff, PluginCallback callback, int maxLatency,
|
PluginCallback callback, int maxLatency, int maxIdleTime,
|
||||||
int maxIdleTime) {
|
int pollingInterval) {
|
||||||
super(connectionLimiter, timeoutMonitor, ioExecutor, secureRandom,
|
super(connectionLimiter, timeoutMonitor, ioExecutor, secureRandom,
|
||||||
backoff, callback, maxLatency, maxIdleTime);
|
callback, maxLatency, maxIdleTime, pollingInterval);
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.androidExecutor = androidExecutor;
|
this.androidExecutor = androidExecutor;
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import android.content.Context;
|
|||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -20,17 +18,17 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60 * 1000; // 1 minute
|
private static final int POLLING_INTERVAL = (int) MINUTES.toMillis(2);
|
||||||
private static final int MAX_POLLING_INTERVAL = 10 * 60 * 1000; // 10 mins
|
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
@@ -40,13 +38,12 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final TimeoutMonitor timeoutMonitor;
|
private final TimeoutMonitor timeoutMonitor;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
|
|
||||||
public AndroidBluetoothPluginFactory(Executor ioExecutor,
|
public AndroidBluetoothPluginFactory(Executor ioExecutor,
|
||||||
ScheduledExecutorService scheduler,
|
ScheduledExecutorService scheduler,
|
||||||
AndroidExecutor androidExecutor, Context appContext,
|
AndroidExecutor androidExecutor, Context appContext,
|
||||||
SecureRandom secureRandom, EventBus eventBus, Clock clock,
|
SecureRandom secureRandom, EventBus eventBus, Clock clock,
|
||||||
TimeoutMonitor timeoutMonitor, BackoffFactory backoffFactory) {
|
TimeoutMonitor timeoutMonitor) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.androidExecutor = androidExecutor;
|
this.androidExecutor = androidExecutor;
|
||||||
@@ -55,7 +52,6 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.timeoutMonitor = timeoutMonitor;
|
this.timeoutMonitor = timeoutMonitor;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -72,12 +68,10 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
BluetoothConnectionLimiter connectionLimiter =
|
BluetoothConnectionLimiter connectionLimiter =
|
||||||
new BluetoothConnectionLimiterImpl(eventBus);
|
new BluetoothConnectionLimiterImpl(eventBus);
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(
|
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(
|
||||||
connectionLimiter, timeoutMonitor, ioExecutor, secureRandom,
|
connectionLimiter, timeoutMonitor, ioExecutor, secureRandom,
|
||||||
scheduler, androidExecutor, appContext, clock, backoff,
|
scheduler, androidExecutor, appContext, clock, callback,
|
||||||
callback, MAX_LATENCY, MAX_IDLE_TIME);
|
MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import org.briarproject.bramble.api.Pair;
|
|||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
|
|
||||||
@@ -42,6 +41,7 @@ import static java.util.Collections.list;
|
|||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
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.Plugin.State.INACTIVE;
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
@@ -61,9 +61,9 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
private volatile SocketFactory socketFactory;
|
private volatile SocketFactory socketFactory;
|
||||||
|
|
||||||
AndroidLanTcpPlugin(Executor ioExecutor, Context appContext,
|
AndroidLanTcpPlugin(Executor ioExecutor, Context appContext,
|
||||||
Backoff backoff, PluginCallback callback, int maxLatency,
|
PluginCallback callback, int maxLatency, int maxIdleTime,
|
||||||
int maxIdleTime, int connectionTimeout) {
|
int pollingInterval, int connectionTimeout) {
|
||||||
super(ioExecutor, backoff, callback, maxLatency, maxIdleTime,
|
super(ioExecutor, callback, maxLatency, maxIdleTime, pollingInterval,
|
||||||
connectionTimeout);
|
connectionTimeout);
|
||||||
// Don't execute more than one connection status check at a time
|
// Don't execute more than one connection status check at a time
|
||||||
connectionStatusExecutor =
|
connectionStatusExecutor =
|
||||||
@@ -82,7 +82,8 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
initialisePortProperty();
|
initialisePortProperty();
|
||||||
Settings settings = callback.getSettings();
|
Settings settings = callback.getSettings();
|
||||||
state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE, false));
|
state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
|
DEFAULT_PREF_PLUGIN_ENABLE));
|
||||||
updateConnectionStatus();
|
updateConnectionStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import android.content.Context;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -15,29 +13,27 @@ import java.util.concurrent.Executor;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30_000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30_000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int CONNECTION_TIMEOUT = 3_000; // 3 seconds
|
private static final int POLLING_INTERVAL = (int) MINUTES.toMillis(1);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60_000; // 1 minute
|
private static final int CONNECTION_TIMEOUT = (int) SECONDS.toMillis(3);
|
||||||
private static final int MAX_POLLING_INTERVAL = 600_000; // 10 mins
|
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
|
|
||||||
public AndroidLanTcpPluginFactory(Executor ioExecutor, EventBus eventBus,
|
public AndroidLanTcpPluginFactory(Executor ioExecutor, EventBus eventBus,
|
||||||
BackoffFactory backoffFactory, Context appContext) {
|
Context appContext) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,11 +49,9 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
AndroidLanTcpPlugin plugin = new AndroidLanTcpPlugin(ioExecutor,
|
AndroidLanTcpPlugin plugin = new AndroidLanTcpPlugin(ioExecutor,
|
||||||
appContext, backoff, callback, MAX_LATENCY, MAX_IDLE_TIME,
|
appContext, callback, MAX_LATENCY, MAX_IDLE_TIME,
|
||||||
CONNECTION_TIMEOUT);
|
POLLING_INTERVAL, CONNECTION_TIMEOUT);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import org.briarproject.bramble.api.battery.BatteryManager;
|
|||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
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.api.system.LocationUtils;
|
||||||
@@ -41,13 +40,15 @@ class AndroidTorPlugin extends TorPlugin {
|
|||||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||||
Clock clock, ResourceProvider resourceProvider,
|
Clock clock, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Backoff backoff,
|
BatteryManager batteryManager,
|
||||||
TorRendezvousCrypto torRendezvousCrypto,
|
TorRendezvousCrypto torRendezvousCrypto,
|
||||||
PluginCallback callback, String architecture, int maxLatency,
|
PluginCallback callback, String architecture, int maxLatency,
|
||||||
int maxIdleTime) {
|
int maxIdleTime, int initialPollingInterval,
|
||||||
|
int stablePollingInterval) {
|
||||||
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
backoff, torRendezvousCrypto, callback, architecture, maxLatency, maxIdleTime,
|
torRendezvousCrypto, callback, architecture, maxLatency,
|
||||||
|
maxIdleTime, initialPollingInterval, stablePollingInterval,
|
||||||
appContext.getDir("tor", MODE_PRIVATE));
|
appContext.getDir("tor", MODE_PRIVATE));
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
PowerManager pm = (PowerManager)
|
PowerManager pm = (PowerManager)
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import org.briarproject.bramble.api.battery.BatteryManager;
|
|||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
@@ -25,18 +23,33 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(AndroidTorPluginFactory.class.getName());
|
getLogger(AndroidTorPluginFactory.class.getName());
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60 * 1000; // 1 minute
|
|
||||||
private static final int MAX_POLLING_INTERVAL = 10 * 60 * 1000; // 10 mins
|
/**
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
* How often to poll before our hidden service becomes reachable.
|
||||||
|
*/
|
||||||
|
private static final int INITIAL_POLLING_INTERVAL =
|
||||||
|
(int) MINUTES.toMillis(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How often to poll when our hidden service is reachable. Our contacts
|
||||||
|
* will poll when they come online, so our polling is just a fallback in
|
||||||
|
* case of repeated connection failures.
|
||||||
|
*/
|
||||||
|
private static final int STABLE_POLLING_INTERVAL =
|
||||||
|
(int) MINUTES.toMillis(15);
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
@@ -45,7 +58,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final SocketFactory torSocketFactory;
|
private final SocketFactory torSocketFactory;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
private final ResourceProvider resourceProvider;
|
private final ResourceProvider resourceProvider;
|
||||||
private final CircumventionProvider circumventionProvider;
|
private final CircumventionProvider circumventionProvider;
|
||||||
private final BatteryManager batteryManager;
|
private final BatteryManager batteryManager;
|
||||||
@@ -55,7 +67,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
ScheduledExecutorService scheduler, Context appContext,
|
ScheduledExecutorService scheduler, Context appContext,
|
||||||
NetworkManager networkManager, LocationUtils locationUtils,
|
NetworkManager networkManager, LocationUtils locationUtils,
|
||||||
EventBus eventBus, SocketFactory torSocketFactory,
|
EventBus eventBus, SocketFactory torSocketFactory,
|
||||||
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
|
ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Clock clock) {
|
BatteryManager batteryManager, Clock clock) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
@@ -65,7 +77,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
this.locationUtils = locationUtils;
|
this.locationUtils = locationUtils;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.torSocketFactory = torSocketFactory;
|
this.torSocketFactory = torSocketFactory;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
this.resourceProvider = resourceProvider;
|
this.resourceProvider = resourceProvider;
|
||||||
this.circumventionProvider = circumventionProvider;
|
this.circumventionProvider = circumventionProvider;
|
||||||
this.batteryManager = batteryManager;
|
this.batteryManager = batteryManager;
|
||||||
@@ -109,14 +120,13 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
// Use position-independent executable
|
// Use position-independent executable
|
||||||
architecture += "_pie";
|
architecture += "_pie";
|
||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
||||||
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
|
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
|
||||||
appContext, networkManager, locationUtils, torSocketFactory,
|
appContext, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
backoff, torRendezvousCrypto, callback, architecture,
|
torRendezvousCrypto, callback, architecture, MAX_LATENCY,
|
||||||
MAX_LATENCY, MAX_IDLE_TIME);
|
MAX_IDLE_TIME, INITIAL_POLLING_INTERVAL,
|
||||||
|
STABLE_POLLING_INTERVAL);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.plugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates polling intervals for transport plugins that use backoff.
|
|
||||||
*/
|
|
||||||
public interface Backoff {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current polling interval.
|
|
||||||
*/
|
|
||||||
int getPollingInterval();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Increments the backoff counter.
|
|
||||||
*/
|
|
||||||
void increment();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the backoff counter.
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.plugin;
|
|
||||||
|
|
||||||
public interface BackoffFactory {
|
|
||||||
|
|
||||||
Backoff createBackoff(int minInterval, int maxInterval,
|
|
||||||
double base);
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,10 @@ public interface BluetoothConstants {
|
|||||||
|
|
||||||
int UUID_BYTES = 16;
|
int UUID_BYTES = 16;
|
||||||
|
|
||||||
|
// Transport properties
|
||||||
String PROP_ADDRESS = "address";
|
String PROP_ADDRESS = "address";
|
||||||
String PROP_UUID = "uuid";
|
String PROP_UUID = "uuid";
|
||||||
|
|
||||||
|
// Default value for PREF_PLUGIN_ENABLE
|
||||||
|
boolean DEFAULT_PREF_PLUGIN_ENABLE = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,7 @@ public interface LanTcpConstants {
|
|||||||
// Local settings (not shared with contacts)
|
// Local settings (not shared with contacts)
|
||||||
String PREF_LAN_IP_PORTS = "ipPorts";
|
String PREF_LAN_IP_PORTS = "ipPorts";
|
||||||
String PREF_IPV6 = "ipv6";
|
String PREF_IPV6 = "ipv6";
|
||||||
|
|
||||||
|
// Default value for PREF_PLUGIN_ENABLE
|
||||||
|
boolean DEFAULT_PREF_PLUGIN_ENABLE = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.briarproject.bramble.api.plugin;
|
package org.briarproject.bramble.api.plugin;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.DAYS;
|
||||||
|
|
||||||
public interface TorConstants {
|
public interface TorConstants {
|
||||||
|
|
||||||
TransportId ID = new TransportId("org.briarproject.bramble.tor");
|
TransportId ID = new TransportId("org.briarproject.bramble.tor");
|
||||||
|
|
||||||
|
// Transport properties
|
||||||
String PROP_ONION_V2 = "onion";
|
String PROP_ONION_V2 = "onion";
|
||||||
String PROP_ONION_V3 = "onion3";
|
String PROP_ONION_V3 = "onion3";
|
||||||
|
|
||||||
@@ -13,17 +16,33 @@ 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
|
||||||
|
|
||||||
|
// Local settings (not shared with contacts)
|
||||||
String PREF_TOR_NETWORK = "network2";
|
String PREF_TOR_NETWORK = "network2";
|
||||||
String PREF_TOR_PORT = "port";
|
String PREF_TOR_PORT = "port";
|
||||||
String PREF_TOR_MOBILE = "useMobileData";
|
String PREF_TOR_MOBILE = "useMobileData";
|
||||||
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
|
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
|
||||||
|
String HS_PRIVATE_KEY_V2 = "onionPrivKey";
|
||||||
|
String HS_PRIVATE_KEY_V3 = "onionPrivKey3";
|
||||||
|
String HS_V3_CREATED = "onionPrivKey3Created";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long to publish a v3 hidden service before retiring the v2 service.
|
||||||
|
*/
|
||||||
|
long V3_MIGRATION_PERIOD_MS = DAYS.toMillis(180);
|
||||||
|
|
||||||
|
// Values for PREF_TOR_NETWORK
|
||||||
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
||||||
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
|
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
|
||||||
int PREF_TOR_NETWORK_WITH_BRIDGES = 2;
|
int PREF_TOR_NETWORK_WITH_BRIDGES = 2;
|
||||||
// TODO: Remove when settings migration code is removed
|
// TODO: Remove when settings migration code is removed
|
||||||
int PREF_TOR_NETWORK_NEVER = 3;
|
int PREF_TOR_NETWORK_NEVER = 3;
|
||||||
|
|
||||||
|
// Default values for local settings
|
||||||
|
boolean DEFAULT_PREF_PLUGIN_ENABLE = true;
|
||||||
|
int DEFAULT_PREF_TOR_NETWORK = PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
|
boolean DEFAULT_PREF_TOR_MOBILE = true;
|
||||||
|
boolean DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reason flag returned by {@link Plugin#getReasonsDisabled()}.
|
* Reason flag returned by {@link Plugin#getReasonsDisabled()}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,4 +4,7 @@ public interface WanTcpConstants {
|
|||||||
|
|
||||||
TransportId ID = new TransportId("org.briarproject.bramble.wan");
|
TransportId ID = new TransportId("org.briarproject.bramble.wan");
|
||||||
|
|
||||||
|
// Default value for PREF_PLUGIN_ENABLE
|
||||||
|
boolean DEFAULT_PREF_PLUGIN_ENABLE = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package org.briarproject.bramble.plugin;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
class BackoffFactoryImpl implements BackoffFactory {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Backoff createBackoff(int minInterval, int maxInterval,
|
|
||||||
double base) {
|
|
||||||
return new BackoffImpl(minInterval, maxInterval, base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.briarproject.bramble.plugin;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
|
||||||
|
|
||||||
@ThreadSafe
|
|
||||||
@NotNullByDefault
|
|
||||||
class BackoffImpl implements Backoff {
|
|
||||||
|
|
||||||
private final int minInterval, maxInterval;
|
|
||||||
private final double base;
|
|
||||||
private final AtomicInteger backoff;
|
|
||||||
|
|
||||||
BackoffImpl(int minInterval, int maxInterval, double base) {
|
|
||||||
this.minInterval = minInterval;
|
|
||||||
this.maxInterval = maxInterval;
|
|
||||||
this.base = base;
|
|
||||||
backoff = new AtomicInteger(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPollingInterval() {
|
|
||||||
double multiplier = Math.pow(base, backoff.get());
|
|
||||||
// Large or infinite values will be rounded to Integer.MAX_VALUE
|
|
||||||
int interval = (int) (minInterval * multiplier);
|
|
||||||
return Math.min(interval, maxInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void increment() {
|
|
||||||
backoff.incrementAndGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
backoff.set(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.plugin;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginConfig;
|
import org.briarproject.bramble.api.plugin.PluginConfig;
|
||||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||||
|
|
||||||
@@ -22,11 +21,6 @@ public class PluginModule {
|
|||||||
Poller poller;
|
Poller poller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
BackoffFactory provideBackoffFactory() {
|
|
||||||
return new BackoffFactoryImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
PluginManager providePluginManager(LifecycleManager lifecycleManager,
|
PluginManager providePluginManager(LifecycleManager lifecycleManager,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import org.briarproject.bramble.api.plugin.TransportId;
|
|||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent;
|
import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent;
|
||||||
import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent;
|
|
||||||
import org.briarproject.bramble.api.plugin.event.TransportActiveEvent;
|
import org.briarproject.bramble.api.plugin.event.TransportActiveEvent;
|
||||||
import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
|
import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
|
||||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin;
|
import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin;
|
||||||
@@ -96,16 +95,10 @@ class PollerImpl implements Poller, EventListener {
|
|||||||
connectToContact(c.getContactId());
|
connectToContact(c.getContactId());
|
||||||
} else if (e instanceof ConnectionClosedEvent) {
|
} else if (e instanceof ConnectionClosedEvent) {
|
||||||
ConnectionClosedEvent c = (ConnectionClosedEvent) e;
|
ConnectionClosedEvent c = (ConnectionClosedEvent) e;
|
||||||
// Reschedule polling, the polling interval may have decreased
|
|
||||||
reschedule(c.getTransportId());
|
|
||||||
// If an outgoing connection failed, try to reconnect
|
// If an outgoing connection failed, try to reconnect
|
||||||
if (!c.isIncoming() && c.isException()) {
|
if (!c.isIncoming() && c.isException()) {
|
||||||
connectToContact(c.getContactId(), c.getTransportId());
|
connectToContact(c.getContactId(), c.getTransportId());
|
||||||
}
|
}
|
||||||
} else if (e instanceof ConnectionOpenedEvent) {
|
|
||||||
ConnectionOpenedEvent c = (ConnectionOpenedEvent) e;
|
|
||||||
// Reschedule polling, the polling interval may have decreased
|
|
||||||
reschedule(c.getTransportId());
|
|
||||||
} else if (e instanceof TransportActiveEvent) {
|
} else if (e instanceof TransportActiveEvent) {
|
||||||
TransportActiveEvent t = (TransportActiveEvent) e;
|
TransportActiveEvent t = (TransportActiveEvent) e;
|
||||||
// Poll the newly activated transport
|
// Poll the newly activated transport
|
||||||
@@ -164,12 +157,6 @@ class PollerImpl implements Poller, EventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reschedule(TransportId t) {
|
|
||||||
Plugin p = pluginManager.getPlugin(t);
|
|
||||||
if (p != null && p.shouldPoll())
|
|
||||||
schedule(p, p.getPollingInterval(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pollNow(TransportId t) {
|
private void pollNow(TransportId t) {
|
||||||
Plugin p = pluginManager.getPlugin(t);
|
Plugin p = pluginManager.getPlugin(t);
|
||||||
// Randomise next polling interval
|
// Randomise next polling interval
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
import org.briarproject.bramble.api.plugin.PluginException;
|
||||||
@@ -46,6 +45,7 @@ import static java.util.logging.Level.INFO;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
||||||
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
|
||||||
@@ -72,9 +72,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final SecureRandom secureRandom;
|
private final SecureRandom secureRandom;
|
||||||
private final Backoff backoff;
|
|
||||||
private final PluginCallback callback;
|
private final PluginCallback callback;
|
||||||
private final int maxLatency, maxIdleTime;
|
private final int maxLatency, maxIdleTime, pollingInterval;
|
||||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
|
|
||||||
protected final PluginState state = new PluginState();
|
protected final PluginState state = new PluginState();
|
||||||
@@ -115,16 +114,16 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
|
BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
|
||||||
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
|
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
|
||||||
SecureRandom secureRandom, Backoff backoff,
|
SecureRandom secureRandom, PluginCallback callback, int maxLatency, int maxIdleTime,
|
||||||
PluginCallback callback, int maxLatency, int maxIdleTime) {
|
int pollingInterval) {
|
||||||
this.connectionLimiter = connectionLimiter;
|
this.connectionLimiter = connectionLimiter;
|
||||||
this.timeoutMonitor = timeoutMonitor;
|
this.timeoutMonitor = timeoutMonitor;
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.secureRandom = secureRandom;
|
this.secureRandom = secureRandom;
|
||||||
this.backoff = backoff;
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.maxLatency = maxLatency;
|
this.maxLatency = maxLatency;
|
||||||
this.maxIdleTime = maxIdleTime;
|
this.maxIdleTime = maxIdleTime;
|
||||||
|
this.pollingInterval = pollingInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAdapterEnabled() {
|
void onAdapterEnabled() {
|
||||||
@@ -164,7 +163,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
public void start() throws PluginException {
|
public void start() throws PluginException {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
Settings settings = callback.getSettings();
|
Settings settings = callback.getSettings();
|
||||||
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, false);
|
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
|
DEFAULT_PREF_PLUGIN_ENABLE);
|
||||||
state.setStarted(enabledByUser);
|
state.setStarted(enabledByUser);
|
||||||
try {
|
try {
|
||||||
initialiseAdapter();
|
initialiseAdapter();
|
||||||
@@ -194,7 +194,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
tryToClose(ss);
|
tryToClose(ss);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
backoff.reset();
|
|
||||||
acceptContactConnections(ss);
|
acceptContactConnections(ss);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -237,7 +236,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
}
|
}
|
||||||
LOG.info("Connection received");
|
LOG.info("Connection received");
|
||||||
connectionLimiter.connectionOpened(conn);
|
connectionLimiter.connectionOpened(conn);
|
||||||
backoff.reset();
|
|
||||||
callback.handleConnection(conn);
|
callback.handleConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,14 +264,13 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPollingInterval() {
|
public int getPollingInterval() {
|
||||||
return backoff.getPollingInterval();
|
return pollingInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void poll(Collection<Pair<TransportProperties, ConnectionHandler>>
|
public void poll(Collection<Pair<TransportProperties, ConnectionHandler>>
|
||||||
properties) {
|
properties) {
|
||||||
if (getState() != ACTIVE) return;
|
if (getState() != ACTIVE) return;
|
||||||
backoff.increment();
|
|
||||||
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
|
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
|
||||||
connect(p.getFirst(), p.getSecond());
|
connect(p.getFirst(), p.getSecond());
|
||||||
}
|
}
|
||||||
@@ -286,10 +283,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
if (isNullOrEmpty(uuid)) return;
|
if (isNullOrEmpty(uuid)) return;
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
DuplexTransportConnection d = createConnection(p);
|
DuplexTransportConnection d = createConnection(p);
|
||||||
if (d != null) {
|
if (d != null) h.handleConnection(d);
|
||||||
backoff.reset();
|
|
||||||
h.handleConnection(d);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,7 +426,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
private void onSettingsUpdated(Settings settings) {
|
private void onSettingsUpdated(Settings settings) {
|
||||||
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, false);
|
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
|
DEFAULT_PREF_PLUGIN_ENABLE);
|
||||||
SS ss = state.setEnabledByUser(enabledByUser);
|
SS ss = state.setEnabledByUser(enabledByUser);
|
||||||
State s = getState();
|
State s = getState();
|
||||||
if (ss != null) {
|
if (ss != null) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.data.BdfList;
|
|||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection;
|
import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection;
|
||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
@@ -38,6 +37,7 @@ import static java.util.logging.Level.INFO;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
|
||||||
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_IPV6;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_IPV6;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
|
||||||
@@ -87,9 +87,9 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LanTcpPlugin(Executor ioExecutor, Backoff backoff, PluginCallback callback,
|
LanTcpPlugin(Executor ioExecutor, PluginCallback callback, int maxLatency,
|
||||||
int maxLatency, int maxIdleTime, int connectionTimeout) {
|
int maxIdleTime, int pollingInterval, int connectionTimeout) {
|
||||||
super(ioExecutor, backoff, callback, maxLatency, maxIdleTime,
|
super(ioExecutor, callback, maxLatency, maxIdleTime, pollingInterval,
|
||||||
connectionTimeout);
|
connectionTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,8 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
initialisePortProperty();
|
initialisePortProperty();
|
||||||
Settings settings = callback.getSettings();
|
Settings settings = callback.getSettings();
|
||||||
state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE, false));
|
state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
|
DEFAULT_PREF_PLUGIN_ENABLE));
|
||||||
bind();
|
bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +117,11 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isEnabledByDefault() {
|
||||||
|
return DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<InetSocketAddress> getLocalSocketAddresses(boolean ipv4) {
|
protected List<InetSocketAddress> getLocalSocketAddresses(boolean ipv4) {
|
||||||
TransportProperties p = callback.getLocalProperties();
|
TransportProperties p = callback.getLocalProperties();
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package org.briarproject.bramble.plugin.tcp;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -13,28 +11,25 @@ import java.util.concurrent.Executor;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class LanTcpPluginFactory implements DuplexPluginFactory {
|
public class LanTcpPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30_000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30_000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int CONNECTION_TIMEOUT = 3_000; // 3 seconds
|
private static final int POLLING_INTERVAL = (int) MINUTES.toMillis(1);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60_000; // 1 minute
|
private static final int CONNECTION_TIMEOUT = (int) SECONDS.toMillis(3);
|
||||||
private static final int MAX_POLLING_INTERVAL = 600_000; // 10 mins
|
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
|
|
||||||
public LanTcpPluginFactory(Executor ioExecutor, EventBus eventBus,
|
public LanTcpPluginFactory(Executor ioExecutor, EventBus eventBus) {
|
||||||
BackoffFactory backoffFactory) {
|
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -49,10 +44,9 @@ public class LanTcpPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
LanTcpPlugin plugin = new LanTcpPlugin(ioExecutor, callback,
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL,
|
||||||
LanTcpPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, MAX_LATENCY,
|
CONNECTION_TIMEOUT);
|
||||||
MAX_IDLE_TIME, CONNECTION_TIMEOUT);
|
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -67,9 +66,8 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$");
|
Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$");
|
||||||
|
|
||||||
protected final Executor ioExecutor, bindExecutor;
|
protected final Executor ioExecutor, bindExecutor;
|
||||||
protected final Backoff backoff;
|
|
||||||
protected final PluginCallback callback;
|
protected final PluginCallback callback;
|
||||||
protected final int maxLatency, maxIdleTime;
|
protected final int maxLatency, maxIdleTime, pollingInterval;
|
||||||
protected final int connectionTimeout, socketTimeout;
|
protected final int connectionTimeout, socketTimeout;
|
||||||
protected final AtomicBoolean used = new AtomicBoolean(false);
|
protected final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
protected final PluginState state = new PluginState();
|
protected final PluginState state = new PluginState();
|
||||||
@@ -102,13 +100,18 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
protected abstract boolean isConnectable(InterfaceAddress local,
|
protected abstract boolean isConnectable(InterfaceAddress local,
|
||||||
InetSocketAddress remote);
|
InetSocketAddress remote);
|
||||||
|
|
||||||
TcpPlugin(Executor ioExecutor, Backoff backoff, PluginCallback callback,
|
/**
|
||||||
int maxLatency, int maxIdleTime, int connectionTimeout) {
|
* Returns true if the plugin is enabled by default.
|
||||||
|
*/
|
||||||
|
protected abstract boolean isEnabledByDefault();
|
||||||
|
|
||||||
|
TcpPlugin(Executor ioExecutor, PluginCallback callback, int maxLatency,
|
||||||
|
int maxIdleTime, int pollingInterval, int connectionTimeout) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.backoff = backoff;
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.maxLatency = maxLatency;
|
this.maxLatency = maxLatency;
|
||||||
this.maxIdleTime = maxIdleTime;
|
this.maxIdleTime = maxIdleTime;
|
||||||
|
this.pollingInterval = pollingInterval;
|
||||||
this.connectionTimeout = connectionTimeout;
|
this.connectionTimeout = connectionTimeout;
|
||||||
if (maxIdleTime > Integer.MAX_VALUE / 2)
|
if (maxIdleTime > Integer.MAX_VALUE / 2)
|
||||||
socketTimeout = Integer.MAX_VALUE;
|
socketTimeout = Integer.MAX_VALUE;
|
||||||
@@ -131,7 +134,8 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
public void start() {
|
public void start() {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
Settings settings = callback.getSettings();
|
Settings settings = callback.getSettings();
|
||||||
state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE, false));
|
state.setStarted(
|
||||||
|
settings.getBoolean(PREF_PLUGIN_ENABLE, isEnabledByDefault()));
|
||||||
bind();
|
bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +169,6 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
tryToClose(ss, LOG, WARNING);
|
tryToClose(ss, LOG, WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
backoff.reset();
|
|
||||||
InetSocketAddress local =
|
InetSocketAddress local =
|
||||||
(InetSocketAddress) ss.getLocalSocketAddress();
|
(InetSocketAddress) ss.getLocalSocketAddress();
|
||||||
setLocalSocketAddress(local, ipv4);
|
setLocalSocketAddress(local, ipv4);
|
||||||
@@ -198,7 +201,6 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
LOG.info("Connection from " +
|
LOG.info("Connection from " +
|
||||||
scrubSocketAddress(s.getRemoteSocketAddress()));
|
scrubSocketAddress(s.getRemoteSocketAddress()));
|
||||||
}
|
}
|
||||||
backoff.reset();
|
|
||||||
callback.handleConnection(new TcpTransportConnection(this, s));
|
callback.handleConnection(new TcpTransportConnection(this, s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,14 +227,13 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPollingInterval() {
|
public int getPollingInterval() {
|
||||||
return backoff.getPollingInterval();
|
return pollingInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void poll(Collection<Pair<TransportProperties, ConnectionHandler>>
|
public void poll(Collection<Pair<TransportProperties, ConnectionHandler>>
|
||||||
properties) {
|
properties) {
|
||||||
if (getState() != ACTIVE) return;
|
if (getState() != ACTIVE) return;
|
||||||
backoff.increment();
|
|
||||||
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
|
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
|
||||||
connect(p.getFirst(), p.getSecond());
|
connect(p.getFirst(), p.getSecond());
|
||||||
}
|
}
|
||||||
@@ -241,10 +242,7 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
private void connect(TransportProperties p, ConnectionHandler h) {
|
private void connect(TransportProperties p, ConnectionHandler h) {
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
DuplexTransportConnection d = createConnection(p);
|
DuplexTransportConnection d = createConnection(p);
|
||||||
if (d != null) {
|
if (d != null) h.handleConnection(d);
|
||||||
backoff.reset();
|
|
||||||
h.handleConnection(d);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +400,8 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
private void onSettingsUpdated(Settings settings) {
|
private void onSettingsUpdated(Settings settings) {
|
||||||
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, false);
|
boolean enabledByUser =
|
||||||
|
settings.getBoolean(PREF_PLUGIN_ENABLE, isEnabledByDefault());
|
||||||
List<ServerSocket> toClose = state.setEnabledByUser(enabledByUser);
|
List<ServerSocket> toClose = state.setEnabledByUser(enabledByUser);
|
||||||
State s = getState();
|
State s = getState();
|
||||||
if (!toClose.isEmpty()) {
|
if (!toClose.isEmpty()) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.plugin.tcp;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
@@ -17,6 +16,7 @@ import java.util.concurrent.Executor;
|
|||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.briarproject.bramble.api.plugin.WanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -29,10 +29,10 @@ class WanTcpPlugin extends TcpPlugin {
|
|||||||
|
|
||||||
private volatile MappingResult mappingResult;
|
private volatile MappingResult mappingResult;
|
||||||
|
|
||||||
WanTcpPlugin(Executor ioExecutor, Backoff backoff, PortMapper portMapper,
|
WanTcpPlugin(Executor ioExecutor, PortMapper portMapper,
|
||||||
PluginCallback callback, int maxLatency, int maxIdleTime,
|
PluginCallback callback, int maxLatency, int maxIdleTime,
|
||||||
int connectionTimeout) {
|
int pollingInterval, int connectionTimeout) {
|
||||||
super(ioExecutor, backoff, callback, maxLatency, maxIdleTime,
|
super(ioExecutor, callback, maxLatency, maxIdleTime, pollingInterval,
|
||||||
connectionTimeout);
|
connectionTimeout);
|
||||||
this.portMapper = portMapper;
|
this.portMapper = portMapper;
|
||||||
}
|
}
|
||||||
@@ -42,6 +42,11 @@ class WanTcpPlugin extends TcpPlugin {
|
|||||||
return ID;
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isEnabledByDefault() {
|
||||||
|
return DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<InetSocketAddress> getLocalSocketAddresses(boolean ipv4) {
|
protected List<InetSocketAddress> getLocalSocketAddresses(boolean ipv4) {
|
||||||
if (!ipv4) return emptyList();
|
if (!ipv4) return emptyList();
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package org.briarproject.bramble.plugin.tcp;
|
|||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -14,29 +12,27 @@ import java.util.concurrent.Executor;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class WanTcpPluginFactory implements DuplexPluginFactory {
|
public class WanTcpPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30_000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30_000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int CONNECTION_TIMEOUT = 30_000; // 30 seconds
|
private static final int POLLING_INTERVAL = (int) MINUTES.toMillis(1);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60_000; // 1 minute
|
private static final int CONNECTION_TIMEOUT = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_POLLING_INTERVAL = 600_000; // 10 mins
|
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
private final ShutdownManager shutdownManager;
|
private final ShutdownManager shutdownManager;
|
||||||
|
|
||||||
public WanTcpPluginFactory(Executor ioExecutor, EventBus eventBus,
|
public WanTcpPluginFactory(Executor ioExecutor, EventBus eventBus,
|
||||||
BackoffFactory backoffFactory, ShutdownManager shutdownManager) {
|
ShutdownManager shutdownManager) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
this.shutdownManager = shutdownManager;
|
this.shutdownManager = shutdownManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,11 +48,9 @@ public class WanTcpPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
WanTcpPlugin plugin = new WanTcpPlugin(ioExecutor,
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
WanTcpPlugin plugin = new WanTcpPlugin(ioExecutor, backoff,
|
|
||||||
new PortMapperImpl(shutdownManager), callback, MAX_LATENCY,
|
new PortMapperImpl(shutdownManager), callback, MAX_LATENCY,
|
||||||
MAX_IDLE_TIME, CONNECTION_TIMEOUT);
|
MAX_IDLE_TIME, POLLING_INTERVAL, CONNECTION_TIMEOUT);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
import org.briarproject.bramble.api.plugin.PluginException;
|
||||||
@@ -46,9 +45,11 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -75,6 +76,13 @@ 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.Plugin.State.INACTIVE;
|
||||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||||
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.DEFAULT_PREF_PLUGIN_ENABLE;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_MOBILE;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_NETWORK;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.HS_PRIVATE_KEY_V2;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.HS_PRIVATE_KEY_V3;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.HS_V3_CREATED;
|
||||||
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_MOBILE;
|
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;
|
||||||
@@ -88,6 +96,7 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
|
|||||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY;
|
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED;
|
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA;
|
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.V3_MIGRATION_PERIOD_MS;
|
||||||
import static org.briarproject.bramble.plugin.tor.TorRendezvousCrypto.SEED_BYTES;
|
import static org.briarproject.bramble.plugin.tor.TorRendezvousCrypto.SEED_BYTES;
|
||||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
@@ -101,28 +110,59 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
private static final Logger LOG = getLogger(TorPlugin.class.getName());
|
private static final Logger LOG = getLogger(TorPlugin.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller events we want to receive.
|
||||||
|
*/
|
||||||
private static final String[] EVENTS = {
|
private static final String[] EVENTS = {
|
||||||
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
|
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command-line argument to set our process as Tor's owning controller
|
||||||
|
* so Tor exits when our process dies.
|
||||||
|
*/
|
||||||
private static final String OWNER = "__OwningControllerProcess";
|
private static final String OWNER = "__OwningControllerProcess";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long to wait for the authentication cookie file to be created.
|
||||||
|
*/
|
||||||
private static final int COOKIE_TIMEOUT_MS = 3000;
|
private static final int COOKIE_TIMEOUT_MS = 3000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How often to check whether the authentication cookie file has been
|
||||||
|
* created.
|
||||||
|
*/
|
||||||
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex for matching v2 hidden service names.
|
||||||
|
*/
|
||||||
private static final Pattern ONION_V2 = Pattern.compile("[a-z2-7]{16}");
|
private static final Pattern ONION_V2 = Pattern.compile("[a-z2-7]{16}");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex for matching v3 hidden service names.
|
||||||
|
*/
|
||||||
private static final Pattern ONION_V3 = Pattern.compile("[a-z2-7]{56}");
|
private static final Pattern ONION_V3 = Pattern.compile("[a-z2-7]{56}");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many copies of our descriptor must be uploaded before we consider
|
||||||
|
* our hidden service to be reachable and switch to less frequent polling.
|
||||||
|
*/
|
||||||
|
private static final int MIN_DESCRIPTORS_UPLOADED = 5;
|
||||||
|
|
||||||
private final Executor ioExecutor, connectionStatusExecutor;
|
private final Executor ioExecutor, connectionStatusExecutor;
|
||||||
private final NetworkManager networkManager;
|
private final NetworkManager networkManager;
|
||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
private final SocketFactory torSocketFactory;
|
private final SocketFactory torSocketFactory;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final BatteryManager batteryManager;
|
private final BatteryManager batteryManager;
|
||||||
private final Backoff backoff;
|
|
||||||
private final TorRendezvousCrypto torRendezvousCrypto;
|
private final TorRendezvousCrypto torRendezvousCrypto;
|
||||||
private final PluginCallback callback;
|
private final PluginCallback callback;
|
||||||
private final String architecture;
|
private final String architecture;
|
||||||
private final CircumventionProvider circumventionProvider;
|
private final CircumventionProvider circumventionProvider;
|
||||||
private final ResourceProvider resourceProvider;
|
private final ResourceProvider resourceProvider;
|
||||||
private final int maxLatency, maxIdleTime, socketTimeout;
|
private final int maxLatency, maxIdleTime, socketTimeout;
|
||||||
|
private final int initialPollingInterval, stablePollingInterval;
|
||||||
private final File torDirectory, torFile, geoIpFile, obfs4File, configFile;
|
private final File torDirectory, torFile, geoIpFile, obfs4File, configFile;
|
||||||
private final File doneFile, cookieFile;
|
private final File doneFile, cookieFile;
|
||||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
@@ -141,10 +181,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||||
Clock clock, ResourceProvider resourceProvider,
|
Clock clock, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Backoff backoff,
|
BatteryManager batteryManager,
|
||||||
TorRendezvousCrypto torRendezvousCrypto,
|
TorRendezvousCrypto torRendezvousCrypto,
|
||||||
PluginCallback callback, String architecture, int maxLatency,
|
PluginCallback callback, String architecture, int maxLatency,
|
||||||
int maxIdleTime, File torDirectory) {
|
int maxIdleTime, int initialPollingInterval,
|
||||||
|
int stablePollingInterval, File torDirectory) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.networkManager = networkManager;
|
this.networkManager = networkManager;
|
||||||
this.locationUtils = locationUtils;
|
this.locationUtils = locationUtils;
|
||||||
@@ -153,7 +194,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
this.resourceProvider = resourceProvider;
|
this.resourceProvider = resourceProvider;
|
||||||
this.circumventionProvider = circumventionProvider;
|
this.circumventionProvider = circumventionProvider;
|
||||||
this.batteryManager = batteryManager;
|
this.batteryManager = batteryManager;
|
||||||
this.backoff = backoff;
|
|
||||||
this.torRendezvousCrypto = torRendezvousCrypto;
|
this.torRendezvousCrypto = torRendezvousCrypto;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.architecture = architecture;
|
this.architecture = architecture;
|
||||||
@@ -162,6 +202,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (maxIdleTime > Integer.MAX_VALUE / 2)
|
if (maxIdleTime > Integer.MAX_VALUE / 2)
|
||||||
socketTimeout = Integer.MAX_VALUE;
|
socketTimeout = Integer.MAX_VALUE;
|
||||||
else socketTimeout = maxIdleTime * 2;
|
else socketTimeout = maxIdleTime * 2;
|
||||||
|
this.initialPollingInterval = initialPollingInterval;
|
||||||
|
this.stablePollingInterval = stablePollingInterval;
|
||||||
this.torDirectory = torDirectory;
|
this.torDirectory = torDirectory;
|
||||||
torFile = new File(torDirectory, "tor");
|
torFile = new File(torDirectory, "tor");
|
||||||
geoIpFile = new File(torDirectory, "geoip");
|
geoIpFile = new File(torDirectory, "geoip");
|
||||||
@@ -290,9 +332,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
// TODO: Remove after a reasonable migration period (added 2020-06-25)
|
// TODO: Remove after a reasonable migration period (added 2020-06-25)
|
||||||
private Settings migrateSettings(Settings settings) {
|
private Settings migrateSettings(Settings settings) {
|
||||||
int network = settings.getInt(PREF_TOR_NETWORK,
|
int network = settings.getInt(PREF_TOR_NETWORK,
|
||||||
PREF_TOR_NETWORK_AUTOMATIC);
|
DEFAULT_PREF_TOR_NETWORK);
|
||||||
if (network == PREF_TOR_NETWORK_NEVER) {
|
if (network == PREF_TOR_NETWORK_NEVER) {
|
||||||
settings.putInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC);
|
settings.putInt(PREF_TOR_NETWORK, DEFAULT_PREF_TOR_NETWORK);
|
||||||
settings.putBoolean(PREF_PLUGIN_ENABLE, false);
|
settings.putBoolean(PREF_PLUGIN_ENABLE, false);
|
||||||
callback.mergeSettings(settings);
|
callback.mergeSettings(settings);
|
||||||
}
|
}
|
||||||
@@ -426,7 +468,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
callback.mergeSettings(s);
|
callback.mergeSettings(s);
|
||||||
// Create a hidden service if necessary
|
// Create a hidden service if necessary
|
||||||
ioExecutor.execute(() -> publishHiddenService(localPort));
|
ioExecutor.execute(() -> publishHiddenService(localPort));
|
||||||
backoff.reset();
|
|
||||||
// Accept incoming hidden service connections from Tor
|
// Accept incoming hidden service connections from Tor
|
||||||
acceptContactConnections(ss);
|
acceptContactConnections(ss);
|
||||||
});
|
});
|
||||||
@@ -434,15 +475,66 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
private void publishHiddenService(String port) {
|
private void publishHiddenService(String port) {
|
||||||
if (!state.isTorRunning()) return;
|
if (!state.isTorRunning()) return;
|
||||||
LOG.info("Creating hidden service");
|
// TODO: Remove support for v2 hidden services after a reasonable
|
||||||
String privKey = settings.get(HS_PRIVKEY);
|
// migration period (migration started 2020-06-30)
|
||||||
|
String privKey2 = settings.get(HS_PRIVATE_KEY_V2);
|
||||||
|
String privKey3 = settings.get(HS_PRIVATE_KEY_V3);
|
||||||
|
String v3Created = settings.get(HS_V3_CREATED);
|
||||||
|
// Publish a v2 hidden service if we've already created one, and
|
||||||
|
// either we've never published a v3 hidden service or we're still
|
||||||
|
// in the migration period since first publishing it
|
||||||
|
if (!isNullOrEmpty(privKey2)) {
|
||||||
|
long now = clock.currentTimeMillis();
|
||||||
|
long then = v3Created == null ? now : Long.valueOf(v3Created);
|
||||||
|
if (now - then >= V3_MIGRATION_PERIOD_MS) retireV2HiddenService();
|
||||||
|
else publishV2HiddenService(port, privKey2);
|
||||||
|
}
|
||||||
|
publishV3HiddenService(port, privKey3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishV2HiddenService(String port, String privKey) {
|
||||||
|
LOG.info("Creating v2 hidden service");
|
||||||
|
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
|
||||||
|
Map<String, String> response;
|
||||||
|
try {
|
||||||
|
response = controlConnection.addOnion(privKey, portLines);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!response.containsKey(HS_ADDRESS)) {
|
||||||
|
LOG.warning("Tor did not return a hidden service address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String onion2 = response.get(HS_ADDRESS);
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("V2 hidden service " + scrubOnion(onion2));
|
||||||
|
}
|
||||||
|
// The hostname has already been published and the private key stored
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retireV2HiddenService() {
|
||||||
|
LOG.info("Retiring v2 hidden service");
|
||||||
|
TransportProperties p = new TransportProperties();
|
||||||
|
p.put(PROP_ONION_V2, "");
|
||||||
|
callback.mergeLocalProperties(p);
|
||||||
|
Settings s = new Settings();
|
||||||
|
s.put(HS_PRIVATE_KEY_V2, "");
|
||||||
|
callback.mergeSettings(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishV3HiddenService(String port, @Nullable String privKey) {
|
||||||
|
LOG.info("Creating v3 hidden service");
|
||||||
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
|
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
|
||||||
Map<String, String> response;
|
Map<String, String> response;
|
||||||
try {
|
try {
|
||||||
// Use the control connection to set up the hidden service
|
// Use the control connection to set up the hidden service
|
||||||
if (privKey == null)
|
if (privKey == null) {
|
||||||
response = controlConnection.addOnion(portLines);
|
response = controlConnection.addOnion("NEW:ED25519-V3",
|
||||||
else response = controlConnection.addOnion(privKey, portLines);
|
portLines, null);
|
||||||
|
} else {
|
||||||
|
response = controlConnection.addOnion(privKey, portLines);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
return;
|
return;
|
||||||
@@ -456,16 +548,18 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Publish the hidden service's onion hostname in transport properties
|
// Publish the hidden service's onion hostname in transport properties
|
||||||
String onion2 = response.get(HS_ADDRESS);
|
String onion3 = response.get(HS_ADDRESS);
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Hidden service " + scrubOnion(onion2));
|
LOG.info("V3 hidden service " + scrubOnion(onion3));
|
||||||
|
}
|
||||||
TransportProperties p = new TransportProperties();
|
TransportProperties p = new TransportProperties();
|
||||||
p.put(PROP_ONION_V2, onion2);
|
p.put(PROP_ONION_V3, onion3);
|
||||||
callback.mergeLocalProperties(p);
|
callback.mergeLocalProperties(p);
|
||||||
if (privKey == null) {
|
if (privKey == null) {
|
||||||
// Save the hidden service's private key for next time
|
// Save the hidden service's private key for next time
|
||||||
Settings s = new Settings();
|
Settings s = new Settings();
|
||||||
s.put(HS_PRIVKEY, response.get(HS_PRIVKEY));
|
s.put(HS_PRIVATE_KEY_V3, response.get(HS_PRIVKEY));
|
||||||
|
s.put(HS_V3_CREATED, String.valueOf(clock.currentTimeMillis()));
|
||||||
callback.mergeSettings(s);
|
callback.mergeSettings(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,7 +577,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG.info("Connection received");
|
LOG.info("Connection received");
|
||||||
backoff.reset();
|
|
||||||
callback.handleConnection(new TorTransportConnection(this, s));
|
callback.handleConnection(new TorTransportConnection(this, s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,14 +638,19 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPollingInterval() {
|
public int getPollingInterval() {
|
||||||
return backoff.getPollingInterval();
|
if (state.isDescriptorPublished()) {
|
||||||
|
LOG.info("Using stable polling interval");
|
||||||
|
return stablePollingInterval;
|
||||||
|
} else {
|
||||||
|
LOG.info("Using initial polling interval");
|
||||||
|
return initialPollingInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void poll(Collection<Pair<TransportProperties, ConnectionHandler>>
|
public void poll(Collection<Pair<TransportProperties, ConnectionHandler>>
|
||||||
properties) {
|
properties) {
|
||||||
if (getState() != ACTIVE) return;
|
if (getState() != ACTIVE) return;
|
||||||
backoff.increment();
|
|
||||||
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
|
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
|
||||||
connect(p.getFirst(), p.getSecond());
|
connect(p.getFirst(), p.getSecond());
|
||||||
}
|
}
|
||||||
@@ -561,22 +659,22 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
private void connect(TransportProperties p, ConnectionHandler h) {
|
private void connect(TransportProperties p, ConnectionHandler h) {
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
DuplexTransportConnection d = createConnection(p);
|
DuplexTransportConnection d = createConnection(p);
|
||||||
if (d != null) {
|
if (d != null) h.handleConnection(d);
|
||||||
backoff.reset();
|
|
||||||
h.handleConnection(d);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DuplexTransportConnection createConnection(TransportProperties p) {
|
public DuplexTransportConnection createConnection(TransportProperties p) {
|
||||||
if (getState() != ACTIVE) return null;
|
if (getState() != ACTIVE) return null;
|
||||||
String bestOnion = null;
|
// TODO: Remove support for v2 hidden services after a reasonable
|
||||||
|
// migration period (migration started 2020-06-30)
|
||||||
|
String bestOnion = null, version = null;
|
||||||
String onion2 = p.get(PROP_ONION_V2);
|
String onion2 = p.get(PROP_ONION_V2);
|
||||||
String onion3 = p.get(PROP_ONION_V3);
|
String onion3 = p.get(PROP_ONION_V3);
|
||||||
if (!isNullOrEmpty(onion2)) {
|
if (!isNullOrEmpty(onion2)) {
|
||||||
if (ONION_V2.matcher(onion2).matches()) {
|
if (ONION_V2.matcher(onion2).matches()) {
|
||||||
bestOnion = onion2;
|
bestOnion = onion2;
|
||||||
|
version = "v2";
|
||||||
} else {
|
} else {
|
||||||
// Don't scrub the address so we can find the problem
|
// Don't scrub the address so we can find the problem
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
@@ -586,6 +684,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (!isNullOrEmpty(onion3)) {
|
if (!isNullOrEmpty(onion3)) {
|
||||||
if (ONION_V3.matcher(onion3).matches()) {
|
if (ONION_V3.matcher(onion3).matches()) {
|
||||||
bestOnion = onion3;
|
bestOnion = onion3;
|
||||||
|
version = "v3";
|
||||||
} else {
|
} else {
|
||||||
// Don't scrub the address so we can find the problem
|
// Don't scrub the address so we can find the problem
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
@@ -595,17 +694,21 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (bestOnion == null) return null;
|
if (bestOnion == null) return null;
|
||||||
Socket s = null;
|
Socket s = null;
|
||||||
try {
|
try {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Connecting to " + scrubOnion(bestOnion));
|
LOG.info("Connecting to " + version + " "
|
||||||
|
+ scrubOnion(bestOnion));
|
||||||
|
}
|
||||||
s = torSocketFactory.createSocket(bestOnion + ".onion", 80);
|
s = torSocketFactory.createSocket(bestOnion + ".onion", 80);
|
||||||
s.setSoTimeout(socketTimeout);
|
s.setSoTimeout(socketTimeout);
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Connected to " + scrubOnion(bestOnion));
|
LOG.info("Connected to " + version + " "
|
||||||
|
+ scrubOnion(bestOnion));
|
||||||
|
}
|
||||||
return new TorTransportConnection(this, s);
|
return new TorTransportConnection(this, s);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Could not connect to " + scrubOnion(bestOnion)
|
LOG.info("Could not connect to " + version + " "
|
||||||
+ ": " + e.toString());
|
+ scrubOnion(bestOnion) + ": " + e.toString());
|
||||||
}
|
}
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s, LOG, WARNING);
|
||||||
return null;
|
return null;
|
||||||
@@ -686,10 +789,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void circuitStatus(String status, String id, String path) {
|
public void circuitStatus(String status, String id, String path) {
|
||||||
if (status.equals("BUILT") &&
|
if (status.equals("BUILT") && state.getAndSetCircuitBuilt()) {
|
||||||
state.getAndSetCircuitBuilt()) {
|
|
||||||
LOG.info("First circuit built");
|
LOG.info("First circuit built");
|
||||||
backoff.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,8 +800,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void orConnStatus(String status, String orName) {
|
public void orConnStatus(String status, String orName) {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO)) LOG.info("OR connection " + status);
|
||||||
LOG.info("OR connection " + status + " " + orName);
|
state.setOrConnectionStatus(orName, status);
|
||||||
if (status.equals("CLOSED") || status.equals("FAILED")) {
|
if (status.equals("CLOSED") || status.equals("FAILED")) {
|
||||||
// Check whether we've lost connectivity
|
// Check whether we've lost connectivity
|
||||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||||
@@ -721,14 +822,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (LOG.isLoggable(INFO)) LOG.info(severity + " " + msg);
|
if (LOG.isLoggable(INFO)) LOG.info(severity + " " + msg);
|
||||||
if (severity.equals("NOTICE") && msg.startsWith("Bootstrapped 100%")) {
|
if (severity.equals("NOTICE") && msg.startsWith("Bootstrapped 100%")) {
|
||||||
state.setBootstrapped();
|
state.setBootstrapped();
|
||||||
backoff.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unrecognized(String type, String msg) {
|
public void unrecognized(String type, String msg) {
|
||||||
if (type.equals("HS_DESC") && msg.startsWith("UPLOADED"))
|
if (type.equals("HS_DESC") && msg.startsWith("UPLOADED")) {
|
||||||
LOG.info("Descriptor uploaded");
|
String[] words = msg.split(" ");
|
||||||
|
if (words.length > 1 && ONION_V3.matcher(words[1]).matches()) {
|
||||||
|
LOG.info("V3 descriptor uploaded");
|
||||||
|
state.descriptorUploaded();
|
||||||
|
} else {
|
||||||
|
LOG.info("V2 descriptor uploaded");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -774,13 +881,15 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
String country = locationUtils.getCurrentCountry();
|
String country = locationUtils.getCurrentCountry();
|
||||||
boolean blocked =
|
boolean blocked =
|
||||||
circumventionProvider.isTorProbablyBlocked(country);
|
circumventionProvider.isTorProbablyBlocked(country);
|
||||||
boolean enabledByUser =
|
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
settings.getBoolean(PREF_PLUGIN_ENABLE, true);
|
DEFAULT_PREF_PLUGIN_ENABLE);
|
||||||
int network = settings.getInt(PREF_TOR_NETWORK,
|
int network = settings.getInt(PREF_TOR_NETWORK,
|
||||||
PREF_TOR_NETWORK_AUTOMATIC);
|
DEFAULT_PREF_TOR_NETWORK);
|
||||||
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
|
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE,
|
||||||
|
DEFAULT_PREF_TOR_MOBILE);
|
||||||
boolean onlyWhenCharging =
|
boolean onlyWhenCharging =
|
||||||
settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false);
|
settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING,
|
||||||
|
DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING);
|
||||||
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
|
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
|
||||||
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
|
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
|
|
||||||
@@ -880,6 +989,12 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private ServerSocket serverSocket = null;
|
private ServerSocket serverSocket = null;
|
||||||
|
|
||||||
|
@GuardedBy("this")
|
||||||
|
private final Set<String> orConnections = new HashSet<>();
|
||||||
|
|
||||||
|
@GuardedBy("this")
|
||||||
|
private int descriptorsUploaded = 0;
|
||||||
|
|
||||||
synchronized void setStarted() {
|
synchronized void setStarted() {
|
||||||
started = true;
|
started = true;
|
||||||
callback.pluginStateChanged(getState());
|
callback.pluginStateChanged(getState());
|
||||||
@@ -913,7 +1028,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
synchronized void enableNetwork(boolean enable) {
|
synchronized void enableNetwork(boolean enable) {
|
||||||
networkInitialised = true;
|
networkInitialised = true;
|
||||||
networkEnabled = enable;
|
networkEnabled = enable;
|
||||||
if (!enable) circuitBuilt = false;
|
if (!enable) {
|
||||||
|
circuitBuilt = false;
|
||||||
|
descriptorsUploaded = 0;
|
||||||
|
}
|
||||||
callback.pluginStateChanged(getState());
|
callback.pluginStateChanged(getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,6 +1041,34 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
callback.pluginStateChanged(getState());
|
callback.pluginStateChanged(getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized void setOrConnectionStatus(String orName, String status) {
|
||||||
|
if (status.equals("CONNECTED")) {
|
||||||
|
if (!orConnections.add(orName)) {
|
||||||
|
LOG.warning("Duplicate OR connection");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
orConnections.remove(orName);
|
||||||
|
if (orConnections.isEmpty()) descriptorsUploaded = 0;
|
||||||
|
}
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info(orConnections.size() + " OR connections");
|
||||||
|
}
|
||||||
|
callback.pluginStateChanged(getState());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't affect getState()
|
||||||
|
synchronized void descriptorUploaded() {
|
||||||
|
if (networkEnabled && !orConnections.isEmpty()) {
|
||||||
|
descriptorsUploaded++;
|
||||||
|
} else {
|
||||||
|
LOG.warning("Descriptor was uploaded with no OR connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized boolean isDescriptorPublished() {
|
||||||
|
return descriptorsUploaded >= MIN_DESCRIPTORS_UPLOADED;
|
||||||
|
}
|
||||||
|
|
||||||
// Doesn't affect getState()
|
// Doesn't affect getState()
|
||||||
synchronized boolean setServerSocket(ServerSocket ss) {
|
synchronized boolean setServerSocket(ServerSocket ss) {
|
||||||
if (stopped || serverSocket != null) return false;
|
if (stopped || serverSocket != null) return false;
|
||||||
@@ -942,7 +1088,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (reasonsDisabled != 0) return DISABLED;
|
if (reasonsDisabled != 0) return DISABLED;
|
||||||
if (!networkInitialised) return ENABLING;
|
if (!networkInitialised) return ENABLING;
|
||||||
if (!networkEnabled) return INACTIVE;
|
if (!networkEnabled) return INACTIVE;
|
||||||
return bootstrapped && circuitBuilt ? ACTIVE : ENABLING;
|
return bootstrapped && circuitBuilt && !orConnections.isEmpty()
|
||||||
|
? ACTIVE : ENABLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized int getReasonsDisabled() {
|
synchronized int getReasonsDisabled() {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
|||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ import static org.briarproject.bramble.api.properties.TransportPropertyConstants
|
|||||||
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MSG_KEY_LOCAL;
|
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MSG_KEY_LOCAL;
|
||||||
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MSG_KEY_TRANSPORT_ID;
|
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MSG_KEY_TRANSPORT_ID;
|
||||||
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MSG_KEY_VERSION;
|
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MSG_KEY_VERSION;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -272,14 +274,22 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
LatestUpdate latest = findLatest(txn, localGroup.getId(), t,
|
LatestUpdate latest = findLatest(txn, localGroup.getId(), t,
|
||||||
true);
|
true);
|
||||||
if (latest == null) {
|
if (latest == null) {
|
||||||
merged = p;
|
merged = new TransportProperties(p);
|
||||||
|
Iterator<String> it = merged.values().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
if (isNullOrEmpty(it.next())) it.remove();
|
||||||
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
latest.messageId);
|
latest.messageId);
|
||||||
TransportProperties old = parseProperties(message);
|
TransportProperties old = parseProperties(message);
|
||||||
merged = new TransportProperties(old);
|
merged = new TransportProperties(old);
|
||||||
merged.putAll(p);
|
for (Entry<String, String> e : p.entrySet()) {
|
||||||
|
String key = e.getKey(), value = e.getValue();
|
||||||
|
if (isNullOrEmpty(value)) merged.remove(key);
|
||||||
|
else merged.put(key, value);
|
||||||
|
}
|
||||||
changed = !merged.equals(old);
|
changed = !merged.equals(old);
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
package org.briarproject.bramble.plugin;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class BackoffImplTest extends BrambleTestCase {
|
|
||||||
|
|
||||||
private static final int MIN_INTERVAL = 60 * 1000;
|
|
||||||
private static final int MAX_INTERVAL = 60 * 60 * 1000;
|
|
||||||
private static final double BASE = 1.2;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPollingIntervalStartsAtMinimum() {
|
|
||||||
BackoffImpl b = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL, BASE);
|
|
||||||
assertEquals(MIN_INTERVAL, b.getPollingInterval());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIncrementIncreasesPollingInterval() {
|
|
||||||
BackoffImpl b = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL, BASE);
|
|
||||||
b.increment();
|
|
||||||
assertTrue(b.getPollingInterval() > MIN_INTERVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testResetResetsPollingInterval() {
|
|
||||||
BackoffImpl b = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL, BASE);
|
|
||||||
b.increment();
|
|
||||||
b.increment();
|
|
||||||
b.reset();
|
|
||||||
assertEquals(MIN_INTERVAL, b.getPollingInterval());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBaseAffectsBackoffSpeed() {
|
|
||||||
BackoffImpl b = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL, BASE);
|
|
||||||
b.increment();
|
|
||||||
int interval = b.getPollingInterval();
|
|
||||||
BackoffImpl b1 = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL, BASE * 2);
|
|
||||||
b1.increment();
|
|
||||||
int interval1 = b1.getPollingInterval();
|
|
||||||
assertTrue(interval < interval1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIntervalDoesNotExceedMaxInterval() {
|
|
||||||
BackoffImpl b = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL, BASE);
|
|
||||||
for (int i = 0; i < 100; i++) b.increment();
|
|
||||||
assertEquals(MAX_INTERVAL, b.getPollingInterval());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIntervalDoesNotExceedMaxIntervalWithInfiniteMultiplier() {
|
|
||||||
BackoffImpl b = new BackoffImpl(MIN_INTERVAL, MAX_INTERVAL,
|
|
||||||
Double.POSITIVE_INFINITY);
|
|
||||||
b.increment();
|
|
||||||
assertEquals(MAX_INTERVAL, b.getPollingInterval());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.plugin.TransportId;
|
|||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent;
|
import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent;
|
||||||
import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent;
|
|
||||||
import org.briarproject.bramble.api.plugin.event.TransportActiveEvent;
|
import org.briarproject.bramble.api.plugin.event.TransportActiveEvent;
|
||||||
import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
|
import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
|
||||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin;
|
import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin;
|
||||||
@@ -157,22 +156,20 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRescheduleOnOutgoingConnectionClosed() {
|
public void testDoesNotReconnectOnOutgoingConnectionClosed() {
|
||||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
allowing(plugin).getId();
|
allowing(plugin).getId();
|
||||||
will(returnValue(transportId));
|
will(returnValue(transportId));
|
||||||
}});
|
}});
|
||||||
expectReschedule(plugin);
|
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
||||||
false, false));
|
false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRescheduleAndReconnectOnOutgoingConnectionFailed()
|
public void testReconnectsOnOutgoingConnectionFailed() throws Exception {
|
||||||
throws Exception {
|
|
||||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||||
DuplexTransportConnection duplexConnection =
|
DuplexTransportConnection duplexConnection =
|
||||||
context.mock(DuplexTransportConnection.class);
|
context.mock(DuplexTransportConnection.class);
|
||||||
@@ -181,7 +178,6 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
allowing(plugin).getId();
|
allowing(plugin).getId();
|
||||||
will(returnValue(transportId));
|
will(returnValue(transportId));
|
||||||
}});
|
}});
|
||||||
expectReschedule(plugin);
|
|
||||||
expectReconnect(plugin, duplexConnection);
|
expectReconnect(plugin, duplexConnection);
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
||||||
@@ -189,147 +185,31 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRescheduleOnIncomingConnectionClosed() {
|
public void testDoesNotReconnectOnIncomingConnectionClosed() {
|
||||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
allowing(plugin).getId();
|
allowing(plugin).getId();
|
||||||
will(returnValue(transportId));
|
will(returnValue(transportId));
|
||||||
}});
|
}});
|
||||||
expectReschedule(plugin);
|
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
||||||
true, false));
|
true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRescheduleOnIncomingConnectionFailed() {
|
public void testDoesNotReconnectOnIncomingConnectionFailed() {
|
||||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
allowing(plugin).getId();
|
allowing(plugin).getId();
|
||||||
will(returnValue(transportId));
|
will(returnValue(transportId));
|
||||||
}});
|
}});
|
||||||
expectReschedule(plugin);
|
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId,
|
||||||
true, false));
|
true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRescheduleOnConnectionOpened() {
|
|
||||||
Plugin plugin = context.mock(Plugin.class);
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
allowing(plugin).getId();
|
|
||||||
will(returnValue(transportId));
|
|
||||||
// Get the plugin
|
|
||||||
oneOf(pluginManager).getPlugin(transportId);
|
|
||||||
will(returnValue(plugin));
|
|
||||||
// The plugin supports polling
|
|
||||||
oneOf(plugin).shouldPoll();
|
|
||||||
will(returnValue(true));
|
|
||||||
// Schedule the next poll
|
|
||||||
oneOf(plugin).getPollingInterval();
|
|
||||||
will(returnValue(pollingInterval));
|
|
||||||
oneOf(clock).currentTimeMillis();
|
|
||||||
will(returnValue(now));
|
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
|
||||||
will(returnValue(future));
|
|
||||||
}});
|
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
|
||||||
false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRescheduleDoesNotReplaceEarlierTask() {
|
|
||||||
Plugin plugin = context.mock(Plugin.class);
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
allowing(plugin).getId();
|
|
||||||
will(returnValue(transportId));
|
|
||||||
// First event
|
|
||||||
// Get the plugin
|
|
||||||
oneOf(pluginManager).getPlugin(transportId);
|
|
||||||
will(returnValue(plugin));
|
|
||||||
// The plugin supports polling
|
|
||||||
oneOf(plugin).shouldPoll();
|
|
||||||
will(returnValue(true));
|
|
||||||
// Schedule the next poll
|
|
||||||
oneOf(plugin).getPollingInterval();
|
|
||||||
will(returnValue(pollingInterval));
|
|
||||||
oneOf(clock).currentTimeMillis();
|
|
||||||
will(returnValue(now));
|
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
|
||||||
will(returnValue(future));
|
|
||||||
// Second event
|
|
||||||
// Get the plugin
|
|
||||||
oneOf(pluginManager).getPlugin(transportId);
|
|
||||||
will(returnValue(plugin));
|
|
||||||
// The plugin supports polling
|
|
||||||
oneOf(plugin).shouldPoll();
|
|
||||||
will(returnValue(true));
|
|
||||||
// Don't replace the previously scheduled task, due earlier
|
|
||||||
oneOf(plugin).getPollingInterval();
|
|
||||||
will(returnValue(pollingInterval));
|
|
||||||
oneOf(clock).currentTimeMillis();
|
|
||||||
will(returnValue(now + 1));
|
|
||||||
}});
|
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
|
||||||
false));
|
|
||||||
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
|
||||||
false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRescheduleReplacesLaterTask() {
|
|
||||||
Plugin plugin = context.mock(Plugin.class);
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
allowing(plugin).getId();
|
|
||||||
will(returnValue(transportId));
|
|
||||||
// First event
|
|
||||||
// Get the plugin
|
|
||||||
oneOf(pluginManager).getPlugin(transportId);
|
|
||||||
will(returnValue(plugin));
|
|
||||||
// The plugin supports polling
|
|
||||||
oneOf(plugin).shouldPoll();
|
|
||||||
will(returnValue(true));
|
|
||||||
// Schedule the next poll
|
|
||||||
oneOf(plugin).getPollingInterval();
|
|
||||||
will(returnValue(pollingInterval));
|
|
||||||
oneOf(clock).currentTimeMillis();
|
|
||||||
will(returnValue(now));
|
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
|
||||||
will(returnValue(future));
|
|
||||||
// Second event
|
|
||||||
// Get the plugin
|
|
||||||
oneOf(pluginManager).getPlugin(transportId);
|
|
||||||
will(returnValue(plugin));
|
|
||||||
// The plugin supports polling
|
|
||||||
oneOf(plugin).shouldPoll();
|
|
||||||
will(returnValue(true));
|
|
||||||
// Replace the previously scheduled task, due later
|
|
||||||
oneOf(plugin).getPollingInterval();
|
|
||||||
will(returnValue(pollingInterval - 2));
|
|
||||||
oneOf(clock).currentTimeMillis();
|
|
||||||
will(returnValue(now + 1));
|
|
||||||
oneOf(future).cancel(false);
|
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
|
||||||
with((long) pollingInterval - 2), with(MILLISECONDS));
|
|
||||||
}});
|
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
|
||||||
false));
|
|
||||||
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
|
||||||
false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPollsOnTransportActivated() throws Exception {
|
public void testPollsOnTransportActivated() throws Exception {
|
||||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||||
@@ -441,25 +321,6 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
poller.eventOccurred(new TransportInactiveEvent(transportId));
|
poller.eventOccurred(new TransportInactiveEvent(transportId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectReschedule(Plugin plugin) {
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
// Get the plugin
|
|
||||||
oneOf(pluginManager).getPlugin(transportId);
|
|
||||||
will(returnValue(plugin));
|
|
||||||
// The plugin supports polling
|
|
||||||
oneOf(plugin).shouldPoll();
|
|
||||||
will(returnValue(true));
|
|
||||||
// Schedule the next poll
|
|
||||||
oneOf(plugin).getPollingInterval();
|
|
||||||
will(returnValue(pollingInterval));
|
|
||||||
oneOf(clock).currentTimeMillis();
|
|
||||||
will(returnValue(now));
|
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
|
||||||
will(returnValue(future));
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void expectReconnect(DuplexPlugin plugin,
|
private void expectReconnect(DuplexPlugin plugin,
|
||||||
DuplexTransportConnection duplexConnection) throws Exception {
|
DuplexTransportConnection duplexConnection) throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.plugin.tcp;
|
|||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.Plugin.State;
|
import org.briarproject.bramble.api.plugin.Plugin.State;
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
||||||
@@ -42,7 +41,6 @@ import static org.junit.Assume.assumeTrue;
|
|||||||
|
|
||||||
public class LanTcpPluginTest extends BrambleTestCase {
|
public class LanTcpPluginTest extends BrambleTestCase {
|
||||||
|
|
||||||
private final Backoff backoff = new TestBackoff();
|
|
||||||
private final ExecutorService ioExecutor = newCachedThreadPool();
|
private final ExecutorService ioExecutor = newCachedThreadPool();
|
||||||
|
|
||||||
private Callback callback = null;
|
private Callback callback = null;
|
||||||
@@ -51,7 +49,7 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
callback = new Callback();
|
callback = new Callback();
|
||||||
plugin = new LanTcpPlugin(ioExecutor, backoff, callback, 0, 0, 1000) {
|
plugin = new LanTcpPlugin(ioExecutor, callback, 0, 0, 0, 1000) {
|
||||||
@Override
|
@Override
|
||||||
protected boolean canConnectToOwnAddress() {
|
protected boolean canConnectToOwnAddress() {
|
||||||
return true;
|
return true;
|
||||||
@@ -347,20 +345,4 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
|||||||
public void handleWriter(TransportConnectionWriter w) {
|
public void handleWriter(TransportConnectionWriter w) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestBackoff implements Backoff {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPollingInterval() {
|
|
||||||
return 60 * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void increment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -566,6 +566,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
Contact contact = getContact();
|
Contact contact = getContact();
|
||||||
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
|
|
||||||
|
// Property with an empty value should be discarded
|
||||||
|
TransportProperties properties = new TransportProperties(fooProperties);
|
||||||
|
properties.put("fooKey3", "");
|
||||||
|
|
||||||
context.checking(new DbExpectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
// There are no existing properties to merge with
|
// There are no existing properties to merge with
|
||||||
@@ -589,7 +593,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
t.mergeLocalProperties(new TransportId("foo"), fooProperties);
|
t.mergeLocalProperties(new TransportId("foo"), properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -605,16 +609,24 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
MessageId localGroupUpdateId = new MessageId(getRandomId());
|
MessageId localGroupUpdateId = new MessageId(getRandomId());
|
||||||
Map<MessageId, BdfDictionary> localGroupMessageMetadata =
|
Map<MessageId, BdfDictionary> localGroupMessageMetadata =
|
||||||
singletonMap(localGroupUpdateId, oldMetadata);
|
singletonMap(localGroupUpdateId, oldMetadata);
|
||||||
|
|
||||||
MessageId contactGroupUpdateId = new MessageId(getRandomId());
|
MessageId contactGroupUpdateId = new MessageId(getRandomId());
|
||||||
Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
|
Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
|
||||||
singletonMap(contactGroupUpdateId, oldMetadata);
|
singletonMap(contactGroupUpdateId, oldMetadata);
|
||||||
|
|
||||||
TransportProperties oldProperties = new TransportProperties();
|
TransportProperties oldProperties = new TransportProperties();
|
||||||
oldProperties.put("fooKey1", "oldFooValue1");
|
oldProperties.put("fooKey1", "oldFooValue1");
|
||||||
|
oldProperties.put("fooKey3", "oldFooValue3");
|
||||||
BdfDictionary oldPropertiesDict = BdfDictionary.of(
|
BdfDictionary oldPropertiesDict = BdfDictionary.of(
|
||||||
new BdfEntry("fooKey1", "oldFooValue1")
|
new BdfEntry("fooKey1", "oldFooValue1"),
|
||||||
|
new BdfEntry("fooKey3", "oldFooValue3")
|
||||||
);
|
);
|
||||||
BdfList oldUpdate = BdfList.of("foo", 1, oldPropertiesDict);
|
BdfList oldUpdate = BdfList.of("foo", 1, oldPropertiesDict);
|
||||||
|
|
||||||
|
// Property assigned an empty value should be removed
|
||||||
|
TransportProperties properties = new TransportProperties(fooProperties);
|
||||||
|
properties.put("fooKey3", "");
|
||||||
|
|
||||||
context.checking(new DbExpectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
// Merge the new properties with the existing properties
|
// Merge the new properties with the existing properties
|
||||||
@@ -647,7 +659,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
t.mergeLocalProperties(new TransportId("foo"), fooProperties);
|
t.mergeLocalProperties(new TransportId("foo"), properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectGetLocalProperties(Transaction txn) throws Exception {
|
private void expectGetLocalProperties(Transaction txn) throws Exception {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.io.TimeoutMonitor;
|
|||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||||
import org.briarproject.bramble.api.plugin.PluginConfig;
|
import org.briarproject.bramble.api.plugin.PluginConfig;
|
||||||
@@ -37,18 +36,16 @@ public class DesktopPluginModule extends PluginModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
PluginConfig getPluginConfig(@IoExecutor Executor ioExecutor,
|
PluginConfig getPluginConfig(@IoExecutor Executor ioExecutor,
|
||||||
SecureRandom random, BackoffFactory backoffFactory,
|
SecureRandom random, ReliabilityLayerFactory reliabilityFactory,
|
||||||
ReliabilityLayerFactory reliabilityFactory,
|
|
||||||
ShutdownManager shutdownManager, EventBus eventBus,
|
ShutdownManager shutdownManager, EventBus eventBus,
|
||||||
TimeoutMonitor timeoutMonitor) {
|
TimeoutMonitor timeoutMonitor) {
|
||||||
DuplexPluginFactory bluetooth = new JavaBluetoothPluginFactory(
|
DuplexPluginFactory bluetooth = new JavaBluetoothPluginFactory(
|
||||||
ioExecutor, random, eventBus, timeoutMonitor, backoffFactory);
|
ioExecutor, random, eventBus, timeoutMonitor);
|
||||||
DuplexPluginFactory modem = new ModemPluginFactory(ioExecutor,
|
DuplexPluginFactory modem = new ModemPluginFactory(ioExecutor,
|
||||||
reliabilityFactory);
|
reliabilityFactory);
|
||||||
DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor, eventBus,
|
DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor, eventBus);
|
||||||
backoffFactory);
|
|
||||||
DuplexPluginFactory wan = new WanTcpPluginFactory(ioExecutor, eventBus,
|
DuplexPluginFactory wan = new WanTcpPluginFactory(ioExecutor, eventBus,
|
||||||
backoffFactory, shutdownManager);
|
shutdownManager);
|
||||||
Collection<DuplexPluginFactory> duplex =
|
Collection<DuplexPluginFactory> duplex =
|
||||||
asList(bluetooth, modem, lan, wan);
|
asList(bluetooth, modem, lan, wan);
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.plugin.bluetooth;
|
|||||||
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
|
|
||||||
@@ -36,10 +35,10 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
|
|||||||
|
|
||||||
JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager,
|
JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager,
|
||||||
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
|
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
|
||||||
SecureRandom secureRandom, Backoff backoff,
|
SecureRandom secureRandom, PluginCallback callback, int maxLatency,
|
||||||
PluginCallback callback, int maxLatency, int maxIdleTime) {
|
int maxIdleTime, int pollingInterval) {
|
||||||
super(connectionManager, timeoutMonitor, ioExecutor, secureRandom,
|
super(connectionManager, timeoutMonitor, ioExecutor, secureRandom,
|
||||||
backoff, callback, maxLatency, maxIdleTime);
|
callback, maxLatency, maxIdleTime, pollingInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package org.briarproject.bramble.plugin.bluetooth;
|
|||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
import org.briarproject.bramble.api.io.TimeoutMonitor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -15,32 +13,30 @@ import java.util.concurrent.Executor;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
|
public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60 * 1000; // 1 minute
|
private static final int POLLING_INTERVAL = (int) MINUTES.toMillis(2);
|
||||||
private static final int MAX_POLLING_INTERVAL = 10 * 60 * 1000; // 10 mins
|
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final SecureRandom secureRandom;
|
private final SecureRandom secureRandom;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final TimeoutMonitor timeoutMonitor;
|
private final TimeoutMonitor timeoutMonitor;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
|
|
||||||
public JavaBluetoothPluginFactory(Executor ioExecutor,
|
public JavaBluetoothPluginFactory(Executor ioExecutor,
|
||||||
SecureRandom secureRandom, EventBus eventBus,
|
SecureRandom secureRandom, EventBus eventBus,
|
||||||
TimeoutMonitor timeoutMonitor, BackoffFactory backoffFactory) {
|
TimeoutMonitor timeoutMonitor) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.secureRandom = secureRandom;
|
this.secureRandom = secureRandom;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.timeoutMonitor = timeoutMonitor;
|
this.timeoutMonitor = timeoutMonitor;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -57,11 +53,9 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
BluetoothConnectionLimiter connectionLimiter =
|
BluetoothConnectionLimiter connectionLimiter =
|
||||||
new BluetoothConnectionLimiterImpl(eventBus);
|
new BluetoothConnectionLimiterImpl(eventBus);
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
JavaBluetoothPlugin plugin = new JavaBluetoothPlugin(connectionLimiter,
|
JavaBluetoothPlugin plugin = new JavaBluetoothPlugin(connectionLimiter,
|
||||||
timeoutMonitor, ioExecutor, secureRandom, backoff, callback,
|
timeoutMonitor, ioExecutor, secureRandom, callback, MAX_LATENCY,
|
||||||
MAX_LATENCY, MAX_IDLE_TIME);
|
MAX_IDLE_TIME, POLLING_INTERVAL);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.plugin.tor;
|
|||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.plugin.PluginCallback;
|
||||||
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.api.system.LocationUtils;
|
||||||
@@ -24,14 +23,16 @@ abstract class JavaTorPlugin extends TorPlugin {
|
|||||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||||
Clock clock, ResourceProvider resourceProvider,
|
Clock clock, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Backoff backoff,
|
BatteryManager batteryManager,
|
||||||
TorRendezvousCrypto torRendezvousCrypto,
|
TorRendezvousCrypto torRendezvousCrypto,
|
||||||
PluginCallback callback, String architecture, int maxLatency,
|
PluginCallback callback, String architecture, int maxLatency,
|
||||||
int maxIdleTime, File torDirectory) {
|
int maxIdleTime, int initialPollingInterval,
|
||||||
|
int stablePollingInterval, File torDirectory) {
|
||||||
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
backoff, torRendezvousCrypto, callback, architecture,
|
torRendezvousCrypto, callback, architecture, maxLatency,
|
||||||
maxLatency, maxIdleTime, torDirectory);
|
maxIdleTime, initialPollingInterval, stablePollingInterval,
|
||||||
|
torDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import com.sun.jna.Native;
|
|||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.plugin.PluginCallback;
|
||||||
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.api.system.LocationUtils;
|
||||||
@@ -24,14 +23,16 @@ class UnixTorPlugin extends JavaTorPlugin {
|
|||||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||||
Clock clock, ResourceProvider resourceProvider,
|
Clock clock, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Backoff backoff,
|
BatteryManager batteryManager,
|
||||||
TorRendezvousCrypto torRendezvousCrypto,
|
TorRendezvousCrypto torRendezvousCrypto,
|
||||||
PluginCallback callback, String architecture, int maxLatency,
|
PluginCallback callback, String architecture, int maxLatency,
|
||||||
int maxIdleTime, File torDirectory) {
|
int maxIdleTime, int initialPollingInterval,
|
||||||
|
int stablePollingInterval, File torDirectory) {
|
||||||
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
backoff, torRendezvousCrypto, callback, architecture,
|
torRendezvousCrypto, callback, architecture,
|
||||||
maxLatency, maxIdleTime, torDirectory);
|
maxLatency, maxIdleTime, initialPollingInterval,
|
||||||
|
stablePollingInterval, torDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import org.briarproject.bramble.api.battery.BatteryManager;
|
|||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
@@ -22,6 +20,8 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
||||||
|
|
||||||
@@ -32,18 +32,28 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(UnixTorPluginFactory.class.getName());
|
getLogger(UnixTorPluginFactory.class.getName());
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
private static final int MAX_LATENCY = (int) SECONDS.toMillis(30);
|
||||||
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
private static final int MAX_IDLE_TIME = (int) SECONDS.toMillis(30);
|
||||||
private static final int MIN_POLLING_INTERVAL = 60 * 1000; // 1 minute
|
|
||||||
private static final int MAX_POLLING_INTERVAL = 10 * 60 * 1000; // 10 mins
|
/**
|
||||||
private static final double BACKOFF_BASE = 1.2;
|
* How often to poll before our hidden service becomes reachable.
|
||||||
|
*/
|
||||||
|
private static final int INITIAL_POLLING_INTERVAL =
|
||||||
|
(int) MINUTES.toMillis(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How often to poll when our hidden service is reachable. Our contacts
|
||||||
|
* will poll when they come online, so our polling is just a fallback in
|
||||||
|
* case of repeated connection failures.
|
||||||
|
*/
|
||||||
|
private static final int STABLE_POLLING_INTERVAL =
|
||||||
|
(int) MINUTES.toMillis(15);
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final NetworkManager networkManager;
|
private final NetworkManager networkManager;
|
||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final SocketFactory torSocketFactory;
|
private final SocketFactory torSocketFactory;
|
||||||
private final BackoffFactory backoffFactory;
|
|
||||||
private final ResourceProvider resourceProvider;
|
private final ResourceProvider resourceProvider;
|
||||||
private final CircumventionProvider circumventionProvider;
|
private final CircumventionProvider circumventionProvider;
|
||||||
private final BatteryManager batteryManager;
|
private final BatteryManager batteryManager;
|
||||||
@@ -53,7 +63,7 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
public UnixTorPluginFactory(Executor ioExecutor,
|
public UnixTorPluginFactory(Executor ioExecutor,
|
||||||
NetworkManager networkManager, LocationUtils locationUtils,
|
NetworkManager networkManager, LocationUtils locationUtils,
|
||||||
EventBus eventBus, SocketFactory torSocketFactory,
|
EventBus eventBus, SocketFactory torSocketFactory,
|
||||||
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
|
ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Clock clock, File torDirectory) {
|
BatteryManager batteryManager, Clock clock, File torDirectory) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
@@ -61,7 +71,6 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
this.locationUtils = locationUtils;
|
this.locationUtils = locationUtils;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.torSocketFactory = torSocketFactory;
|
this.torSocketFactory = torSocketFactory;
|
||||||
this.backoffFactory = backoffFactory;
|
|
||||||
this.resourceProvider = resourceProvider;
|
this.resourceProvider = resourceProvider;
|
||||||
this.circumventionProvider = circumventionProvider;
|
this.circumventionProvider = circumventionProvider;
|
||||||
this.batteryManager = batteryManager;
|
this.batteryManager = batteryManager;
|
||||||
@@ -94,14 +103,13 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
||||||
UnixTorPlugin plugin = new UnixTorPlugin(ioExecutor, networkManager,
|
UnixTorPlugin plugin = new UnixTorPlugin(ioExecutor, networkManager,
|
||||||
locationUtils, torSocketFactory, clock, resourceProvider,
|
locationUtils, torSocketFactory, clock, resourceProvider,
|
||||||
circumventionProvider, batteryManager, backoff,
|
circumventionProvider, batteryManager, torRendezvousCrypto,
|
||||||
torRendezvousCrypto, callback, architecture, MAX_LATENCY,
|
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
|
||||||
MAX_IDLE_TIME, torDirectory);
|
INITIAL_POLLING_INTERVAL, STABLE_POLLING_INTERVAL,
|
||||||
|
torDirectory);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.battery.BatteryManager;
|
|||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
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.api.system.LocationUtils;
|
||||||
@@ -69,8 +68,6 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
@Inject
|
@Inject
|
||||||
EventBus eventBus;
|
EventBus eventBus;
|
||||||
@Inject
|
@Inject
|
||||||
BackoffFactory backoffFactory;
|
|
||||||
@Inject
|
|
||||||
Clock clock;
|
Clock clock;
|
||||||
|
|
||||||
private final File torDir = getTestDirectory();
|
private final File torDir = getTestDirectory();
|
||||||
@@ -120,9 +117,8 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory = new UnixTorPluginFactory(ioExecutor, networkManager,
|
factory = new UnixTorPluginFactory(ioExecutor, networkManager,
|
||||||
locationUtils, eventBus, torSocketFactory, backoffFactory,
|
locationUtils, eventBus, torSocketFactory, resourceProvider,
|
||||||
resourceProvider, bridgeProvider, batteryManager, clock,
|
bridgeProvider, batteryManager, clock, torDir);
|
||||||
torDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
nc.setLockscreenVisibility(VISIBILITY_SECRET);
|
nc.setLockscreenVisibility(VISIBILITY_SECRET);
|
||||||
nc.enableVibration(true);
|
nc.enableVibration(true);
|
||||||
nc.enableLights(true);
|
nc.enableLights(true);
|
||||||
nc.setLightColor(getColor(appContext, R.color.briar_green_light));
|
nc.setLightColor(getColor(appContext, R.color.briar_lime_400));
|
||||||
notificationManager.createNotificationChannel(nc);
|
notificationManager.createNotificationChannel(nc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
|||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
|
||||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||||
import org.briarproject.bramble.api.plugin.PluginConfig;
|
import org.briarproject.bramble.api.plugin.PluginConfig;
|
||||||
@@ -127,23 +126,22 @@ public class AppModule {
|
|||||||
PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor,
|
PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor,
|
||||||
@Scheduler ScheduledExecutorService scheduler,
|
@Scheduler ScheduledExecutorService scheduler,
|
||||||
AndroidExecutor androidExecutor, SecureRandom random,
|
AndroidExecutor androidExecutor, SecureRandom random,
|
||||||
SocketFactory torSocketFactory, BackoffFactory backoffFactory,
|
SocketFactory torSocketFactory, Application app,
|
||||||
Application app, NetworkManager networkManager,
|
NetworkManager networkManager, LocationUtils locationUtils,
|
||||||
LocationUtils locationUtils, EventBus eventBus,
|
EventBus eventBus, ResourceProvider resourceProvider,
|
||||||
ResourceProvider resourceProvider,
|
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager, Clock clock,
|
BatteryManager batteryManager, Clock clock,
|
||||||
TimeoutMonitor timeoutMonitor) {
|
TimeoutMonitor timeoutMonitor) {
|
||||||
Context appContext = app.getApplicationContext();
|
Context appContext = app.getApplicationContext();
|
||||||
DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(
|
DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(
|
||||||
ioExecutor, scheduler, androidExecutor, appContext, random,
|
ioExecutor, scheduler, androidExecutor, appContext, random,
|
||||||
eventBus, clock, timeoutMonitor, backoffFactory);
|
eventBus, clock, timeoutMonitor);
|
||||||
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
|
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
|
||||||
scheduler, appContext, networkManager, locationUtils, eventBus,
|
scheduler, appContext, networkManager, locationUtils, eventBus,
|
||||||
torSocketFactory, backoffFactory, resourceProvider,
|
torSocketFactory, resourceProvider, circumventionProvider,
|
||||||
circumventionProvider, batteryManager, clock);
|
batteryManager, clock);
|
||||||
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
||||||
eventBus, backoffFactory, appContext);
|
eventBus, appContext);
|
||||||
Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan);
|
Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan);
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
PluginConfig pluginConfig = new PluginConfig() {
|
PluginConfig pluginConfig = new PluginConfig() {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class PendingContactListActivity extends BriarActivity
|
|||||||
list.showProgressBar();
|
list.showProgressBar();
|
||||||
|
|
||||||
offlineSnackbar = new BriarSnackbarBuilder()
|
offlineSnackbar = new BriarSnackbarBuilder()
|
||||||
.setBackgroundColor(R.color.briar_red)
|
.setBackgroundColor(R.color.briar_red_500)
|
||||||
.make(list, R.string.offline_state, LENGTH_INDEFINITE);
|
.make(list, R.string.offline_state, LENGTH_INDEFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ class PendingContactViewHolder extends ViewHolder {
|
|||||||
});
|
});
|
||||||
|
|
||||||
int color = ContextCompat
|
int color = ContextCompat
|
||||||
.getColor(status.getContext(), R.color.briar_green);
|
.getColor(status.getContext(), R.color.briar_lime_600);
|
||||||
switch (item.getState()) {
|
switch (item.getState()) {
|
||||||
case WAITING_FOR_CONNECTION:
|
case WAITING_FOR_CONNECTION:
|
||||||
color = ContextCompat
|
color = ContextCompat.getColor(status.getContext(),
|
||||||
.getColor(status.getContext(), R.color.briar_yellow);
|
R.color.briar_orange_500);
|
||||||
status.setText(R.string.waiting_for_contact_to_come_online);
|
status.setText(R.string.waiting_for_contact_to_come_online);
|
||||||
break;
|
break;
|
||||||
case OFFLINE:
|
case OFFLINE:
|
||||||
@@ -64,7 +64,7 @@ class PendingContactViewHolder extends ViewHolder {
|
|||||||
break;
|
break;
|
||||||
case FAILED:
|
case FAILED:
|
||||||
color = ContextCompat
|
color = ContextCompat
|
||||||
.getColor(status.getContext(), R.color.briar_red);
|
.getColor(status.getContext(), R.color.briar_red_500);
|
||||||
status.setText(R.string.adding_contact_failed);
|
status.setText(R.string.adding_contact_failed);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ class ConversationMessageViewHolder extends ConversationItemViewHolder {
|
|||||||
|
|
||||||
// remember original status text color
|
// remember original status text color
|
||||||
timeColor = time.getCurrentTextColor();
|
timeColor = time.getCurrentTextColor();
|
||||||
timeColorBubble = getColor(v.getContext(), R.color.briar_white);
|
timeColorBubble =
|
||||||
|
getColor(v.getContext(), R.color.msg_status_bubble_foreground);
|
||||||
|
|
||||||
// clone constraint sets from layout files
|
// clone constraint sets from layout files
|
||||||
textConstraints.clone(v.getContext(),
|
textConstraints.clone(v.getContext(),
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ public class ImageActivity extends BriarActivity
|
|||||||
int stringRes = error ?
|
int stringRes = error ?
|
||||||
R.string.save_image_error : R.string.save_image_success;
|
R.string.save_image_error : R.string.save_image_success;
|
||||||
int colorRes = error ?
|
int colorRes = error ?
|
||||||
R.color.briar_red : R.color.briar_primary;
|
R.color.briar_red_500 : R.color.briar_primary;
|
||||||
new BriarSnackbarBuilder()
|
new BriarSnackbarBuilder()
|
||||||
.setBackgroundColor(colorRes)
|
.setBackgroundColor(colorRes)
|
||||||
.make(layout, stringRes, LENGTH_LONG)
|
.make(layout, stringRes, LENGTH_LONG)
|
||||||
|
|||||||
@@ -432,8 +432,8 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
|
|
||||||
@ColorRes
|
@ColorRes
|
||||||
private int getIconColor(State state) {
|
private int getIconColor(State state) {
|
||||||
if (state == ACTIVE) return R.color.briar_green_light;
|
if (state == ACTIVE) return R.color.briar_lime_400;
|
||||||
else if (state == ENABLING) return R.color.briar_yellow;
|
else if (state == ENABLING) return R.color.briar_orange_500;
|
||||||
else return android.R.color.tertiary_text_light;
|
else return android.R.color.tertiary_text_light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR;
|
|||||||
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.Plugin.PREF_PLUGIN_ENABLE;
|
import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_MOBILE;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_NETWORK;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
|
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_AUTOMATIC;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
@@ -372,9 +375,9 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
|
|
||||||
// TODO: Remove after a reasonable migration period (added 2020-06-25)
|
// TODO: Remove after a reasonable migration period (added 2020-06-25)
|
||||||
private Settings migrateTorSettings(Settings s) {
|
private Settings migrateTorSettings(Settings s) {
|
||||||
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC);
|
int network = s.getInt(PREF_TOR_NETWORK, DEFAULT_PREF_TOR_NETWORK);
|
||||||
if (network == PREF_TOR_NETWORK_NEVER) {
|
if (network == PREF_TOR_NETWORK_NEVER) {
|
||||||
s.putInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC);
|
s.putInt(PREF_TOR_NETWORK, DEFAULT_PREF_TOR_NETWORK);
|
||||||
s.putBoolean(PREF_PLUGIN_ENABLE, false);
|
s.putBoolean(PREF_PLUGIN_ENABLE, false);
|
||||||
// We don't need to save the migrated settings - the Tor plugin is
|
// We don't need to save the migrated settings - the Tor plugin is
|
||||||
// responsible for that. This code just handles the case where the
|
// responsible for that. This code just handles the case where the
|
||||||
@@ -388,29 +391,32 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
// due to events, we might try to display before a load completed
|
// due to events, we might try to display before a load completed
|
||||||
if (!settingsLoaded) return;
|
if (!settingsLoaded) return;
|
||||||
|
|
||||||
boolean btEnabledSetting =
|
boolean btEnabledSetting = btSettings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
btSettings.getBoolean(PREF_PLUGIN_ENABLE, false);
|
BluetoothConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||||
enableBluetooth.setChecked(btEnabledSetting);
|
enableBluetooth.setChecked(btEnabledSetting);
|
||||||
|
|
||||||
boolean wifiEnabledSetting =
|
boolean wifiEnabledSetting =
|
||||||
wifiSettings.getBoolean(PREF_PLUGIN_ENABLE, false);
|
wifiSettings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
|
LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||||
enableWifi.setChecked(wifiEnabledSetting);
|
enableWifi.setChecked(wifiEnabledSetting);
|
||||||
|
|
||||||
boolean torEnabledSetting =
|
boolean torEnabledSetting =
|
||||||
torSettings.getBoolean(PREF_PLUGIN_ENABLE, true);
|
torSettings.getBoolean(PREF_PLUGIN_ENABLE,
|
||||||
|
TorConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||||
enableTor.setChecked(torEnabledSetting);
|
enableTor.setChecked(torEnabledSetting);
|
||||||
|
|
||||||
int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK,
|
int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK,
|
||||||
PREF_TOR_NETWORK_AUTOMATIC);
|
DEFAULT_PREF_TOR_NETWORK);
|
||||||
torNetwork.setValue(Integer.toString(torNetworkSetting));
|
torNetwork.setValue(Integer.toString(torNetworkSetting));
|
||||||
setTorNetworkSummary(torNetworkSetting);
|
setTorNetworkSummary(torNetworkSetting);
|
||||||
|
|
||||||
boolean torMobileSetting =
|
boolean torMobileSetting = torSettings.getBoolean(PREF_TOR_MOBILE,
|
||||||
torSettings.getBoolean(PREF_TOR_MOBILE, true);
|
DEFAULT_PREF_TOR_MOBILE);
|
||||||
torMobile.setChecked(torMobileSetting);
|
torMobile.setChecked(torMobileSetting);
|
||||||
|
|
||||||
boolean torChargingSetting =
|
boolean torChargingSetting =
|
||||||
torSettings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false);
|
torSettings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING,
|
||||||
|
DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING);
|
||||||
torOnlyWhenCharging.setChecked(torChargingSetting);
|
torOnlyWhenCharging.setChecked(torChargingSetting);
|
||||||
|
|
||||||
displayScreenLockSetting();
|
displayScreenLockSetting();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
|||||||
// https://issuetracker.google.com/issues/36961721
|
// https://issuetracker.google.com/issues/36961721
|
||||||
setAutoCancel(true);
|
setAutoCancel(true);
|
||||||
|
|
||||||
setLights(ContextCompat.getColor(context, R.color.briar_green_light),
|
setLights(ContextCompat.getColor(context, R.color.briar_lime_400),
|
||||||
750, 500);
|
750, 500);
|
||||||
if (SDK_INT >= 21) setVisibility(VISIBILITY_PRIVATE);
|
if (SDK_INT >= 21) setVisibility(VISIBILITY_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
C7.58,20,4,16.42,4,12 S7.58,4,12,4 S20,7.58,20,12 S16.42,20,12,20 Z"/>
|
C7.58,20,4,16.42,4,12 S7.58,4,12,4 S20,7.58,20,12 S16.42,20,12,20 Z"/>
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#95d220"
|
android:fillColor="#82c91e"
|
||||||
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
||||||
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
||||||
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
||||||
|
|||||||
@@ -17,12 +17,12 @@
|
|||||||
android:fillColor="#ffffff"
|
android:fillColor="#ffffff"
|
||||||
android:pathData="M175.3 16.5l-9.8 0 0 -5.7c0 -1.4 -1.2 -2.6 -2.6 -2.6l-19.3 0c-1.4 0 -2.6 1.2 -2.6 2.6l0 14.4c0 1.4 1.2 2.6 2.6 2.6l15.1 0 0 17.3c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.2c0.1 -2.4 -1.9 -4.4 -4.4 -4.4zm-12.4 -5.9l-9.6 6 -9.6 -6 19.2 0zm-19.4 14.8l0 -12.3 9.8 6.1 9.8 -6.1 0 12.3 -19.6 0zm28.6 21.2l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -14.2 1.6 0c1.4 0 2.6 -1.2 2.6 -2.6l0 -4.1 11.6 0 0 20.9z"/>
|
android:pathData="M175.3 16.5l-9.8 0 0 -5.7c0 -1.4 -1.2 -2.6 -2.6 -2.6l-19.3 0c-1.4 0 -2.6 1.2 -2.6 2.6l0 14.4c0 1.4 1.2 2.6 2.6 2.6l15.1 0 0 17.3c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.2c0.1 -2.4 -1.9 -4.4 -4.4 -4.4zm-12.4 -5.9l-9.6 6 -9.6 -6 19.2 0zm-19.4 14.8l0 -12.3 9.8 6.1 9.8 -6.1 0 12.3 -19.6 0zm28.6 21.2l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -14.2 1.6 0c1.4 0 2.6 -1.2 2.6 -2.6l0 -4.1 11.6 0 0 20.9z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ff0000"
|
android:fillColor="#db3b21"
|
||||||
android:pathData="M101.4 17.8l2 2 7.4 -7.3 7.3 7.3 2.1 -2 -7.4 -7.4 7.4 -7.3 -2.1 -2.1 -7.3 7.4 -7.4 -7.4 -2 2.1 7.3 7.3z"/>
|
android:pathData="M101.4 17.8l2 2 7.4 -7.3 7.3 7.3 2.1 -2 -7.4 -7.4 7.4 -7.3 -2.1 -2.1 -7.3 7.4 -7.4 -7.4 -2 2.1 7.3 7.3z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ff0000"
|
android:fillColor="#db3b21"
|
||||||
android:pathData="M176 17.8l2.1 2 7.3 -7.3 7.4 7.3 2 -2 -7.3 -7.4 7.3 -7.3 -2 -2.1 -7.4 7.4 -7.3 -7.4 -2.1 2.1 7.3 7.3z"/>
|
android:pathData="M176 17.8l2.1 2 7.3 -7.3 7.4 7.3 2 -2 -7.3 -7.4 7.3 -7.3 -2 -2.1 -7.4 7.4 -7.3 -7.4 -2.1 2.1 7.3 7.3z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#08b124"
|
android:fillColor="#67a60f"
|
||||||
android:pathData="M35.8 18.8l0 0L52.5 2.1 50.5 0 35.6 14.8 28.5 7.7l-2.1 2.1 9.2 9.1z"/>
|
android:pathData="M35.8 18.8l0 0L52.5 2.1 50.5 0 35.6 14.8 28.5 7.7l-2.1 2.1 9.2 9.1z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
android:radius="32dp"/>
|
android:radius="32dp"/>
|
||||||
|
|
||||||
<solid
|
<solid
|
||||||
android:color="@color/briar_green"/>
|
android:color="@color/briar_lime_600"/>
|
||||||
|
|
||||||
</shape>
|
</shape>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ C7.58,20,4,16.42,4,12 S7.58,4,12,4 S20,7.58,20,12 S16.42,20,12,20 Z"/>
|
|||||||
<path
|
<path
|
||||||
android:pathData="M0,0 L24,0 L24,24 L0,24 Z"/>
|
android:pathData="M0,0 L24,0 L24,24 L0,24 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#95d220"
|
android:fillColor="#82c91e"
|
||||||
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
||||||
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
||||||
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
android:viewportWidth="24">
|
android:viewportWidth="24">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#2D3E50"
|
android:fillColor="#2e3d4f"
|
||||||
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
||||||
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
||||||
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
android:viewportWidth="24">
|
android:viewportWidth="24">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#95D220"
|
android:fillColor="#82c91e"
|
||||||
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896
|
||||||
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
C4.55452,7.53099,7.09451,4.8236,10.394,4.14714
|
||||||
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:tint="#2A93C6"
|
android:tint="#418cd8"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:tint="#2A93C6"
|
android:tint="#418cd8"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#808080"
|
android:fillColor="#707070"
|
||||||
android:pathData="M21,5v6.59l-3,-3.01 -4,4.01 -4,-4 -4,4 -3,-3.01L3,5c0,-1.1 0.9,-2 2,-2h14c1.1,0 2,0.9 2,2zM18,11.42l3,3.01L21,19c0,1.1 -0.9,2 -2,2L5,21c-1.1,0 -2,-0.9 -2,-2v-6.58l3,2.99 4,-4 4,4 4,-3.99z"/>
|
android:pathData="M21,5v6.59l-3,-3.01 -4,4.01 -4,-4 -4,4 -3,-3.01L3,5c0,-1.1 0.9,-2 2,-2h14c1.1,0 2,0.9 2,2zM18,11.42l3,3.01L21,19c0,1.1 -0.9,2 -2,2L5,21c-1.1,0 -2,-0.9 -2,-2v-6.58l3,2.99 4,-4 4,4 4,-3.99z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF2D3E50"
|
android:fillColor="#2e3d4f"
|
||||||
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
android:viewportWidth="30">
|
android:viewportWidth="30">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ffa500"
|
android:fillColor="#fc9403"
|
||||||
android:pathData="M0,0 L30,0 L30,30 L0,30 L0,0 Z"/>
|
android:pathData="M0,0 L30,0 L30,30 L0,30 L0,0 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ffffff"
|
android:fillColor="#ffffff"
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
android:fillColor="#000000"
|
android:fillColor="#000000"
|
||||||
android:pathData="M175.3 16.5l-9.8 0 0 -5.7c0 -1.4 -1.2 -2.6 -2.6 -2.6l-19.3 0c-1.4 0 -2.6 1.2 -2.6 2.6l0 14.4c0 1.4 1.2 2.6 2.6 2.6l15.1 0 0 17.3c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.2c0.1 -2.4 -1.9 -4.4 -4.4 -4.4zm-12.4 -5.9l-9.6 6 -9.6 -6 19.2 0zm-19.4 14.8l0 -12.3 9.8 6.1 9.8 -6.1 0 12.3 -19.6 0zm28.6 21.2l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -14.2 1.6 0c1.4 0 2.6 -1.2 2.6 -2.6l0 -4.1 11.6 0 0 20.9z"/>
|
android:pathData="M175.3 16.5l-9.8 0 0 -5.7c0 -1.4 -1.2 -2.6 -2.6 -2.6l-19.3 0c-1.4 0 -2.6 1.2 -2.6 2.6l0 14.4c0 1.4 1.2 2.6 2.6 2.6l15.1 0 0 17.3c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.2c0.1 -2.4 -1.9 -4.4 -4.4 -4.4zm-12.4 -5.9l-9.6 6 -9.6 -6 19.2 0zm-19.4 14.8l0 -12.3 9.8 6.1 9.8 -6.1 0 12.3 -19.6 0zm28.6 21.2l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -14.2 1.6 0c1.4 0 2.6 -1.2 2.6 -2.6l0 -4.1 11.6 0 0 20.9z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ff0000"
|
android:fillColor="#db3b21"
|
||||||
android:pathData="M101.4 17.8l2 2 7.4 -7.3 7.3 7.3 2.1 -2 -7.4 -7.4 7.4 -7.3 -2.1 -2.1 -7.3 7.4 -7.4 -7.4 -2 2.1 7.3 7.3z"/>
|
android:pathData="M101.4 17.8l2 2 7.4 -7.3 7.3 7.3 2.1 -2 -7.4 -7.4 7.4 -7.3 -2.1 -2.1 -7.3 7.4 -7.4 -7.4 -2 2.1 7.3 7.3z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ff0000"
|
android:fillColor="#db3b21"
|
||||||
android:pathData="M176 17.8l2.1 2 7.3 -7.3 7.4 7.3 2 -2 -7.3 -7.4 7.3 -7.3 -2 -2.1 -7.4 7.4 -7.3 -7.4 -2.1 2.1 7.3 7.3z"/>
|
android:pathData="M176 17.8l2.1 2 7.3 -7.3 7.4 7.3 2 -2 -7.3 -7.4 7.3 -7.3 -2 -2.1 -7.4 7.4 -7.3 -7.4 -2.1 2.1 7.3 7.3z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#08b124"
|
android:fillColor="#67a60f"
|
||||||
android:pathData="M35.8 18.8l0 0L52.5 2.1 50.5 0 35.6 14.8 28.5 7.7l-2.1 2.1 9.2 9.1z"/>
|
android:pathData="M35.8 18.8l0 0L52.5 2.1 50.5 0 35.6 14.8 28.5 7.7l-2.1 2.1 9.2 9.1z"/>
|
||||||
</vector>
|
</vector>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:tint="#2A93C6"
|
android:tint="#418cd8"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:viewportHeight="20"
|
android:viewportHeight="20"
|
||||||
android:viewportWidth="49">
|
android:viewportWidth="49">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#b7b7b7"
|
android:fillColor="#a7a7a7"
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
||||||
@@ -16,7 +16,7 @@ L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#b7b7b7"
|
android:fillColor="#a7a7a7"
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
||||||
@@ -27,7 +27,7 @@ L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#b7b7b7"
|
android:fillColor="#a7a7a7"
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:viewportHeight="20"
|
android:viewportHeight="20"
|
||||||
android:viewportWidth="49">
|
android:viewportWidth="49">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#c34032"
|
android:fillColor="#db3b21"
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
||||||
@@ -16,7 +16,7 @@ L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#b7b7b7"
|
android:fillColor="#a7a7a7"
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
||||||
@@ -27,7 +27,7 @@ L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#b7b7b7"
|
android:fillColor="#a7a7a7"
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:viewportHeight="20"
|
android:viewportHeight="20"
|
||||||
android:viewportWidth="49">
|
android:viewportWidth="49">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#fcd53a"
|
android:fillColor="#fc9403"
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
||||||
@@ -16,7 +16,7 @@ L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#fcd53a"
|
android:fillColor="#fc9403"
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
||||||
@@ -27,7 +27,7 @@ L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#b7b7b7"
|
android:fillColor="#a7a7a7"
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:viewportHeight="20"
|
android:viewportHeight="20"
|
||||||
android:viewportWidth="49">
|
android:viewportWidth="49">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#7fac49"
|
android:fillColor="#67a60f"
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
||||||
@@ -16,7 +16,7 @@ L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#7fac49"
|
android:fillColor="#67a60f"
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
||||||
@@ -27,7 +27,7 @@ L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#7fac49"
|
android:fillColor="#67a60f"
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
||||||
|
|||||||
@@ -4,14 +4,13 @@
|
|||||||
android:id="@+id/layout"
|
android:id="@+id/layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/briar_black"
|
android:background="@android:color/black"
|
||||||
tools:context=".android.conversation.ImageActivity">
|
tools:context=".android.conversation.ImageActivity">
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager.widget.ViewPager
|
||||||
android:id="@+id/viewPager"
|
android:id="@+id/viewPager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
tools:background="@color/briar_green_light" />
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appBarLayout"
|
android:id="@+id/appBarLayout"
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:background="@color/briar_white"
|
android:background="@android:color/white"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:textColor="@color/briar_text_primary"
|
android:textColor="@color/briar_text_primary"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
android:src="@drawable/ic_call_made"
|
android:src="@drawable/ic_call_made"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stepOneText"
|
app:layout_constraintTop_toBottomOf="@+id/stepOneText"
|
||||||
app:tint="@color/briar_white" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/yourLink"
|
android:id="@+id/yourLink"
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:background="@color/briar_white"
|
android:background="@android:color/white"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
@@ -160,7 +160,7 @@
|
|||||||
android:src="@drawable/ic_call_received"
|
android:src="@drawable/ic_call_received"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/copyButton"
|
app:layout_constraintTop_toBottomOf="@+id/copyButton"
|
||||||
app:tint="@color/briar_white" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/inputLink"
|
android:id="@+id/inputLink"
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
app:layout_constraintBottom_toTopOf="@+id/contactNameLayout"
|
app:layout_constraintBottom_toTopOf="@+id/contactNameLayout"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/imageView"
|
app:layout_constraintTop_toBottomOf="@+id/imageView"
|
||||||
app:tint="@color/briar_white" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/nicknameIntro"
|
android:id="@+id/nicknameIntro"
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
app:layout_constraintEnd_toStartOf="@+id/time"
|
app:layout_constraintEnd_toStartOf="@+id/time"
|
||||||
app:layout_constraintStart_toStartOf="@+id/name"
|
app:layout_constraintStart_toStartOf="@+id/name"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/name"
|
app:layout_constraintTop_toBottomOf="@+id/name"
|
||||||
tools:textColor="@color/briar_red" />
|
tools:textColor="@color/briar_red_500" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/time"
|
android:id="@+id/time"
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="briar_primary">@color/briar_blue_dark</color>
|
<color name="briar_primary">@color/briar_night_800</color>
|
||||||
<color name="briar_accent">@color/briar_green</color>
|
<color name="briar_accent">@color/briar_lime_600</color>
|
||||||
|
|
||||||
<color name="preference_category">@color/briar_accent</color>
|
<color name="preference_category">@color/briar_accent</color>
|
||||||
<color name="preference_category_background">@color/briar_black_almost</color>
|
<color name="preference_category_background">@color/briar_night_950</color>
|
||||||
|
|
||||||
<color name="color_primary">@color/briar_white</color>
|
<color name="color_primary">@android:color/white</color>
|
||||||
|
|
||||||
<color name="msg_in">@color/briar_blue</color>
|
<color name="msg_in">@color/briar_night_700</color>
|
||||||
<color name="msg_out">@color/briar_blue_elio_light</color>
|
<color name="msg_out">@color/briar_blue_600</color>
|
||||||
<color name="notice_in">@color/briar_blue_dark</color>
|
<color name="notice_in">@color/briar_night_800</color>
|
||||||
<color name="notice_out">@color/briar_blue_elio</color>
|
<color name="notice_out">@color/briar_blue_800</color>
|
||||||
<color name="msg_stroke">@color/msg_stroke_dark</color>
|
<color name="msg_stroke">@color/msg_stroke_dark</color>
|
||||||
|
|
||||||
<color name="window_background">@color/briar_blue_very_dark</color>
|
<color name="window_background">@color/briar_night_950</color>
|
||||||
<color name="card_background">@color/briar_blue_dark</color>
|
<color name="card_background">@color/briar_night_800</color>
|
||||||
<color name="item_background_highlight">@color/briar_blue</color>
|
<color name="item_background_highlight">@color/briar_night_700</color>
|
||||||
|
|
||||||
<color name="briar_button_background_color">@color/briar_blue_medium</color>
|
<color name="briar_button_background_color">@color/briar_night_500</color>
|
||||||
<color name="briar_button_text_neutral">@color/briar_blue_light</color>
|
<color name="briar_button_text_neutral">@color/briar_blue_400</color>
|
||||||
<color name="briar_button_text_disabled">#23cccccc</color>
|
<color name="briar_button_text_disabled">#23cccccc</color>
|
||||||
|
|
||||||
<color name="thread_indicator">@color/briar_blue</color>
|
<color name="thread_indicator">@color/briar_night_700</color>
|
||||||
<color name="thread_item_highlight">@color/briar_black</color>
|
<color name="thread_item_highlight">@android:color/black</color>
|
||||||
|
|
||||||
<color name="divider">@color/briar_black</color>
|
<color name="divider">@android:color/black</color>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,68 +1,75 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="briar_blue">#2D3E50</color>
|
<color name="briar_lime_600">#67a60f</color>
|
||||||
<color name="briar_blue_dark">#222E3C</color>
|
<color name="briar_lime_400">#82c91e</color>
|
||||||
<color name="briar_blue_very_dark">#0F1720</color>
|
|
||||||
<color name="briar_blue_medium">#4F6C8C</color>
|
|
||||||
<color name="briar_blue_elio">#236087</color>
|
|
||||||
<color name="briar_blue_elio_light">#3C80A9</color>
|
|
||||||
<color name="briar_blue_light">#2A93C6</color>
|
|
||||||
<color name="briar_blue_grey">#EBEFF2</color>
|
|
||||||
<color name="briar_yellow">#9e9d24</color>
|
|
||||||
<color name="briar_green">#5C940D</color>
|
|
||||||
<color name="briar_green_light">#95D220</color>
|
|
||||||
<color name="briar_red">#ff0000</color>
|
|
||||||
<color name="briar_white">#FFFFFF</color>
|
|
||||||
<color name="briar_black">#000000</color>
|
|
||||||
<color name="briar_black_almost">#080C10</color>
|
|
||||||
|
|
||||||
<color name="m_grey_300">#e0e0e0</color>
|
<color name="briar_blue_800">#134a81</color>
|
||||||
<color name="m_grey_500">#9e9e9e</color>
|
<color name="briar_blue_600">#1b69b6</color>
|
||||||
<color name="m_blue_grey_50">#eceff1</color>
|
<color name="briar_blue_400">#418cd8</color>
|
||||||
|
|
||||||
<color name="briar_primary">@color/briar_blue</color>
|
<color name="briar_orange_500">#fc9403</color>
|
||||||
<color name="briar_primary_dark">@color/briar_blue_very_dark</color>
|
|
||||||
<color name="briar_accent">@color/briar_blue</color>
|
|
||||||
|
|
||||||
<color name="window_background">#EBEBEB</color>
|
<color name="briar_red_500">#db3b21</color>
|
||||||
|
|
||||||
|
<color name="briar_night_950">#0e171f</color>
|
||||||
|
<color name="briar_night_800">#212d3b</color>
|
||||||
|
<color name="briar_night_700">#2e3d4f</color>
|
||||||
|
<color name="briar_night_500">#435b77</color>
|
||||||
|
<color name="briar_night_50">#ebf3fa</color>
|
||||||
|
|
||||||
|
<color name="briar_gray_900">#2e2e2e</color>
|
||||||
|
<color name="briar_gray_500">#a7a7a7</color>
|
||||||
|
<color name="briar_gray_300">#cccccc</color>
|
||||||
|
<color name="briar_gray_200">#dfdfdf</color>
|
||||||
|
<color name="briar_gray_100">#f2f2f2</color>
|
||||||
|
|
||||||
|
<color name="briar_brand_blue">@color/briar_night_700</color>
|
||||||
|
<color name="briar_brand_green">@color/briar_lime_400</color>
|
||||||
|
|
||||||
|
<color name="briar_primary">@color/briar_brand_blue</color>
|
||||||
|
<color name="briar_primary_dark">@color/briar_night_950</color>
|
||||||
|
<color name="briar_accent">@color/briar_brand_blue</color>
|
||||||
|
|
||||||
|
<color name="window_background">@color/briar_gray_100</color>
|
||||||
<color name="card_background">@color/cardview_light_background</color>
|
<color name="card_background">@color/cardview_light_background</color>
|
||||||
<color name="item_background_highlight">#DCDCDC</color>
|
<color name="item_background_highlight">@color/briar_gray_200</color>
|
||||||
<color name="briar_warning_background">@color/briar_red</color>
|
<color name="briar_warning_background">@color/briar_red_500</color>
|
||||||
<color name="action_bar_text">@color/briar_white</color>
|
<color name="action_bar_text">@android:color/white</color>
|
||||||
<color name="private_message_date_inverse">@color/m_grey_300</color>
|
<color name="private_message_date_inverse">@color/briar_gray_200</color>
|
||||||
<color name="forum_avatar_shadow">#99000000</color>
|
<color name="forum_avatar_shadow">#99000000</color>
|
||||||
|
|
||||||
<color name="color_primary">#dd000000</color>
|
<color name="color_primary">#dd000000</color>
|
||||||
|
|
||||||
<color name="msg_in">@color/briar_white</color>
|
<color name="msg_in">@android:color/white</color>
|
||||||
<color name="msg_out">@color/briar_blue_elio_light</color>
|
<color name="msg_out">@color/briar_blue_400</color>
|
||||||
<color name="notice_in">@color/briar_blue_grey</color>
|
<color name="notice_in">@color/briar_night_50</color>
|
||||||
<color name="notice_out">@color/briar_blue_elio</color>
|
<color name="notice_out">@color/briar_blue_600</color>
|
||||||
<color name="msg_stroke_light">#cbcbcb</color>
|
<color name="msg_stroke_light">@color/briar_gray_300</color>
|
||||||
<color name="msg_stroke_dark">#333333</color>
|
<color name="msg_stroke_dark">@color/briar_gray_900</color>
|
||||||
<color name="msg_stroke">@color/msg_stroke_light</color>
|
<color name="msg_stroke">@color/msg_stroke_light</color>
|
||||||
<color name="msg_status_bubble_background">#66000000</color>
|
<color name="msg_status_bubble_background">#66000000</color>
|
||||||
|
<color name="msg_status_bubble_foreground">@android:color/white</color>
|
||||||
<color name="msg_selected_background">@color/briar_accent</color>
|
<color name="msg_selected_background">@color/briar_accent</color>
|
||||||
|
|
||||||
<!-- text colors -->
|
<!-- text colors -->
|
||||||
<color name="briar_text_link">@color/briar_blue_light</color>
|
<color name="briar_text_link">@color/briar_blue_400</color>
|
||||||
<color name="briar_text_primary">#df000000</color>
|
<color name="briar_text_primary">#df000000</color>
|
||||||
<color name="briar_text_primary_inverse">@color/briar_white</color>
|
<color name="briar_text_primary_inverse">@android:color/white</color>
|
||||||
<color name="briar_text_secondary_inverse">#b4ffffff</color>
|
<color name="briar_text_secondary_inverse">#b4ffffff</color>
|
||||||
<color name="briar_text_tertiary_inverse">#80ffffff</color>
|
<color name="briar_text_tertiary_inverse">#80ffffff</color>
|
||||||
|
|
||||||
<color name="preference_category">@color/briar_blue_medium</color>
|
<color name="preference_category">@color/briar_night_500</color>
|
||||||
<color name="preference_category_background">@color/window_background</color>
|
<color name="preference_category_background">@color/window_background</color>
|
||||||
|
|
||||||
<color name="briar_button_background_color">@color/briar_accent</color>
|
<color name="briar_button_background_color">@color/briar_accent</color>
|
||||||
<color name="briar_button_text_positive">@color/briar_blue_light</color>
|
<color name="briar_button_text_positive">@color/briar_blue_400</color>
|
||||||
<color name="briar_button_text_neutral">@color/briar_blue_medium</color>
|
<color name="briar_button_text_neutral">@color/briar_night_500</color>
|
||||||
<color name="briar_button_text_negative">@color/briar_red</color>
|
<color name="briar_button_text_negative">@color/briar_red_500</color>
|
||||||
<color name="briar_button_text_disabled">#28000000</color>
|
<color name="briar_button_text_disabled">#28000000</color>
|
||||||
|
|
||||||
<color name="thread_indicator">@color/m_grey_500</color>
|
<color name="thread_indicator">@color/briar_gray_500</color>
|
||||||
<color name="thread_item_background">@color/window_background</color>
|
<color name="thread_item_background">@color/window_background</color>
|
||||||
<color name="thread_item_highlight">@color/briar_white</color>
|
<color name="thread_item_highlight">@android:color/white</color>
|
||||||
|
|
||||||
<color name="divider">#c1c1c1</color>
|
<color name="divider">@color/briar_gray_200</color>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
<item name="android:layout_height">28dp</item>
|
<item name="android:layout_height">28dp</item>
|
||||||
<item name="android:background">@drawable/bubble_accent</item>
|
<item name="android:background">@drawable/bubble_accent</item>
|
||||||
<item name="android:gravity">center</item>
|
<item name="android:gravity">center</item>
|
||||||
<item name="android:textColor">@color/briar_white</item>
|
<item name="android:textColor">@android:color/white</item>
|
||||||
<item name="android:textSize">18sp</item>
|
<item name="android:textSize">18sp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.db.DatabaseConfig
|
|||||||
import org.briarproject.bramble.api.event.EventBus
|
import org.briarproject.bramble.api.event.EventBus
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor
|
import org.briarproject.bramble.api.lifecycle.IoExecutor
|
||||||
import org.briarproject.bramble.api.network.NetworkManager
|
import org.briarproject.bramble.api.network.NetworkManager
|
||||||
import org.briarproject.bramble.api.plugin.BackoffFactory
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginConfig
|
import org.briarproject.bramble.api.plugin.PluginConfig
|
||||||
import org.briarproject.bramble.api.plugin.TransportId
|
import org.briarproject.bramble.api.plugin.TransportId
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory
|
||||||
@@ -70,16 +69,15 @@ internal class HeadlessModule(private val appDir: File) {
|
|||||||
@Provides
|
@Provides
|
||||||
internal fun providePluginConfig(
|
internal fun providePluginConfig(
|
||||||
@IoExecutor ioExecutor: Executor, torSocketFactory: SocketFactory,
|
@IoExecutor ioExecutor: Executor, torSocketFactory: SocketFactory,
|
||||||
backoffFactory: BackoffFactory, networkManager: NetworkManager,
|
networkManager: NetworkManager, locationUtils: LocationUtils, eventBus: EventBus,
|
||||||
locationUtils: LocationUtils, eventBus: EventBus, resourceProvider: ResourceProvider,
|
resourceProvider: ResourceProvider, circumventionProvider: CircumventionProvider,
|
||||||
circumventionProvider: CircumventionProvider, batteryManager: BatteryManager, clock: Clock
|
batteryManager: BatteryManager, clock: Clock
|
||||||
): PluginConfig {
|
): PluginConfig {
|
||||||
val duplex: List<DuplexPluginFactory> = if (isLinux() || isMac()) {
|
val duplex: List<DuplexPluginFactory> = if (isLinux() || isMac()) {
|
||||||
val torDirectory = File(appDir, "tor")
|
val torDirectory = File(appDir, "tor")
|
||||||
val tor = UnixTorPluginFactory(
|
val tor = UnixTorPluginFactory(
|
||||||
ioExecutor, networkManager, locationUtils, eventBus, torSocketFactory,
|
ioExecutor, networkManager, locationUtils, eventBus, torSocketFactory,
|
||||||
backoffFactory, resourceProvider, circumventionProvider, batteryManager, clock,
|
resourceProvider, circumventionProvider, batteryManager, clock, torDirectory
|
||||||
torDirectory
|
|
||||||
)
|
)
|
||||||
listOf(tor)
|
listOf(tor)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user