Use Guice rather than reflection to load plugins.

This allows different plugins to have different dependencies without
cluttering the plugin factory API.
This commit is contained in:
akwizgran
2012-12-15 01:16:48 +00:00
parent 8bc27528a6
commit f5628e5581
14 changed files with 209 additions and 158 deletions

View File

@@ -0,0 +1,8 @@
package net.sf.briar.api.plugins.duplex;
import java.util.Collection;
public interface DuplexPluginConfig {
Collection<DuplexPluginFactory> getFactories();
}

View File

@@ -1,17 +1,10 @@
package net.sf.briar.api.plugins.duplex; package net.sf.briar.api.plugins.duplex;
import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import android.content.Context;
public interface DuplexPluginFactory { public interface DuplexPluginFactory {
TransportId getId(); TransportId getId();
DuplexPlugin createPlugin(Executor pluginExecutor, DuplexPlugin createPlugin(DuplexPluginCallback callback);
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback);
} }

View File

@@ -0,0 +1,8 @@
package net.sf.briar.api.plugins.simplex;
import java.util.Collection;
public interface SimplexPluginConfig {
Collection<SimplexPluginFactory> getFactories();
}

View File

@@ -1,17 +1,10 @@
package net.sf.briar.api.plugins.simplex; package net.sf.briar.api.plugins.simplex;
import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import android.content.Context;
public interface SimplexPluginFactory { public interface SimplexPluginFactory {
TransportId getId(); TransportId getId();
SimplexPlugin createPlugin(Executor pluginExecutor, SimplexPlugin createPlugin(SimplexPluginCallback callback);
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, SimplexPluginCallback callback);
} }

View File

