Merge branch 'use-android-executor' into 'master'

Use Android executor for background API calls

Some Android API calls need to be made from a thread with a message queue, but to keep the UI responsive they shouldn't be made from the UI thread.

This patch gives AndroidExecutor a captive thread with a message queue to execute tasks, and converts various background tasks from creating their own threads to using AndroidExecutor and IoExecutor.

This allows us to upgrade the support library to 23.2.1. Fixes #332.

See merge request !161
This commit is contained in:
akwizgran
2016-05-03 14:34:49 +00:00
13 changed files with 133 additions and 87 deletions

View File

@@ -37,7 +37,7 @@ dependencies {
compile project(':briar-core') compile project(':briar-core')
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'net.jodah:concurrentunit:0.4.2' testCompile 'net.jodah:concurrentunit:0.4.2'
compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:appcompat-v7:23.2.1'
testApt 'com.google.dagger:dagger-compiler:2.0.2' testApt 'com.google.dagger:dagger-compiler:2.0.2'
provided 'javax.annotation:jsr250-api:1.0' provided 'javax.annotation:jsr250-api:1.0'
testCompile project(':briar-tests') testCompile project(':briar-tests')
@@ -45,8 +45,10 @@ dependencies {
dependencyVerification { dependencyVerification {
verify = [ verify = [
'com.android.support:appcompat-v7:0a8762214382b7e8d4b989b4ac10b5c846b957d767ccb7bccbc6be5afa885a82', 'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
'com.android.support:support-v4:5c7dceb6c824089fe80f502e5206264048ef8bffa4e8ddeab180b81723e79b7f', 'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
'com.android.support:support-annotations:f347a35b9748a4103b39a6714a77e2100f488d623fd6268e259c177b200e9d82', 'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
] ]
} }

View File

@@ -11,7 +11,7 @@ repositories {
} }
dependencies { dependencies {
def supportVersion = '23.1.1' def supportVersion = '23.2.1'
compile project(':briar-api') compile project(':briar-api')
compile project(':briar-core') compile project(':briar-core')
compile fileTree(dir: 'libs', include: '*.jar') compile fileTree(dir: 'libs', include: '*.jar')
@@ -53,13 +53,15 @@ dependencyVerification {
'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e', 'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
'de.hdodenhof:circleimageview:c76d936395b50705a3f98c9220c22d2599aeb9e609f559f6048975cfc1f686b8', 'de.hdodenhof:circleimageview:c76d936395b50705a3f98c9220c22d2599aeb9e609f559f6048975cfc1f686b8',
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259', 'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
'com.android.support:support-v4:5c7dceb6c824089fe80f502e5206264048ef8bffa4e8ddeab180b81723e79b7f', 'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
'com.android.support:appcompat-v7:0a8762214382b7e8d4b989b4ac10b5c846b957d767ccb7bccbc6be5afa885a82', 'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
'com.android.support:preference-v7:4b6dabaa4400cbed885c7edc885aa6372468f48d628cc0d4a04b9ccd128ed324', 'com.android.support:preference-v7:775101bd07bd052e455761c5c5d9523d7ad59f2f320e3e8cbde241fd6b1d6025',
'com.android.support:preference-v14:a69906c2b29b315ac3c1fdf01537a7557660a65b8ea1cf891baa8665e1197459', 'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
'com.android.support:design:41a9cd75ca78f25df5f573db7cedf8bb66beae00c330943923ba9f3e2051736d', 'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
'com.android.support:support-annotations:f347a35b9748a4103b39a6714a77e2100f488d623fd6268e259c177b200e9d82', 'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
'com.android.support:recyclerview-v7:7606373da0931a1e62588335465a0e390cd676c98117edab29220317495faefd', 'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe',
] ]
} }

View File

