From 2d5f5d4419aa0a1591a636e5e7090e873866fbd5 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 18 Sep 2018 20:21:57 -0300 Subject: [PATCH] WIP: FakeTestData proof-of-concept --- briar-android/build.gradle | 3 + briar-android/proguard-rules.txt | 2 + briar-android/proguard-test.txt | 1 + .../BriarTestComponentApplication.java | 2 +- .../briarproject/briar/android/UiTest.java | 5 +- .../briar/android/BriarUiTestComponent.java | 4 +- .../briar/android/FakeDataTestComponent.java | 95 ++++++++ .../briar/android/SetupDataTest.java | 206 +++++++++++++++++- .../briar/android/TestAppModule.java | 161 ++++++++++++++ .../briar/android/TestPluginConfigModule.java | 71 ++++++ .../briarproject/briar/android/AppModule.java | 66 +----- .../briar/android/PluginConfigModule.java | 81 +++++++ 12 files changed, 619 insertions(+), 78 deletions(-) create mode 100644 briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/FakeDataTestComponent.java create mode 100644 briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestAppModule.java create mode 100644 briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestPluginConfigModule.java create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/PluginConfigModule.java diff --git a/briar-android/build.gradle b/briar-android/build.gradle index a9054b908..340504dd4 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -140,6 +140,9 @@ dependencies { androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2" androidTestCompileOnly 'javax.annotation:jsr250-api:1.0' androidTestImplementation 'junit:junit:4.12' + + androidTestScreenshotImplementation project(path: ':bramble-api', configuration: 'testOutput') + androidTestScreenshotImplementation project(path: ':bramble-core', configuration: 'testOutput') androidTestScreenshotImplementation "tools.fastlane:screengrab:1.2.0" androidTestScreenshotImplementation "com.android.support.test.uiautomator:uiautomator-v18:2.1.3" } diff --git a/briar-android/proguard-rules.txt b/briar-android/proguard-rules.txt index f673f857a..1736388d5 100644 --- a/briar-android/proguard-rules.txt +++ b/briar-android/proguard-rules.txt @@ -28,3 +28,5 @@ # Emoji -keep class com.vanniktech.emoji.** + +-keepclasseswithmembers public class android.support.v7.widget.RecyclerView { *; } diff --git a/briar-android/proguard-test.txt b/briar-android/proguard-test.txt index 91b89ae58..a4997ace6 100644 --- a/briar-android/proguard-test.txt +++ b/briar-android/proguard-test.txt @@ -13,3 +13,4 @@ -dontwarn junit.** -dontwarn org.briarproject.briar.android.** +-dontwarn org.briarproject.bramble.** diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java index 156620b1d..2919555e0 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java @@ -8,7 +8,7 @@ public class BriarTestComponentApplication extends BriarApplicationImpl { @Override protected AndroidComponent createApplicationComponent() { AndroidComponent component = DaggerBriarUiTestComponent.builder() - .appModule(new AppModule(this)).build(); + .testAppModule(new TestAppModule(this)).build(); // We need to load the eager singletons directly after making the // dependency graphs BrambleCoreModule.initEagerSingletons(component); diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java index 7d9249cfb..e3332d1b3 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java @@ -21,6 +21,8 @@ public abstract class UiTest { getTargetContext().getString(R.string.screenshot_alice); protected static final String PASSWORD = "123456"; + protected final BriarUiTestComponent alice; + @Inject protected AccountManager accountManager; @Inject @@ -30,7 +32,8 @@ public abstract class UiTest { BriarTestComponentApplication app = (BriarTestComponentApplication) getTargetContext() .getApplicationContext(); - inject((BriarUiTestComponent) app.getApplicationComponent()); + alice = (BriarUiTestComponent) app.getApplicationComponent(); + inject(alice); } protected abstract void inject(BriarUiTestComponent component); diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java index 860166099..6507eddf3 100644 --- a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java @@ -13,13 +13,13 @@ import dagger.Component; @Singleton @Component(modules = { - AppModule.class, + TestAppModule.class, BriarCoreModule.class, BrambleAndroidModule.class, BriarAccountModule.class, BrambleCoreModule.class }) -public interface BriarUiTestComponent extends AndroidComponent { +public interface BriarUiTestComponent extends AndroidComponent, FakeDataTestComponent { void inject(SetupDataTest test); diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/FakeDataTestComponent.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/FakeDataTestComponent.java new file mode 100644 index 000000000..339969717 --- /dev/null +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/FakeDataTestComponent.java @@ -0,0 +1,95 @@ +package org.briarproject.briar.android; + +import org.briarproject.bramble.api.contact.ContactManager; +import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.identity.IdentityManager; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; +import org.briarproject.bramble.client.ClientModule; +import org.briarproject.bramble.contact.ContactModule; +import org.briarproject.bramble.crypto.CryptoModule; +import org.briarproject.bramble.data.DataModule; +import org.briarproject.bramble.db.DatabaseModule; +import org.briarproject.bramble.event.EventModule; +import org.briarproject.bramble.identity.IdentityModule; +import org.briarproject.bramble.lifecycle.LifecycleModule; +import org.briarproject.bramble.record.RecordModule; +import org.briarproject.bramble.sync.SyncModule; +import org.briarproject.bramble.system.SystemModule; +import org.briarproject.bramble.test.TestCryptoExecutorModule; +import org.briarproject.bramble.test.TestDatabaseModule; +import org.briarproject.bramble.test.TestSecureRandomModule; +import org.briarproject.bramble.transport.TransportModule; +import org.briarproject.bramble.versioning.VersioningModule; +import org.briarproject.briar.api.messaging.MessagingManager; +import org.briarproject.briar.api.messaging.PrivateMessageFactory; +import org.briarproject.briar.client.BriarClientModule; +import org.briarproject.briar.messaging.MessagingModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + TestCryptoExecutorModule.class, + TestDatabaseModule.class, + TestPluginConfigModule.class, + TestSecureRandomModule.class, + BriarClientModule.class, + ClientModule.class, + ContactModule.class, + CryptoModule.class, + DataModule.class, + DatabaseModule.class, + EventModule.class, + IdentityModule.class, + LifecycleModule.class, + MessagingModule.class, + RecordModule.class, + SyncModule.class, + SystemModule.class, + TransportModule.class, + VersioningModule.class +}) +interface FakeDataTestComponent { + + void inject(ContactModule.EagerSingletons init); + + void inject(IdentityModule.EagerSingletons init); + + void inject(LifecycleModule.EagerSingletons init); + + void inject(MessagingModule.EagerSingletons init); + + void inject(SyncModule.EagerSingletons init); + + void inject(SystemModule.EagerSingletons init); + + void inject(TransportModule.EagerSingletons init); + + void inject(VersioningModule.EagerSingletons init); + + LifecycleManager getLifecycleManager(); + + IdentityManager getIdentityManager(); + + ContactManager getContactManager(); + + MessagingManager getMessagingManager(); + + KeyManager getKeyManager(); + + PrivateMessageFactory getPrivateMessageFactory(); + + EventBus getEventBus(); + + StreamWriterFactory getStreamWriterFactory(); + + StreamReaderFactory getStreamReaderFactory(); + + SyncSessionFactory getSyncSessionFactory(); +} diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java index 53b5d308f..059de3d5c 100644 --- a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java @@ -5,23 +5,59 @@ import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiSelector; +import android.util.Log; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.contact.Contact; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.sync.GroupId; +import org.briarproject.bramble.api.sync.SyncSession; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriter; +import org.briarproject.bramble.api.transport.StreamWriterFactory; +import org.briarproject.bramble.contact.ContactModule; +import org.briarproject.bramble.identity.IdentityModule; +import org.briarproject.bramble.lifecycle.LifecycleModule; +import org.briarproject.bramble.sync.SyncModule; +import org.briarproject.bramble.system.SystemModule; +import org.briarproject.bramble.test.TestDatabaseModule; +import org.briarproject.bramble.test.TestUtils; +import org.briarproject.bramble.transport.TransportModule; +import org.briarproject.bramble.versioning.VersioningModule; import org.briarproject.briar.R; import org.briarproject.briar.android.login.OpenDatabaseActivity; import org.briarproject.briar.android.login.SetupActivity; +import org.briarproject.briar.android.navdrawer.NavDrawerActivity; +import org.briarproject.briar.api.messaging.MessagingManager; +import org.briarproject.briar.api.messaging.PrivateMessage; +import org.briarproject.briar.api.messaging.PrivateMessageFactory; +import org.briarproject.briar.messaging.MessagingModule; +import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; + +import static android.content.Context.MODE_PRIVATE; import static android.support.test.InstrumentationRegistry.getInstrumentation; import static android.support.test.InstrumentationRegistry.getTargetContext; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; import static android.support.test.espresso.intent.Intents.intended; import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; @@ -30,9 +66,17 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static android.support.test.runner.lifecycle.Stage.PAUSED; import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID; +import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; +import static org.briarproject.bramble.test.TestUtils.getSecretKey; +import static org.briarproject.briar.android.TestPluginConfigModule.MAX_LATENCY; +import static org.briarproject.briar.android.TestPluginConfigModule.TRANSPORT_ID; import static org.briarproject.briar.android.ViewActions.waitForActivity; import static org.briarproject.briar.android.ViewActions.waitUntilMatches; import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @RunWith(AndroidJUnit4.class) @@ -48,11 +92,49 @@ public class SetupDataTest extends ScreenshotTest { } }; + private FakeDataTestComponent bob; + private final File testDir = + getTargetContext().getDir("test", MODE_PRIVATE); + private final File bobDir = new File(testDir, "bob"); + private final SecretKey master = getSecretKey(); + @Override protected void inject(BriarUiTestComponent component) { component.inject(this); } + @Before + public void setUp() { + Log.e("TEST", testDir.getAbsolutePath()); + Log.e("TEST", "exists: " + testDir.exists()); + assertTrue(testDir.mkdirs()); + bob = DaggerFakeDataTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(bobDir)).build(); + injectEagerSingletons(bob); + Log.e("TEST", "built bob"); + } + + @After + public void tearDown() throws Exception { + // Stop the lifecycle manager + LifecycleManager lifecycleManager = bob.getLifecycleManager(); + lifecycleManager.stopServices(); + lifecycleManager.waitForShutdown(); + + TestUtils.deleteTestDirectory(testDir); + } + + private static void injectEagerSingletons(FakeDataTestComponent component) { + component.inject(new ContactModule.EagerSingletons()); + component.inject(new IdentityModule.EagerSingletons()); + component.inject(new LifecycleModule.EagerSingletons()); + component.inject(new MessagingModule.EagerSingletons()); + component.inject(new SyncModule.EagerSingletons()); + component.inject(new SystemModule.EagerSingletons()); + component.inject(new TransportModule.EagerSingletons()); + component.inject(new VersioningModule.EagerSingletons()); + } + @Test public void createAccount() throws Exception { // Enter username @@ -103,26 +185,132 @@ public class SetupDataTest extends ScreenshotTest { assertTrue(accountManager.hasDatabaseKey()); + // WIP below + + // wait for OpenDatabaseActivity to go away + onView(isRoot()) + .perform(waitUntilMatches( + allOf(withId(R.id.progressBar), not(isDisplayed())))); lifecycleManager.waitForStartup(); - createTestData(); + intended(hasComponent(NavDrawerActivity.class.getName())); // close expiry warning - onView(withId(R.id.expiryWarning)) - .perform(waitUntilMatches(isDisplayed())); onView(withId(R.id.expiryWarningClose)) .check(matches(isDisplayed())); onView(withId(R.id.expiryWarningClose)) .perform(click()); + + LocalAuthor aliceAuthor = alice.identityManager().getLocalAuthor(); + + LocalAuthor bobAuthor = bob.getIdentityManager().createLocalAuthor( + getTargetContext().getString(R.string.screenshot_bob)); + bob.getIdentityManager().registerLocalAuthor(bobAuthor); + // Start the lifecycle manager + bob.getLifecycleManager().startServices(getSecretKey()); + bob.getLifecycleManager().waitForStartup(); + long timestamp = clock.currentTimeMillis(); + // Bob adds Alice as a contact + ContactId aliceContactId = bob.getContactManager() + .addContact(aliceAuthor, bobAuthor.getId(), master, + timestamp, true, true, true); + // Alice adds Bob as a contact + ContactId bobContactId = alice.contactManager() + .addContact(bobAuthor, aliceAuthor.getId(), master, + timestamp, false, true, true); + + // TODO figure out how many messages + read(alice, bobContactId, write(bob, aliceContactId)); + read(bob, aliceContactId, write(alice, bobContactId)); + read(alice, bobContactId, write(bob, aliceContactId)); + read(bob, aliceContactId, write(alice, bobContactId)); + read(alice, bobContactId, write(bob, aliceContactId)); + read(bob, aliceContactId, write(alice, bobContactId)); + read(alice, bobContactId, write(bob, aliceContactId)); + read(bob, aliceContactId, write(alice, bobContactId)); + read(alice, bobContactId, write(bob, aliceContactId)); + read(bob, aliceContactId, write(alice, bobContactId)); + read(alice, bobContactId, write(bob, aliceContactId)); + read(bob, aliceContactId, write(alice, bobContactId)); + read(alice, bobContactId, write(bob, aliceContactId)); + + sendMessage(bob, aliceContactId); + read(alice, bobContactId, write(bob, aliceContactId)); + + onView(isRoot()) + .perform(waitUntilMatches(withText(bobAuthor.getName()))); + onView(withId(R.id.recyclerView)) + .perform(actionOnItemAtPosition(0, click())); + onView(isRoot()) + .perform(waitUntilMatches(withText(R.string.screenshot_message_2))); + + assertEquals(1, + alice.conversationManager().getGroupCount(bobContactId).getMsgCount()); + + Thread.sleep(5000); } - private void createTestData() { - try { - createTestDataExceptions(); - } catch (DbException | FormatException e) { - throw new AssertionError(e); - } + private void sendMessage(FakeDataTestComponent device, ContactId contactId) + throws Exception { + // Send Bob a message + MessagingManager messagingManager = device.getMessagingManager(); + GroupId groupId = messagingManager.getConversationId(contactId); + PrivateMessageFactory privateMessageFactory = + device.getPrivateMessageFactory(); + PrivateMessage message = privateMessageFactory.createPrivateMessage( + groupId, getMinutesAgo(3), + getTargetContext().getString(R.string.screenshot_message_2)); + messagingManager.addLocalMessage(message); } + private void read(FakeDataTestComponent device, + ContactId contactId, byte[] stream) throws Exception { + // Read and recognise the tag + ByteArrayInputStream in = new ByteArrayInputStream(stream); + byte[] tag = new byte[TAG_LENGTH]; + int read = in.read(tag); + assertEquals(tag.length, read); + KeyManager keyManager = device.getKeyManager(); + StreamContext ctx = keyManager.getStreamContext(TRANSPORT_ID, tag); + assertNotNull(ctx); + // Create a stream reader + StreamReaderFactory streamReaderFactory = + device.getStreamReaderFactory(); + InputStream streamReader = streamReaderFactory.createStreamReader( + in, ctx); + // Create an incoming sync session + SyncSessionFactory syncSessionFactory = device.getSyncSessionFactory(); + SyncSession session = syncSessionFactory.createIncomingSession( + contactId, streamReader); + // Read whatever needs to be read + session.run(); + streamReader.close(); + } + + private byte[] write(FakeDataTestComponent device, + ContactId contactId) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + // Get a stream context + KeyManager keyManager = device.getKeyManager(); + StreamContext ctx = keyManager.getStreamContext(contactId, + TRANSPORT_ID); + assertNotNull(ctx); + // Create a stream writer + StreamWriterFactory streamWriterFactory = + device.getStreamWriterFactory(); + StreamWriter streamWriter = + streamWriterFactory.createStreamWriter(out, ctx); + // Create an outgoing sync session + SyncSessionFactory syncSessionFactory = device.getSyncSessionFactory(); + SyncSession session = syncSessionFactory.createSimplexOutgoingSession( + contactId, MAX_LATENCY, streamWriter); + // Write whatever needs to be written + session.run(); + streamWriter.sendEndOfStream(); + // Return the contents of the stream + return out.toByteArray(); + } + + @Deprecated private void createTestDataExceptions() throws DbException, FormatException { String bobName = diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestAppModule.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestAppModule.java new file mode 100644 index 000000000..b00057b90 --- /dev/null +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestAppModule.java @@ -0,0 +1,161 @@ +package org.briarproject.briar.android; + +import android.app.Application; +import android.content.SharedPreferences; +import android.os.StrictMode; + +import com.vanniktech.emoji.RecentEmoji; + +import org.briarproject.bramble.api.crypto.CryptoComponent; +import org.briarproject.bramble.api.crypto.PublicKey; +import org.briarproject.bramble.api.db.DatabaseConfig; +import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.reporting.DevConfig; +import org.briarproject.bramble.util.AndroidUtils; +import org.briarproject.bramble.util.StringUtils; +import org.briarproject.briar.android.account.LockManagerImpl; +import org.briarproject.briar.api.android.AndroidNotificationManager; +import org.briarproject.briar.api.android.DozeWatchdog; +import org.briarproject.briar.api.android.LockManager; +import org.briarproject.briar.api.android.ScreenFilterMonitor; + +import java.io.File; +import java.security.GeneralSecurityException; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +import static android.content.Context.MODE_PRIVATE; +import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONION_ADDRESS; +import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX; + +@Module(includes = TestPluginConfigModule.class) +public class TestAppModule { + + static class EagerSingletons { + @Inject + AndroidNotificationManager androidNotificationManager; + @Inject + NetworkUsageLogger networkUsageLogger; + @Inject + DozeWatchdog dozeWatchdog; + @Inject + RecentEmoji recentEmoji; + } + + private final Application application; + + public TestAppModule(Application application) { + this.application = application; + } + + @Provides + @Singleton + Application providesApplication() { + return application; + } + + @Provides + @Singleton + DatabaseConfig provideDatabaseConfig(Application app) { + //FIXME: StrictMode + StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskReads(); + StrictMode.allowThreadDiskWrites(); + File dbDir = app.getApplicationContext().getDir("db", MODE_PRIVATE); + File keyDir = app.getApplicationContext().getDir("key", MODE_PRIVATE); + StrictMode.setThreadPolicy(tp); + return new AndroidDatabaseConfig(dbDir, keyDir); + } + + @Provides + @Singleton + DevConfig provideDevConfig(Application app, CryptoComponent crypto) { + @NotNullByDefault + DevConfig devConfig = new DevConfig() { + + @Override + public PublicKey getDevPublicKey() { + try { + return crypto.getMessageKeyParser().parsePublicKey( + StringUtils.fromHexString(DEV_PUBLIC_KEY_HEX)); + } catch (GeneralSecurityException e) { + throw new RuntimeException(e); + } + } + + @Override + public String getDevOnionAddress() { + return DEV_ONION_ADDRESS; + } + + @Override + public File getReportDir() { + return AndroidUtils.getReportDir(app.getApplicationContext()); + } + }; + return devConfig; + } + + @Provides + SharedPreferences provideSharedPreferences(Application app) { + // FIXME unify this with getDefaultSharedPreferences() + return app.getSharedPreferences("db", MODE_PRIVATE); + } + + @Provides + @Singleton + AndroidNotificationManager provideAndroidNotificationManager( + LifecycleManager lifecycleManager, EventBus eventBus, + AndroidNotificationManagerImpl notificationManager) { + lifecycleManager.registerService(notificationManager); + eventBus.addListener(notificationManager); + return notificationManager; + } + + @Provides + @Singleton + ScreenFilterMonitor provideScreenFilterMonitor( + LifecycleManager lifecycleManager, + ScreenFilterMonitorImpl screenFilterMonitor) { + lifecycleManager.registerService(screenFilterMonitor); + return screenFilterMonitor; + } + + @Provides + NetworkUsageLogger provideNetworkUsageLogger( + LifecycleManager lifecycleManager) { + NetworkUsageLogger networkUsageLogger = new NetworkUsageLogger(); + lifecycleManager.registerService(networkUsageLogger); + return networkUsageLogger; + } + + @Provides + @Singleton + DozeWatchdog provideDozeWatchdog(LifecycleManager lifecycleManager) { + DozeWatchdogImpl dozeWatchdog = new DozeWatchdogImpl(application); + lifecycleManager.registerService(dozeWatchdog); + return dozeWatchdog; + } + + @Provides + @Singleton + LockManager provideLockManager(LifecycleManager lifecycleManager, + EventBus eventBus, LockManagerImpl lockManager) { + lifecycleManager.registerService(lockManager); + eventBus.addListener(lockManager); + return lockManager; + } + + @Provides + @Singleton + RecentEmoji provideRecentEmoji(LifecycleManager lifecycleManager, + RecentEmojiImpl recentEmoji) { + lifecycleManager.registerClient(recentEmoji); + return recentEmoji; + } +} diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestPluginConfigModule.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestPluginConfigModule.java new file mode 100644 index 000000000..d73a4765b --- /dev/null +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/TestPluginConfigModule.java @@ -0,0 +1,71 @@ +package org.briarproject.briar.android; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.PluginConfig; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; +import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; +import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback; +import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; + +import java.util.Collection; + +import javax.annotation.Nullable; + +import dagger.Module; +import dagger.Provides; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.briarproject.bramble.test.TestUtils.getTransportId; + +@Module +public class TestPluginConfigModule { + + public static final TransportId TRANSPORT_ID = getTransportId(); + public static final int MAX_LATENCY = 2 * 60 * 1000; // 2 minutes + + @NotNullByDefault + private final SimplexPluginFactory simplex = new SimplexPluginFactory() { + + @Override + public TransportId getId() { + return TRANSPORT_ID; + } + + @Override + public int getMaxLatency() { + return MAX_LATENCY; + } + + @Override + @Nullable + public SimplexPlugin createPlugin(SimplexPluginCallback callback) { + return null; + } + }; + + @Provides + PluginConfig providePluginConfig() { + @NotNullByDefault + PluginConfig pluginConfig = new PluginConfig() { + + @Override + public Collection getDuplexFactories() { + return emptyList(); + } + + @Override + public Collection getSimplexFactories() { + return singletonList(simplex); + } + + @Override + public boolean shouldPoll() { + return false; + } + }; + return pluginConfig; + } + +} 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 606647958..89078d9dd 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 @@ -1,7 +1,6 @@ package org.briarproject.briar.android; import android.app.Application; -import android.content.Context; import android.content.SharedPreferences; import android.os.StrictMode; @@ -11,24 +10,9 @@ import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.event.EventBus; -import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.BackoffFactory; -import org.briarproject.bramble.api.plugin.PluginConfig; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; -import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; 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; -import org.briarproject.bramble.plugin.tor.AndroidTorPluginFactory; -import org.briarproject.bramble.plugin.tor.CircumventionProvider; import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.android.account.LockManagerImpl; @@ -39,25 +23,18 @@ import org.briarproject.briar.api.android.ScreenFilterMonitor; import java.io.File; import java.security.GeneralSecurityException; -import java.security.SecureRandom; -import java.util.Collection; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; import javax.inject.Singleton; -import javax.net.SocketFactory; import dagger.Module; import dagger.Provides; import static android.content.Context.MODE_PRIVATE; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONION_ADDRESS; import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX; -@Module +@Module(includes = PluginConfigModule.class) public class AppModule { static class EagerSingletons { @@ -95,47 +72,6 @@ public class AppModule { return new AndroidDatabaseConfig(dbDir, keyDir); } - @Provides - PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor, - @Scheduler ScheduledExecutorService scheduler, - AndroidExecutor androidExecutor, SecureRandom random, - SocketFactory torSocketFactory, BackoffFactory backoffFactory, - Application app, NetworkManager networkManager, - LocationUtils locationUtils, EventBus eventBus, - ResourceProvider resourceProvider, - CircumventionProvider circumventionProvider, Clock clock) { - Context appContext = app.getApplicationContext(); - DuplexPluginFactory bluetooth = - new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor, - appContext, random, eventBus, backoffFactory); - DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor, - scheduler, appContext, networkManager, locationUtils, eventBus, - torSocketFactory, backoffFactory, resourceProvider, - circumventionProvider, clock); - DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, - eventBus, backoffFactory, appContext); - Collection duplex = asList(bluetooth, tor, lan); - @NotNullByDefault - PluginConfig pluginConfig = new PluginConfig() { - - @Override - public Collection getDuplexFactories() { - return duplex; - } - - @Override - public Collection getSimplexFactories() { - return emptyList(); - } - - @Override - public boolean shouldPoll() { - return true; - } - }; - return pluginConfig; - } - @Provides @Singleton DevConfig provideDevConfig(Application app, CryptoComponent crypto) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/PluginConfigModule.java b/briar-android/src/main/java/org/briarproject/briar/android/PluginConfigModule.java new file mode 100644 index 000000000..b7c169064 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/PluginConfigModule.java @@ -0,0 +1,81 @@ +package org.briarproject.briar.android; + +import android.app.Application; +import android.content.Context; + +import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.network.NetworkManager; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginConfig; +import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; +import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; +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; +import org.briarproject.bramble.plugin.tor.AndroidTorPluginFactory; +import org.briarproject.bramble.plugin.tor.CircumventionProvider; + +import java.security.SecureRandom; +import java.util.Collection; +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; + +import javax.net.SocketFactory; + +import dagger.Module; +import dagger.Provides; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; + +@Module +public class PluginConfigModule { + + @Provides + PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor, + @Scheduler ScheduledExecutorService scheduler, + AndroidExecutor androidExecutor, SecureRandom random, + SocketFactory torSocketFactory, BackoffFactory backoffFactory, + Application app, NetworkManager networkManager, + LocationUtils locationUtils, EventBus eventBus, + ResourceProvider resourceProvider, + CircumventionProvider circumventionProvider, Clock clock) { + Context appContext = app.getApplicationContext(); + DuplexPluginFactory bluetooth = + new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor, + appContext, random, eventBus, backoffFactory); + DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor, + scheduler, appContext, networkManager, locationUtils, eventBus, + torSocketFactory, backoffFactory, resourceProvider, + circumventionProvider, clock); + DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, + eventBus, backoffFactory, appContext); + Collection duplex = asList(bluetooth, tor, lan); + @NotNullByDefault + PluginConfig pluginConfig = new PluginConfig() { + + @Override + public Collection getDuplexFactories() { + return duplex; + } + + @Override + public Collection getSimplexFactories() { + return emptyList(); + } + + @Override + public boolean shouldPoll() { + return true; + } + }; + return pluginConfig; + } + +}