diff --git a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java index ebd0dc0b9..0ad71b26c 100644 --- a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java +++ b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java @@ -9,6 +9,7 @@ import org.briarproject.bramble.api.plugin.BackoffFactory; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.test.BrambleAndroidIntegrationTestComponent; import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.DaggerBrambleAndroidIntegrationTestComponent; @@ -45,6 +46,8 @@ public class BridgeTest extends BrambleTestCase { @Inject NetworkManager networkManager; @Inject + ResourceProvider resourceProvider; + @Inject CircumventionProvider circumventionProvider; @Inject EventBus eventBus; @@ -59,7 +62,7 @@ public class BridgeTest extends BrambleTestCase { private List bridges; private AndroidTorPluginFactory factory; - private volatile int currentBridge = 0; + private volatile String currentBridge = null; @Before public void setUp() { @@ -73,7 +76,7 @@ public class BridgeTest extends BrambleTestCase { SocketFactory torSocketFactory = SocketFactory.getDefault(); bridges = circumventionProvider.getBridges(); - CircumventionProvider testProvider = new CircumventionProvider() { + CircumventionProvider bridgeProvider = new CircumventionProvider() { @Override public boolean isTorProbablyBlocked(String countryCode) { return true; @@ -86,31 +89,29 @@ public class BridgeTest extends BrambleTestCase { @Override public List getBridges() { - return singletonList(bridges.get(currentBridge)); + return singletonList(currentBridge); } }; factory = new AndroidTorPluginFactory(ioExecutor, scheduler, appContext, networkManager, locationUtils, eventBus, torSocketFactory, - backoffFactory, testProvider, clock); + backoffFactory, resourceProvider, bridgeProvider, clock); } @Test public void testBridges() throws Exception { assertTrue(bridges.size() > 0); - for (int i = 0; i < bridges.size(); i++) { - testBridge(i); - } + for (String bridge : bridges) testBridge(bridge); } - private void testBridge(int bridge) throws Exception { + private void testBridge(String bridge) throws Exception { DuplexPlugin duplexPlugin = factory.createPlugin(new TorPluginCallBack()); assertNotNull(duplexPlugin); AndroidTorPlugin plugin = (AndroidTorPlugin) duplexPlugin; currentBridge = bridge; - LOG.warning("Testing " + bridges.get(currentBridge)); + LOG.warning("Testing " + bridge); try { plugin.start(); long start = clock.currentTimeMillis(); diff --git a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java index bde183ba6..713c007c5 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java @@ -1,15 +1,15 @@ package org.briarproject.bramble; import org.briarproject.bramble.network.AndroidNetworkModule; -import org.briarproject.bramble.plugin.tor.AndroidCircumventionModule; +import org.briarproject.bramble.plugin.tor.CircumventionModule; import org.briarproject.bramble.system.AndroidSystemModule; import dagger.Module; @Module(includes = { - AndroidCircumventionModule.class, AndroidNetworkModule.class, - AndroidSystemModule.class + AndroidSystemModule.class, + CircumventionModule.class }) public class BrambleAndroidModule { diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java index b7e1c96c6..c2cdac186 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.Resources; import android.os.PowerManager; import org.briarproject.bramble.api.network.NetworkManager; @@ -14,10 +13,10 @@ import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.util.RenewableWakeLock; import java.io.IOException; -import java.io.InputStream; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; @@ -41,12 +40,13 @@ class AndroidTorPlugin extends TorPlugin { AndroidTorPlugin(Executor ioExecutor, ScheduledExecutorService scheduler, Context appContext, NetworkManager networkManager, LocationUtils locationUtils, SocketFactory torSocketFactory, - Clock clock, CircumventionProvider circumventionProvider, - Backoff backoff, DuplexPluginCallback callback, - String architecture, int maxLatency, int maxIdleTime) { + Clock clock, ResourceProvider resourceProvider, + CircumventionProvider circumventionProvider, Backoff backoff, + DuplexPluginCallback callback, String architecture, int maxLatency, + int maxIdleTime) { super(ioExecutor, networkManager, locationUtils, torSocketFactory, - clock, circumventionProvider, backoff, callback, architecture, - maxLatency, maxIdleTime, + clock, resourceProvider, circumventionProvider, backoff, + callback, architecture, maxLatency, maxIdleTime, appContext.getDir("tor", MODE_PRIVATE)); this.appContext = appContext; PowerManager pm = (PowerManager) @@ -72,13 +72,6 @@ class AndroidTorPlugin extends TorPlugin { } } - @Override - protected InputStream getResourceInputStream(String name) { - Resources res = appContext.getResources(); - int resId = res.getIdentifier(name, "raw", appContext.getPackageName()); - return res.openRawResource(resId); - } - @Override protected void enableNetwork(boolean enable) throws IOException { if (!running) return; diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java index 854c2bcea..7287317a9 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java @@ -15,6 +15,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.util.AndroidUtils; import java.util.concurrent.Executor; @@ -45,6 +46,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory { private final EventBus eventBus; private final SocketFactory torSocketFactory; private final BackoffFactory backoffFactory; + private final ResourceProvider resourceProvider; private final CircumventionProvider circumventionProvider; private final Clock clock; @@ -52,7 +54,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory { ScheduledExecutorService scheduler, Context appContext, NetworkManager networkManager, LocationUtils locationUtils, EventBus eventBus, SocketFactory torSocketFactory, - BackoffFactory backoffFactory, + BackoffFactory backoffFactory, ResourceProvider resourceProvider, CircumventionProvider circumventionProvider, Clock clock) { this.ioExecutor = ioExecutor; this.scheduler = scheduler; @@ -62,6 +64,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory { this.eventBus = eventBus; this.torSocketFactory = torSocketFactory; this.backoffFactory = backoffFactory; + this.resourceProvider = resourceProvider; this.circumventionProvider = circumventionProvider; this.clock = clock; } @@ -99,11 +102,10 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); - AndroidTorPlugin - plugin = new AndroidTorPlugin(ioExecutor, scheduler, appContext, - networkManager, locationUtils, torSocketFactory, clock, - circumventionProvider, backoff, callback, architecture, - MAX_LATENCY, MAX_IDLE_TIME); + AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler, + appContext, networkManager, locationUtils, torSocketFactory, + clock, resourceProvider, circumventionProvider, backoff, + callback, architecture, MAX_LATENCY, MAX_IDLE_TIME); eventBus.addListener(plugin); return plugin; } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidCircumventionProvider.java b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidResourceProvider.java similarity index 55% rename from bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidCircumventionProvider.java rename to bramble-android/src/main/java/org/briarproject/bramble/system/AndroidResourceProvider.java index 39a44c3b9..6d391e5ec 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidCircumventionProvider.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidResourceProvider.java @@ -1,24 +1,28 @@ -package org.briarproject.bramble.plugin.tor; +package org.briarproject.bramble.system; import android.app.Application; import android.content.Context; import android.content.res.Resources; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.system.ResourceProvider; + import java.io.InputStream; import javax.inject.Inject; -class AndroidCircumventionProvider extends CircumventionProviderImpl { +@NotNullByDefault +class AndroidResourceProvider implements ResourceProvider { private final Context appContext; @Inject - AndroidCircumventionProvider(Application app) { + AndroidResourceProvider(Application app) { this.appContext = app.getApplicationContext(); } @Override - protected InputStream getResourceInputStream(String name) { + public InputStream getResourceInputStream(String name) { Resources res = appContext.getResources(); int resId = res.getIdentifier(name, "raw", appContext.getPackageName()); return res.openRawResource(resId); diff --git a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSystemModule.java b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSystemModule.java index 79fbf44b5..2f7ea5543 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSystemModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSystemModule.java @@ -1,9 +1,8 @@ package org.briarproject.bramble.system; -import android.app.Application; - import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.SecureRandomProvider; import javax.inject.Singleton; @@ -16,18 +15,26 @@ public class AndroidSystemModule { @Provides @Singleton - SecureRandomProvider provideSecureRandomProvider(Application app) { - return new AndroidSecureRandomProvider(app); + SecureRandomProvider provideSecureRandomProvider( + AndroidSecureRandomProvider provider) { + return provider; } @Provides - LocationUtils provideLocationUtils(Application app) { - return new AndroidLocationUtils(app); + LocationUtils provideLocationUtils(AndroidLocationUtils locationUtils) { + return locationUtils; } @Provides @Singleton - AndroidExecutor provideAndroidExecutor(Application app) { - return new AndroidExecutorImpl(app); + AndroidExecutor provideAndroidExecutor( + AndroidExecutorImpl androidExecutor) { + return androidExecutor; + } + + @Provides + @Singleton + ResourceProvider provideResourceProvider(AndroidResourceProvider provider) { + return provider; } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/system/ResourceProvider.java b/bramble-api/src/main/java/org/briarproject/bramble/api/system/ResourceProvider.java new file mode 100644 index 000000000..e0bbc63d4 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/system/ResourceProvider.java @@ -0,0 +1,11 @@ +package org.briarproject.bramble.api.system; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.io.InputStream; + +@NotNullByDefault +public interface ResourceProvider { + + InputStream getResourceInputStream(String name); +} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidCircumventionModule.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionModule.java similarity index 62% rename from bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidCircumventionModule.java rename to bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionModule.java index 656b20ad3..9ad744861 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidCircumventionModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionModule.java @@ -6,12 +6,12 @@ import dagger.Module; import dagger.Provides; @Module -public class AndroidCircumventionModule { +public class CircumventionModule { @Provides @Singleton CircumventionProvider provideCircumventionProvider( - AndroidCircumventionProvider circumventionProvider) { - return circumventionProvider; + CircumventionProviderImpl provider) { + return provider; } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java index e4c00738c..8396dd774 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.plugin.tor; import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.system.ResourceProvider; import java.io.InputStream; import java.util.ArrayList; @@ -10,10 +11,11 @@ import java.util.Scanner; import java.util.Set; import javax.annotation.Nullable; +import javax.inject.Inject; import static java.util.Arrays.asList; -abstract class CircumventionProviderImpl implements CircumventionProvider { +class CircumventionProviderImpl implements CircumventionProvider { private final static String BRIDGE_FILE_NAME = "bridges"; @@ -22,10 +24,15 @@ abstract class CircumventionProviderImpl implements CircumventionProvider { private static final Set BRIDGES_WORK_IN_COUNTRIES = new HashSet<>(asList(BRIDGES)); + private final ResourceProvider resourceProvider; + @Nullable private volatile List bridges = null; - protected abstract InputStream getResourceInputStream(String name); + @Inject + CircumventionProviderImpl(ResourceProvider resourceProvider) { + this.resourceProvider = resourceProvider; + } @Override public boolean isTorProbablyBlocked(String countryCode) { @@ -40,12 +47,14 @@ abstract class CircumventionProviderImpl implements CircumventionProvider { @Override @IoExecutor public List getBridges() { - if (this.bridges != null) return this.bridges; + List bridges = this.bridges; + if (bridges != null) return new ArrayList<>(bridges); - InputStream is = getResourceInputStream(BRIDGE_FILE_NAME); + InputStream is = + resourceProvider.getResourceInputStream(BRIDGE_FILE_NAME); Scanner scanner = new Scanner(is); - List bridges = new ArrayList<>(); + bridges = new ArrayList<>(); while (scanner.hasNextLine()) { String line = scanner.nextLine(); if (!line.startsWith("#")) bridges.add(line); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 707e118ed..3c6f4cb04 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -26,6 +26,7 @@ import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.util.IoUtils; import org.briarproject.bramble.util.StringUtils; @@ -97,6 +98,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private final DuplexPluginCallback callback; private final String architecture; private final CircumventionProvider circumventionProvider; + private final ResourceProvider resourceProvider; private final int maxLatency, maxIdleTime, socketTimeout; private final File torDirectory, torFile, geoIpFile, configFile; private final File doneFile, cookieFile; @@ -113,23 +115,22 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { protected abstract long getLastUpdateTime(); - protected abstract InputStream getResourceInputStream(String name); - TorPlugin(Executor ioExecutor, NetworkManager networkManager, LocationUtils locationUtils, SocketFactory torSocketFactory, - Clock clock, CircumventionProvider circumventionProvider, - Backoff backoff, DuplexPluginCallback callback, - String architecture, int maxLatency, int maxIdleTime, - File torDirectory) { + Clock clock, ResourceProvider resourceProvider, + CircumventionProvider circumventionProvider, Backoff backoff, + DuplexPluginCallback callback, String architecture, int maxLatency, + int maxIdleTime, File torDirectory) { this.ioExecutor = ioExecutor; this.networkManager = networkManager; this.locationUtils = locationUtils; this.torSocketFactory = torSocketFactory; this.clock = clock; + this.resourceProvider = resourceProvider; + this.circumventionProvider = circumventionProvider; this.backoff = backoff; this.callback = callback; this.architecture = architecture; - this.circumventionProvider = circumventionProvider; this.maxLatency = maxLatency; this.maxIdleTime = maxIdleTime; if (maxIdleTime > Integer.MAX_VALUE / 2) @@ -285,21 +286,22 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private InputStream getTorInputStream() throws IOException { if (LOG.isLoggable(INFO)) LOG.info("Installing Tor binary for " + architecture); - InputStream in = getResourceInputStream("tor_" + architecture); + InputStream in = + resourceProvider.getResourceInputStream("tor_" + architecture); ZipInputStream zin = new ZipInputStream(in); if (zin.getNextEntry() == null) throw new IOException(); return zin; } private InputStream getGeoIpInputStream() throws IOException { - InputStream in = getResourceInputStream("geoip"); + InputStream in = resourceProvider.getResourceInputStream("geoip"); ZipInputStream zin = new ZipInputStream(in); if (zin.getNextEntry() == null) throw new IOException(); return zin; } private InputStream getConfigInputStream() { - return getResourceInputStream("torrc"); + return resourceProvider.getResourceInputStream("torrc"); } private void tryToClose(@Nullable Closeable c) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index 8938c3c22..9f4ba2d14 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -21,6 +21,7 @@ import org.briarproject.bramble.api.reporting.DevConfig; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory; import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory; @@ -95,6 +96,7 @@ public class AppModule { SocketFactory torSocketFactory, BackoffFactory backoffFactory, Application app, NetworkManager networkManager, LocationUtils locationUtils, EventBus eventBus, + ResourceProvider resourceProvider, CircumventionProvider circumventionProvider, Clock clock) { Context appContext = app.getApplicationContext(); DuplexPluginFactory bluetooth = @@ -102,7 +104,8 @@ public class AppModule { appContext, random, eventBus, backoffFactory); DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor, scheduler, appContext, networkManager, locationUtils, eventBus, - torSocketFactory, backoffFactory, circumventionProvider, clock); + torSocketFactory, backoffFactory, resourceProvider, + circumventionProvider, clock); DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, eventBus, backoffFactory, appContext); Collection duplex = asList(bluetooth, tor, lan);