@@ -41,7 +41,8 @@ public abstract class BriarActivity extends BaseActivity {
new BriarServiceConnection(); new BriarServiceConnection();
@Inject @Inject
DatabaseConfig databaseConfig; protected DatabaseConfig databaseConfig;
private boolean bound = false; private boolean bound = false;
// Fields that are accessed from background threads must be volatile // Fields that are accessed from background threads must be volatile
@@ -94,6 +95,7 @@ public abstract class BriarActivity extends BaseActivity {
} }
protected void signOut(final boolean removeFromRecentApps) { protected void signOut(final boolean removeFromRecentApps) {
// Use a new thread to avoid deadlock with executor tasks
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {

View File

@@ -5,6 +5,7 @@ import android.support.v7.app.ActionBar;
import android.view.MenuItem; import android.view.MenuItem;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.settings.SettingsManager; import org.briarproject.api.settings.SettingsManager;
@@ -12,8 +13,12 @@ import javax.inject.Inject;
public class SettingsActivity extends BriarActivity { public class SettingsActivity extends BriarActivity {
@Inject protected SettingsManager settingsManager; @Inject
@Inject protected EventBus eventBus; protected AndroidExecutor androidExecutor;
@Inject
protected SettingsManager settingsManager;
@Inject
protected EventBus eventBus;
@Override @Override
public void onCreate(Bundle bundle) { public void onCreate(Bundle bundle) {
@@ -33,6 +38,10 @@ public class SettingsActivity extends BriarActivity {
component.inject(this); component.inject(this);
} }
public AndroidExecutor getAndroidExecutor() {
return androidExecutor;
}
public SettingsManager getSettingsManager() { public SettingsManager getSettingsManager() {
return settingsManager; return settingsManager;
} }

View File

@@ -9,6 +9,7 @@ import android.os.StrictMode.VmPolicy;
import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceManager;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.db.DatabaseConfig;
@@ -29,6 +30,8 @@ public class SplashScreenActivity extends BaseActivity {
@Inject @Inject
protected DatabaseConfig dbConfig; protected DatabaseConfig dbConfig;
@Inject
protected AndroidExecutor androidExecutor;
public SplashScreenActivity() { public SplashScreenActivity() {
Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL); Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL);
@@ -87,12 +90,11 @@ public class SplashScreenActivity extends BaseActivity {
} }
private void setPreferencesDefaults() { private void setPreferencesDefaults() {
new Thread() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
PreferenceManager.setDefaultValues(SplashScreenActivity.this, PreferenceManager.setDefaultValues(SplashScreenActivity.this,
R.xml.panic_preferences, false); R.xml.panic_preferences, false);
} }
}.start(); });
} }
} }

View File

@@ -10,11 +10,13 @@ import java.util.concurrent.Future;
public interface AndroidExecutor { public interface AndroidExecutor {
/** /**
* Runs the given task on the main UI thread and returns a Future for * Runs the given task on a background thread with a message queue and
* getting the result. * returns a Future for getting the result.
*/ */
<V> Future<V> submit(Callable<V> c); <V> Future<V> submit(Callable<V> c);
/** Runs the given task on the main UI thread. */ /**
* Runs the given task on a background thread with a message queue.
*/
void execute(Runnable r); void execute(Runnable r);
} }

View File