@@ -20,24 +20,24 @@ import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.android.AndroidExecutor; import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.DbException;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.Plugin; import net.sf.briar.api.plugins.Plugin;
import net.sf.briar.api.plugins.PluginCallback; import net.sf.briar.api.plugins.PluginCallback;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.PluginManager; import net.sf.briar.api.plugins.PluginManager;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
import net.sf.briar.api.plugins.duplex.DuplexPluginConfig;
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory; import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
import net.sf.briar.api.plugins.duplex.DuplexTransportConnection; import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
import net.sf.briar.api.plugins.simplex.SimplexPlugin; import net.sf.briar.api.plugins.simplex.SimplexPlugin;
import net.sf.briar.api.plugins.simplex.SimplexPluginCallback; import net.sf.briar.api.plugins.simplex.SimplexPluginCallback;
import net.sf.briar.api.plugins.simplex.SimplexPluginConfig;
import net.sf.briar.api.plugins.simplex.SimplexPluginFactory; import net.sf.briar.api.plugins.simplex.SimplexPluginFactory;
import net.sf.briar.api.plugins.simplex.SimplexTransportReader; import net.sf.briar.api.plugins.simplex.SimplexTransportReader;
import net.sf.briar.api.plugins.simplex.SimplexTransportWriter; import net.sf.briar.api.plugins.simplex.SimplexTransportWriter;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.transport.ConnectionDispatcher; import net.sf.briar.api.transport.ConnectionDispatcher;
import net.sf.briar.api.ui.UiCallback; import net.sf.briar.api.ui.UiCallback;
import net.sf.briar.util.OsUtils;
import android.content.Context; import android.content.Context;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -47,30 +47,10 @@ class PluginManagerImpl implements PluginManager {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(PluginManagerImpl.class.getName()); Logger.getLogger(PluginManagerImpl.class.getName());
private static final String[] ANDROID_SIMPLEX_FACTORIES = new String[0];
private static final String[] ANDROID_DUPLEX_FACTORIES = new String[] {
"net.sf.briar.plugins.droidtooth.DroidtoothPluginFactory",
"net.sf.briar.plugins.tcp.LanTcpPluginFactory",
"net.sf.briar.plugins.tcp.WanTcpPluginFactory",
"net.sf.briar.plugins.tor.TorPluginFactory"
};
private static final String[] J2SE_SIMPLEX_FACTORIES = new String[] {
"net.sf.briar.plugins.file.RemovableDrivePluginFactory"
};
private static final String[] J2SE_DUPLEX_FACTORIES = new String[] {
"net.sf.briar.plugins.bluetooth.BluetoothPluginFactory",
"net.sf.briar.plugins.modem.ModemPluginFactory",
"net.sf.briar.plugins.tcp.LanTcpPluginFactory",
"net.sf.briar.plugins.tcp.WanTcpPluginFactory",
"net.sf.briar.plugins.tor.TorPluginFactory"
};
private final ExecutorService pluginExecutor; private final ExecutorService pluginExecutor;
private final AndroidExecutor androidExecutor; private final AndroidExecutor androidExecutor;
private final ShutdownManager shutdownManager; private final SimplexPluginConfig simplexPluginConfig;
private final DuplexPluginConfig duplexPluginConfig;
private final DatabaseComponent db; private final DatabaseComponent db;
private final Poller poller; private final Poller poller;
private final ConnectionDispatcher dispatcher; private final ConnectionDispatcher dispatcher;
@@ -80,12 +60,15 @@ class PluginManagerImpl implements PluginManager {
@Inject @Inject
PluginManagerImpl(@PluginExecutor ExecutorService pluginExecutor, PluginManagerImpl(@PluginExecutor ExecutorService pluginExecutor,
AndroidExecutor androidExecutor, ShutdownManager shutdownManager, AndroidExecutor androidExecutor,
DatabaseComponent db, Poller poller, SimplexPluginConfig simplexPluginConfig,
ConnectionDispatcher dispatcher, UiCallback uiCallback) { DuplexPluginConfig duplexPluginConfig, DatabaseComponent db,
Poller poller, ConnectionDispatcher dispatcher,
UiCallback uiCallback) {
this.pluginExecutor = pluginExecutor; this.pluginExecutor = pluginExecutor;
this.androidExecutor = androidExecutor; this.androidExecutor = androidExecutor;
this.shutdownManager = shutdownManager; this.simplexPluginConfig = simplexPluginConfig;
this.duplexPluginConfig = duplexPluginConfig;
this.db = db; this.db = db;
this.poller = poller; this.poller = poller;
this.dispatcher = dispatcher; this.dispatcher = dispatcher;
@@ -98,27 +81,23 @@ class PluginManagerImpl implements PluginManager {
Set<TransportId> ids = new HashSet<TransportId>(); Set<TransportId> ids = new HashSet<TransportId>();
// Instantiate and start the simplex plugins // Instantiate and start the simplex plugins
if(LOG.isLoggable(INFO)) LOG.info("Starting simplex plugins"); if(LOG.isLoggable(INFO)) LOG.info("Starting simplex plugins");
for(String s : getSimplexPluginFactoryNames()) { for(SimplexPluginFactory factory : simplexPluginConfig.getFactories()) {
TransportId id = factory.getId();
if(!ids.add(id)) {
if(LOG.isLoggable(WARNING))
LOG.warning("Duplicate transport ID: " + id);
continue;
}
SimplexCallback callback = new SimplexCallback(id);
SimplexPlugin plugin = factory.createPlugin(callback);
if(plugin == null) {
if(LOG.isLoggable(INFO)) {
LOG.info(factory.getClass().getSimpleName()
+ " did not create a plugin");
}
continue;
}
try { try {
Class<?> c = Class.forName(s);
SimplexPluginFactory factory =
(SimplexPluginFactory) c.newInstance();
TransportId id = factory.getId();
if(!ids.add(id)) {
if(LOG.isLoggable(WARNING))
LOG.warning("Duplicate transport ID: " + id);
continue;
}
SimplexCallback callback = new SimplexCallback(id);
SimplexPlugin plugin = factory.createPlugin(pluginExecutor,
androidExecutor, appContext, shutdownManager, callback);
if(plugin == null) {
if(LOG.isLoggable(INFO)) {
LOG.info(factory.getClass().getSimpleName()
+ " did not create a plugin");
}
continue;
}
if(plugin.start()) { if(plugin.start()) {
simplexPlugins.add(plugin); simplexPlugins.add(plugin);
} else { } else {
@@ -126,37 +105,29 @@ class PluginManagerImpl implements PluginManager {
LOG.info(plugin.getClass().getSimpleName() LOG.info(plugin.getClass().getSimpleName()
+ " did not start"); + " did not start");
} }
} catch(ClassCastException e) { } catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
continue;
} catch(Exception e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
continue;
} }
} }
// Instantiate and start the duplex plugins // Instantiate and start the duplex plugins
if(LOG.isLoggable(INFO)) LOG.info("Starting duplex plugins"); if(LOG.isLoggable(INFO)) LOG.info("Starting duplex plugins");
for(String s : getDuplexPluginFactoryNames()) { for(DuplexPluginFactory factory : duplexPluginConfig.getFactories()) {
TransportId id = factory.getId();
if(!ids.add(id)) {
if(LOG.isLoggable(WARNING))
LOG.warning("Duplicate transport ID: " + id);
continue;
}
DuplexCallback callback = new DuplexCallback(id);
DuplexPlugin plugin = factory.createPlugin(callback);
if(plugin == null) {
if(LOG.isLoggable(INFO)) {
LOG.info(factory.getClass().getSimpleName()
+ " did not create a plugin");
}
continue;
}
try { try {
Class<?> c = Class.forName(s);
DuplexPluginFactory factory =
(DuplexPluginFactory) c.newInstance();
TransportId id = factory.getId();
if(!ids.add(id)) {
if(LOG.isLoggable(WARNING))
LOG.warning("Duplicate transport ID: " + id);
continue;
}
DuplexCallback callback = new DuplexCallback(id);
DuplexPlugin plugin = factory.createPlugin(pluginExecutor,
androidExecutor, appContext, shutdownManager, callback);
if(plugin == null) {
if(LOG.isLoggable(INFO)) {
LOG.info(factory.getClass().getSimpleName()
+ " did not create a plugin");
}
continue;
}
if(plugin.start()) { if(plugin.start()) {
duplexPlugins.add(plugin); duplexPlugins.add(plugin);
} else { } else {
@@ -164,12 +135,8 @@ class PluginManagerImpl implements PluginManager {
LOG.info(plugin.getClass().getSimpleName() LOG.info(plugin.getClass().getSimpleName()
+ " did not start"); + " did not start");
} }
} catch(ClassCastException e) { } catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
continue;
} catch(Exception e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
continue;
} }
} }
// Start the poller // Start the poller
@@ -182,16 +149,6 @@ class PluginManagerImpl implements PluginManager {
return simplexPlugins.size() + duplexPlugins.size(); return simplexPlugins.size() + duplexPlugins.size();
} }
private static String[] getSimplexPluginFactoryNames() {
if(OsUtils.isAndroid()) return ANDROID_SIMPLEX_FACTORIES;
return J2SE_SIMPLEX_FACTORIES;
}
private static String[] getDuplexPluginFactoryNames() {
if(OsUtils.isAndroid()) return ANDROID_DUPLEX_FACTORIES;
return J2SE_DUPLEX_FACTORIES;
}
public synchronized int stop() { public synchronized int stop() {
int stopped = 0; int stopped = 0;
// Stop the poller // Stop the poller

View File

@@ -1,12 +1,31 @@
package net.sf.briar.plugins; package net.sf.briar.plugins;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.PluginManager; import net.sf.briar.api.plugins.PluginManager;
import net.sf.briar.api.plugins.duplex.DuplexPluginConfig;
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
import net.sf.briar.api.plugins.simplex.SimplexPluginConfig;
import net.sf.briar.api.plugins.simplex.SimplexPluginFactory;
import net.sf.briar.plugins.bluetooth.BluetoothPluginFactory;
import net.sf.briar.plugins.droidtooth.DroidtoothPluginFactory;
import net.sf.briar.plugins.file.RemovableDrivePluginFactory;
import net.sf.briar.plugins.modem.ModemPluginFactory;
import net.sf.briar.plugins.tcp.LanTcpPluginFactory;
import net.sf.briar.plugins.tcp.WanTcpPluginFactory;
import net.sf.briar.plugins.tor.TorPluginFactory;
import net.sf.briar.util.OsUtils;
import android.content.Context;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton; import com.google.inject.Singleton;
public class PluginsModule extends AbstractModule { public class PluginsModule extends AbstractModule {
@@ -21,4 +40,45 @@ public class PluginsModule extends AbstractModule {
PluginManagerImpl.class).in(Singleton.class); PluginManagerImpl.class).in(Singleton.class);
bind(Poller.class).to(PollerImpl.class); bind(Poller.class).to(PollerImpl.class);
} }
@Provides
SimplexPluginConfig getSimplexPluginConfig(
@PluginExecutor Executor pluginExecutor) {
final Collection<SimplexPluginFactory> factories =
new ArrayList<SimplexPluginFactory>();
if(!OsUtils.isAndroid()) {
// No simplex plugins for Android
} else {
factories.add(new RemovableDrivePluginFactory(pluginExecutor));
}
return new SimplexPluginConfig() {
public Collection<SimplexPluginFactory> getFactories() {
return factories;
}
};
}
@Provides
DuplexPluginConfig getDuplexPluginConfig(
@PluginExecutor Executor pluginExecutor,
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager) {
final Collection<DuplexPluginFactory> factories =
new ArrayList<DuplexPluginFactory>();
if(OsUtils.isAndroid()) {
factories.add(new DroidtoothPluginFactory(pluginExecutor,
androidExecutor, appContext));
} else {
factories.add(new BluetoothPluginFactory(pluginExecutor));
factories.add(new ModemPluginFactory(pluginExecutor));
}
factories.add(new LanTcpPluginFactory(pluginExecutor));
factories.add(new WanTcpPluginFactory(pluginExecutor, shutdownManager));
factories.add(new TorPluginFactory(pluginExecutor));
return new DuplexPluginConfig() {
public Collection<DuplexPluginFactory> getFactories() {
return factories;
}
};
}
} }

View File

@@ -2,27 +2,28 @@ package net.sf.briar.plugins.bluetooth;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.clock.SystemClock; import net.sf.briar.api.clock.SystemClock;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory; import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import android.content.Context;
public class BluetoothPluginFactory implements DuplexPluginFactory { public class BluetoothPluginFactory implements DuplexPluginFactory {
private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins
private final Executor pluginExecutor;
public BluetoothPluginFactory(@PluginExecutor Executor pluginExecutor) {
this.pluginExecutor = pluginExecutor;
}
public TransportId getId() { public TransportId getId() {
return BluetoothPlugin.ID; return BluetoothPlugin.ID;
} }
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback) {
return new BluetoothPlugin(pluginExecutor, new SystemClock(), callback, return new BluetoothPlugin(pluginExecutor, new SystemClock(), callback,
POLLING_INTERVAL); POLLING_INTERVAL);
} }

View File

@@ -3,7 +3,6 @@ package net.sf.briar.plugins.droidtooth;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor; import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
@@ -15,13 +14,22 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory {
private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins
private final Executor pluginExecutor;
private final AndroidExecutor androidExecutor;
private final Context appContext;
public DroidtoothPluginFactory(@PluginExecutor Executor pluginExecutor,
AndroidExecutor androidExecutor, Context appContext) {
this.pluginExecutor = pluginExecutor;
this.androidExecutor = androidExecutor;
this.appContext = appContext;
}
public TransportId getId() { public TransportId getId() {
return DroidtoothPlugin.ID; return DroidtoothPlugin.ID;
} }
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback) {
return new DroidtoothPlugin(pluginExecutor, androidExecutor, appContext, return new DroidtoothPlugin(pluginExecutor, androidExecutor, appContext,
callback, POLLING_INTERVAL); callback, POLLING_INTERVAL);
} }

View File

@@ -2,27 +2,29 @@ package net.sf.briar.plugins.file;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.simplex.SimplexPlugin; import net.sf.briar.api.plugins.simplex.SimplexPlugin;
import net.sf.briar.api.plugins.simplex.SimplexPluginCallback; import net.sf.briar.api.plugins.simplex.SimplexPluginCallback;
import net.sf.briar.api.plugins.simplex.SimplexPluginFactory; import net.sf.briar.api.plugins.simplex.SimplexPluginFactory;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.util.OsUtils; import net.sf.briar.util.OsUtils;
import android.content.Context;
public class RemovableDrivePluginFactory implements SimplexPluginFactory { public class RemovableDrivePluginFactory implements SimplexPluginFactory {
private static final long POLLING_INTERVAL = 10L * 1000L; // 10 seconds private static final long POLLING_INTERVAL = 10L * 1000L; // 10 seconds
private final Executor pluginExecutor;
public RemovableDrivePluginFactory(
@PluginExecutor Executor pluginExecutor) {
this.pluginExecutor = pluginExecutor;
}
public TransportId getId() { public TransportId getId() {
return RemovableDrivePlugin.ID; return RemovableDrivePlugin.ID;
} }
public SimplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public SimplexPlugin createPlugin(SimplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, SimplexPluginCallback callback) {
RemovableDriveFinder finder; RemovableDriveFinder finder;
RemovableDriveMonitor monitor; RemovableDriveMonitor monitor;
if(OsUtils.isLinux()) { if(OsUtils.isLinux()) {

View File

@@ -2,8 +2,6 @@ package net.sf.briar.plugins.modem;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
@@ -12,19 +10,21 @@ import net.sf.briar.api.protocol.TransportId;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import android.content.Context;
public class ModemPluginFactory implements DuplexPluginFactory { public class ModemPluginFactory implements DuplexPluginFactory {
private static final long POLLING_INTERVAL = 60L * 60L * 1000L; // 1 hour private static final long POLLING_INTERVAL = 60L * 60L * 1000L; // 1 hour
private final Executor pluginExecutor;
public ModemPluginFactory(@PluginExecutor Executor pluginExecutor) {
this.pluginExecutor = pluginExecutor;
}
public TransportId getId() { public TransportId getId() {
return ModemPlugin.ID; return ModemPlugin.ID;
} }
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback) {
// This plugin is not enabled by default // This plugin is not enabled by default
String enabled = callback.getConfig().get("enabled"); String enabled = callback.getConfig().get("enabled");
if(StringUtils.isNullOrEmpty(enabled)) return null; if(StringUtils.isNullOrEmpty(enabled)) return null;

View File

@@ -2,26 +2,27 @@ package net.sf.briar.plugins.tcp;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory; import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import android.content.Context;
public class LanTcpPluginFactory implements DuplexPluginFactory { public class LanTcpPluginFactory implements DuplexPluginFactory {
private static final long POLLING_INTERVAL = 60L * 1000L; // 1 minute private static final long POLLING_INTERVAL = 60L * 1000L; // 1 minute
private final Executor pluginExecutor;
public LanTcpPluginFactory(@PluginExecutor Executor pluginExecutor) {
this.pluginExecutor = pluginExecutor;
}
public TransportId getId() { public TransportId getId() {
return LanTcpPlugin.ID; return LanTcpPlugin.ID;
} }
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback) {
return new LanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL); return new LanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL);
} }
} }

View File

@@ -2,26 +2,31 @@ package net.sf.briar.plugins.tcp;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory; import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import android.content.Context;
public class WanTcpPluginFactory implements DuplexPluginFactory { public class WanTcpPluginFactory implements DuplexPluginFactory {
private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 minutes private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 minutes
private final Executor pluginExecutor;
private final ShutdownManager shutdownManager;
public WanTcpPluginFactory(@PluginExecutor Executor pluginExecutor,
ShutdownManager shutdownManager) {
this.pluginExecutor = pluginExecutor;
this.shutdownManager = shutdownManager;
}
public TransportId getId() { public TransportId getId() {
return WanTcpPlugin.ID; return WanTcpPlugin.ID;
} }
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback) {
return new WanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL, return new WanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL,
new PortMapperImpl(shutdownManager)); new PortMapperImpl(shutdownManager));
} }

View File

@@ -2,8 +2,6 @@ package net.sf.briar.plugins.tor;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.PluginExecutor;
import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPlugin;
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
@@ -12,19 +10,21 @@ import net.sf.briar.api.protocol.TransportId;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import android.content.Context;
public class TorPluginFactory implements DuplexPluginFactory { public class TorPluginFactory implements DuplexPluginFactory {
private static final long POLLING_INTERVAL = 15L * 60L * 1000L; // 15 mins private static final long POLLING_INTERVAL = 15L * 60L * 1000L; // 15 mins
private final Executor pluginExecutor;
public TorPluginFactory(@PluginExecutor Executor pluginExecutor) {
this.pluginExecutor = pluginExecutor;
}
public TransportId getId() { public TransportId getId() {
return TorPlugin.ID; return TorPlugin.ID;
} }
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
AndroidExecutor androidExecutor, Context appContext,
ShutdownManager shutdownManager, DuplexPluginCallback callback) {
// This plugin is not enabled by default // This plugin is not enabled by default
String enabled = callback.getConfig().get("enabled"); String enabled = callback.getConfig().get("enabled");
if(StringUtils.isNullOrEmpty(enabled)) return null; if(StringUtils.isNullOrEmpty(enabled)) return null;

View File

@@ -1,5 +1,6 @@
package net.sf.briar.plugins; package net.sf.briar.plugins;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@@ -9,10 +10,15 @@ import net.sf.briar.api.TransportConfig;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.android.AndroidExecutor; import net.sf.briar.api.android.AndroidExecutor;
import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.duplex.DuplexPluginConfig;
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
import net.sf.briar.api.plugins.simplex.SimplexPluginConfig;
import net.sf.briar.api.plugins.simplex.SimplexPluginFactory;
import net.sf.briar.api.protocol.TransportId; import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.transport.ConnectionDispatcher; import net.sf.briar.api.transport.ConnectionDispatcher;
import net.sf.briar.api.ui.UiCallback; import net.sf.briar.api.ui.UiCallback;
import net.sf.briar.plugins.file.RemovableDrivePluginFactory;
import net.sf.briar.plugins.tcp.LanTcpPluginFactory;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.jmock.Mockery; import org.jmock.Mockery;
@@ -24,17 +30,30 @@ public class PluginManagerImplTest extends BriarTestCase {
@Test @Test
public void testStartAndStop() throws Exception { public void testStartAndStop() throws Exception {
Mockery context = new Mockery(); Mockery context = new Mockery();
final ExecutorService pluginExecutor = Executors.newCachedThreadPool();
final AndroidExecutor androidExecutor = final AndroidExecutor androidExecutor =
context.mock(AndroidExecutor.class); context.mock(AndroidExecutor.class);
final ShutdownManager shutdownManager = final SimplexPluginConfig simplexPluginConfig =
context.mock(ShutdownManager.class); context.mock(SimplexPluginConfig.class);
final DuplexPluginConfig duplexPluginConfig =
context.mock(DuplexPluginConfig.class);
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final Poller poller = context.mock(Poller.class); final Poller poller = context.mock(Poller.class);
final ConnectionDispatcher dispatcher = final ConnectionDispatcher dispatcher =
context.mock(ConnectionDispatcher.class); context.mock(ConnectionDispatcher.class);
final UiCallback uiCallback = context.mock(UiCallback.class); final UiCallback uiCallback = context.mock(UiCallback.class);
// One simplex plugin
final SimplexPluginFactory removableDrive =
new RemovableDrivePluginFactory(pluginExecutor);
// One duplex plugin
final DuplexPluginFactory lanTcp =
new LanTcpPluginFactory(pluginExecutor);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Start // Start
oneOf(simplexPluginConfig).getFactories();
will(returnValue(Arrays.asList(removableDrive)));
oneOf(duplexPluginConfig).getFactories();
will(returnValue(Arrays.asList(lanTcp)));
oneOf(poller).start(with(any(Collection.class))); oneOf(poller).start(with(any(Collection.class)));
allowing(db).getConfig(with(any(TransportId.class))); allowing(db).getConfig(with(any(TransportId.class)));
will(returnValue(new TransportConfig())); will(returnValue(new TransportConfig()));
@@ -48,16 +67,12 @@ public class PluginManagerImplTest extends BriarTestCase {
oneOf(poller).stop(); oneOf(poller).stop();
oneOf(androidExecutor).shutdown(); oneOf(androidExecutor).shutdown();
}}); }});
ExecutorService executor = Executors.newCachedThreadPool(); PluginManagerImpl p = new PluginManagerImpl(pluginExecutor,
PluginManagerImpl p = new PluginManagerImpl(executor, androidExecutor, androidExecutor, simplexPluginConfig, duplexPluginConfig, db,
shutdownManager, db, poller, dispatcher, uiCallback); poller, dispatcher, uiCallback);
// We expect either 3 or 4 plugins to be started, depending on whether // Two plugins should be started and stopped
// the test machine has a Bluetooth device assertEquals(2, p.start(null));
int started = p.start(null); assertEquals(2, p.stop());
int stopped = p.stop();
assertEquals(started, stopped);
assertTrue(started >= 3);
assertTrue(started <= 4);
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
} }