mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Merge branch 'simpler-threading'.
This merge reduces the number of thread pools.
This commit is contained in:
@@ -1,21 +1,13 @@
|
||||
package org.briarproject.android;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.briarproject.api.android.AndroidExecutor;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||
import org.briarproject.api.android.ReferenceManager;
|
||||
import org.briarproject.api.db.DatabaseConfig;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
@@ -28,18 +20,9 @@ import com.google.inject.Provides;
|
||||
|
||||
public class AndroidModule extends AbstractModule {
|
||||
|
||||
private final ExecutorService databaseUiExecutor;
|
||||
private final UiCallback uiCallback;
|
||||
|
||||
public AndroidModule() {
|
||||
// The queue is unbounded, so tasks can be dependent
|
||||
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
|
||||
// Discard tasks that are submitted during shutdown
|
||||
RejectedExecutionHandler policy =
|
||||
new ThreadPoolExecutor.DiscardPolicy();
|
||||
// Use a single thread so DB accesses from the UI don't overlap
|
||||
databaseUiExecutor = new ThreadPoolExecutor(1, 1, 60, SECONDS, queue,
|
||||
policy);
|
||||
// Use a dummy UI callback
|
||||
uiCallback = new UiCallback() {
|
||||
|
||||
@@ -53,10 +36,11 @@ public class AndroidModule extends AbstractModule {
|
||||
|
||||
public void showMessage(String... message) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AndroidExecutor.class).to(AndroidExecutorImpl.class).in(
|
||||
Singleton.class);
|
||||
@@ -65,12 +49,6 @@ public class AndroidModule extends AbstractModule {
|
||||
bind(UiCallback.class).toInstance(uiCallback);
|
||||
}
|
||||
|
||||
@Provides @Singleton @DatabaseUiExecutor
|
||||
Executor getDatabaseUiExecutor(LifecycleManager lifecycleManager) {
|
||||
lifecycleManager.registerForShutdown(databaseUiExecutor);
|
||||
return databaseUiExecutor;
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
DatabaseConfig getDatabaseConfig(final Application app) {
|
||||
final File dir = app.getApplicationContext().getDir("db", MODE_PRIVATE);
|
||||
|
||||
@@ -23,8 +23,8 @@ import org.briarproject.android.groups.GroupListActivity;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.Settings;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
@@ -51,7 +51,7 @@ Service, EventListener {
|
||||
Logger.getLogger(AndroidNotificationManagerImpl.class.getName());
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final Executor dbUiExecutor;
|
||||
private final Executor dbExecutor;
|
||||
private final Context appContext;
|
||||
private final Map<ContactId, Integer> contactCounts =
|
||||
new HashMap<ContactId, Integer>(); // Locking: this
|
||||
@@ -65,9 +65,9 @@ Service, EventListener {
|
||||
|
||||
@Inject
|
||||
public AndroidNotificationManagerImpl(DatabaseComponent db,
|
||||
@DatabaseUiExecutor Executor dbExecutor, Application app) {
|
||||
@DatabaseExecutor Executor dbExecutor, Application app) {
|
||||
this.db = db;
|
||||
this.dbUiExecutor = dbExecutor;
|
||||
this.dbExecutor = dbExecutor;
|
||||
appContext = app.getApplicationContext();
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ Service, EventListener {
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
dbUiExecutor.execute(new Runnable() {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
settings = db.getSettings();
|
||||
|
||||
@@ -5,14 +5,18 @@ import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
|
||||
import static android.view.inputmethod.InputMethodManager.HIDE_IMPLICIT_ONLY;
|
||||
import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.briarproject.android.BriarService.BriarBinder;
|
||||
import org.briarproject.android.BriarService.BriarServiceConnection;
|
||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||
import org.briarproject.api.db.DatabaseConfig;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
|
||||
import roboguice.activity.RoboActivity;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
@@ -35,7 +39,7 @@ public class BriarActivity extends RoboActivity {
|
||||
private boolean bound = false;
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
|
||||
@Inject @DatabaseExecutor private volatile Executor dbExecutor;
|
||||
@Inject private volatile LifecycleManager lifecycleManager;
|
||||
|
||||
@Override
|
||||
@@ -113,7 +117,7 @@ public class BriarActivity extends RoboActivity {
|
||||
}
|
||||
|
||||
protected void runOnDbThread(final Runnable task) {
|
||||
dbUiExecutor.execute(new Runnable() {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
lifecycleManager.waitForDatabase();
|
||||
|
||||
@@ -18,9 +18,9 @@ import org.briarproject.R;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.android.AndroidExecutor;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DatabaseConfig;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
@@ -56,7 +56,7 @@ public class BriarService extends RoboService implements EventListener {
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject private volatile LifecycleManager lifecycleManager;
|
||||
@Inject private volatile AndroidExecutor androidExecutor;
|
||||
@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
|
||||
@Inject @DatabaseExecutor private volatile Executor dbExecutor;
|
||||
@Inject private volatile DatabaseComponent db;
|
||||
private volatile boolean started = false;
|
||||
|
||||
@@ -130,6 +130,7 @@ public class BriarService extends RoboService implements EventListener {
|
||||
return START_NOT_STICKY; // Don't restart automatically if killed
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ public class BriarService extends RoboService implements EventListener {
|
||||
}
|
||||
|
||||
private void showMessageNotification(final GroupId g, final ContactId c) {
|
||||
dbUiExecutor.execute(new Runnable() {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
lifecycleManager.waitForDatabase();
|
||||
|
||||
@@ -30,8 +30,8 @@ public class SplashScreenActivity extends RoboSplashActivity {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SplashScreenActivity.class.getName());
|
||||
|
||||
// This build expires on 12 July 2014
|
||||
private static final long EXPIRY_DATE = 1405123200 * 1000L;
|
||||
// This build expires on 8 October 2014
|
||||
private static final long EXPIRY_DATE = 1412726400 * 1000L;
|
||||
|
||||
private long now = System.currentTimeMillis();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.concurrent.Executor;
|
||||
|
||||
import org.briarproject.api.android.AndroidExecutor;
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.plugins.PluginExecutor;
|
||||
import org.briarproject.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPluginConfig;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
|
||||
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
|
||||
@@ -20,13 +20,9 @@ import org.briarproject.plugins.tor.TorPluginFactory;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
public class AndroidPluginsModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {}
|
||||
public class AndroidPluginsModule extends PluginsModule {
|
||||
|
||||
@Provides
|
||||
SimplexPluginConfig getSimplexPluginConfig() {
|
||||
@@ -38,18 +34,16 @@ public class AndroidPluginsModule extends AbstractModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
DuplexPluginConfig getDuplexPluginConfig(
|
||||
@PluginExecutor Executor pluginExecutor,
|
||||
DuplexPluginConfig getDuplexPluginConfig(@IoExecutor Executor ioExecutor,
|
||||
AndroidExecutor androidExecutor, Application app,
|
||||
CryptoComponent crypto, LocationUtils locationUtils) {
|
||||
Context appContext = app.getApplicationContext();
|
||||
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(
|
||||
pluginExecutor, androidExecutor, appContext,
|
||||
crypto.getSecureRandom());
|
||||
DuplexPluginFactory tor = new TorPluginFactory(pluginExecutor,
|
||||
appContext, locationUtils);
|
||||
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(
|
||||
pluginExecutor, appContext);
|
||||
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(ioExecutor,
|
||||
androidExecutor, appContext, crypto.getSecureRandom());
|
||||
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext,
|
||||
locationUtils);
|
||||
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
||||
appContext);
|
||||
final Collection<DuplexPluginFactory> factories =
|
||||
Arrays.asList(bluetooth, tor, lan);
|
||||
return new DuplexPluginConfig() {
|
||||
|
||||
@@ -63,7 +63,7 @@ class DroidtoothPlugin implements DuplexPlugin {
|
||||
private static final String DISCOVERY_FINISHED =
|
||||
"android.bluetooth.adapter.action.DISCOVERY_FINISHED";
|
||||
|
||||
private final Executor pluginExecutor;
|
||||
private final Executor ioExecutor;
|
||||
private final AndroidExecutor androidExecutor;
|
||||
private final Context appContext;
|
||||
private final SecureRandom secureRandom;
|
||||
@@ -80,11 +80,11 @@ class DroidtoothPlugin implements DuplexPlugin {
|
||||
// Non-null if the plugin started successfully
|
||||
private volatile BluetoothAdapter adapter = null;
|
||||
|
||||
DroidtoothPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor,
|
||||
DroidtoothPlugin(Executor ioExecutor, AndroidExecutor androidExecutor,
|
||||
Context appContext, SecureRandom secureRandom, Clock clock,
|
||||
DuplexPluginCallback callback, int maxFrameLength, long maxLatency,
|
||||
long pollingInterval) {
|
||||
this.pluginExecutor = pluginExecutor;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.androidExecutor = androidExecutor;
|
||||
this.appContext = appContext;
|
||||
this.secureRandom = secureRandom;
|
||||
@@ -147,7 +147,7 @@ class DroidtoothPlugin implements DuplexPlugin {
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
pluginExecutor.execute(new Runnable() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
if(!isRunning()) return;
|
||||
if(LOG.isLoggable(INFO))
|
||||
@@ -256,7 +256,7 @@ class DroidtoothPlugin implements DuplexPlugin {
|
||||
if(StringUtils.isNullOrEmpty(address)) continue;
|
||||
final String uuid = e.getValue().get("uuid");
|
||||
if(StringUtils.isNullOrEmpty(uuid)) continue;
|
||||
pluginExecutor.execute(new Runnable() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
if(!running) return;
|
||||
BluetoothSocket s = connect(address, uuid);
|
||||
|
||||
@@ -19,16 +19,16 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory {
|
||||
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
|
||||
private static final long POLLING_INTERVAL = 3 * 60 * 1000; // 3 minutes
|
||||
|
||||
private final Executor pluginExecutor;
|
||||
private final Executor ioExecutor;
|
||||
private final AndroidExecutor androidExecutor;
|
||||
private final Context appContext;
|
||||
private final SecureRandom secureRandom;
|
||||
private final Clock clock;
|
||||
|
||||
public DroidtoothPluginFactory(Executor pluginExecutor,
|
||||
public DroidtoothPluginFactory(Executor ioExecutor,
|
||||
AndroidExecutor androidExecutor, Context appContext,
|
||||
SecureRandom secureRandom) {
|
||||
this.pluginExecutor = pluginExecutor;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.androidExecutor = androidExecutor;
|
||||
this.appContext = appContext;
|
||||
this.secureRandom = secureRandom;
|
||||
@@ -40,7 +40,7 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory {
|
||||
}
|
||||
|
||||
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
|
||||
return new DroidtoothPlugin(pluginExecutor, androidExecutor, appContext,
|
||||
return new DroidtoothPlugin(ioExecutor, androidExecutor, appContext,
|
||||
secureRandom, clock, callback, MAX_FRAME_LENGTH, MAX_LATENCY,
|
||||
POLLING_INTERVAL);
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
|
||||
private volatile BroadcastReceiver networkStateReceiver = null;
|
||||
|
||||
AndroidLanTcpPlugin(Executor pluginExecutor, Context appContext,
|
||||
AndroidLanTcpPlugin(Executor ioExecutor, Context appContext,
|
||||
DuplexPluginCallback callback, int maxFrameLength, long maxLatency,
|
||||
long pollingInterval) {
|
||||
super(pluginExecutor, callback, maxFrameLength, maxLatency,
|
||||
super(ioExecutor, callback, maxFrameLength, maxLatency,
|
||||
pollingInterval);
|
||||
this.appContext = appContext;
|
||||
}
|
||||
|
||||
@@ -15,12 +15,11 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
||||
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
|
||||
private static final long POLLING_INTERVAL = 60 * 1000; // 1 minute
|
||||
|
||||
private final Executor pluginExecutor;
|
||||
private final Executor ioExecutor;
|
||||
private final Context appContext;
|
||||
|
||||
public AndroidLanTcpPluginFactory(Executor pluginExecutor,
|
||||
Context appContext) {
|
||||
this.pluginExecutor = pluginExecutor;
|
||||
public AndroidLanTcpPluginFactory(Executor ioExecutor, Context appContext) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.appContext = appContext;
|
||||
}
|
||||
|
||||
@@ -29,7 +28,7 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
||||
}
|
||||
|
||||
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
|
||||
return new AndroidLanTcpPlugin(pluginExecutor, appContext, callback,
|
||||
return new AndroidLanTcpPlugin(ioExecutor, appContext, callback,
|
||||
MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(TorPlugin.class.getName());
|
||||
|
||||
private final Executor pluginExecutor;
|
||||
private final Executor ioExecutor;
|
||||
private final Context appContext;
|
||||
private final LocationUtils locationUtils;
|
||||
private final DuplexPluginCallback callback;
|
||||
@@ -89,10 +89,10 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
private volatile TorControlConnection controlConnection = null;
|
||||
private volatile BroadcastReceiver networkStateReceiver = null;
|
||||
|
||||
TorPlugin(Executor pluginExecutor, Context appContext,
|
||||
TorPlugin(Executor ioExecutor, Context appContext,
|
||||
LocationUtils locationUtils, DuplexPluginCallback callback,
|
||||
int maxFrameLength, long maxLatency, long pollingInterval) {
|
||||
this.pluginExecutor = pluginExecutor;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.appContext = appContext;
|
||||
this.locationUtils = locationUtils;
|
||||
this.callback = callback;
|
||||
@@ -351,7 +351,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
pluginExecutor.execute(new Runnable() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
// If there's already a port number stored in config, reuse it
|
||||
String portString = callback.getConfig().get("port");
|
||||
@@ -379,7 +379,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
c.put("port", localPort);
|
||||
callback.mergeConfig(c);
|
||||
// Create a hidden service if necessary
|
||||
pluginExecutor.execute(new Runnable() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
publishHiddenService(localPort);
|
||||
}
|
||||
@@ -506,7 +506,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
}
|
||||
|
||||
private void connectAndCallBack(final ContactId c) {
|
||||
pluginExecutor.execute(new Runnable() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
DuplexTransportConnection d = createConnection(c);
|
||||
if(d != null) callback.outgoingConnectionCreated(c, d);
|
||||
|
||||
@@ -21,13 +21,13 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
||||
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
|
||||
private static final long POLLING_INTERVAL = 3 * 60 * 1000; // 3 minutes
|
||||
|
||||
private final Executor pluginExecutor;
|
||||
private final Executor ioExecutor;
|
||||
private final Context appContext;
|
||||
private final LocationUtils locationUtils;
|
||||
|
||||
public TorPluginFactory(Executor pluginExecutor, Context appContext,
|
||||
public TorPluginFactory(Executor ioExecutor, Context appContext,
|
||||
LocationUtils locationUtils) {
|
||||
this.pluginExecutor = pluginExecutor;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.appContext = appContext;
|
||||
this.locationUtils = locationUtils;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
||||
LOG.info("Tor is not supported on this architecture");
|
||||
return null;
|
||||
}
|
||||
return new TorPlugin(pluginExecutor,appContext, locationUtils,
|
||||
callback, MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL);
|
||||
return new TorPlugin(ioExecutor,appContext, locationUtils, callback,
|
||||
MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user