@@ -18,7 +18,7 @@ import android.view.ViewGroup;
import org.acra.ACRA; import org.acra.ACRA;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.SettingsActivity; import org.briarproject.android.SettingsActivity;
import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.android.util.UserFeedback; import org.briarproject.android.util.UserFeedback;
import org.briarproject.android.widget.PreferenceDividerDecoration; import org.briarproject.android.widget.PreferenceDividerDecoration;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
@@ -55,6 +55,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
Logger.getLogger(SettingsFragment.class.getName()); Logger.getLogger(SettingsFragment.class.getName());
private SettingsActivity listener; private SettingsActivity listener;
private AndroidExecutor androidExecutor;
private ListPreference enableBluetooth; private ListPreference enableBluetooth;
private ListPreference torOverMobile; private ListPreference torOverMobile;
private CheckBoxPreference notifyPrivateMessages; private CheckBoxPreference notifyPrivateMessages;
@@ -74,6 +75,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
try { try {
listener = (SettingsActivity) context; listener = (SettingsActivity) context;
androidExecutor = listener.getAndroidExecutor();
settingsManager = listener.getSettingsManager(); settingsManager = listener.getSettingsManager();
eventBus = listener.getEventBus(); eventBus = listener.getEventBus();
} catch (ClassCastException e) { } catch (ClassCastException e) {
@@ -218,23 +220,19 @@ public class SettingsFragment extends PreferenceFragmentCompat
} }
private void triggerFeedback() { private void triggerFeedback() {
new Thread(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
ACRA.getErrorReporter() ACRA.getErrorReporter().handleException(new UserFeedback(),
.handleException(new UserFeedback(), false); false);
} }
}).start(); });
} }
@Override @Override
public boolean onPreferenceChange(Preference preference, Object o) { public boolean onPreferenceChange(Preference preference, Object o) {
if (preference == enableBluetooth) { if (preference == enableBluetooth) {
bluetoothSetting = Boolean.valueOf((String) o); bluetoothSetting = Boolean.valueOf((String) o);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); enableOrDisableBluetooth(bluetoothSetting);
if (adapter != null) {
AndroidUtils.enableBluetooth(adapter, bluetoothSetting);
}
storeBluetoothSettings(); storeBluetoothSettings();
} else if (preference == torOverMobile) { } else if (preference == torOverMobile) {
torSetting = Boolean.valueOf((String) o); torSetting = Boolean.valueOf((String) o);
@@ -255,6 +253,18 @@ public class SettingsFragment extends PreferenceFragmentCompat
return true; return true;
} }
private void enableOrDisableBluetooth(final boolean enable) {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
androidExecutor.execute(new Runnable() {
public void run() {
if (enable) adapter.enable();
else adapter.disable();
}
});
}
}
private void storeTorSettings() { private void storeTorSettings() {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(new Runnable() {
public void run() { public void run() {

View File

@@ -24,8 +24,8 @@ import com.google.zxing.Result;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.AndroidComponent; import org.briarproject.android.AndroidComponent;
import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.android.fragment.BaseEventFragment; import org.briarproject.android.fragment.BaseEventFragment;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.android.util.CameraView; import org.briarproject.android.util.CameraView;
import org.briarproject.android.util.QrCodeDecoder; import org.briarproject.android.util.QrCodeDecoder;
import org.briarproject.android.util.QrCodeUtils; import org.briarproject.android.util.QrCodeUtils;
@@ -40,8 +40,10 @@ import org.briarproject.api.keyagreement.KeyAgreementTaskFactory;
import org.briarproject.api.keyagreement.Payload; import org.briarproject.api.keyagreement.Payload;
import org.briarproject.api.keyagreement.PayloadEncoder; import org.briarproject.api.keyagreement.PayloadEncoder;
import org.briarproject.api.keyagreement.PayloadParser; import org.briarproject.api.keyagreement.PayloadParser;
import org.briarproject.api.lifecycle.IoExecutor;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
@@ -70,6 +72,11 @@ public class ShowQrCodeFragment extends BaseEventFragment
protected PayloadEncoder payloadEncoder; protected PayloadEncoder payloadEncoder;
@Inject @Inject
protected PayloadParser payloadParser; protected PayloadParser payloadParser;
@Inject
protected AndroidExecutor androidExecutor;
@Inject
@IoExecutor
protected Executor ioExecutor;
private LinearLayout qrLayout; private LinearLayout qrLayout;
private CameraView cameraView; private CameraView cameraView;
@@ -81,7 +88,6 @@ public class ShowQrCodeFragment extends BaseEventFragment
private boolean gotRemotePayload; private boolean gotRemotePayload;
private volatile KeyAgreementTask task; private volatile KeyAgreementTask task;
private volatile BluetoothAdapter adapter;
private volatile boolean waitingForBluetooth; private volatile boolean waitingForBluetooth;
public static ShowQrCodeFragment newInstance() { public static ShowQrCodeFragment newInstance() {
@@ -130,8 +136,6 @@ public class ShowQrCodeFragment extends BaseEventFragment
Display display = getActivity().getWindowManager().getDefaultDisplay(); Display display = getActivity().getWindowManager().getDefaultDisplay();
boolean portrait = display.getWidth() < display.getHeight(); boolean portrait = display.getWidth() < display.getHeight();
qrLayout.setOrientation(portrait ? VERTICAL : HORIZONTAL); qrLayout.setOrientation(portrait ? VERTICAL : HORIZONTAL);
adapter = BluetoothAdapter.getDefaultAdapter();
} }
@Override @Override
@@ -145,11 +149,17 @@ public class ShowQrCodeFragment extends BaseEventFragment
getActivity().registerReceiver(receiver, filter); getActivity().registerReceiver(receiver, filter);
// Enable BT adapter if it is not already on. // Enable BT adapter if it is not already on.
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null && !adapter.isEnabled()) { if (adapter != null && !adapter.isEnabled()) {
waitingForBluetooth = true; waitingForBluetooth = true;
AndroidUtils.enableBluetooth(adapter, true); androidExecutor.execute(new Runnable() {
} else public void run() {
adapter.enable();
}
});
} else {
startListening(); startListening();
}
} }
@Override @Override
@@ -174,21 +184,21 @@ public class ShowQrCodeFragment extends BaseEventFragment
private void startListening() { private void startListening() {
task = keyAgreementTaskFactory.getTask(); task = keyAgreementTaskFactory.getTask();
gotRemotePayload = false; gotRemotePayload = false;
new Thread(new Runnable() { ioExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
task.listen(); task.listen();
} }
}).start(); });
} }
private void stopListening() { private void stopListening() {
new Thread(new Runnable() { ioExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
task.stopListening(); task.stopListening();
} }
}).start(); });
} }
private void openCamera() { private void openCamera() {

View File

@@ -9,9 +9,9 @@ import android.support.v7.preference.PreferenceManager;
import org.briarproject.android.AndroidComponent; import org.briarproject.android.AndroidComponent;
import org.briarproject.android.BriarActivity; import org.briarproject.android.BriarActivity;
import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.db.DatabaseConfig;
import org.briarproject.util.FileUtils;
import org.iilab.IilabEngineeringRSA2048Pin; import org.iilab.IilabEngineeringRSA2048Pin;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -23,6 +23,7 @@ import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder; import info.guardianproject.panic.PanicResponder;
import info.guardianproject.trustedintents.TrustedIntents; import info.guardianproject.trustedintents.TrustedIntents;
import static android.content.Intent.ACTION_DELETE;
import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_LOCK; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_LOCK;
import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_PURGE; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_PURGE;
import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_UNINSTALL; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_UNINSTALL;
@@ -31,7 +32,11 @@ public class PanicResponderActivity extends BriarActivity {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(PanicResponderActivity.class.getName()); Logger.getLogger(PanicResponderActivity.class.getName());
@Inject protected DatabaseConfig databaseConfig;
@Inject
protected DatabaseConfig databaseConfig;
@Inject
protected AndroidExecutor androidExecutor;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@@ -62,16 +67,14 @@ public class PanicResponderActivity extends BriarActivity {
deleteAllData(); deleteAllData();
LOG.info("Uninstalling..."); LOG.info("Uninstalling...");
Intent uninstall = new Intent(Intent.ACTION_DELETE); Intent uninstall = new Intent(ACTION_DELETE);
uninstall.setData( uninstall.setData(
Uri.parse("package:" + getPackageName())); Uri.parse("package:" + getPackageName()));
startActivity(uninstall); startActivity(uninstall);
} } else if (sharedPref.getBoolean(KEY_PURGE, false)) {
else if (sharedPref.getBoolean(KEY_PURGE, false)) {
LOG.info("Purging all data..."); LOG.info("Purging all data...");
deleteAllData(); deleteAllData();
} } else if (sharedPref.getBoolean(KEY_LOCK, true)) {
else if (sharedPref.getBoolean(KEY_LOCK, true)) {
LOG.info("Signing out..."); LOG.info("Signing out...");
signOut(true); signOut(true);
} }
@@ -107,8 +110,7 @@ public class PanicResponderActivity extends BriarActivity {
} }
private void deleteAllData() { private void deleteAllData() {
new Thread() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
clearSharedPrefs(); clearSharedPrefs();
// TODO somehow delete/shred the database more thoroughly // TODO somehow delete/shred the database more thoroughly
@@ -120,7 +122,6 @@ public class PanicResponderActivity extends BriarActivity {
LOG.info("Signing out..."); LOG.info("Signing out...");
signOut(true); signOut(true);
} }
}.start(); });
} }
} }

View File

@@ -48,17 +48,6 @@ public class AndroidUtils {
til.setError(null); til.setError(null);
} }
public static void enableBluetooth(final BluetoothAdapter adapter,
final boolean enable) {
new Thread() {
@Override
public void run() {
if (enable) adapter.enable();
else adapter.disable();
}
}.start();
}
public static String getBluetoothAddress(Context ctx, public static String getBluetoothAddress(Context ctx,
BluetoothAdapter adapter) { BluetoothAdapter adapter) {
// Return the adapter's address if it's valid and not fake // Return the adapter's address if it's valid and not fake

View File

@@ -1,46 +1,59 @@
package org.briarproject.system; package org.briarproject.system;
import android.app.Application;
import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message;
import org.briarproject.android.api.AndroidExecutor; import org.briarproject.android.api.AndroidExecutor;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.FutureTask; import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
class AndroidExecutorImpl implements AndroidExecutor { class AndroidExecutorImpl implements AndroidExecutor {
private final Handler handler; private final Runnable loop;
private final AtomicBoolean started = new AtomicBoolean(false);
private final CountDownLatch startLatch = new CountDownLatch(1);
AndroidExecutorImpl(Application app) { private volatile Handler handler = null;
Context ctx = app.getApplicationContext();
handler = new FutureTaskHandler(ctx.getMainLooper()); @Inject
AndroidExecutorImpl() {
loop = new Runnable() {
public void run() {
Looper.prepare();
handler = new Handler();
startLatch.countDown();
Looper.loop();
}
};
}
private void startIfNecessary() {
if (started.getAndSet(true)) return;
Thread t = new Thread(loop, "AndroidExecutor");
t.setDaemon(true);
t.start();
try {
startLatch.await();
} catch (InterruptedException e) {
throw new RejectedExecutionException(e);
}
} }
public <V> Future<V> submit(Callable<V> c) { public <V> Future<V> submit(Callable<V> c) {
Future<V> f = new FutureTask<V>(c); FutureTask<V> f = new FutureTask<>(c);
handler.sendMessage(Message.obtain(handler, 0, f)); execute(f);
return f; return f;
} }
public void execute(Runnable r) { public void execute(Runnable r) {
startIfNecessary();
handler.post(r); handler.post(r);
} }
private static class FutureTaskHandler extends Handler {
private FutureTaskHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message m) {
((FutureTask<?>) m.obj).run();
}
}
} }

View File

@@ -6,6 +6,8 @@ import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.api.system.LocationUtils; import org.briarproject.api.system.LocationUtils;
import org.briarproject.api.system.SeedProvider; import org.briarproject.api.system.SeedProvider;
import javax.inject.Singleton;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
@@ -23,7 +25,8 @@ public class AndroidSystemModule {
} }
@Provides @Provides
public AndroidExecutor providePlatformExecutor(Application app) { @Singleton
return new AndroidExecutorImpl(app); public AndroidExecutor provideAndroidExecutor() {
return new AndroidExecutorImpl();
} }
} }

View File

@@ -27,6 +27,7 @@ dependencyVerification {
'org.jmock:jmock:75d4bdaf636879f0215830c5e6ab99407069a625eaffde5d57b32d887b75dc14', 'org.jmock:jmock:75d4bdaf636879f0215830c5e6ab99407069a625eaffde5d57b32d887b75dc14',
'org.jmock:jmock-junit4:81e3fff46ed56738a6f3f5147525d1d85cda591ce5df007cc193e735cee31113', 'org.jmock:jmock-junit4:81e3fff46ed56738a6f3f5147525d1d85cda591ce5df007cc193e735cee31113',
'org.jmock:jmock-legacy:19c76059eb254775ba884fc8039bc5c7d1700dc68cc55ad3be5b405a2a8a1819', 'org.jmock:jmock-legacy:19c76059eb254775ba884fc8039bc5c7d1700dc68cc55ad3be5b405a2a8a1819',
'org.jmock:jmock-testjar:c3642147a5980771dde19d5f1d782d4790a7f9b1521bf9c8cd2b4c23f6384730',
'org.hamcrest:hamcrest-library:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c', 'org.hamcrest:hamcrest-library:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
'org.hamcrest:hamcrest-core:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9', 'org.hamcrest:hamcrest-core:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
'cglib:cglib-nodep:3a9ab1f5de15b49dedc7e96d35363c4c43a2b2cd42275f5d4731846042f3fcf2', 'cglib:cglib-nodep:3a9ab1f5de15b49dedc7e96d35363c4c43a2b2cd42275f5d4731846042f3fcf2',