From 7b552bde1eb25d6cc69abbefaf14382eeae8909a Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Thu, 31 Mar 2016 00:17:05 +0200 Subject: [PATCH 01/19] phase 1: Activities and Fragments --- .../res/layout/fragment_dashboard.xml | 10 --- .../android/ActivityComponent.java | 76 +++++++++++++++++++ .../briarproject/android/ActivityModule.java | 71 +++++++++++++++++ .../briarproject/android/ActivityScope.java | 11 +++ .../android/AndroidComponent.java | 60 ++++++++++++--- .../briarproject/android/BaseActivity.java | 21 ++++- .../android/BriarFragmentActivity.java | 8 +- .../android/NavDrawerActivity.java | 18 ++--- .../android/PasswordActivity.java | 2 +- .../android/SettingsActivity.java | 2 +- .../briarproject/android/SetupActivity.java | 2 +- .../android/SplashScreenActivity.java | 2 +- .../android/StartupFailureActivity.java | 2 +- .../android/contact/ContactListFragment.java | 21 +++-- .../android/contact/ConversationActivity.java | 3 +- .../forum/AvailableForumsActivity.java | 3 +- .../android/forum/CreateForumActivity.java | 4 +- .../android/forum/ForumActivity.java | 3 +- .../android/forum/ForumListFragment.java | 16 +++- .../android/forum/ReadForumPostActivity.java | 3 +- .../android/forum/ShareForumActivity.java | 1 + .../android/forum/WriteForumPostActivity.java | 3 +- .../android/fragment/BaseEventFragment.java | 3 - .../android/fragment/BaseFragment.java | 11 ++- .../android/fragment/DashboardFragment.java | 67 ---------------- .../identity/CreateIdentityActivity.java | 3 +- .../invitation/AddContactActivity.java | 3 +- .../android/panic/ExitActivity.java | 3 +- .../panic/PanicPreferencesActivity.java | 3 +- .../android/panic/PanicResponderActivity.java | 3 +- .../briarproject/android/sdk/BriarHelper.java | 4 + .../android/sdk/BriarHelperImp.java | 13 ++++ 32 files changed, 312 insertions(+), 143 deletions(-) delete mode 100644 briar-android/res/layout/fragment_dashboard.xml create mode 100644 briar-android/src/org/briarproject/android/ActivityComponent.java create mode 100644 briar-android/src/org/briarproject/android/ActivityModule.java create mode 100644 briar-android/src/org/briarproject/android/ActivityScope.java delete mode 100644 briar-android/src/org/briarproject/android/fragment/DashboardFragment.java create mode 100644 briar-android/src/org/briarproject/android/sdk/BriarHelper.java create mode 100644 briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java diff --git a/briar-android/res/layout/fragment_dashboard.xml b/briar-android/res/layout/fragment_dashboard.xml deleted file mode 100644 index 1d73431f5..000000000 --- a/briar-android/res/layout/fragment_dashboard.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java new file mode 100644 index 000000000..4032d7bd7 --- /dev/null +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -0,0 +1,76 @@ +package org.briarproject.android; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.Fragment; + +import org.briarproject.android.contact.ContactListFragment; +import org.briarproject.android.contact.ConversationActivity; +import org.briarproject.android.forum.AvailableForumsActivity; +import org.briarproject.android.forum.CreateForumActivity; +import org.briarproject.android.forum.ForumActivity; +import org.briarproject.android.forum.ForumListFragment; +import org.briarproject.android.forum.ReadForumPostActivity; +import org.briarproject.android.forum.ShareForumActivity; +import org.briarproject.android.forum.WriteForumPostActivity; +import org.briarproject.android.fragment.BaseFragment; +import org.briarproject.android.identity.CreateIdentityActivity; +import org.briarproject.android.invitation.AddContactActivity; +import org.briarproject.android.panic.PanicPreferencesActivity; +import org.briarproject.android.panic.PanicResponderActivity; + +import javax.inject.Named; + +import dagger.Component; +import dagger.Provides; + +@ActivityScope +@Component(modules = ActivityModule.class, + dependencies = AndroidComponent.class) +public interface ActivityComponent { + Activity activity(); + + void inject(SplashScreenActivity activity); + + void inject(SetupActivity activity); + + void inject(NavDrawerActivity activity); + + void inject(PasswordActivity activity); + + void inject(PanicResponderActivity activity); + + void inject(PanicPreferencesActivity activity); + + void inject(AddContactActivity activity); + + void inject(ConversationActivity activity); + + void inject(CreateIdentityActivity activity); + + void inject(TestingActivity activity); + + void inject(AvailableForumsActivity activity); + + void inject(WriteForumPostActivity activity); + + void inject(CreateForumActivity activity); + + void inject(ShareForumActivity activity); + + void inject(ReadForumPostActivity activity); + + void inject(ForumActivity activity); + + void inject(SettingsActivity activity); + + @Named("ContactListFragment") + BaseFragment newContactListFragment(); + + @Named("ForumListFragment") + BaseFragment newForumListFragment(); + +// void inject(ContactListFragment fragment); + +// void inject(ForumListFragment fragment); +} diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java new file mode 100644 index 000000000..8c1989a71 --- /dev/null +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -0,0 +1,71 @@ +package org.briarproject.android; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v4.app.Fragment; + +import org.briarproject.android.contact.ContactListFragment; +import org.briarproject.android.forum.ForumListFragment; +import org.briarproject.android.fragment.BaseFragment; +import org.briarproject.android.sdk.BriarHelper; +import org.briarproject.android.sdk.BriarHelperImp; + +import java.util.logging.Logger; + +import javax.inject.Named; + +import dagger.Module; +import dagger.Provides; + +@Module +public class ActivityModule { + + private final BaseActivity activity; + + public ActivityModule(BaseActivity activity) { + this.activity = activity; + } + + @ActivityScope + @Provides + Activity providesActivity() { + return activity; + } + + @ActivityScope + @Provides + BriarHelper provideBriarHelper(BriarHelperImp briarHelperImp) { + return briarHelperImp; + } + + @ActivityScope + Logger provideLogger(Activity activity) { + return Logger.getLogger(activity.getClass().getName()); + } + + @ActivityScope + @Provides + SharedPreferences provideSharedPreferences(Activity activity) { + return activity.getSharedPreferences("db", Context.MODE_PRIVATE); + } + + + @Provides + @Named("ForumListFragment") + BaseFragment provideForumListFragment( + ForumListFragment forumListFragment) { + forumListFragment.setArguments(new Bundle()); + return forumListFragment; + } + + @Provides + @Named("ContactListFragment") + BaseFragment provideContactListFragment( + ContactListFragment contactListFragment) { + contactListFragment.setArguments(new Bundle()); + return contactListFragment; + } + +} diff --git a/briar-android/src/org/briarproject/android/ActivityScope.java b/briar-android/src/org/briarproject/android/ActivityScope.java new file mode 100644 index 000000000..a6ceb30ab --- /dev/null +++ b/briar-android/src/org/briarproject/android/ActivityScope.java @@ -0,0 +1,11 @@ +package org.briarproject.android; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.inject.Scope; + +@Scope +@Retention(RetentionPolicy.RUNTIME) +public @interface ActivityScope { +} diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 8b2ac951a..8766c4324 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -2,6 +2,8 @@ package org.briarproject.android; import org.briarproject.CoreEagerSingletons; import org.briarproject.CoreModule; +import org.briarproject.android.api.AndroidNotificationManager; +import org.briarproject.android.api.ReferenceManager; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; import org.briarproject.android.forum.AvailableForumsActivity; @@ -23,10 +25,31 @@ import org.briarproject.android.keyagreement.KeyAgreementActivity; import org.briarproject.android.keyagreement.ShowQrCodeFragment; import org.briarproject.android.panic.PanicPreferencesActivity; import org.briarproject.android.panic.PanicResponderActivity; -import org.briarproject.android.util.BriarReportSender; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.CryptoExecutor; +import org.briarproject.api.crypto.PasswordStrengthEstimator; +import org.briarproject.api.db.DatabaseConfig; +import org.briarproject.api.db.DatabaseExecutor; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.forum.ForumManager; +import org.briarproject.api.forum.ForumPostFactory; +import org.briarproject.api.forum.ForumSharingManager; +import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.invitation.InvitationTaskFactory; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.messaging.MessagingManager; +import org.briarproject.api.messaging.PrivateMessageFactory; +import org.briarproject.api.plugins.ConnectionRegistry; +import org.briarproject.api.plugins.PluginManager; +import org.briarproject.api.properties.TransportPropertyManager; +import org.briarproject.api.settings.SettingsManager; import org.briarproject.plugins.AndroidPluginsModule; import org.briarproject.system.AndroidSystemModule; +import java.util.concurrent.Executor; + import javax.inject.Singleton; import dagger.Component; @@ -39,16 +62,29 @@ import dagger.Component; AndroidSystemModule.class }) public interface AndroidComponent extends CoreEagerSingletons { - - void inject(DevReportActivity devReportActivity); - - void inject(SplashScreenActivity activity); - - void inject(SetupActivity activity); - - void inject(NavDrawerActivity activity); - - void inject(PasswordActivity activity); + // Exposed objects + @CryptoExecutor Executor cryptoExecutor(); + PasswordStrengthEstimator passwordStrengthIndicator(); + CryptoComponent cryptoComponent(); + DatabaseConfig databaseConfig(); + AuthorFactory authFactory(); + ReferenceManager referenceMangager(); + @DatabaseExecutor Executor databaseExecutor(); + LifecycleManager lifecycleManager(); + IdentityManager identityManager(); + PluginManager pluginManager(); + EventBus eventBus(); + InvitationTaskFactory invitationTaskFactory(); + AndroidNotificationManager androidNotificationManager(); + ConnectionRegistry connectionRegistry(); + ContactManager contactManager(); + MessagingManager messagingManager(); + PrivateMessageFactory privateMessageFactory(); + TransportPropertyManager transportPropertyManager(); + ForumManager forumManager(); + ForumSharingManager forumSharingManager(); + ForumPostFactory forumPostFactory(); + SettingsManager settingsManager(); void inject(BriarService activity); @@ -64,6 +100,8 @@ public interface AndroidComponent extends CoreEagerSingletons { void inject(CreateIdentityActivity activity); + void inject(TestingActivity activity); + void inject(AvailableForumsActivity activity); void inject(WriteForumPostActivity activity); diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 1a93a006e..9e602c9e5 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -1,12 +1,16 @@ package org.briarproject.android; +import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.inputmethod.InputMethodManager; +import javax.inject.Inject; + import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; @@ -17,17 +21,28 @@ public abstract class BaseActivity extends AppCompatActivity { public final static String PREF_DB_KEY = "key"; public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; + protected ActivityComponent activityComponent; + + // TODO Shared prefs + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); - BriarApplication application = (BriarApplication) getApplication(); - injectActivity(application.getApplicationComponent()); + AndroidComponent applicationComponent = + ((BriarApplication) getApplication()).getApplicationComponent(); + + activityComponent = DaggerActivityComponent.builder() + .androidComponent(applicationComponent) + .activityModule(new ActivityModule(this)) + .build(); + + injectActivity(activityComponent); } - public abstract void injectActivity(AndroidComponent component); + public abstract void injectActivity(ActivityComponent component); private SharedPreferences getSharedPrefs() { return getSharedPreferences(PREFS_NAME, MODE_PRIVATE); diff --git a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java index 766a11e33..28f992326 100644 --- a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java +++ b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java @@ -10,7 +10,6 @@ import org.briarproject.R; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.forum.ForumListFragment; import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.android.fragment.DashboardFragment; /** * This class should be extended by classes that wish to utilise fragments in @@ -23,9 +22,7 @@ public abstract class BriarFragmentActivity extends BriarActivity { if (actionBar == null) return; - if (fragmentTag.equals(DashboardFragment.TAG)) { - actionBar.setTitle(R.string.dashboard_toolbar_header); - } else if (fragmentTag.equals(ContactListFragment.TAG)) { + if (fragmentTag.equals(ContactListFragment.TAG)) { actionBar.setTitle(R.string.contacts_toolbar_header); } else if (fragmentTag.equals(ForumListFragment.TAG)) { actionBar.setTitle(R.string.forums_toolbar_header); @@ -52,7 +49,8 @@ public abstract class BriarFragmentActivity extends BriarActivity { exiting. This models the typical Google navigation behaviour such as in Gmail/Inbox. */ - startFragment(ContactListFragment.newInstance()); + // FIXME +// startFragment(ContactListFragment.newInstance()); } else { super.onBackPressed(); diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index 367bb12ba..af98c88fa 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -68,9 +68,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements private Toolbar toolbar; private DrawerLayout drawerLayout; - private Button contactButton; - private Button forumsButton; - private Button settingsButton; private GridView transportsView; private TextView progressTitle; private ViewGroup progressViewGroup; @@ -85,14 +82,14 @@ public class NavDrawerActivity extends BriarFragmentActivity implements checkAuthorHandle(intent); clearBackStack(); if (intent.getBooleanExtra(INTENT_FORUMS, false)) - startFragment(ForumListFragment.newInstance()); + startFragment(activityComponent.newForumListFragment()); else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) - startFragment(ContactListFragment.newInstance()); + startFragment(activityComponent.newContactListFragment()); } } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } @@ -108,9 +105,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements toolbar = (Toolbar)findViewById(R.id.toolbar); drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); - contactButton = (Button)findViewById(R.id.nav_btn_contacts); - forumsButton = (Button)findViewById(R.id.nav_btn_forums); - settingsButton = (Button)findViewById(R.id.nav_btn_settings); transportsView = (GridView)findViewById(R.id.transportsView); progressTitle = (TextView)findViewById(R.id.title_progress_bar); progressViewGroup = (ViewGroup)findViewById(R.id.container_progress); @@ -133,7 +127,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements } }; drawerLayout.setDrawerListener(drawerToggle); - if (state == null) startFragment(ContactListFragment.newInstance()); + if (state == null) startFragment(activityComponent.newContactListFragment()); checkAuthorHandle(getIntent()); initializeTransports(getLayoutInflater()); @@ -217,10 +211,10 @@ public class NavDrawerActivity extends BriarFragmentActivity implements clearBackStack(); switch (view.getId()) { case R.id.nav_btn_contacts: - startFragment(ContactListFragment.newInstance()); + startFragment(activityComponent.newContactListFragment()); break; case R.id.nav_btn_forums: - startFragment(ForumListFragment.newInstance()); + startFragment(activityComponent.newForumListFragment()); break; case R.id.nav_btn_settings: startActivity(new Intent(this, SettingsActivity.class)); diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java index 33f14f206..41c2459de 100644 --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -90,7 +90,7 @@ public class PasswordActivity extends BaseActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/SettingsActivity.java b/briar-android/src/org/briarproject/android/SettingsActivity.java index e270578a7..bb783a065 100644 --- a/briar-android/src/org/briarproject/android/SettingsActivity.java +++ b/briar-android/src/org/briarproject/android/SettingsActivity.java @@ -34,7 +34,7 @@ public class SettingsActivity extends BriarActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index 6caf20e5a..1ddb6dd58 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -109,7 +109,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/SplashScreenActivity.java b/briar-android/src/org/briarproject/android/SplashScreenActivity.java index 0ba0d47b9..9a736d916 100644 --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -56,7 +56,7 @@ public class SplashScreenActivity extends BaseActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/StartupFailureActivity.java b/briar-android/src/org/briarproject/android/StartupFailureActivity.java index 5180c33c2..b25836939 100644 --- a/briar-android/src/org/briarproject/android/StartupFailureActivity.java +++ b/briar-android/src/org/briarproject/android/StartupFailureActivity.java @@ -20,7 +20,7 @@ public class StartupFailureActivity extends BaseActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index 82137d92a..62e1e349f 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -13,12 +13,14 @@ import android.view.ViewGroup; import org.briarproject.R; import org.briarproject.android.AndroidComponent; +import org.briarproject.android.BriarApplication; import org.briarproject.android.fragment.BaseEventFragment; import org.briarproject.android.keyagreement.KeyAgreementActivity; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.db.NoSuchContactException; import org.briarproject.api.event.ContactAddedEvent; @@ -28,6 +30,7 @@ import org.briarproject.api.event.ContactRemovedEvent; import org.briarproject.api.event.ContactStatusChangedEvent; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; +import org.briarproject.api.event.EventListener; import org.briarproject.api.event.MessageValidatedEvent; import org.briarproject.api.forum.ForumInvitationMessage; import org.briarproject.api.forum.ForumSharingManager; @@ -52,13 +55,14 @@ import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.android.BriarActivity.GROUP_ID; -public class ContactListFragment extends BaseEventFragment { +public class ContactListFragment extends BaseFragment implements EventListener { private static final Logger LOG = Logger.getLogger(ContactListFragment.class.getName()); public final static String TAG = "ContactListFragment"; + /* public static ContactListFragment newInstance() { Bundle args = new Bundle(); @@ -67,6 +71,7 @@ public class ContactListFragment extends BaseEventFragment { fragment.setArguments(args); return fragment; } + */ @Override public String getUniqueTag() { @@ -92,9 +97,14 @@ public class ContactListFragment extends BaseEventFragment { @Inject protected volatile EventBus eventBus; - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); + +// @Override +// public void injectActivity(AndroidComponent component) { +// component.inject(this); +// } + @Inject + public ContactListFragment() { + } @Nullable @@ -155,7 +165,7 @@ public class ContactListFragment extends BaseEventFragment { @Override public void onResume() { super.onResume(); - + eventBus.addListener(this); loadContacts(); } @@ -163,6 +173,7 @@ public class ContactListFragment extends BaseEventFragment { public void onPause() { super.onPause(); adapter.clear(); + eventBus.removeListener(this); } private void loadContacts() { diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index 5a62bef1f..045c58e7f 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -23,6 +23,7 @@ import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.AndroidNotificationManager; @@ -157,7 +158,7 @@ public class ConversationActivity extends BriarActivity } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java b/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java index dd7a722e7..f1e1a7b9e 100644 --- a/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java +++ b/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java @@ -5,6 +5,7 @@ import android.support.v7.widget.LinearLayoutManager; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.util.BriarRecyclerView; @@ -61,7 +62,7 @@ public class AvailableForumsActivity extends BriarActivity } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java b/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java index a35834c93..fbb10650e 100644 --- a/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java @@ -15,7 +15,7 @@ import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; import org.briarproject.R; -import org.briarproject.android.AndroidComponent; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; import org.briarproject.api.db.DbException; import org.briarproject.api.forum.Forum; @@ -86,7 +86,7 @@ public class CreateForumActivity extends BriarActivity } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index 9a2ec711d..1ea92c3c0 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -19,6 +19,7 @@ import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.AndroidNotificationManager; @@ -127,7 +128,7 @@ public class ForumActivity extends BriarActivity implements EventListener, } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index 4aa853bd7..a6ba633f7 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -14,6 +14,7 @@ import android.view.View; import android.view.ViewGroup; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.fragment.BaseEventFragment; import org.briarproject.android.util.BriarRecyclerView; @@ -50,6 +51,7 @@ public class ForumListFragment extends BaseEventFragment implements private static final Logger LOG = Logger.getLogger(ForumListFragment.class.getName()); + /* public static ForumListFragment newInstance() { Bundle args = new Bundle(); @@ -58,6 +60,7 @@ public class ForumListFragment extends BaseEventFragment implements fragment.setArguments(args); return fragment; } + */ private BriarRecyclerView list; private ForumListAdapter adapter; @@ -67,6 +70,11 @@ public class ForumListFragment extends BaseEventFragment implements @Inject protected volatile ForumManager forumManager; @Inject protected volatile ForumSharingManager forumSharingManager; + @Inject + public ForumListFragment() { + + } + @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -99,10 +107,10 @@ public class ForumListFragment extends BaseEventFragment implements return TAG; } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } +// @Override +// public void injectActivity(ActivityComponent component) { +// component.inject(this); +// } @Override public void onResume() { diff --git a/briar-android/src/org/briarproject/android/forum/ReadForumPostActivity.java b/briar-android/src/org/briarproject/android/forum/ReadForumPostActivity.java index f320ed6ef..cfc80ace2 100644 --- a/briar-android/src/org/briarproject/android/forum/ReadForumPostActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ReadForumPostActivity.java @@ -12,6 +12,7 @@ import android.widget.ScrollView; import android.widget.TextView; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.util.AuthorView; @@ -168,7 +169,7 @@ implements OnClickListener { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java b/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java index 820e25666..75a0bc676 100644 --- a/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.view.View; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.fragment.BaseFragment; diff --git a/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java b/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java index 4087115e0..d2185aa46 100644 --- a/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java +++ b/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java @@ -16,6 +16,7 @@ import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.identity.CreateIdentityActivity; @@ -161,7 +162,7 @@ implements OnItemSelectedListener, OnClickListener { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/fragment/BaseEventFragment.java b/briar-android/src/org/briarproject/android/fragment/BaseEventFragment.java index f353b6e08..69ceab43a 100644 --- a/briar-android/src/org/briarproject/android/fragment/BaseEventFragment.java +++ b/briar-android/src/org/briarproject/android/fragment/BaseEventFragment.java @@ -5,9 +5,6 @@ import org.briarproject.api.event.EventListener; import javax.inject.Inject; -/** - * Created by Ernir Erlingsson (ernir@ymirmobile.com) on 8.1.2016. - */ public abstract class BaseEventFragment extends BaseFragment implements EventListener { diff --git a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java index 494f93c2d..47f98f366 100644 --- a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java +++ b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java @@ -28,15 +28,13 @@ public abstract class BaseFragment extends Fragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - BriarApplication application = - (BriarApplication) getActivity().getApplication(); - injectActivity(application.getApplicationComponent()); +// AndroidComponent component = +// ((BriarApplication) getActivity().getApplication()) +// .getApplicationComponent(); +// injectActivity(component); } - public abstract void injectActivity(AndroidComponent component); - public interface BaseFragmentListener { - void showLoadingScreen(boolean isBlocking, int stringId); void hideLoadingScreen(); @@ -45,4 +43,5 @@ public abstract class BaseFragment extends Fragment { void runOnDbThread(Runnable runnable); } + } diff --git a/briar-android/src/org/briarproject/android/fragment/DashboardFragment.java b/briar-android/src/org/briarproject/android/fragment/DashboardFragment.java deleted file mode 100644 index f98c16ab0..000000000 --- a/briar-android/src/org/briarproject/android/fragment/DashboardFragment.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.briarproject.android.fragment; - - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.GridView; - -import org.briarproject.R; -import org.briarproject.android.AndroidComponent; -import org.briarproject.api.event.Event; -import org.briarproject.api.plugins.PluginManager; - -import java.util.logging.Logger; - -import javax.inject.Inject; - -public class DashboardFragment extends BaseEventFragment { - - public final static String TAG = "DashboardFragment"; - - private static final Logger LOG = - Logger.getLogger(DashboardFragment.class.getName()); - - @Inject - protected PluginManager pluginManager; - - public static DashboardFragment newInstance() { - - Bundle args = new Bundle(); - - DashboardFragment fragment = new DashboardFragment(); - fragment.setArguments(args); - return fragment; - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View contentView = - inflater.inflate(R.layout.fragment_dashboard, container, false); - return contentView; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - } - - @Override - public String getUniqueTag() { - return TAG; - } - - @Override - public void injectActivity(AndroidComponent component) { - - } - - @Override - public void eventOccurred(Event e) { - - } -} diff --git a/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java b/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java index d1d37f9fa..b95ca581f 100644 --- a/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java +++ b/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java @@ -14,6 +14,7 @@ import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.util.LayoutUtils; @@ -114,7 +115,7 @@ implements OnEditorActionListener, OnClickListener { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java index 2faf5f619..66a5c63ea 100644 --- a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java +++ b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.ReferenceManager; @@ -145,7 +146,7 @@ implements InvitationListener { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/panic/ExitActivity.java b/briar-android/src/org/briarproject/android/panic/ExitActivity.java index 4417c1fe8..7e8540201 100644 --- a/briar-android/src/org/briarproject/android/panic/ExitActivity.java +++ b/briar-android/src/org/briarproject/android/panic/ExitActivity.java @@ -3,6 +3,7 @@ package org.briarproject.android.panic; import android.os.Build; import android.os.Bundle; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BaseActivity; @@ -23,7 +24,7 @@ public class ExitActivity extends BaseActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { } } \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java b/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java index c25461c34..f0645f3c2 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java @@ -5,6 +5,7 @@ import android.support.v7.app.ActionBar; import android.view.MenuItem; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; @@ -24,7 +25,7 @@ public class PanicPreferencesActivity extends BriarActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java index 87ba49e70..c57e44d03 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -7,6 +7,7 @@ import android.os.Build; import android.os.Bundle; import android.support.v7.preference.PreferenceManager; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.AndroidExecutor; @@ -105,7 +106,7 @@ public class PanicResponderActivity extends BriarActivity { } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } diff --git a/briar-android/src/org/briarproject/android/sdk/BriarHelper.java b/briar-android/src/org/briarproject/android/sdk/BriarHelper.java new file mode 100644 index 000000000..1cb8993ae --- /dev/null +++ b/briar-android/src/org/briarproject/android/sdk/BriarHelper.java @@ -0,0 +1,4 @@ +package org.briarproject.android.sdk; + +public interface BriarHelper { +} diff --git a/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java b/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java new file mode 100644 index 000000000..c83c33ac8 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java @@ -0,0 +1,13 @@ +package org.briarproject.android.sdk; + +import javax.inject.Inject; + +public class BriarHelperImp implements BriarHelper { + + + + @Inject + public BriarHelperImp() { + + } +} From a9de12520da337d47c703969b339afca0a7b824b Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 1 Apr 2016 14:34:41 +0200 Subject: [PATCH 02/19] phase 2: helpers and app bus --- .../briarproject/android/ActivityModule.java | 25 ++-- .../android/AndroidComponent.java | 3 + .../briarproject/android/BaseActivity.java | 60 ++++----- .../android/NavDrawerActivity.java | 6 +- .../android/PasswordActivity.java | 87 +++++-------- .../briarproject/android/SetupActivity.java | 62 +++------ .../android/SplashScreenActivity.java | 12 +- .../briarproject/android/event/AppBus.java | 6 + .../briarproject/android/event/AppBusImp.java | 25 ++++ .../android/event/ErrorEvent.java | 10 ++ .../event/LocalAuthorCreatedEvent.java | 16 +++ .../android/event/PasswordValidateEvent.java | 16 +++ .../android/helper/ConfigHelper.java | 9 ++ .../android/helper/ConfigHelperImp.java | 41 ++++++ .../android/helper/PasswordHelper.java | 5 + .../android/helper/PasswordHelperImp.java | 70 +++++++++++ .../android/helper/SetupHelper.java | 6 + .../android/helper/SetupHelperImp.java | 119 ++++++++++++++++++ .../android/panic/PanicResponderActivity.java | 11 +- .../briarproject/android/sdk/BriarHelper.java | 4 - .../android/sdk/BriarHelperImp.java | 13 -- 21 files changed, 435 insertions(+), 171 deletions(-) create mode 100644 briar-android/src/org/briarproject/android/event/AppBus.java create mode 100644 briar-android/src/org/briarproject/android/event/AppBusImp.java create mode 100644 briar-android/src/org/briarproject/android/event/ErrorEvent.java create mode 100644 briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java create mode 100644 briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java create mode 100644 briar-android/src/org/briarproject/android/helper/ConfigHelper.java create mode 100644 briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java create mode 100644 briar-android/src/org/briarproject/android/helper/PasswordHelper.java create mode 100644 briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java create mode 100644 briar-android/src/org/briarproject/android/helper/SetupHelper.java create mode 100644 briar-android/src/org/briarproject/android/helper/SetupHelperImp.java delete mode 100644 briar-android/src/org/briarproject/android/sdk/BriarHelper.java delete mode 100644 briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 8c1989a71..3ae6e004c 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -4,15 +4,16 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; -import android.support.v4.app.Fragment; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.forum.ForumListFragment; import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.android.sdk.BriarHelper; -import org.briarproject.android.sdk.BriarHelperImp; - -import java.util.logging.Logger; +import org.briarproject.android.helper.PasswordHelper; +import org.briarproject.android.helper.PasswordHelperImp; +import org.briarproject.android.helper.SetupHelper; +import org.briarproject.android.helper.SetupHelperImp; +import org.briarproject.android.helper.ConfigHelper; +import org.briarproject.android.helper.ConfigHelperImp; import javax.inject.Named; @@ -36,13 +37,14 @@ public class ActivityModule { @ActivityScope @Provides - BriarHelper provideBriarHelper(BriarHelperImp briarHelperImp) { - return briarHelperImp; + SetupHelper provideSetupHelper(SetupHelperImp setupHelperImp) { + return setupHelperImp; } @ActivityScope - Logger provideLogger(Activity activity) { - return Logger.getLogger(activity.getClass().getName()); + @Provides + ConfigHelper provideConfigHelper(ConfigHelperImp configHelperImp) { + return configHelperImp; } @ActivityScope @@ -51,6 +53,11 @@ public class ActivityModule { return activity.getSharedPreferences("db", Context.MODE_PRIVATE); } + @ActivityScope + @Provides + PasswordHelper providePasswordHelper(PasswordHelperImp passwordHelperImp) { + return passwordHelperImp; + } @Provides @Named("ForumListFragment") diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 8766c4324..02469114f 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -6,6 +6,7 @@ import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.api.ReferenceManager; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; +import org.briarproject.android.event.AppBus; import org.briarproject.android.forum.AvailableForumsActivity; import org.briarproject.android.forum.ContactSelectorFragment; import org.briarproject.android.forum.CreateForumActivity; @@ -50,6 +51,7 @@ import org.briarproject.system.AndroidSystemModule; import java.util.concurrent.Executor; +import javax.inject.Named; import javax.inject.Singleton; import dagger.Component; @@ -74,6 +76,7 @@ public interface AndroidComponent extends CoreEagerSingletons { IdentityManager identityManager(); PluginManager pluginManager(); EventBus eventBus(); + AppBus appEventBus(); InvitationTaskFactory invitationTaskFactory(); AndroidNotificationManager androidNotificationManager(); ConnectionRegistry connectionRegistry(); diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 9e602c9e5..213088daa 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -1,29 +1,30 @@ package org.briarproject.android; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; +import android.support.annotation.CallSuper; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.inputmethod.InputMethodManager; +import org.briarproject.android.event.AppBus; +import org.briarproject.android.event.ErrorEvent; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; + import javax.inject.Inject; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; -public abstract class BaseActivity extends AppCompatActivity { - - public final static String PREFS_NAME = "db"; - public final static String PREF_DB_KEY = "key"; - public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; +public abstract class BaseActivity extends AppCompatActivity implements + EventListener { protected ActivityComponent activityComponent; - // TODO Shared prefs + @Inject + protected AppBus appBus; @Override public void onCreate(Bundle savedInstanceState) { @@ -42,28 +43,28 @@ public abstract class BaseActivity extends AppCompatActivity { injectActivity(activityComponent); } + @Override + protected void onResume() { + super.onResume(); + appBus.addListener(this); + } + + @Override + protected void onPause() { + appBus.removeListener(this); + super.onPause(); + } + + @Override + @CallSuper + public void eventOccurred(Event e) { + if (e instanceof ErrorEvent) { + finish(); + } + } + public abstract void injectActivity(ActivityComponent component); - private SharedPreferences getSharedPrefs() { - return getSharedPreferences(PREFS_NAME, MODE_PRIVATE); - } - - protected String getEncryptedDatabaseKey() { - return getSharedPrefs().getString(PREF_DB_KEY, null); - } - - protected void storeEncryptedDatabaseKey(final String hex) { - SharedPreferences.Editor editor = getSharedPrefs().edit(); - editor.putString(PREF_DB_KEY, hex); - editor.apply(); - } - - protected void clearSharedPrefs() { - SharedPreferences.Editor editor = getSharedPrefs().edit(); - editor.clear(); - editor.apply(); - } - protected void showSoftKeyboard(View view) { Object o = getSystemService(INPUT_METHOD_SERVICE); ((InputMethodManager) o).showSoftInput(view, SHOW_IMPLICIT); @@ -74,4 +75,5 @@ public abstract class BaseActivity extends AppCompatActivity { Object o = getSystemService(INPUT_METHOD_SERVICE); ((InputMethodManager) o).hideSoftInputFromWindow(token, 0); } + } diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index af98c88fa..c058bc196 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -1,5 +1,6 @@ package org.briarproject.android; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -48,6 +49,8 @@ import static java.util.logging.Level.WARNING; public class NavDrawerActivity extends BriarFragmentActivity implements BaseFragment.BaseFragmentListener, EventListener { + public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; + public static final String INTENT_CONTACTS = "intent_contacts"; public static final String INTENT_FORUMS = "intent_forums"; @@ -137,8 +140,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements } private void welcomeMessageCheck() { - SharedPreferences prefs = getSharedPreferences(PREFS_NAME, - MODE_PRIVATE); + SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE); if (!prefs.getBoolean(PREF_SEEN_WELCOME_MESSAGE, false)) { showMessageDialog(R.string.dialog_title_welcome, R.string.dialog_welcome_message); diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java index 41c2459de..34dde0fb1 100644 --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -16,14 +16,10 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; +import org.briarproject.android.event.PasswordValidateEvent; +import org.briarproject.android.helper.PasswordHelper; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.CryptoExecutor; -import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.db.DatabaseConfig; -import org.briarproject.util.StringUtils; - -import java.util.concurrent.Executor; +import org.briarproject.api.event.Event; import javax.inject.Inject; @@ -34,28 +30,22 @@ import static android.view.View.VISIBLE; public class PasswordActivity extends BaseActivity { - @Inject @CryptoExecutor protected Executor cryptoExecutor; private Button signInButton; private ProgressBar progress; private TextInputLayout input; private EditText password; - private byte[] encrypted; - - // Fields that are accessed from background threads must be volatile - @Inject protected volatile CryptoComponent crypto; - @Inject protected volatile DatabaseConfig databaseConfig; + @Inject + PasswordHelper passwordHelper; @Override public void onCreate(Bundle state) { super.onCreate(state); - String hex = getEncryptedDatabaseKey(); - if (hex == null || !databaseConfig.databaseExists()) { + if (!passwordHelper.initialized()) { clearSharedPrefsAndDeleteEverything(); return; } - encrypted = StringUtils.fromHexString(hex); setContentView(R.layout.activity_password); signInButton = (Button) findViewById(R.id.btn_sign_in); @@ -66,8 +56,7 @@ public class PasswordActivity extends BaseActivity { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - hideSoftKeyboard(password); - validatePassword(encrypted, password.getText()); + validatePassword(); return true; } }); @@ -103,7 +92,7 @@ public class PasswordActivity extends BaseActivity { } private void clearSharedPrefsAndDeleteEverything() { - clearSharedPrefs(); + passwordHelper.clearPrefs(); AndroidUtils.deleteAppData(this); setResult(RESULT_CANCELED); startActivity(new Intent(this, SetupActivity.class)); @@ -111,7 +100,7 @@ public class PasswordActivity extends BaseActivity { } public void onSignInClick(View v) { - validatePassword(encrypted, password.getText()); + validatePassword(); } public void onForgottenPasswordClick(View v) { @@ -132,47 +121,37 @@ public class PasswordActivity extends BaseActivity { dialog.show(); } - private void validatePassword(final byte[] encrypted, Editable e) { + private void validatePassword() { hideSoftKeyboard(password); - // Replace the button with a progress bar signInButton.setVisibility(INVISIBLE); progress.setVisibility(VISIBLE); - // Decrypt the database key in a background thread - final String password = e.toString(); - cryptoExecutor.execute(new Runnable() { - public void run() { - byte[] key = crypto.decryptWithPassword(encrypted, password); - if (key == null) { - tryAgain(); - } else { - databaseConfig.setEncryptionKey(new SecretKey(key)); - setResultAndFinish(); - } - } - }); + passwordHelper.validatePassword(password.getText().toString()); } - private void tryAgain() { - runOnUiThread(new Runnable() { - public void run() { - AndroidUtils.setError(input, getString(R.string.try_again), - true); - signInButton.setVisibility(VISIBLE); - progress.setVisibility(INVISIBLE); - password.setText(""); - - // show the keyboard again - showSoftKeyboard(password); - } - }); - } - - private void setResultAndFinish() { - runOnUiThread(new Runnable() { - public void run() { + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + if (e instanceof PasswordValidateEvent) { + boolean validated = ((PasswordValidateEvent)e).passwordValidated(); + if (validated) { setResult(RESULT_OK); finish(); } - }); + else { + tryAgain(); + } + } } + + private void tryAgain() { + AndroidUtils.setError(input, getString(R.string.try_again), + true); + signInButton.setVisibility(VISIBLE); + progress.setVisibility(INVISIBLE); + password.setText(""); + + // show the keyboard again + showSoftKeyboard(password); + } + } diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index 1ddb6dd58..8305e09d7 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -15,6 +15,7 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; +import org.briarproject.android.helper.SetupHelper; import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.StrengthMeter; import org.briarproject.android.api.ReferenceManager; @@ -45,17 +46,8 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENG public class SetupActivity extends BaseActivity implements OnClickListener, OnEditorActionListener { - private static final Logger LOG = - Logger.getLogger(SetupActivity.class.getName()); - - @Inject @CryptoExecutor protected Executor cryptoExecutor; - @Inject protected PasswordStrengthEstimator strengthEstimator; - - // Fields that are accessed from background threads must be volatile - @Inject protected volatile CryptoComponent crypto; - @Inject protected volatile DatabaseConfig databaseConfig; - @Inject protected volatile AuthorFactory authorFactory; - @Inject protected volatile ReferenceManager referenceManager; + @Inject + SetupHelper setupHelper; TextInputLayout nicknameEntryWrapper; TextInputLayout passwordEntryWrapper; @@ -123,7 +115,8 @@ public class SetupActivity extends BaseActivity implements OnClickListener, String firstPassword = passwordEntry.getText().toString(); String secondPassword = passwordConfirmation.getText().toString(); boolean passwordsMatch = firstPassword.equals(secondPassword); - float strength = strengthEstimator.estimateStrength(firstPassword); +// float strength = strengthEstimator.estimateStrength(firstPassword); + float strength = setupHelper.estimatePasswordStrength(firstPassword); strengthMeter.setStrength(strength); AndroidUtils.setError(nicknameEntryWrapper, getString(R.string.name_too_long), @@ -150,41 +143,22 @@ public class SetupActivity extends BaseActivity implements OnClickListener, progress.setVisibility(VISIBLE); final String nickname = nicknameEntry.getText().toString(); final String password = passwordEntry.getText().toString(); - // Store the DB key and create the identity in a background thread - cryptoExecutor.execute(new Runnable() { - public void run() { - SecretKey key = crypto.generateSecretKey(); - databaseConfig.setEncryptionKey(key); - String hex = encryptDatabaseKey(key, password); - storeEncryptedDatabaseKey(hex); - LocalAuthor localAuthor = createLocalAuthor(nickname); - showDashboard(referenceManager.putReference(localAuthor, - LocalAuthor.class)); - } - }); + setupHelper.createIdentity(nickname, password); +// // Store the DB key and create the identity in a background thread +// cryptoExecutor.execute(new Runnable() { +// public void run() { +// SecretKey key = crypto.generateSecretKey(); +// databaseConfig.setEncryptionKey(key); +// String hex = encryptDatabaseKey(key, password); +// storeEncryptedDatabaseKey(hex); +// LocalAuthor localAuthor = createLocalAuthor(nickname); +// showDashboard(referenceManager.putReference(localAuthor, +// LocalAuthor.class)); +// } +// }); } - private String encryptDatabaseKey(SecretKey key, String password) { - long now = System.currentTimeMillis(); - byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Key derivation took " + duration + " ms"); - return StringUtils.toHexString(encrypted); - } - private LocalAuthor createLocalAuthor(String nickname) { - long now = System.currentTimeMillis(); - KeyPair keyPair = crypto.generateSignatureKeyPair(); - byte[] publicKey = keyPair.getPublic().getEncoded(); - byte[] privateKey = keyPair.getPrivate().getEncoded(); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname, - publicKey, privateKey); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Identity creation took " + duration + " ms"); - return localAuthor; - } private void showDashboard(final long handle) { runOnUiThread(new Runnable() { diff --git a/briar-android/src/org/briarproject/android/SplashScreenActivity.java b/briar-android/src/org/briarproject/android/SplashScreenActivity.java index 9a736d916..043915970 100644 --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -9,9 +9,8 @@ import android.os.StrictMode.VmPolicy; import android.support.v7.preference.PreferenceManager; import org.briarproject.R; -import org.briarproject.android.api.AndroidExecutor; +import org.briarproject.android.helper.ConfigHelper; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.api.db.DatabaseConfig; import java.util.logging.Logger; @@ -29,9 +28,7 @@ public class SplashScreenActivity extends BaseActivity { private static final long EXPIRY_DATE = 1464735600 * 1000L; @Inject - protected DatabaseConfig dbConfig; - @Inject - protected AndroidExecutor androidExecutor; + ConfigHelper configHelper; public SplashScreenActivity() { Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL); @@ -65,11 +62,10 @@ public class SplashScreenActivity extends BaseActivity { LOG.info("Expired"); startActivity(new Intent(this, ExpiredActivity.class)); } else { - String hex = getEncryptedDatabaseKey(); - if (hex != null && dbConfig.databaseExists()) { + if (configHelper.initialized()) { startActivity(new Intent(this, NavDrawerActivity.class)); } else { - clearSharedPrefs(); + configHelper.clearPrefs(); AndroidUtils.deleteAppData(this); startActivity(new Intent(this, SetupActivity.class)); } diff --git a/briar-android/src/org/briarproject/android/event/AppBus.java b/briar-android/src/org/briarproject/android/event/AppBus.java new file mode 100644 index 000000000..08008e28e --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/AppBus.java @@ -0,0 +1,6 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.EventBus; + +public interface AppBus extends EventBus{ +} diff --git a/briar-android/src/org/briarproject/android/event/AppBusImp.java b/briar-android/src/org/briarproject/android/event/AppBusImp.java new file mode 100644 index 000000000..f193e1310 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/AppBusImp.java @@ -0,0 +1,25 @@ +package org.briarproject.android.event; + + +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; + +import java.util.Collection; +import java.util.concurrent.CopyOnWriteArrayList; + +public class AppBusImp implements AppBus { + private final Collection listeners = + new CopyOnWriteArrayList(); + + public void addListener(EventListener l) { + listeners.add(l); + } + + public void removeListener(EventListener l) { + listeners.remove(l); + } + + public void broadcast(Event e) { + for (EventListener l : listeners) l.eventOccurred(e); + } +} diff --git a/briar-android/src/org/briarproject/android/event/ErrorEvent.java b/briar-android/src/org/briarproject/android/event/ErrorEvent.java new file mode 100644 index 000000000..f326fd575 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/ErrorEvent.java @@ -0,0 +1,10 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.Event; + +public class ErrorEvent extends Event { + + public ErrorEvent() { + + } +} diff --git a/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java b/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java new file mode 100644 index 000000000..6a9b2e256 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java @@ -0,0 +1,16 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.Event; + +public class LocalAuthorCreatedEvent extends Event { + + private final long handle; + + public LocalAuthorCreatedEvent(long handle) { + this.handle = handle; + } + + public long getAuthorHandle() { + return handle; + } +} diff --git a/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java b/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java new file mode 100644 index 000000000..35a355282 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java @@ -0,0 +1,16 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.Event; + +public class PasswordValidateEvent extends Event { + + private final boolean passwordValidated; + + public PasswordValidateEvent(boolean passwordValidated) { + this.passwordValidated = passwordValidated; + } + + public boolean passwordValidated() { + return passwordValidated; + } +} diff --git a/briar-android/src/org/briarproject/android/helper/ConfigHelper.java b/briar-android/src/org/briarproject/android/helper/ConfigHelper.java new file mode 100644 index 000000000..0fe70579d --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/ConfigHelper.java @@ -0,0 +1,9 @@ +package org.briarproject.android.helper; + +public interface ConfigHelper { + String getEncryptedDatabaseKey(); + + void clearPrefs(); + + boolean initialized(); +} diff --git a/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java b/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java new file mode 100644 index 000000000..ca818148a --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java @@ -0,0 +1,41 @@ +package org.briarproject.android.helper; + +import android.content.SharedPreferences; + +import org.briarproject.api.db.DatabaseConfig; + +import javax.inject.Inject; + +public class ConfigHelperImp implements ConfigHelper { + + private final static String PREF_DB_KEY = "key"; + + @Inject + protected SharedPreferences briarPrefs; + @Inject + protected volatile DatabaseConfig databaseConfig; + + @Inject + public ConfigHelperImp() { + + } + + public String getEncryptedDatabaseKey() { + return briarPrefs.getString(PREF_DB_KEY, null); + } + + public void clearPrefs() { + SharedPreferences.Editor editor = briarPrefs.edit(); + editor.clear(); + editor.apply(); + } + + @Override + public boolean initialized() { + String hex = getEncryptedDatabaseKey(); + if (hex != null && databaseConfig.databaseExists()) { + return true; + } + return false; + } +} diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelper.java b/briar-android/src/org/briarproject/android/helper/PasswordHelper.java new file mode 100644 index 000000000..00aeb3da6 --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/PasswordHelper.java @@ -0,0 +1,5 @@ +package org.briarproject.android.helper; + +public interface PasswordHelper extends ConfigHelper { + void validatePassword(String password); +} diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java b/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java new file mode 100644 index 000000000..95481bd4a --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java @@ -0,0 +1,70 @@ +package org.briarproject.android.helper; + +import android.app.Activity; + +import org.briarproject.android.event.AppBus; +import org.briarproject.android.event.ErrorEvent; +import org.briarproject.android.event.PasswordValidateEvent; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.CryptoExecutor; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.util.StringUtils; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +public class PasswordHelperImp extends ConfigHelperImp + implements PasswordHelper { + + @Inject + @CryptoExecutor + protected Executor cryptoExecutor; + @Inject + protected CryptoComponent crypto; + @Inject + protected Activity activity; + @Inject + protected AppBus appBus; + + @Inject + public PasswordHelperImp() { + + } + + @Override + public void validatePassword(final String password) { + final byte[] encrypted = getEncryptedKey(); + if (encrypted == null) { + appBus.broadcast(new ErrorEvent()); + } + cryptoExecutor.execute(new Runnable() { + public void run() { + byte[] key = crypto.decryptWithPassword(encrypted, password); + if (key == null) { +// tryAgain();. + onPasswordValidated(false); + } else { + databaseConfig.setEncryptionKey(new SecretKey(key)); + onPasswordValidated(true); +// setResultAndFinish(); + } + } + }); + } + + private void onPasswordValidated(final boolean validated) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + appBus.broadcast(new PasswordValidateEvent(validated)); + } + }); + } + + + private byte[] getEncryptedKey() { + String hex = getEncryptedDatabaseKey(); + return hex == null? null : StringUtils.fromHexString(hex); + } +} diff --git a/briar-android/src/org/briarproject/android/helper/SetupHelper.java b/briar-android/src/org/briarproject/android/helper/SetupHelper.java new file mode 100644 index 000000000..329b8b210 --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/SetupHelper.java @@ -0,0 +1,6 @@ +package org.briarproject.android.helper; + +public interface SetupHelper { + float estimatePasswordStrength(String password); + void createIdentity(String nickname, String password); +} diff --git a/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java b/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java new file mode 100644 index 000000000..9015c482f --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java @@ -0,0 +1,119 @@ +package org.briarproject.android.helper; + +import android.app.Activity; +import android.content.SharedPreferences; + +import org.briarproject.android.api.ReferenceManager; +import org.briarproject.android.event.AppBus; +import org.briarproject.android.event.LocalAuthorCreatedEvent; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.CryptoExecutor; +import org.briarproject.api.crypto.KeyPair; +import org.briarproject.api.crypto.PasswordStrengthEstimator; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.api.db.DatabaseConfig; +import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.util.StringUtils; + +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import static java.util.logging.Level.INFO; + +public class SetupHelperImp implements SetupHelper { + + private static final Logger LOG = + Logger.getLogger(SetupHelperImp.class.getName()); + + private final static String PREF_DB_KEY = "key"; + + @Inject + @CryptoExecutor + protected Executor cryptoExecutor; + @Inject + protected PasswordStrengthEstimator strengthEstimator; + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile CryptoComponent crypto; + @Inject + protected volatile DatabaseConfig databaseConfig; + @Inject + protected volatile AuthorFactory authorFactory; + @Inject + protected volatile ReferenceManager referenceManager; + + @Inject + protected Activity activity; + @Inject + protected SharedPreferences briarPrefs; + @Inject + protected AppBus appBus; + + @Inject + public SetupHelperImp() { + + } + + private String encryptDatabaseKey(SecretKey key, String password) { + long now = System.currentTimeMillis(); + byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password); + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Key derivation took " + duration + " ms"); + return StringUtils.toHexString(encrypted); + } + + private LocalAuthor createLocalAuthor(String nickname) { + long now = System.currentTimeMillis(); + KeyPair keyPair = crypto.generateSignatureKeyPair(); + byte[] publicKey = keyPair.getPublic().getEncoded(); + byte[] privateKey = keyPair.getPrivate().getEncoded(); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname, + publicKey, privateKey); + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Identity creation took " + duration + " ms"); + return localAuthor; + } + + @Override + public float estimatePasswordStrength(String password) { + return strengthEstimator.estimateStrength(password); + } + + @Override + public void createIdentity(final String nickname, final String password) { + cryptoExecutor.execute(new Runnable() { + public void run() { + SecretKey key = crypto.generateSecretKey(); + databaseConfig.setEncryptionKey(key); + String hex = encryptDatabaseKey(key, password); + storeEncryptedDatabaseKey(hex); + final LocalAuthor localAuthor = createLocalAuthor(nickname); + onIdentityCreated(referenceManager.putReference(localAuthor, + LocalAuthor.class)); + + } + }); + } + + private void onIdentityCreated(final long handle) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + appBus.broadcast(new LocalAuthorCreatedEvent(handle)); + } + }); + } + + private void storeEncryptedDatabaseKey(final String hex) { + SharedPreferences.Editor editor = briarPrefs.edit(); + editor.putString(PREF_DB_KEY, hex); + editor.apply(); + } + +} diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java index c57e44d03..03198cf48 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -10,7 +10,7 @@ import android.support.v7.preference.PreferenceManager; import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; -import org.briarproject.android.api.AndroidExecutor; +import org.briarproject.android.helper.ConfigHelper; import org.briarproject.android.util.AndroidUtils; import org.briarproject.api.db.DatabaseConfig; import org.iilab.IilabEngineeringRSA2048Pin; @@ -24,7 +24,6 @@ import info.guardianproject.panic.Panic; import info.guardianproject.panic.PanicResponder; 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_PURGE; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_UNINSTALL; @@ -33,11 +32,7 @@ public class PanicResponderActivity extends BriarActivity { private static final Logger LOG = Logger.getLogger(PanicResponderActivity.class.getName()); - - @Inject - protected DatabaseConfig databaseConfig; - @Inject - protected AndroidExecutor androidExecutor; + @Inject protected ConfigHelper configHelper; @Override public void onCreate(Bundle savedInstanceState) { @@ -113,7 +108,7 @@ public class PanicResponderActivity extends BriarActivity { private void deleteAllData() { androidExecutor.execute(new Runnable() { public void run() { - clearSharedPrefs(); + configHelper.clearPrefs(); // TODO somehow delete/shred the database more thoroughly AndroidUtils.deleteAppData(PanicResponderActivity.this); PanicResponder.deleteAllAppData(PanicResponderActivity.this); diff --git a/briar-android/src/org/briarproject/android/sdk/BriarHelper.java b/briar-android/src/org/briarproject/android/sdk/BriarHelper.java deleted file mode 100644 index 1cb8993ae..000000000 --- a/briar-android/src/org/briarproject/android/sdk/BriarHelper.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.briarproject.android.sdk; - -public interface BriarHelper { -} diff --git a/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java b/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java deleted file mode 100644 index c83c33ac8..000000000 --- a/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.briarproject.android.sdk; - -import javax.inject.Inject; - -public class BriarHelperImp implements BriarHelper { - - - - @Inject - public BriarHelperImp() { - - } -} From 5d8ba660c2592c74427a5b84ba6ff4d5e047894c Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 1 Apr 2016 14:52:17 +0200 Subject: [PATCH 03/19] merge --- .../android/ActivityComponent.java | 22 ++++- .../briarproject/android/ActivityModule.java | 19 ++++ .../android/AndroidComponent.java | 93 +++++++------------ .../android/contact/ContactListFragment.java | 16 +--- .../keyagreement/ChooseIdentityFragment.java | 14 +-- .../keyagreement/KeyAgreementActivity.java | 7 +- .../keyagreement/ShowQrCodeFragment.java | 13 +-- 7 files changed, 79 insertions(+), 105 deletions(-) diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java index 4032d7bd7..ca2e8b334 100644 --- a/briar-android/src/org/briarproject/android/ActivityComponent.java +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -1,8 +1,6 @@ package org.briarproject.android; import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; @@ -16,13 +14,15 @@ import org.briarproject.android.forum.WriteForumPostActivity; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.identity.CreateIdentityActivity; import org.briarproject.android.invitation.AddContactActivity; +import org.briarproject.android.keyagreement.ChooseIdentityFragment; +import org.briarproject.android.keyagreement.KeyAgreementActivity; +import org.briarproject.android.keyagreement.ShowQrCodeFragment; import org.briarproject.android.panic.PanicPreferencesActivity; import org.briarproject.android.panic.PanicResponderActivity; import javax.inject.Named; import dagger.Component; -import dagger.Provides; @ActivityScope @Component(modules = ActivityModule.class, @@ -44,6 +44,8 @@ public interface ActivityComponent { void inject(AddContactActivity activity); + void inject(KeyAgreementActivity activity); + void inject(ConversationActivity activity); void inject(CreateIdentityActivity activity); @@ -64,13 +66,23 @@ public interface ActivityComponent { void inject(SettingsActivity activity); + void inject(ContactListFragment fragment); + + void inject(ForumListFragment fragment); + + void inject(ChooseIdentityFragment fragment); + + void inject(ShowQrCodeFragment fragment); + @Named("ContactListFragment") BaseFragment newContactListFragment(); @Named("ForumListFragment") BaseFragment newForumListFragment(); -// void inject(ContactListFragment fragment); + @Named("ChooseIdentityFragment") + BaseFragment newChooseIdentityFragment(); -// void inject(ForumListFragment fragment); + @Named("ShowQrCodeFragment") + BaseFragment newShowQrCodeFragment(); } diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 3ae6e004c..1f398b8e5 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -14,6 +14,8 @@ import org.briarproject.android.helper.SetupHelper; import org.briarproject.android.helper.SetupHelperImp; import org.briarproject.android.helper.ConfigHelper; import org.briarproject.android.helper.ConfigHelperImp; +import org.briarproject.android.keyagreement.ChooseIdentityFragment; +import org.briarproject.android.keyagreement.ShowQrCodeFragment; import javax.inject.Named; @@ -75,4 +77,21 @@ public class ActivityModule { return contactListFragment; } + @Provides + @Named("ChooseIdentityFragment") + BaseFragment provideChooseIdendityFragment() { + ChooseIdentityFragment fragment = new ChooseIdentityFragment(); + fragment.setArguments(new Bundle()); + return fragment; + } + + @Provides + @Named("ShowQrCodeFragment") + BaseFragment provideShowQrCodeFragment() { + ShowQrCodeFragment fragment = new ShowQrCodeFragment(); + fragment.setArguments(new Bundle()); + return fragment; + } + + } diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 02469114f..f482e5298 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -7,25 +7,7 @@ import org.briarproject.android.api.ReferenceManager; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; import org.briarproject.android.event.AppBus; -import org.briarproject.android.forum.AvailableForumsActivity; -import org.briarproject.android.forum.ContactSelectorFragment; -import org.briarproject.android.forum.CreateForumActivity; -import org.briarproject.android.forum.ForumActivity; -import org.briarproject.android.forum.ForumListFragment; -import org.briarproject.android.forum.ReadForumPostActivity; -import org.briarproject.android.forum.ShareForumActivity; -import org.briarproject.android.forum.ShareForumMessageFragment; -import org.briarproject.android.forum.WriteForumPostActivity; -import org.briarproject.android.identity.CreateIdentityActivity; -import org.briarproject.android.introduction.ContactChooserFragment; -import org.briarproject.android.introduction.IntroductionActivity; -import org.briarproject.android.introduction.IntroductionMessageFragment; -import org.briarproject.android.invitation.AddContactActivity; -import org.briarproject.android.keyagreement.ChooseIdentityFragment; -import org.briarproject.android.keyagreement.KeyAgreementActivity; -import org.briarproject.android.keyagreement.ShowQrCodeFragment; -import org.briarproject.android.panic.PanicPreferencesActivity; -import org.briarproject.android.panic.PanicResponderActivity; +import org.briarproject.api.contact.ContactExchangeTask; import org.briarproject.api.contact.ContactManager; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; @@ -39,6 +21,9 @@ import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.invitation.InvitationTaskFactory; +import org.briarproject.api.keyagreement.KeyAgreementTaskFactory; +import org.briarproject.api.keyagreement.PayloadEncoder; +import org.briarproject.api.keyagreement.PayloadParser; import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessageFactory; @@ -71,68 +56,52 @@ public interface AndroidComponent extends CoreEagerSingletons { DatabaseConfig databaseConfig(); AuthorFactory authFactory(); ReferenceManager referenceMangager(); - @DatabaseExecutor Executor databaseExecutor(); + + @DatabaseExecutor + Executor databaseExecutor(); + LifecycleManager lifecycleManager(); + IdentityManager identityManager(); + PluginManager pluginManager(); + EventBus eventBus(); + AppBus appEventBus(); + InvitationTaskFactory invitationTaskFactory(); + AndroidNotificationManager androidNotificationManager(); + ConnectionRegistry connectionRegistry(); + ContactManager contactManager(); + MessagingManager messagingManager(); + PrivateMessageFactory privateMessageFactory(); + TransportPropertyManager transportPropertyManager(); + ForumManager forumManager(); + ForumSharingManager forumSharingManager(); + ForumPostFactory forumPostFactory(); + SettingsManager settingsManager(); + ContactExchangeTask contactExchangeTask(); + + KeyAgreementTaskFactory keyAgreementTaskFactory(); + + PayloadEncoder payloadEncoder(); + + PayloadParser payloadParser(); + void inject(BriarService activity); - void inject(PanicResponderActivity activity); - - void inject(PanicPreferencesActivity activity); - - void inject(AddContactActivity activity); - - void inject(KeyAgreementActivity activity); - - void inject(ConversationActivity activity); - - void inject(CreateIdentityActivity activity); - - void inject(TestingActivity activity); - - void inject(AvailableForumsActivity activity); - - void inject(WriteForumPostActivity activity); - - void inject(CreateForumActivity activity); - - void inject(ShareForumActivity activity); - - void inject(ContactSelectorFragment fragment); - - void inject(ShareForumMessageFragment fragment); - - void inject(ReadForumPostActivity activity); - - void inject(ForumActivity activity); - - void inject(SettingsActivity activity); - - void inject(ContactListFragment fragment); - - void inject(ForumListFragment fragment); - - void inject(ChooseIdentityFragment fragment); - - void inject(ShowQrCodeFragment fragment); - - void inject(IntroductionActivity activity); - void inject(ContactChooserFragment fragment); void inject(IntroductionMessageFragment fragment); diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index 62e1e349f..bb22af3bf 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -15,6 +15,7 @@ import org.briarproject.R; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarApplication; import org.briarproject.android.fragment.BaseEventFragment; +import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.keyagreement.KeyAgreementActivity; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.contact.Contact; @@ -62,17 +63,6 @@ public class ContactListFragment extends BaseFragment implements EventListener { public final static String TAG = "ContactListFragment"; - /* - public static ContactListFragment newInstance() { - - Bundle args = new Bundle(); - - ContactListFragment fragment = new ContactListFragment(); - fragment.setArguments(args); - return fragment; - } - */ - @Override public String getUniqueTag() { return TAG; @@ -98,10 +88,6 @@ public class ContactListFragment extends BaseFragment implements EventListener { protected volatile EventBus eventBus; -// @Override -// public void injectActivity(AndroidComponent component) { -// component.inject(this); -// } @Inject public ContactListFragment() { diff --git a/briar-android/src/org/briarproject/android/keyagreement/ChooseIdentityFragment.java b/briar-android/src/org/briarproject/android/keyagreement/ChooseIdentityFragment.java index 16818d36a..40206766e 100644 --- a/briar-android/src/org/briarproject/android/keyagreement/ChooseIdentityFragment.java +++ b/briar-android/src/org/briarproject/android/keyagreement/ChooseIdentityFragment.java @@ -13,6 +13,7 @@ import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Spinner; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.identity.CreateIdentityActivity; @@ -59,11 +60,9 @@ public class ChooseIdentityFragment extends BaseFragment @Inject protected volatile IdentityManager identityManager; - public static ChooseIdentityFragment newInstance() { - Bundle args = new Bundle(); - ChooseIdentityFragment fragment = new ChooseIdentityFragment(); - fragment.setArguments(args); - return fragment; + @Inject + public ChooseIdentityFragment() { + } @Override @@ -82,11 +81,6 @@ public class ChooseIdentityFragment extends BaseFragment return TAG; } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } - @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, diff --git a/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java index 185d3c0b1..b2395eaa2 100644 --- a/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java +++ b/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java @@ -7,6 +7,7 @@ import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarFragmentActivity; import org.briarproject.android.fragment.BaseFragment; @@ -63,7 +64,7 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements protected volatile IdentityManager identityManager; @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } @@ -96,11 +97,11 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements STEPS)); switch (step) { case STEP_QR: - startFragment(ShowQrCodeFragment.newInstance()); + startFragment(activityComponent.newShowQrCodeFragment()); break; case STEP_ID: default: - startFragment(ChooseIdentityFragment.newInstance()); + startFragment(activityComponent.newChooseIdentityFragment()); break; } } diff --git a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java index cbe175d8e..8a997168d 100644 --- a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java +++ b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java @@ -86,11 +86,9 @@ public class ShowQrCodeFragment extends BaseEventFragment private volatile KeyAgreementTask task; private volatile boolean waitingForBluetooth; - public static ShowQrCodeFragment newInstance() { - Bundle args = new Bundle(); - ShowQrCodeFragment fragment = new ShowQrCodeFragment(); - fragment.setArguments(args); - return fragment; + @Inject + public ShowQrCodeFragment() { + } @Override @@ -98,11 +96,6 @@ public class ShowQrCodeFragment extends BaseEventFragment return TAG; } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } - @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, From 8d021aab50158341872a0c7498537eb1e7f35d5a Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 1 Apr 2016 16:38:16 +0200 Subject: [PATCH 04/19] cleaning up --- .../briarproject/android/SetupActivity.java | 61 +++++++++---------- .../android/fragment/BaseFragment.java | 5 -- .../android/helper/PasswordHelperImp.java | 2 - 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index 8305e09d7..e3aaf510c 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -15,6 +15,7 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; +import org.briarproject.android.event.LocalAuthorCreatedEvent; import org.briarproject.android.helper.SetupHelper; import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.StrengthMeter; @@ -25,6 +26,7 @@ import org.briarproject.api.crypto.KeyPair; import org.briarproject.api.crypto.PasswordStrengthEstimator; import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.db.DatabaseConfig; +import org.briarproject.api.event.Event; import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.LocalAuthor; import org.briarproject.util.StringUtils; @@ -64,15 +66,18 @@ public class SetupActivity extends BaseActivity implements OnClickListener, super.onCreate(state); setContentView(R.layout.activity_setup); - nicknameEntryWrapper = (TextInputLayout)findViewById(R.id.nickname_entry_wrapper); - passwordEntryWrapper = (TextInputLayout)findViewById(R.id.password_entry_wrapper); - passwordConfirmationWrapper = (TextInputLayout)findViewById(R.id.password_confirm_wrapper); - nicknameEntry = (EditText)findViewById(R.id.nickname_entry); - passwordEntry = (EditText)findViewById(R.id.password_entry); - passwordConfirmation = (EditText)findViewById(R.id.password_confirm); - strengthMeter = (StrengthMeter)findViewById(R.id.strength_meter); - createAccountButton = (Button)findViewById(R.id.create_account); - progress = (ProgressBar)findViewById(R.id.progress_wheel); + nicknameEntryWrapper = + (TextInputLayout) findViewById(R.id.nickname_entry_wrapper); + passwordEntryWrapper = + (TextInputLayout) findViewById(R.id.password_entry_wrapper); + passwordConfirmationWrapper = + (TextInputLayout) findViewById(R.id.password_confirm_wrapper); + nicknameEntry = (EditText) findViewById(R.id.nickname_entry); + passwordEntry = (EditText) findViewById(R.id.password_entry); + passwordConfirmation = (EditText) findViewById(R.id.password_confirm); + strengthMeter = (StrengthMeter) findViewById(R.id.strength_meter); + createAccountButton = (Button) findViewById(R.id.create_account); + progress = (ProgressBar) findViewById(R.id.progress_wheel); if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); @@ -144,32 +149,24 @@ public class SetupActivity extends BaseActivity implements OnClickListener, final String nickname = nicknameEntry.getText().toString(); final String password = passwordEntry.getText().toString(); setupHelper.createIdentity(nickname, password); -// // Store the DB key and create the identity in a background thread -// cryptoExecutor.execute(new Runnable() { -// public void run() { -// SecretKey key = crypto.generateSecretKey(); -// databaseConfig.setEncryptionKey(key); -// String hex = encryptDatabaseKey(key, password); -// storeEncryptedDatabaseKey(hex); -// LocalAuthor localAuthor = createLocalAuthor(nickname); -// showDashboard(referenceManager.putReference(localAuthor, -// LocalAuthor.class)); -// } -// }); } - + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + if (e instanceof LocalAuthorCreatedEvent) { + long handle = ((LocalAuthorCreatedEvent)e).getAuthorHandle(); + showDashboard(handle); + } + } private void showDashboard(final long handle) { - runOnUiThread(new Runnable() { - public void run() { - Intent i = new Intent(SetupActivity.this, - NavDrawerActivity.class); - i.putExtra(BriarActivity.KEY_LOCAL_AUTHOR_HANDLE, handle); - i.setFlags(FLAG_ACTIVITY_NEW_TASK); - startActivity(i); - finish(); - } - }); + Intent i = new Intent(SetupActivity.this, + NavDrawerActivity.class); + i.putExtra(BriarActivity.KEY_LOCAL_AUTHOR_HANDLE, handle); + i.setFlags(FLAG_ACTIVITY_NEW_TASK); + startActivity(i); + finish(); } } +} diff --git a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java index 47f98f366..34e00e0c3 100644 --- a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java +++ b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java @@ -27,11 +27,6 @@ public abstract class BaseFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - -// AndroidComponent component = -// ((BriarApplication) getActivity().getApplication()) -// .getApplicationComponent(); -// injectActivity(component); } public interface BaseFragmentListener { diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java b/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java index 95481bd4a..f999337ae 100644 --- a/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java +++ b/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java @@ -42,12 +42,10 @@ public class PasswordHelperImp extends ConfigHelperImp public void run() { byte[] key = crypto.decryptWithPassword(encrypted, password); if (key == null) { -// tryAgain();. onPasswordValidated(false); } else { databaseConfig.setEncryptionKey(new SecretKey(key)); onPasswordValidated(true); -// setResultAndFinish(); } } }); From 27098db18f5968f4cb200d464bcddcef45aaf004 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 1 Apr 2016 16:48:27 +0200 Subject: [PATCH 05/19] fix compile error --- briar-android/src/org/briarproject/android/SetupActivity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index e3aaf510c..d50e38b21 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -169,4 +169,3 @@ public class SetupActivity extends BaseActivity implements OnClickListener, finish(); } } -} From a14e981236b7582ae246244625d7458f14098d27 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Thu, 7 Apr 2016 12:54:23 +0200 Subject: [PATCH 06/19] Switched AppBus for ResultHandler, Controller for Helper. Added the basics for LifecycleControllers and implemented it for BriarActivity and NavDrawerActivity --- .../briarproject/android/ActivityModule.java | 66 ++++++-- .../android/AndroidComponent.java | 5 - .../briarproject/android/BaseActivity.java | 48 ++++-- .../briarproject/android/BriarActivity.java | 98 ++++------- .../briarproject/android/BriarService.java | 2 +- .../android/NavDrawerActivity.java | 106 +++--------- .../android/PasswordActivity.java | 39 ++--- .../briarproject/android/SetupActivity.java | 49 +++--- .../android/SplashScreenActivity.java | 8 +- .../ActivityLifecycleController.java | 11 ++ .../android/controller/BriarController.java | 14 ++ .../controller/BriarControllerImp.java | 123 ++++++++++++++ .../ConfigController.java} | 4 +- .../ConfigControllerImp.java} | 6 +- .../controller/EncryptedKeyNullException.java | 9 + .../controller/NavDrawerController.java | 16 ++ .../controller/NavDrawerControllerImp.java | 159 ++++++++++++++++++ .../controller/PasswordController.java | 6 + .../PasswordControllerImp.java} | 29 ++-- .../android/controller/ResultHandler.java | 6 + .../android/controller/SetupController.java | 8 + .../SetupControllerImp.java} | 27 ++- .../controller/TransportStateListener.java | 7 + .../briarproject/android/event/AppBus.java | 6 - .../briarproject/android/event/AppBusImp.java | 25 --- .../android/event/ErrorEvent.java | 10 -- .../event/LocalAuthorCreatedEvent.java | 16 -- .../android/event/PasswordValidateEvent.java | 16 -- .../android/helper/PasswordHelper.java | 5 - .../android/helper/SetupHelper.java | 6 - .../invitation/AddContactActivity.java | 2 +- .../android/panic/PanicResponderActivity.java | 8 +- 32 files changed, 584 insertions(+), 356 deletions(-) create mode 100644 briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java create mode 100644 briar-android/src/org/briarproject/android/controller/BriarController.java create mode 100644 briar-android/src/org/briarproject/android/controller/BriarControllerImp.java rename briar-android/src/org/briarproject/android/{helper/ConfigHelper.java => controller/ConfigController.java} (50%) rename briar-android/src/org/briarproject/android/{helper/ConfigHelperImp.java => controller/ConfigControllerImp.java} (83%) create mode 100644 briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java create mode 100644 briar-android/src/org/briarproject/android/controller/NavDrawerController.java create mode 100644 briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java create mode 100644 briar-android/src/org/briarproject/android/controller/PasswordController.java rename briar-android/src/org/briarproject/android/{helper/PasswordHelperImp.java => controller/PasswordControllerImp.java} (57%) create mode 100644 briar-android/src/org/briarproject/android/controller/ResultHandler.java create mode 100644 briar-android/src/org/briarproject/android/controller/SetupController.java rename briar-android/src/org/briarproject/android/{helper/SetupHelperImp.java => controller/SetupControllerImp.java} (83%) create mode 100644 briar-android/src/org/briarproject/android/controller/TransportStateListener.java delete mode 100644 briar-android/src/org/briarproject/android/event/AppBus.java delete mode 100644 briar-android/src/org/briarproject/android/event/AppBusImp.java delete mode 100644 briar-android/src/org/briarproject/android/event/ErrorEvent.java delete mode 100644 briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java delete mode 100644 briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java delete mode 100644 briar-android/src/org/briarproject/android/helper/PasswordHelper.java delete mode 100644 briar-android/src/org/briarproject/android/helper/SetupHelper.java diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 1f398b8e5..33e291abc 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -6,14 +6,19 @@ import android.content.SharedPreferences; import android.os.Bundle; import org.briarproject.android.contact.ContactListFragment; +import org.briarproject.android.controller.BriarController; +import org.briarproject.android.controller.BriarControllerImp; +import org.briarproject.android.controller.NavDrawerController; +import org.briarproject.android.controller.NavDrawerControllerImp; +import org.briarproject.android.controller.TransportStateListener; import org.briarproject.android.forum.ForumListFragment; import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.android.helper.PasswordHelper; -import org.briarproject.android.helper.PasswordHelperImp; -import org.briarproject.android.helper.SetupHelper; -import org.briarproject.android.helper.SetupHelperImp; -import org.briarproject.android.helper.ConfigHelper; -import org.briarproject.android.helper.ConfigHelperImp; +import org.briarproject.android.controller.PasswordController; +import org.briarproject.android.controller.PasswordControllerImp; +import org.briarproject.android.controller.SetupController; +import org.briarproject.android.controller.SetupControllerImp; +import org.briarproject.android.controller.ConfigController; +import org.briarproject.android.controller.ConfigControllerImp; import org.briarproject.android.keyagreement.ChooseIdentityFragment; import org.briarproject.android.keyagreement.ShowQrCodeFragment; @@ -22,6 +27,8 @@ import javax.inject.Named; import dagger.Module; import dagger.Provides; +import static org.briarproject.android.BriarService.*; + @Module public class ActivityModule { @@ -31,6 +38,12 @@ public class ActivityModule { this.activity = activity; } + @ActivityScope + @Provides + BaseActivity providesBaseActivity() { + return activity; + } + @ActivityScope @Provides Activity providesActivity() { @@ -39,14 +52,16 @@ public class ActivityModule { @ActivityScope @Provides - SetupHelper provideSetupHelper(SetupHelperImp setupHelperImp) { - return setupHelperImp; + SetupController provideSetupController( + SetupControllerImp setupControllerImp) { + return setupControllerImp; } @ActivityScope @Provides - ConfigHelper provideConfigHelper(ConfigHelperImp configHelperImp) { - return configHelperImp; + ConfigController provideConfigController( + ConfigControllerImp configControllerImp) { + return configControllerImp; } @ActivityScope @@ -57,8 +72,35 @@ public class ActivityModule { @ActivityScope @Provides - PasswordHelper providePasswordHelper(PasswordHelperImp passwordHelperImp) { - return passwordHelperImp; + PasswordController providePasswordController( + PasswordControllerImp passwordControllerImp) { + return passwordControllerImp; + } + + @ActivityScope + @Provides + BriarController provideBriarController( + BriarControllerImp briarControllerImp) { + activity.addLifecycleController(briarControllerImp); + return briarControllerImp; + } + + @ActivityScope + @Provides + NavDrawerController provideNavDrawerController( + NavDrawerControllerImp navDrawerControllerImp) { + activity.addLifecycleController(navDrawerControllerImp); + if (activity instanceof TransportStateListener) { + navDrawerControllerImp + .setTransportListener((TransportStateListener) activity); + } + return navDrawerControllerImp; + } + + @ActivityScope + @Provides + BriarServiceConnection provideBriarServiceConnection() { + return new BriarServiceConnection(); } @Provides diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index f482e5298..c5396da79 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -4,9 +4,6 @@ import org.briarproject.CoreEagerSingletons; import org.briarproject.CoreModule; import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.api.ReferenceManager; -import org.briarproject.android.contact.ContactListFragment; -import org.briarproject.android.contact.ConversationActivity; -import org.briarproject.android.event.AppBus; import org.briarproject.api.contact.ContactExchangeTask; import org.briarproject.api.contact.ContactManager; import org.briarproject.api.crypto.CryptoComponent; @@ -68,8 +65,6 @@ public interface AndroidComponent extends CoreEagerSingletons { EventBus eventBus(); - AppBus appEventBus(); - InvitationTaskFactory invitationTaskFactory(); AndroidNotificationManager androidNotificationManager(); diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 213088daa..1bbbc6fde 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -2,29 +2,31 @@ package org.briarproject.android; import android.os.Bundle; import android.os.IBinder; -import android.support.annotation.CallSuper; +import android.os.PersistableBundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.inputmethod.InputMethodManager; -import org.briarproject.android.event.AppBus; -import org.briarproject.android.event.ErrorEvent; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventListener; +import org.briarproject.android.controller.ActivityLifecycleController; -import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; -public abstract class BaseActivity extends AppCompatActivity implements - EventListener { +public abstract class BaseActivity extends AppCompatActivity { protected ActivityComponent activityComponent; - @Inject - protected AppBus appBus; + private List lifecycleControllers = + new ArrayList(); + + public void addLifecycleController( + ActivityLifecycleController lifecycleController) { + this.lifecycleControllers.add(lifecycleController); + } @Override public void onCreate(Bundle savedInstanceState) { @@ -43,23 +45,37 @@ public abstract class BaseActivity extends AppCompatActivity implements injectActivity(activityComponent); } + @Override + public void onPostCreate(Bundle savedInstanceState, + PersistableBundle persistentState) { + super.onPostCreate(savedInstanceState, persistentState); + for (ActivityLifecycleController alc : lifecycleControllers) { + alc.onActivityCreate(); + } + + } + @Override protected void onResume() { super.onResume(); - appBus.addListener(this); + for (ActivityLifecycleController alc : lifecycleControllers) { + alc.onActivityResume(); + } } @Override protected void onPause() { - appBus.removeListener(this); super.onPause(); + for (ActivityLifecycleController alc : lifecycleControllers) { + alc.onActivityPause(); + } } @Override - @CallSuper - public void eventOccurred(Event e) { - if (e instanceof ErrorEvent) { - finish(); + protected void onDestroy() { + super.onDestroy(); + for (ActivityLifecycleController alc : lifecycleControllers) { + alc.onActivityDestroy(); } } diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java index 8043b1a14..a61e4059d 100644 --- a/briar-android/src/org/briarproject/android/BriarActivity.java +++ b/briar-android/src/org/briarproject/android/BriarActivity.java @@ -8,6 +8,8 @@ import android.os.IBinder; import org.briarproject.android.BriarService.BriarBinder; import org.briarproject.android.BriarService.BriarServiceConnection; +import org.briarproject.android.controller.BriarController; +import org.briarproject.android.controller.ResultHandler; import org.briarproject.android.panic.ExitActivity; import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.db.DatabaseExecutor; @@ -37,12 +39,12 @@ public abstract class BriarActivity extends BaseActivity { private static final Logger LOG = Logger.getLogger(BriarActivity.class.getName()); + /* private final BriarServiceConnection serviceConnection = new BriarServiceConnection(); @Inject - protected DatabaseConfig databaseConfig; - + DatabaseConfig databaseConfig; private boolean bound = false; // Fields that are accessed from background threads must be volatile @@ -51,19 +53,23 @@ public abstract class BriarActivity extends BaseActivity { protected volatile Executor dbExecutor; @Inject protected volatile LifecycleManager lifecycleManager; + */ + @Inject + protected BriarController briarController; @Override public void onCreate(Bundle state) { super.onCreate(state); - if (databaseConfig.getEncryptionKey() != null) startAndBindService(); + briarController.startAndBindService(); +// if (databaseConfig.getEncryptionKey() != null) startAndBindService(); } @Override protected void onActivityResult(int request, int result, Intent data) { super.onActivityResult(request, result, data); if (request == REQUEST_PASSWORD) { - if (result == RESULT_OK) startAndBindService(); + if (result == RESULT_OK) briarController.startAndBindService(); else finish(); } } @@ -71,7 +77,7 @@ public abstract class BriarActivity extends BaseActivity { @Override public void onResume() { super.onResume(); - if (databaseConfig.getEncryptionKey() == null && !isFinishing()) { + if (!briarController.encryptionKey() && !isFinishing()) { Intent i = new Intent(this, PasswordActivity.class); i.setFlags(FLAG_ACTIVITY_NO_ANIMATION | FLAG_ACTIVITY_SINGLE_TOP); startActivityForResult(i, REQUEST_PASSWORD); @@ -81,41 +87,22 @@ public abstract class BriarActivity extends BaseActivity { @Override public void onDestroy() { super.onDestroy(); - unbindService(); - } - - private void startAndBindService() { - startService(new Intent(this, BriarService.class)); - bound = bindService(new Intent(this, BriarService.class), - serviceConnection, 0); - } - - private void unbindService() { - if (bound) unbindService(serviceConnection); + briarController.unbindService(); } protected void signOut(final boolean removeFromRecentApps) { - // Use a new thread to avoid deadlock with executor tasks - new Thread() { + briarController.signOut(new ResultHandler() { @Override - public void run() { - try { - // Wait for the service to finish starting up - IBinder binder = serviceConnection.waitForBinder(); - BriarService service = ((BriarBinder) binder).getService(); - service.waitForStartup(); - // Shut down the service and wait for it to shut down - LOG.info("Shutting down service"); - service.shutdown(); - service.waitForShutdown(); - } catch (InterruptedException e) { - LOG.warning("Interrupted while waiting for service"); - Thread.currentThread().interrupt(); - } + public void onResult(Void result) { if (removeFromRecentApps) startExitActivity(); else finishAndExit(); } - }.start(); + + @Override + public void onException(RuntimeException exception) { + // TODO ? + } + }); } protected void signOut() { @@ -123,44 +110,25 @@ public abstract class BriarActivity extends BaseActivity { } private void startExitActivity() { - runOnUiThread(new Runnable() { - @Override - public void run() { - Intent intent = new Intent(BriarActivity.this, - ExitActivity.class); - intent.addFlags(FLAG_ACTIVITY_NEW_TASK - | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS - | FLAG_ACTIVITY_NO_ANIMATION); - if (Build.VERSION.SDK_INT >= 11) - intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK); - startActivity(intent); - } - }); + Intent intent = new Intent(BriarActivity.this, + ExitActivity.class); + intent.addFlags(FLAG_ACTIVITY_NEW_TASK + | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + | FLAG_ACTIVITY_NO_ANIMATION); + if (Build.VERSION.SDK_INT >= 11) + intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); } private void finishAndExit() { - runOnUiThread(new Runnable() { - public void run() { - if (Build.VERSION.SDK_INT >= 21) finishAndRemoveTask(); - else finish(); - LOG.info("Exiting"); - System.exit(0); - } - }); + if (Build.VERSION.SDK_INT >= 21) finishAndRemoveTask(); + else finish(); + LOG.info("Exiting"); + System.exit(0); } public void runOnDbThread(final Runnable task) { - dbExecutor.execute(new Runnable() { - public void run() { - try { - lifecycleManager.waitForDatabase(); - task.run(); - } catch (InterruptedException e) { - LOG.warning("Interrupted while waiting for database"); - Thread.currentThread().interrupt(); - } - } - }); + briarController.runOnDbThread(task); } protected void finishOnUiThread() { diff --git a/briar-android/src/org/briarproject/android/BriarService.java b/briar-android/src/org/briarproject/android/BriarService.java index 33d69c8f6..6055c2d69 100644 --- a/briar-android/src/org/briarproject/android/BriarService.java +++ b/briar-android/src/org/briarproject/android/BriarService.java @@ -180,7 +180,7 @@ public class BriarService extends Service { /** Starts the shutdown process. */ public void shutdown() { - stopSelf(); // This will call onDestroy() + stopSelf(); // This will call onActivityDestroy() } public class BriarBinder extends Binder { diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index c058bc196..a5c8f8e29 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -14,28 +14,19 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; import org.briarproject.R; -import org.briarproject.android.contact.ContactListFragment; -import org.briarproject.android.forum.ForumListFragment; +import org.briarproject.android.controller.NavDrawerController; +import org.briarproject.android.controller.ResultHandler; +import org.briarproject.android.controller.TransportStateListener; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.util.CustomAnimations; import org.briarproject.api.TransportId; -import org.briarproject.android.api.ReferenceManager; import org.briarproject.api.db.DbException; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventBus; -import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.TransportDisabledEvent; -import org.briarproject.api.event.TransportEnabledEvent; -import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; -import org.briarproject.api.plugins.Plugin; -import org.briarproject.api.plugins.PluginManager; import java.util.ArrayList; import java.util.List; @@ -43,11 +34,8 @@ import java.util.logging.Logger; import javax.inject.Inject; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; - public class NavDrawerActivity extends BriarFragmentActivity implements - BaseFragment.BaseFragmentListener, EventListener { + BaseFragment.BaseFragmentListener, TransportStateListener { public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; @@ -60,14 +48,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements private ActionBarDrawerToggle drawerToggle; @Inject - protected ReferenceManager referenceManager; - // Fields that are accessed from background threads must be volatile - @Inject - protected volatile IdentityManager identityManager; - @Inject - protected PluginManager pluginManager; - @Inject - protected volatile EventBus eventBus; + NavDrawerController controller; private Toolbar toolbar; private DrawerLayout drawerLayout; @@ -106,11 +87,11 @@ public class NavDrawerActivity extends BriarFragmentActivity implements setContentView(R.layout.activity_nav_drawer); - toolbar = (Toolbar)findViewById(R.id.toolbar); - drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); - transportsView = (GridView)findViewById(R.id.transportsView); - progressTitle = (TextView)findViewById(R.id.title_progress_bar); - progressViewGroup = (ViewGroup)findViewById(R.id.container_progress); + toolbar = (Toolbar) findViewById(R.id.toolbar); + drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); + transportsView = (GridView) findViewById(R.id.transportsView); + progressTitle = (TextView) findViewById(R.id.title_progress_bar); + progressViewGroup = (ViewGroup) findViewById(R.id.container_progress); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); @@ -151,22 +132,14 @@ public class NavDrawerActivity extends BriarFragmentActivity implements @Override public void onResume() { super.onResume(); - eventBus.addListener(this); updateTransports(); } - @Override - protected void onPause() { - super.onPause(); - eventBus.removeListener(this); - } - private void checkAuthorHandle(Intent intent) { long handle = intent.getLongExtra(KEY_LOCAL_AUTHOR_HANDLE, -1); if (handle != -1) { + LocalAuthor a = controller.removeAuthorHandle(handle); // The activity was launched from the setup wizard - LocalAuthor a = referenceManager.removeReference(handle, - LocalAuthor.class); if (a != null) { showLoadingScreen(true, R.string.progress_title_please_wait); storeLocalAuthor(a); @@ -185,27 +158,18 @@ public class NavDrawerActivity extends BriarFragmentActivity implements } private void storeLocalAuthor(final LocalAuthor a) { - runOnDbThread(new Runnable() { - public void run() { - try { - long now = System.currentTimeMillis(); - identityManager.addLocalAuthor(a); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Storing author took " + duration + " ms"); + controller.storeLocalAuthor(a, + new ResultHandler() { + @Override + public void onResult(Void result) { + hideLoadingScreen(); + } - runOnUiThread(new Runnable() { - public void run() { - hideLoadingScreen(); - } - }); + @Override + public void onException(DbException exception) { - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); + } + }); } public void onNavigationClick(View view) { @@ -281,24 +245,21 @@ public class NavDrawerActivity extends BriarFragmentActivity implements Transport tor = new Transport(); tor.id = new TransportId("tor"); - Plugin torPlugin = pluginManager.getPlugin(tor.id); - tor.enabled = torPlugin != null && torPlugin.isRunning(); + tor.enabled = controller.transportRunning(tor.id); tor.iconId = R.drawable.transport_tor; tor.textId = R.string.transport_tor; transports.add(tor); Transport bt = new Transport(); bt.id = new TransportId("bt"); - Plugin btPlugin = pluginManager.getPlugin(bt.id); - bt.enabled = btPlugin != null && btPlugin.isRunning(); + bt.enabled = controller.transportRunning(bt.id); bt.iconId = R.drawable.transport_bt; bt.textId = R.string.transport_bt; transports.add(bt); Transport lan = new Transport(); lan.id = new TransportId("lan"); - Plugin lanPlugin = pluginManager.getPlugin(lan.id); - lan.enabled = lanPlugin != null && lanPlugin.isRunning(); + lan.enabled = controller.transportRunning(lan.id); lan.iconId = R.drawable.transport_lan; lan.textId = R.string.transport_lan; transports.add(lan); @@ -365,27 +326,14 @@ public class NavDrawerActivity extends BriarFragmentActivity implements private void updateTransports() { if (transports == null || transportsAdapter == null) return; for (Transport t : transports) { - Plugin plugin = pluginManager.getPlugin(t.id); - t.enabled = plugin != null && plugin.isRunning(); + t.enabled = controller.transportRunning(t.id); } transportsAdapter.notifyDataSetChanged(); } @Override - public void eventOccurred(Event e) { - if (e instanceof TransportEnabledEvent) { - TransportId id = ((TransportEnabledEvent) e).getTransportId(); - if (LOG.isLoggable(INFO)) { - LOG.info("TransportEnabledEvent: " + id.getString()); - } - setTransport(id, true); - } else if (e instanceof TransportDisabledEvent) { - TransportId id = ((TransportDisabledEvent) e).getTransportId(); - if (LOG.isLoggable(INFO)) { - LOG.info("TransportDisabledEvent: " + id.getString()); - } - setTransport(id, false); - } + public void stateUpdate(TransportId id, boolean enabled) { + setTransport(id, enabled); } private static class Transport { diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java index 34dde0fb1..9f004527a 100644 --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -16,10 +16,10 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; -import org.briarproject.android.event.PasswordValidateEvent; -import org.briarproject.android.helper.PasswordHelper; +import org.briarproject.android.controller.EncryptedKeyNullException; +import org.briarproject.android.controller.PasswordController; +import org.briarproject.android.controller.ResultHandler; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.api.event.Event; import javax.inject.Inject; @@ -36,7 +36,7 @@ public class PasswordActivity extends BaseActivity { private EditText password; @Inject - PasswordHelper passwordHelper; + PasswordController passwordHelper; @Override public void onCreate(Bundle state) { @@ -125,22 +125,23 @@ public class PasswordActivity extends BaseActivity { hideSoftKeyboard(password); signInButton.setVisibility(INVISIBLE); progress.setVisibility(VISIBLE); - passwordHelper.validatePassword(password.getText().toString()); - } + passwordHelper.validatePassword(password.getText().toString(), + new ResultHandler() { + @Override + public void onResult(Boolean result) { + if (result != null && result) { + setResult(RESULT_OK); + finish(); + } else { + tryAgain(); + } + } - @Override - public void eventOccurred(Event e) { - super.eventOccurred(e); - if (e instanceof PasswordValidateEvent) { - boolean validated = ((PasswordValidateEvent)e).passwordValidated(); - if (validated) { - setResult(RESULT_OK); - finish(); - } - else { - tryAgain(); - } - } + @Override + public void onException(EncryptedKeyNullException e) { + // TODO ? + } + }); } private void tryAgain() { diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index d50e38b21..1aaba344c 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -15,24 +15,12 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; -import org.briarproject.android.event.LocalAuthorCreatedEvent; -import org.briarproject.android.helper.SetupHelper; +import org.briarproject.android.controller.ResultHandler; +import org.briarproject.android.controller.SetupController; import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.StrengthMeter; -import org.briarproject.android.api.ReferenceManager; -import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.CryptoExecutor; -import org.briarproject.api.crypto.KeyPair; -import org.briarproject.api.crypto.PasswordStrengthEstimator; -import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.db.DatabaseConfig; -import org.briarproject.api.event.Event; -import org.briarproject.api.identity.AuthorFactory; -import org.briarproject.api.identity.LocalAuthor; -import org.briarproject.util.StringUtils; -import java.util.concurrent.Executor; -import java.util.logging.Logger; +import org.briarproject.util.StringUtils; import javax.inject.Inject; @@ -40,7 +28,6 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; -import static java.util.logging.Level.INFO; import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; @@ -49,7 +36,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, OnEditorActionListener { @Inject - SetupHelper setupHelper; + SetupController setupController; TextInputLayout nicknameEntryWrapper; TextInputLayout passwordEntryWrapper; @@ -120,8 +107,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, String firstPassword = passwordEntry.getText().toString(); String secondPassword = passwordConfirmation.getText().toString(); boolean passwordsMatch = firstPassword.equals(secondPassword); -// float strength = strengthEstimator.estimateStrength(firstPassword); - float strength = setupHelper.estimatePasswordStrength(firstPassword); + float strength = setupController.estimatePasswordStrength(firstPassword); strengthMeter.setStrength(strength); AndroidUtils.setError(nicknameEntryWrapper, getString(R.string.name_too_long), @@ -148,19 +134,22 @@ public class SetupActivity extends BaseActivity implements OnClickListener, progress.setVisibility(VISIBLE); final String nickname = nicknameEntry.getText().toString(); final String password = passwordEntry.getText().toString(); - setupHelper.createIdentity(nickname, password); + setupController.createIdentity(nickname, password, + new ResultHandler() { + @Override + public void onResult(Long result) { + if (result != null) + showMain(result); + } + + @Override + public void onException(RuntimeException exception) { + + } + }); } - @Override - public void eventOccurred(Event e) { - super.eventOccurred(e); - if (e instanceof LocalAuthorCreatedEvent) { - long handle = ((LocalAuthorCreatedEvent)e).getAuthorHandle(); - showDashboard(handle); - } - } - - private void showDashboard(final long handle) { + private void showMain(final long handle) { Intent i = new Intent(SetupActivity.this, NavDrawerActivity.class); i.putExtra(BriarActivity.KEY_LOCAL_AUTHOR_HANDLE, handle); diff --git a/briar-android/src/org/briarproject/android/SplashScreenActivity.java b/briar-android/src/org/briarproject/android/SplashScreenActivity.java index 043915970..2064c67d6 100644 --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -9,7 +9,7 @@ import android.os.StrictMode.VmPolicy; import android.support.v7.preference.PreferenceManager; import org.briarproject.R; -import org.briarproject.android.helper.ConfigHelper; +import org.briarproject.android.controller.ConfigController; import org.briarproject.android.util.AndroidUtils; import java.util.logging.Logger; @@ -28,7 +28,7 @@ public class SplashScreenActivity extends BaseActivity { private static final long EXPIRY_DATE = 1464735600 * 1000L; @Inject - ConfigHelper configHelper; + ConfigController configController; public SplashScreenActivity() { Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL); @@ -62,10 +62,10 @@ public class SplashScreenActivity extends BaseActivity { LOG.info("Expired"); startActivity(new Intent(this, ExpiredActivity.class)); } else { - if (configHelper.initialized()) { + if (configController.initialized()) { startActivity(new Intent(this, NavDrawerActivity.class)); } else { - configHelper.clearPrefs(); + configController.clearPrefs(); AndroidUtils.deleteAppData(this); startActivity(new Intent(this, SetupActivity.class)); } diff --git a/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java b/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java new file mode 100644 index 000000000..68b15592c --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java @@ -0,0 +1,11 @@ +package org.briarproject.android.controller; + +public interface ActivityLifecycleController { + void onActivityCreate(); + + void onActivityResume(); + + void onActivityPause(); + + void onActivityDestroy(); +} diff --git a/briar-android/src/org/briarproject/android/controller/BriarController.java b/briar-android/src/org/briarproject/android/controller/BriarController.java new file mode 100644 index 000000000..edb035cb3 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/BriarController.java @@ -0,0 +1,14 @@ +package org.briarproject.android.controller; + + +public interface BriarController extends ActivityLifecycleController { + void runOnDbThread(final Runnable task); + + void startAndBindService(); + + void unbindService(); + + boolean encryptionKey(); + + void signOut(ResultHandler eventHandler); +} diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java new file mode 100644 index 000000000..789b27af4 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java @@ -0,0 +1,123 @@ +package org.briarproject.android.controller; + +import android.app.Activity; +import android.content.Intent; +import android.os.IBinder; +import android.support.annotation.CallSuper; + +import org.briarproject.android.BriarService; +import org.briarproject.android.BriarService.BriarServiceConnection; +import org.briarproject.api.db.DatabaseConfig; +import org.briarproject.api.db.DatabaseExecutor; +import org.briarproject.api.lifecycle.LifecycleManager; + +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import javax.inject.Inject; + +public class BriarControllerImp implements BriarController { + + private static final Logger LOG = + Logger.getLogger(BriarControllerImp.class.getName()); + + @Inject + protected BriarServiceConnection serviceConnection; + @Inject + protected DatabaseConfig databaseConfig; + // Fields that are accessed from background threads must be volatile + @Inject + @DatabaseExecutor + protected volatile Executor dbExecutor; + @Inject + protected volatile LifecycleManager lifecycleManager; + @Inject + protected Activity activity; + + private boolean bound = false; + + @Inject + public BriarControllerImp() { + + } + + @Override + @CallSuper + public void onActivityCreate() { + if (databaseConfig.getEncryptionKey() != null) startAndBindService(); + } + + @Override + @CallSuper + public void onActivityResume() { + } + + @Override + @CallSuper + public void onActivityPause() { + } + + @Override + @CallSuper + public void onActivityDestroy() { + unbindService(); + } + + public void startAndBindService() { + activity.startService(new Intent(activity, BriarService.class)); + bound = activity.bindService(new Intent(activity, BriarService.class), + serviceConnection, 0); + } + + @Override + public boolean encryptionKey() { + return databaseConfig.getEncryptionKey() != null; + } + + @Override + public void signOut(final ResultHandler eventHandler) { + new Thread() { + @Override + public void run() { + try { + // Wait for the service to finish starting up + IBinder binder = serviceConnection.waitForBinder(); + BriarService service = ((BriarService.BriarBinder) binder).getService(); + service.waitForStartup(); + // Shut down the service and wait for it to shut down + LOG.info("Shutting down service"); + service.shutdown(); + service.waitForShutdown(); + } catch (InterruptedException e) { + LOG.warning("Interrupted while waiting for service"); + Thread.currentThread().interrupt(); + } + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + eventHandler.onResult(null); + } + }); + } + }.start(); + } + + public void unbindService() { + if (bound) activity.unbindService(serviceConnection); + } + + public void runOnDbThread(final Runnable task) { + dbExecutor.execute(new Runnable() { + public void run() { + try { + lifecycleManager.waitForDatabase(); + task.run(); + } catch (InterruptedException e) { + LOG.warning("Interrupted while waiting for database"); + Thread.currentThread().interrupt(); + } + } + }); + } + +} diff --git a/briar-android/src/org/briarproject/android/helper/ConfigHelper.java b/briar-android/src/org/briarproject/android/controller/ConfigController.java similarity index 50% rename from briar-android/src/org/briarproject/android/helper/ConfigHelper.java rename to briar-android/src/org/briarproject/android/controller/ConfigController.java index 0fe70579d..cddbc1bc6 100644 --- a/briar-android/src/org/briarproject/android/helper/ConfigHelper.java +++ b/briar-android/src/org/briarproject/android/controller/ConfigController.java @@ -1,6 +1,6 @@ -package org.briarproject.android.helper; +package org.briarproject.android.controller; -public interface ConfigHelper { +public interface ConfigController { String getEncryptedDatabaseKey(); void clearPrefs(); diff --git a/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java b/briar-android/src/org/briarproject/android/controller/ConfigControllerImp.java similarity index 83% rename from briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java rename to briar-android/src/org/briarproject/android/controller/ConfigControllerImp.java index ca818148a..d37ab8f1b 100644 --- a/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java +++ b/briar-android/src/org/briarproject/android/controller/ConfigControllerImp.java @@ -1,4 +1,4 @@ -package org.briarproject.android.helper; +package org.briarproject.android.controller; import android.content.SharedPreferences; @@ -6,7 +6,7 @@ import org.briarproject.api.db.DatabaseConfig; import javax.inject.Inject; -public class ConfigHelperImp implements ConfigHelper { +public class ConfigControllerImp implements ConfigController { private final static String PREF_DB_KEY = "key"; @@ -16,7 +16,7 @@ public class ConfigHelperImp implements ConfigHelper { protected volatile DatabaseConfig databaseConfig; @Inject - public ConfigHelperImp() { + public ConfigControllerImp() { } diff --git a/briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java b/briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java new file mode 100644 index 000000000..3da38efa4 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java @@ -0,0 +1,9 @@ +package org.briarproject.android.controller; + +public class EncryptedKeyNullException extends NullPointerException { + + @Override + public String toString() { + return "Encrypted key can't be null"; + } +} diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java new file mode 100644 index 000000000..13dfbcc29 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java @@ -0,0 +1,16 @@ +package org.briarproject.android.controller; + +import org.briarproject.api.TransportId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.identity.LocalAuthor; + +public interface NavDrawerController extends BriarController { + void setTransportListener(TransportStateListener transportListener); + + boolean transportRunning(TransportId transportId); + + void storeLocalAuthor(LocalAuthor author, + ResultHandler resultHandler); + + LocalAuthor removeAuthorHandle(long handle); +} diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java new file mode 100644 index 000000000..a86b7231d --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java @@ -0,0 +1,159 @@ +package org.briarproject.android.controller; + +import android.app.Activity; + +import org.briarproject.android.api.ReferenceManager; +import org.briarproject.api.TransportId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.TransportDisabledEvent; +import org.briarproject.api.event.TransportEnabledEvent; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.api.plugins.Plugin; +import org.briarproject.api.plugins.PluginManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + +public class NavDrawerControllerImp extends BriarControllerImp + implements NavDrawerController, EventListener { + + private static final Logger LOG = + Logger.getLogger(NavDrawerControllerImp.class.getName()); + + @Inject + protected ReferenceManager referenceManager; + @Inject + protected volatile IdentityManager identityManager; + @Inject + protected PluginManager pluginManager; + @Inject + protected volatile EventBus eventBus; + @Inject + protected Activity activity; + + private List transports = new ArrayList(); + + private TransportStateListener transportStateListener; + + @Inject + public NavDrawerControllerImp() { + + } + + @Override + public void onActivityCreate() { + super.onActivityCreate(); + initializeTransports(); + } + + @Override + public void onActivityResume() { + super.onActivityResume(); + eventBus.addListener(this); + } + + @Override + public void onActivityPause() { + super.onActivityPause(); + eventBus.removeListener(this); + } + + @Override + public void eventOccurred(Event e) { + if (e instanceof TransportEnabledEvent) { + TransportId id = ((TransportEnabledEvent) e).getTransportId(); + if (LOG.isLoggable(INFO)) { + LOG.info("TransportEnabledEvent: " + id.getString()); + } + transportStateUpdate(id, true); + } else if (e instanceof TransportDisabledEvent) { + TransportId id = ((TransportDisabledEvent) e).getTransportId(); + if (LOG.isLoggable(INFO)) { + LOG.info("TransportDisabledEvent: " + id.getString()); + } + transportStateUpdate(id, false); + } + } + + private void transportStateUpdate(final TransportId id, final boolean enabled) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (transportStateListener != null) { + transportStateListener.stateUpdate(id, enabled); + } + } + }); + } + + private void initializeTransports() { + transports.clear(); + transports.add(pluginManager.getPlugin(new TransportId("tor"))); + transports.add(pluginManager.getPlugin(new TransportId("bt"))); + transports.add(pluginManager.getPlugin(new TransportId("lan"))); + } + + @Override + public void setTransportListener(TransportStateListener transportListener) { + this.transportStateListener = transportListener; + } + + @Override + public boolean transportRunning(TransportId transportId) { + for (Plugin transport : transports) { + if (transport.getId().equals(transportId)) { + return transport.isRunning(); + } + } + return false; + } + + @Override + public void storeLocalAuthor(final LocalAuthor author, + final ResultHandler resultHandler) { + runOnDbThread(new Runnable() { + public void run() { + try { + long now = System.currentTimeMillis(); + identityManager.addLocalAuthor(author); + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Storing author took " + duration + " ms"); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + resultHandler.onResult(null); + } + }); + } catch (final DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + resultHandler.onException(e); + } + }); + } + } + }); + } + + @Override + public LocalAuthor removeAuthorHandle(long handle) { + return referenceManager.removeReference(handle, + LocalAuthor.class); + } +} diff --git a/briar-android/src/org/briarproject/android/controller/PasswordController.java b/briar-android/src/org/briarproject/android/controller/PasswordController.java new file mode 100644 index 000000000..b40ddb670 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/PasswordController.java @@ -0,0 +1,6 @@ +package org.briarproject.android.controller; + +public interface PasswordController extends ConfigController { + void validatePassword(String password, + ResultHandler resultHandler); +} diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java b/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java similarity index 57% rename from briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java rename to briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java index f999337ae..ed86bb9bd 100644 --- a/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java +++ b/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java @@ -1,10 +1,7 @@ -package org.briarproject.android.helper; +package org.briarproject.android.controller; import android.app.Activity; -import org.briarproject.android.event.AppBus; -import org.briarproject.android.event.ErrorEvent; -import org.briarproject.android.event.PasswordValidateEvent; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.SecretKey; @@ -14,8 +11,8 @@ import java.util.concurrent.Executor; import javax.inject.Inject; -public class PasswordHelperImp extends ConfigHelperImp - implements PasswordHelper { +public class PasswordControllerImp extends ConfigControllerImp + implements PasswordController { @Inject @CryptoExecutor @@ -24,38 +21,38 @@ public class PasswordHelperImp extends ConfigHelperImp protected CryptoComponent crypto; @Inject protected Activity activity; - @Inject - protected AppBus appBus; @Inject - public PasswordHelperImp() { + public PasswordControllerImp() { } @Override - public void validatePassword(final String password) { + public void validatePassword(final String password, + final ResultHandler resultHandler) { final byte[] encrypted = getEncryptedKey(); if (encrypted == null) { - appBus.broadcast(new ErrorEvent()); + resultHandler.onException(new EncryptedKeyNullException()); } cryptoExecutor.execute(new Runnable() { public void run() { byte[] key = crypto.decryptWithPassword(encrypted, password); if (key == null) { - onPasswordValidated(false); + onPasswordValidated(false, resultHandler); } else { databaseConfig.setEncryptionKey(new SecretKey(key)); - onPasswordValidated(true); + onPasswordValidated(true, resultHandler); } } }); } - private void onPasswordValidated(final boolean validated) { + private void onPasswordValidated(final boolean validated, + final ResultHandler resultHandler) { activity.runOnUiThread(new Runnable() { @Override public void run() { - appBus.broadcast(new PasswordValidateEvent(validated)); + resultHandler.onResult(validated); } }); } @@ -63,6 +60,6 @@ public class PasswordHelperImp extends ConfigHelperImp private byte[] getEncryptedKey() { String hex = getEncryptedDatabaseKey(); - return hex == null? null : StringUtils.fromHexString(hex); + return hex == null ? null : StringUtils.fromHexString(hex); } } diff --git a/briar-android/src/org/briarproject/android/controller/ResultHandler.java b/briar-android/src/org/briarproject/android/controller/ResultHandler.java new file mode 100644 index 000000000..5f98763aa --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/ResultHandler.java @@ -0,0 +1,6 @@ +package org.briarproject.android.controller; + +public interface ResultHandler { + void onResult(R result); + void onException(E exception); +} diff --git a/briar-android/src/org/briarproject/android/controller/SetupController.java b/briar-android/src/org/briarproject/android/controller/SetupController.java new file mode 100644 index 000000000..884706c3f --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/SetupController.java @@ -0,0 +1,8 @@ +package org.briarproject.android.controller; + +public interface SetupController { + float estimatePasswordStrength(String password); + + void createIdentity(String nickname, String password, + ResultHandler resultHandler); +} diff --git a/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java similarity index 83% rename from briar-android/src/org/briarproject/android/helper/SetupHelperImp.java rename to briar-android/src/org/briarproject/android/controller/SetupControllerImp.java index 9015c482f..312502f42 100644 --- a/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java +++ b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java @@ -1,11 +1,10 @@ -package org.briarproject.android.helper; +package org.briarproject.android.controller; import android.app.Activity; import android.content.SharedPreferences; +import org.briarproject.android.BaseActivity; import org.briarproject.android.api.ReferenceManager; -import org.briarproject.android.event.AppBus; -import org.briarproject.android.event.LocalAuthorCreatedEvent; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.KeyPair; @@ -23,10 +22,10 @@ import javax.inject.Inject; import static java.util.logging.Level.INFO; -public class SetupHelperImp implements SetupHelper { +public class SetupControllerImp implements SetupController { private static final Logger LOG = - Logger.getLogger(SetupHelperImp.class.getName()); + Logger.getLogger(SetupControllerImp.class.getName()); private final static String PREF_DB_KEY = "key"; @@ -45,16 +44,13 @@ public class SetupHelperImp implements SetupHelper { protected volatile AuthorFactory authorFactory; @Inject protected volatile ReferenceManager referenceManager; - @Inject protected Activity activity; @Inject protected SharedPreferences briarPrefs; - @Inject - protected AppBus appBus; @Inject - public SetupHelperImp() { + public SetupControllerImp() { } @@ -86,7 +82,8 @@ public class SetupHelperImp implements SetupHelper { } @Override - public void createIdentity(final String nickname, final String password) { + public void createIdentity(final String nickname, final String password, + final ResultHandler resultHandler) { cryptoExecutor.execute(new Runnable() { public void run() { SecretKey key = crypto.generateSecretKey(); @@ -94,18 +91,20 @@ public class SetupHelperImp implements SetupHelper { String hex = encryptDatabaseKey(key, password); storeEncryptedDatabaseKey(hex); final LocalAuthor localAuthor = createLocalAuthor(nickname); - onIdentityCreated(referenceManager.putReference(localAuthor, - LocalAuthor.class)); + long handle = referenceManager.putReference(localAuthor, + LocalAuthor.class); + onIdentityCreated(handle, resultHandler); } }); } - private void onIdentityCreated(final long handle) { + private void onIdentityCreated(final long handle, + final ResultHandler resultHandler) { activity.runOnUiThread(new Runnable() { @Override public void run() { - appBus.broadcast(new LocalAuthorCreatedEvent(handle)); + resultHandler.onResult(handle); } }); } diff --git a/briar-android/src/org/briarproject/android/controller/TransportStateListener.java b/briar-android/src/org/briarproject/android/controller/TransportStateListener.java new file mode 100644 index 000000000..0a00c0f7d --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/TransportStateListener.java @@ -0,0 +1,7 @@ +package org.briarproject.android.controller; + +import org.briarproject.api.TransportId; + +public interface TransportStateListener { + void stateUpdate(TransportId id, boolean enabled); +} diff --git a/briar-android/src/org/briarproject/android/event/AppBus.java b/briar-android/src/org/briarproject/android/event/AppBus.java deleted file mode 100644 index 08008e28e..000000000 --- a/briar-android/src/org/briarproject/android/event/AppBus.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.briarproject.android.event; - -import org.briarproject.api.event.EventBus; - -public interface AppBus extends EventBus{ -} diff --git a/briar-android/src/org/briarproject/android/event/AppBusImp.java b/briar-android/src/org/briarproject/android/event/AppBusImp.java deleted file mode 100644 index f193e1310..000000000 --- a/briar-android/src/org/briarproject/android/event/AppBusImp.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.briarproject.android.event; - - -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventListener; - -import java.util.Collection; -import java.util.concurrent.CopyOnWriteArrayList; - -public class AppBusImp implements AppBus { - private final Collection listeners = - new CopyOnWriteArrayList(); - - public void addListener(EventListener l) { - listeners.add(l); - } - - public void removeListener(EventListener l) { - listeners.remove(l); - } - - public void broadcast(Event e) { - for (EventListener l : listeners) l.eventOccurred(e); - } -} diff --git a/briar-android/src/org/briarproject/android/event/ErrorEvent.java b/briar-android/src/org/briarproject/android/event/ErrorEvent.java deleted file mode 100644 index f326fd575..000000000 --- a/briar-android/src/org/briarproject/android/event/ErrorEvent.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.briarproject.android.event; - -import org.briarproject.api.event.Event; - -public class ErrorEvent extends Event { - - public ErrorEvent() { - - } -} diff --git a/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java b/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java deleted file mode 100644 index 6a9b2e256..000000000 --- a/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.briarproject.android.event; - -import org.briarproject.api.event.Event; - -public class LocalAuthorCreatedEvent extends Event { - - private final long handle; - - public LocalAuthorCreatedEvent(long handle) { - this.handle = handle; - } - - public long getAuthorHandle() { - return handle; - } -} diff --git a/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java b/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java deleted file mode 100644 index 35a355282..000000000 --- a/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.briarproject.android.event; - -import org.briarproject.api.event.Event; - -public class PasswordValidateEvent extends Event { - - private final boolean passwordValidated; - - public PasswordValidateEvent(boolean passwordValidated) { - this.passwordValidated = passwordValidated; - } - - public boolean passwordValidated() { - return passwordValidated; - } -} diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelper.java b/briar-android/src/org/briarproject/android/helper/PasswordHelper.java deleted file mode 100644 index 00aeb3da6..000000000 --- a/briar-android/src/org/briarproject/android/helper/PasswordHelper.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.briarproject.android.helper; - -public interface PasswordHelper extends ConfigHelper { - void validatePassword(String password); -} diff --git a/briar-android/src/org/briarproject/android/helper/SetupHelper.java b/briar-android/src/org/briarproject/android/helper/SetupHelper.java deleted file mode 100644 index 329b8b210..000000000 --- a/briar-android/src/org/briarproject/android/helper/SetupHelper.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.briarproject.android.helper; - -public interface SetupHelper { - float estimatePasswordStrength(String password); - void createIdentity(String nickname, String password); -} diff --git a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java index 66a5c63ea..332efc655 100644 --- a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java +++ b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java @@ -287,7 +287,7 @@ implements InvitationListener { localInvitationCode, code); taskHandle = referenceManager.putReference(task, InvitationTask.class); task.addListener(AddContactActivity.this); - // Add a second listener so we can remove the first in onDestroy(), + // Add a second listener so we can remove the first in onActivityDestroy(), // allowing the activity to be garbage collected if it's destroyed task.addListener(new ReferenceCleaner(referenceManager, taskHandle)); task.connect(); diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java index 03198cf48..bdb037785 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -8,11 +8,9 @@ import android.os.Bundle; import android.support.v7.preference.PreferenceManager; import org.briarproject.android.ActivityComponent; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; -import org.briarproject.android.helper.ConfigHelper; +import org.briarproject.android.controller.ConfigController; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.api.db.DatabaseConfig; import org.iilab.IilabEngineeringRSA2048Pin; import java.util.logging.Logger; @@ -32,7 +30,7 @@ public class PanicResponderActivity extends BriarActivity { private static final Logger LOG = Logger.getLogger(PanicResponderActivity.class.getName()); - @Inject protected ConfigHelper configHelper; + @Inject protected ConfigController configController; @Override public void onCreate(Bundle savedInstanceState) { @@ -108,7 +106,7 @@ public class PanicResponderActivity extends BriarActivity { private void deleteAllData() { androidExecutor.execute(new Runnable() { public void run() { - configHelper.clearPrefs(); + configController.clearPrefs(); // TODO somehow delete/shred the database more thoroughly AndroidUtils.deleteAppData(PanicResponderActivity.this); PanicResponder.deleteAllAppData(PanicResponderActivity.this); From 604cfd5202de883091921143790d9df6bc49d2b1 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 8 Apr 2016 12:03:01 +0200 Subject: [PATCH 07/19] Fix transport update --- .../briarproject/android/BaseActivity.java | 9 ++++---- .../briarproject/android/BriarActivity.java | 16 ------------- .../android/NavDrawerActivity.java | 3 ++- .../controller/NavDrawerControllerImp.java | 23 ++++++++----------- 4 files changed, 16 insertions(+), 35 deletions(-) diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 1bbbc6fde..7e1b7165a 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.PersistableBundle; import android.support.v7.app.AppCompatActivity; +import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; @@ -46,13 +47,13 @@ public abstract class BaseActivity extends AppCompatActivity { } @Override - public void onPostCreate(Bundle savedInstanceState, - PersistableBundle persistentState) { - super.onPostCreate(savedInstanceState, persistentState); + public void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + // Post call used for controllers to ensure that the onCreate method + // override in inherited Activities has finished for (ActivityLifecycleController alc : lifecycleControllers) { alc.onActivityCreate(); } - } @Override diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java index a61e4059d..9bd1e27db 100644 --- a/briar-android/src/org/briarproject/android/BriarActivity.java +++ b/briar-android/src/org/briarproject/android/BriarActivity.java @@ -39,21 +39,6 @@ public abstract class BriarActivity extends BaseActivity { private static final Logger LOG = Logger.getLogger(BriarActivity.class.getName()); - /* - private final BriarServiceConnection serviceConnection = - new BriarServiceConnection(); - - @Inject - DatabaseConfig databaseConfig; - private boolean bound = false; - - // Fields that are accessed from background threads must be volatile - @Inject - @DatabaseExecutor - protected volatile Executor dbExecutor; - @Inject - protected volatile LifecycleManager lifecycleManager; - */ @Inject protected BriarController briarController; @@ -62,7 +47,6 @@ public abstract class BriarActivity extends BaseActivity { super.onCreate(state); briarController.startAndBindService(); -// if (databaseConfig.getEncryptionKey() != null) startAndBindService(); } @Override diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index a5c8f8e29..854504485 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -10,6 +10,7 @@ import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -203,7 +204,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements } @Override - protected void onPostCreate(Bundle savedInstanceState) { + public void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); drawerToggle.syncState(); } diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java index a86b7231d..72e93293c 100644 --- a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java @@ -17,7 +17,6 @@ import org.briarproject.api.plugins.PluginManager; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; @@ -54,13 +53,13 @@ public class NavDrawerControllerImp extends BriarControllerImp @Override public void onActivityCreate() { super.onActivityCreate(); - initializeTransports(); } @Override public void onActivityResume() { super.onActivityResume(); eventBus.addListener(this); + LOG.info("onActivityResume"); } @Override @@ -97,12 +96,12 @@ public class NavDrawerControllerImp extends BriarControllerImp }); } - private void initializeTransports() { - transports.clear(); - transports.add(pluginManager.getPlugin(new TransportId("tor"))); - transports.add(pluginManager.getPlugin(new TransportId("bt"))); - transports.add(pluginManager.getPlugin(new TransportId("lan"))); - } +// private void initializeTransports() { +// transports.clear(); +// transports.add(pluginManager.getPlugin(new TransportId("tor"))); +// transports.add(pluginManager.getPlugin(new TransportId("bt"))); +// transports.add(pluginManager.getPlugin(new TransportId("lan"))); +// } @Override public void setTransportListener(TransportStateListener transportListener) { @@ -111,12 +110,8 @@ public class NavDrawerControllerImp extends BriarControllerImp @Override public boolean transportRunning(TransportId transportId) { - for (Plugin transport : transports) { - if (transport.getId().equals(transportId)) { - return transport.isRunning(); - } - } - return false; + Plugin plugin = pluginManager.getPlugin(transportId); + return plugin != null && plugin.isRunning(); } @Override From ef3b41dc1d5d365242c80f6a8c133f9fbf8f54f9 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 8 Apr 2016 12:17:46 +0200 Subject: [PATCH 08/19] comment & log cleanup --- .../android/controller/NavDrawerControllerImp.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java index 72e93293c..f6b76c543 100644 --- a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java @@ -59,7 +59,6 @@ public class NavDrawerControllerImp extends BriarControllerImp public void onActivityResume() { super.onActivityResume(); eventBus.addListener(this); - LOG.info("onActivityResume"); } @Override @@ -96,13 +95,6 @@ public class NavDrawerControllerImp extends BriarControllerImp }); } -// private void initializeTransports() { -// transports.clear(); -// transports.add(pluginManager.getPlugin(new TransportId("tor"))); -// transports.add(pluginManager.getPlugin(new TransportId("bt"))); -// transports.add(pluginManager.getPlugin(new TransportId("lan"))); -// } - @Override public void setTransportListener(TransportStateListener transportListener) { this.transportStateListener = transportListener; From e809aaa93252f5192b23f047ede5bde4d53acdd6 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Tue, 26 Apr 2016 10:59:58 +0200 Subject: [PATCH 09/19] merge and update --- .../android/ActivityComponent.java | 15 +++++++++ .../briarproject/android/ActivityModule.java | 17 ++++++++++ .../android/AndroidComponent.java | 4 ++- .../briarproject/android/BaseActivity.java | 12 ++++--- .../briarproject/android/BriarActivity.java | 27 ++++----------- .../android/NavDrawerActivity.java | 9 +++-- .../android/PasswordActivity.java | 23 +++++-------- .../briarproject/android/SetupActivity.java | 16 +++------ .../android/controller/BriarController.java | 4 ++- .../controller/BriarControllerImp.java | 11 ++----- .../controller/EncryptedKeyNullException.java | 9 ----- .../controller/NavDrawerController.java | 3 +- .../controller/NavDrawerControllerImp.java | 22 ++++--------- .../controller/PasswordController.java | 4 ++- .../controller/PasswordControllerImp.java | 21 +++--------- .../android/controller/ResultHandler.java | 6 ---- .../android/controller/SetupController.java | 4 ++- .../controller/SetupControllerImp.java | 15 ++------- .../handler/ResultExceptionHandler.java | 6 ++++ .../controller/handler/ResultHandler.java | 5 +++ .../handler/UiResultExceptionHandler.java | 33 +++++++++++++++++++ .../controller/handler/UiResultHandler.java | 22 +++++++++++++ .../introduction/ContactChooserFragment.java | 11 +++---- .../introduction/IntroductionActivity.java | 18 +++++----- .../IntroductionMessageFragment.java | 24 ++++++-------- .../invitation/AddContactActivity.java | 3 +- .../introduction/IntroductionModule.java | 4 +-- 27 files changed, 187 insertions(+), 161 deletions(-) delete mode 100644 briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java delete mode 100644 briar-android/src/org/briarproject/android/controller/ResultHandler.java create mode 100644 briar-android/src/org/briarproject/android/controller/handler/ResultExceptionHandler.java create mode 100644 briar-android/src/org/briarproject/android/controller/handler/ResultHandler.java create mode 100644 briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java create mode 100644 briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java index ca2e8b334..37fd1f17c 100644 --- a/briar-android/src/org/briarproject/android/ActivityComponent.java +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -13,6 +13,9 @@ import org.briarproject.android.forum.ShareForumActivity; import org.briarproject.android.forum.WriteForumPostActivity; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.identity.CreateIdentityActivity; +import org.briarproject.android.introduction.ContactChooserFragment; +import org.briarproject.android.introduction.IntroductionActivity; +import org.briarproject.android.introduction.IntroductionMessageFragment; import org.briarproject.android.invitation.AddContactActivity; import org.briarproject.android.keyagreement.ChooseIdentityFragment; import org.briarproject.android.keyagreement.KeyAgreementActivity; @@ -74,6 +77,12 @@ public interface ActivityComponent { void inject(ShowQrCodeFragment fragment); + void inject(IntroductionActivity activity); + + void inject(ContactChooserFragment fragment); + + void inject(IntroductionMessageFragment fragment); + @Named("ContactListFragment") BaseFragment newContactListFragment(); @@ -85,4 +94,10 @@ public interface ActivityComponent { @Named("ShowQrCodeFragment") BaseFragment newShowQrCodeFragment(); + + @Named("ContactChooserFragment") + BaseFragment newContactChooserFragment(); + + @Named("IntroductionMessageFragment") + IntroductionMessageFragment newIntroductionMessageFragment(); } diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 33e291abc..33accc970 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -19,6 +19,8 @@ import org.briarproject.android.controller.SetupController; import org.briarproject.android.controller.SetupControllerImp; import org.briarproject.android.controller.ConfigController; import org.briarproject.android.controller.ConfigControllerImp; +import org.briarproject.android.introduction.ContactChooserFragment; +import org.briarproject.android.introduction.IntroductionMessageFragment; import org.briarproject.android.keyagreement.ChooseIdentityFragment; import org.briarproject.android.keyagreement.ShowQrCodeFragment; @@ -135,5 +137,20 @@ public class ActivityModule { return fragment; } + @Provides + @Named("ContactChooserFragment") + BaseFragment provideContactChooserFragment() { + ContactChooserFragment fragment = new ContactChooserFragment(); + fragment.setArguments(new Bundle()); + return fragment; + } + + @Provides + @Named("IntroductionMessageFragment") + IntroductionMessageFragment provideIntroductionMessageFragment() { + IntroductionMessageFragment fragment = new IntroductionMessageFragment(); + fragment.setArguments(new Bundle()); + return fragment; + } } diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index c5396da79..623aba6e5 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -17,6 +17,7 @@ import org.briarproject.api.forum.ForumPostFactory; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.introduction.IntroductionManager; import org.briarproject.api.invitation.InvitationTaskFactory; import org.briarproject.api.keyagreement.KeyAgreementTaskFactory; import org.briarproject.api.keyagreement.PayloadEncoder; @@ -33,7 +34,6 @@ import org.briarproject.system.AndroidSystemModule; import java.util.concurrent.Executor; -import javax.inject.Named; import javax.inject.Singleton; import dagger.Component; @@ -95,6 +95,8 @@ public interface AndroidComponent extends CoreEagerSingletons { PayloadParser payloadParser(); + IntroductionManager introductionManager(); + void inject(BriarService activity); void inject(ContactChooserFragment fragment); diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 7e1b7165a..6ae3eb8c2 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -2,9 +2,7 @@ package org.briarproject.android; import android.os.Bundle; import android.os.IBinder; -import android.os.PersistableBundle; import android.support.v7.app.AppCompatActivity; -import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; @@ -44,6 +42,10 @@ public abstract class BaseActivity extends AppCompatActivity { .build(); injectActivity(activityComponent); + + for (ActivityLifecycleController alc : lifecycleControllers) { + alc.onActivityCreate(); + } } @Override @@ -51,9 +53,9 @@ public abstract class BaseActivity extends AppCompatActivity { super.onPostCreate(savedInstanceState); // Post call used for controllers to ensure that the onCreate method // override in inherited Activities has finished - for (ActivityLifecycleController alc : lifecycleControllers) { - alc.onActivityCreate(); - } +// for (ActivityLifecycleController alc : lifecycleControllers) { +// alc.onActivityCreate(); +// } } @Override diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java index 9bd1e27db..fca3fd12d 100644 --- a/briar-android/src/org/briarproject/android/BriarActivity.java +++ b/briar-android/src/org/briarproject/android/BriarActivity.java @@ -4,18 +4,11 @@ import android.annotation.SuppressLint; import android.content.Intent; import android.os.Build; import android.os.Bundle; -import android.os.IBinder; -import org.briarproject.android.BriarService.BriarBinder; -import org.briarproject.android.BriarService.BriarServiceConnection; import org.briarproject.android.controller.BriarController; -import org.briarproject.android.controller.ResultHandler; +import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.panic.ExitActivity; -import org.briarproject.api.db.DatabaseConfig; -import org.briarproject.api.db.DatabaseExecutor; -import org.briarproject.api.lifecycle.LifecycleManager; -import java.util.concurrent.Executor; import java.util.logging.Logger; import javax.inject.Inject; @@ -68,24 +61,14 @@ public abstract class BriarActivity extends BaseActivity { } } - @Override - public void onDestroy() { - super.onDestroy(); - briarController.unbindService(); - } - protected void signOut(final boolean removeFromRecentApps) { - briarController.signOut(new ResultHandler() { + briarController.signOut(new UiResultHandler(this) { + @Override - public void onResult(Void result) { + public void onResultUi(Void result) { if (removeFromRecentApps) startExitActivity(); else finishAndExit(); } - - @Override - public void onException(RuntimeException exception) { - // TODO ? - } }); } @@ -111,10 +94,12 @@ public abstract class BriarActivity extends BaseActivity { System.exit(0); } + @Deprecated public void runOnDbThread(final Runnable task) { briarController.runOnDbThread(task); } + @Deprecated protected void finishOnUiThread() { runOnUiThread(new Runnable() { public void run() { diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index 854504485..49fb824c2 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -10,7 +10,6 @@ import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.Toolbar; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -21,8 +20,8 @@ import android.widget.TextView; import org.briarproject.R; import org.briarproject.android.controller.NavDrawerController; -import org.briarproject.android.controller.ResultHandler; import org.briarproject.android.controller.TransportStateListener; +import org.briarproject.android.controller.handler.UiResultExceptionHandler; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.util.CustomAnimations; import org.briarproject.api.TransportId; @@ -160,14 +159,14 @@ public class NavDrawerActivity extends BriarFragmentActivity implements private void storeLocalAuthor(final LocalAuthor a) { controller.storeLocalAuthor(a, - new ResultHandler() { + new UiResultExceptionHandler(this) { @Override - public void onResult(Void result) { + public void onResultUi(Void result) { hideLoadingScreen(); } @Override - public void onException(DbException exception) { + public void onExceptionUi(DbException exception) { } }); diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java index 9f004527a..346b2f2cd 100644 --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -3,6 +3,7 @@ package org.briarproject.android; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; import android.text.Editable; @@ -16,9 +17,8 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; -import org.briarproject.android.controller.EncryptedKeyNullException; import org.briarproject.android.controller.PasswordController; -import org.briarproject.android.controller.ResultHandler; +import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.util.AndroidUtils; import javax.inject.Inject; @@ -36,13 +36,13 @@ public class PasswordActivity extends BaseActivity { private EditText password; @Inject - PasswordController passwordHelper; + PasswordController passwordController; @Override public void onCreate(Bundle state) { super.onCreate(state); - if (!passwordHelper.initialized()) { + if (!passwordController.initialized()) { clearSharedPrefsAndDeleteEverything(); return; } @@ -92,7 +92,7 @@ public class PasswordActivity extends BaseActivity { } private void clearSharedPrefsAndDeleteEverything() { - passwordHelper.clearPrefs(); + passwordController.clearPrefs(); AndroidUtils.deleteAppData(this); setResult(RESULT_CANCELED); startActivity(new Intent(this, SetupActivity.class)); @@ -125,22 +125,17 @@ public class PasswordActivity extends BaseActivity { hideSoftKeyboard(password); signInButton.setVisibility(INVISIBLE); progress.setVisibility(VISIBLE); - passwordHelper.validatePassword(password.getText().toString(), - new ResultHandler() { + passwordController.validatePassword(password.getText().toString(), + new UiResultHandler(this) { @Override - public void onResult(Boolean result) { - if (result != null && result) { + public void onResultUi(@NonNull Boolean result) { + if (result) { setResult(RESULT_OK); finish(); } else { tryAgain(); } } - - @Override - public void onException(EncryptedKeyNullException e) { - // TODO ? - } }); } diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index 1aaba344c..f54d1e861 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -2,6 +2,7 @@ package org.briarproject.android; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.design.widget.TextInputLayout; import android.text.Editable; import android.text.TextWatcher; @@ -15,11 +16,10 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; -import org.briarproject.android.controller.ResultHandler; import org.briarproject.android.controller.SetupController; +import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.StrengthMeter; - import org.briarproject.util.StringUtils; import javax.inject.Inject; @@ -135,16 +135,10 @@ public class SetupActivity extends BaseActivity implements OnClickListener, final String nickname = nicknameEntry.getText().toString(); final String password = passwordEntry.getText().toString(); setupController.createIdentity(nickname, password, - new ResultHandler() { + new UiResultHandler(this) { @Override - public void onResult(Long result) { - if (result != null) - showMain(result); - } - - @Override - public void onException(RuntimeException exception) { - + public void onResultUi(@NonNull Long result) { + showMain(result); } }); } diff --git a/briar-android/src/org/briarproject/android/controller/BriarController.java b/briar-android/src/org/briarproject/android/controller/BriarController.java index edb035cb3..342e19359 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarController.java +++ b/briar-android/src/org/briarproject/android/controller/BriarController.java @@ -1,6 +1,8 @@ package org.briarproject.android.controller; +import org.briarproject.android.controller.handler.ResultHandler; + public interface BriarController extends ActivityLifecycleController { void runOnDbThread(final Runnable task); @@ -10,5 +12,5 @@ public interface BriarController extends ActivityLifecycleController { boolean encryptionKey(); - void signOut(ResultHandler eventHandler); + void signOut(ResultHandler eventHandler); } diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java index 789b27af4..59ed95d3b 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java @@ -7,6 +7,7 @@ import android.support.annotation.CallSuper; import org.briarproject.android.BriarService; import org.briarproject.android.BriarService.BriarServiceConnection; +import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.lifecycle.LifecycleManager; @@ -75,7 +76,7 @@ public class BriarControllerImp implements BriarController { } @Override - public void signOut(final ResultHandler eventHandler) { + public void signOut(final ResultHandler eventHandler) { new Thread() { @Override public void run() { @@ -90,14 +91,8 @@ public class BriarControllerImp implements BriarController { service.waitForShutdown(); } catch (InterruptedException e) { LOG.warning("Interrupted while waiting for service"); - Thread.currentThread().interrupt(); } - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - eventHandler.onResult(null); - } - }); + eventHandler.onResult(null); } }.start(); } diff --git a/briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java b/briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java deleted file mode 100644 index 3da38efa4..000000000 --- a/briar-android/src/org/briarproject/android/controller/EncryptedKeyNullException.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.briarproject.android.controller; - -public class EncryptedKeyNullException extends NullPointerException { - - @Override - public String toString() { - return "Encrypted key can't be null"; - } -} diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java index 13dfbcc29..2669cc455 100644 --- a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java @@ -1,5 +1,6 @@ package org.briarproject.android.controller; +import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.api.TransportId; import org.briarproject.api.db.DbException; import org.briarproject.api.identity.LocalAuthor; @@ -10,7 +11,7 @@ public interface NavDrawerController extends BriarController { boolean transportRunning(TransportId transportId); void storeLocalAuthor(LocalAuthor author, - ResultHandler resultHandler); + ResultExceptionHandler resultHandler); LocalAuthor removeAuthorHandle(long handle); } diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java index f6b76c543..0a5d2c865 100644 --- a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java @@ -3,6 +3,7 @@ package org.briarproject.android.controller; import android.app.Activity; import org.briarproject.android.api.ReferenceManager; +import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.api.TransportId; import org.briarproject.api.db.DbException; import org.briarproject.api.event.Event; @@ -84,7 +85,8 @@ public class NavDrawerControllerImp extends BriarControllerImp } } - private void transportStateUpdate(final TransportId id, final boolean enabled) { + private void transportStateUpdate(final TransportId id, + final boolean enabled) { activity.runOnUiThread(new Runnable() { @Override public void run() { @@ -108,7 +110,8 @@ public class NavDrawerControllerImp extends BriarControllerImp @Override public void storeLocalAuthor(final LocalAuthor author, - final ResultHandler resultHandler) { + final ResultExceptionHandler resultHandler) { + runOnDbThread(new Runnable() { public void run() { try { @@ -117,22 +120,11 @@ public class NavDrawerControllerImp extends BriarControllerImp long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) LOG.info("Storing author took " + duration + " ms"); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - resultHandler.onResult(null); - } - }); + resultHandler.onResult(null); } catch (final DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - resultHandler.onException(e); - } - }); + resultHandler.onException(e); } } }); diff --git a/briar-android/src/org/briarproject/android/controller/PasswordController.java b/briar-android/src/org/briarproject/android/controller/PasswordController.java index b40ddb670..bf1c9b230 100644 --- a/briar-android/src/org/briarproject/android/controller/PasswordController.java +++ b/briar-android/src/org/briarproject/android/controller/PasswordController.java @@ -1,6 +1,8 @@ package org.briarproject.android.controller; +import org.briarproject.android.controller.handler.ResultHandler; + public interface PasswordController extends ConfigController { void validatePassword(String password, - ResultHandler resultHandler); + ResultHandler resultHandler); } diff --git a/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java b/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java index ed86bb9bd..8a85fc51b 100644 --- a/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java @@ -2,6 +2,7 @@ package org.briarproject.android.controller; import android.app.Activity; +import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.SecretKey; @@ -29,35 +30,21 @@ public class PasswordControllerImp extends ConfigControllerImp @Override public void validatePassword(final String password, - final ResultHandler resultHandler) { + final ResultHandler resultHandler) { final byte[] encrypted = getEncryptedKey(); - if (encrypted == null) { - resultHandler.onException(new EncryptedKeyNullException()); - } cryptoExecutor.execute(new Runnable() { public void run() { byte[] key = crypto.decryptWithPassword(encrypted, password); if (key == null) { - onPasswordValidated(false, resultHandler); + resultHandler.onResult(false); } else { databaseConfig.setEncryptionKey(new SecretKey(key)); - onPasswordValidated(true, resultHandler); + resultHandler.onResult(true); } } }); } - private void onPasswordValidated(final boolean validated, - final ResultHandler resultHandler) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - resultHandler.onResult(validated); - } - }); - } - - private byte[] getEncryptedKey() { String hex = getEncryptedDatabaseKey(); return hex == null ? null : StringUtils.fromHexString(hex); diff --git a/briar-android/src/org/briarproject/android/controller/ResultHandler.java b/briar-android/src/org/briarproject/android/controller/ResultHandler.java deleted file mode 100644 index 5f98763aa..000000000 --- a/briar-android/src/org/briarproject/android/controller/ResultHandler.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.briarproject.android.controller; - -public interface ResultHandler { - void onResult(R result); - void onException(E exception); -} diff --git a/briar-android/src/org/briarproject/android/controller/SetupController.java b/briar-android/src/org/briarproject/android/controller/SetupController.java index 884706c3f..476db0f5e 100644 --- a/briar-android/src/org/briarproject/android/controller/SetupController.java +++ b/briar-android/src/org/briarproject/android/controller/SetupController.java @@ -1,8 +1,10 @@ package org.briarproject.android.controller; +import org.briarproject.android.controller.handler.ResultHandler; + public interface SetupController { float estimatePasswordStrength(String password); void createIdentity(String nickname, String password, - ResultHandler resultHandler); + ResultHandler resultHandler); } diff --git a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java index 312502f42..61a933e67 100644 --- a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java @@ -3,8 +3,8 @@ package org.briarproject.android.controller; import android.app.Activity; import android.content.SharedPreferences; -import org.briarproject.android.BaseActivity; import org.briarproject.android.api.ReferenceManager; +import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.KeyPair; @@ -83,7 +83,7 @@ public class SetupControllerImp implements SetupController { @Override public void createIdentity(final String nickname, final String password, - final ResultHandler resultHandler) { + final ResultHandler resultHandler) { cryptoExecutor.execute(new Runnable() { public void run() { SecretKey key = crypto.generateSecretKey(); @@ -93,17 +93,6 @@ public class SetupControllerImp implements SetupController { final LocalAuthor localAuthor = createLocalAuthor(nickname); long handle = referenceManager.putReference(localAuthor, LocalAuthor.class); - onIdentityCreated(handle, resultHandler); - - } - }); - } - - private void onIdentityCreated(final long handle, - final ResultHandler resultHandler) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { resultHandler.onResult(handle); } }); diff --git a/briar-android/src/org/briarproject/android/controller/handler/ResultExceptionHandler.java b/briar-android/src/org/briarproject/android/controller/handler/ResultExceptionHandler.java new file mode 100644 index 000000000..5d3cb0301 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/handler/ResultExceptionHandler.java @@ -0,0 +1,6 @@ +package org.briarproject.android.controller.handler; + +public interface ResultExceptionHandler { + void onResult(R result); + void onException(E exception); +} diff --git a/briar-android/src/org/briarproject/android/controller/handler/ResultHandler.java b/briar-android/src/org/briarproject/android/controller/handler/ResultHandler.java new file mode 100644 index 000000000..55516f942 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/handler/ResultHandler.java @@ -0,0 +1,5 @@ +package org.briarproject.android.controller.handler; + +public interface ResultHandler { + void onResult(R result); +} diff --git a/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java b/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java new file mode 100644 index 000000000..7d9c08f4f --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java @@ -0,0 +1,33 @@ +package org.briarproject.android.controller.handler; + +import android.app.Activity; + +public abstract class UiResultExceptionHandler + implements ResultExceptionHandler { + + private final Activity activity; + + public UiResultExceptionHandler(Activity activity) { + this.activity = activity; + } + + public void onResult(final R result) { + activity.runOnUiThread(new Runnable() { + public void run() { + onResultUi(result); + } + }); + } + + public void onException(final E exception) { + activity.runOnUiThread(new Runnable() { + public void run() { + onExceptionUi(exception); + } + }); + } + + public abstract void onResultUi(R result); + + public abstract void onExceptionUi(E exception); +} diff --git a/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java b/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java new file mode 100644 index 000000000..1998060a5 --- /dev/null +++ b/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java @@ -0,0 +1,22 @@ +package org.briarproject.android.controller.handler; + +import android.app.Activity; + +public abstract class UiResultHandler implements ResultHandler { + + private final Activity activity; + + public UiResultHandler(Activity activity) { + this.activity = activity; + } + + public void onResult(final R result) { + activity.runOnUiThread(new Runnable() { + public void run() { + onResultUi(result); + } + }); + } + + public abstract void onResultUi(R result); +} diff --git a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java index 11e30d635..7b1bcbb5c 100644 --- a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java +++ b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java @@ -12,7 +12,6 @@ import android.view.View; import android.view.ViewGroup; import org.briarproject.R; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.contact.ContactListAdapter; import org.briarproject.android.contact.ContactListItem; import org.briarproject.android.contact.ConversationItem; @@ -66,6 +65,11 @@ public class ContactChooserFragment extends BaseFragment { @Inject protected volatile ConnectionRegistry connectionRegistry; + @Inject + public ContactChooserFragment() { + + } + @Override public void onAttach(Context context) { super.onAttach(context); @@ -77,11 +81,6 @@ public class ContactChooserFragment extends BaseFragment { } } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java b/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java index 2faee1a8a..79d511291 100644 --- a/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java +++ b/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java @@ -3,6 +3,7 @@ package org.briarproject.android.introduction; import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.transition.ChangeBounds; import android.transition.Fade; @@ -10,7 +11,7 @@ import android.view.MenuItem; import android.view.View; import org.briarproject.R; -import org.briarproject.android.AndroidComponent; +import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.api.contact.Contact; @@ -33,15 +34,15 @@ public class IntroductionActivity extends BriarActivity implements setContentView(R.layout.activity_introduction); if (savedInstanceState == null) { - ContactChooserFragment chooserFragment = - new ContactChooserFragment(); getSupportFragmentManager().beginTransaction() - .add(R.id.introductionContainer, chooserFragment).commit(); + .add(R.id.introductionContainer, + activityComponent.newContactChooserFragment()) + .commit(); } } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } @@ -85,13 +86,14 @@ public class IntroductionActivity extends BriarActivity implements final Contact c2) { IntroductionMessageFragment messageFragment = - IntroductionMessageFragment - .newInstance(c1.getId().getInt(), c2.getId().getInt()); + activityComponent.newIntroductionMessageFragment(); + messageFragment.initBundle(c1.getId().getInt(), c2.getId().getInt()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { messageFragment.setSharedElementEnterTransition(new ChangeBounds()); messageFragment.setEnterTransition(new Fade()); - messageFragment.setSharedElementReturnTransition(new ChangeBounds()); + messageFragment + .setSharedElementReturnTransition(new ChangeBounds()); } getSupportFragmentManager().beginTransaction() diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java index ed0547da4..ed9c7b3c7 100644 --- a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java +++ b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java @@ -13,7 +13,6 @@ import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.api.FormatException; import org.briarproject.api.contact.Contact; @@ -49,18 +48,19 @@ public class IntroductionMessageFragment extends BaseFragment { @Inject protected volatile IntroductionManager introductionManager; - public static IntroductionMessageFragment newInstance(int contactId1, - int contactId2) { - IntroductionMessageFragment f = new IntroductionMessageFragment(); - + public void initBundle(int contactId1, int contactId2) { Bundle args = new Bundle(); args.putInt(CONTACT_ID_1, contactId1); args.putInt(CONTACT_ID_2, contactId2); - f.setArguments(args); - - return f; + this.setArguments(args); } + @Inject + public IntroductionMessageFragment() { + + } + + @Override public void onAttach(Context context) { super.onAttach(context); @@ -72,11 +72,6 @@ public class IntroductionMessageFragment extends BaseFragment { } } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -183,7 +178,8 @@ public class IntroductionMessageFragment extends BaseFragment { // actually make the introduction try { long timestamp = System.currentTimeMillis(); - introductionManager.makeIntroduction(c1, c2, msg, timestamp); + introductionManager + .makeIntroduction(c1, c2, msg, timestamp); } catch (DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); diff --git a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java index 332efc655..acd8d36a1 100644 --- a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java +++ b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java @@ -6,7 +6,6 @@ import android.widget.Toast; import org.briarproject.R; import org.briarproject.android.ActivityComponent; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.ReferenceManager; import org.briarproject.api.crypto.CryptoComponent; @@ -287,7 +286,7 @@ implements InvitationListener { localInvitationCode, code); taskHandle = referenceManager.putReference(task, InvitationTask.class); task.addListener(AddContactActivity.this); - // Add a second listener so we can remove the first in onActivityDestroy(), + // Add a second listener so we can remove the first in onDestroy(), // allowing the activity to be garbage collected if it's destroyed task.addListener(new ReferenceCleaner(referenceManager, taskHandle)); task.connect(); diff --git a/briar-core/src/org/briarproject/introduction/IntroductionModule.java b/briar-core/src/org/briarproject/introduction/IntroductionModule.java index 9e51aca73..4ea0ac6c3 100644 --- a/briar-core/src/org/briarproject/introduction/IntroductionModule.java +++ b/briar-core/src/org/briarproject/introduction/IntroductionModule.java @@ -26,7 +26,7 @@ public class IntroductionModule { @Provides @Singleton - MessageValidator getValidator(MessageQueueManager messageQueueManager, + MessageValidator provideValidator(MessageQueueManager messageQueueManager, IntroductionManager introductionManager, MetadataEncoder metadataEncoder, ClientHelper clientHelper, Clock clock) { @@ -43,7 +43,7 @@ public class IntroductionModule { @Provides @Singleton - IntroductionManager getIntroductionManager( + IntroductionManager provideIntroductionManager( LifecycleManager lifecycleManager, ContactManager contactManager, MessageQueueManager messageQueueManager, From da50c5dcc31ba46d7b23236dabc8de13df835137 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Tue, 26 Apr 2016 12:05:25 +0200 Subject: [PATCH 10/19] cleanup and minor refactoring --- .../src/org/briarproject/android/AndroidComponent.java | 8 +++++++- .../src/org/briarproject/android/BaseActivity.java | 10 ---------- .../src/org/briarproject/android/BriarActivity.java | 2 -- .../src/org/briarproject/android/BriarService.java | 2 +- .../android/controller/BriarController.java | 2 -- .../android/controller/BriarControllerImp.java | 3 ++- 6 files changed, 10 insertions(+), 17 deletions(-) diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 623aba6e5..fe444a02f 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -47,11 +47,17 @@ import dagger.Component; }) public interface AndroidComponent extends CoreEagerSingletons { // Exposed objects - @CryptoExecutor Executor cryptoExecutor(); + @CryptoExecutor + Executor cryptoExecutor(); + PasswordStrengthEstimator passwordStrengthIndicator(); + CryptoComponent cryptoComponent(); + DatabaseConfig databaseConfig(); + AuthorFactory authFactory(); + ReferenceManager referenceMangager(); @DatabaseExecutor diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 6ae3eb8c2..e14eb2963 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -48,16 +48,6 @@ public abstract class BaseActivity extends AppCompatActivity { } } - @Override - public void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - // Post call used for controllers to ensure that the onCreate method - // override in inherited Activities has finished -// for (ActivityLifecycleController alc : lifecycleControllers) { -// alc.onActivityCreate(); -// } - } - @Override protected void onResume() { super.onResume(); diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java index fca3fd12d..901a04e42 100644 --- a/briar-android/src/org/briarproject/android/BriarActivity.java +++ b/briar-android/src/org/briarproject/android/BriarActivity.java @@ -38,8 +38,6 @@ public abstract class BriarActivity extends BaseActivity { @Override public void onCreate(Bundle state) { super.onCreate(state); - - briarController.startAndBindService(); } @Override diff --git a/briar-android/src/org/briarproject/android/BriarService.java b/briar-android/src/org/briarproject/android/BriarService.java index 6055c2d69..33d69c8f6 100644 --- a/briar-android/src/org/briarproject/android/BriarService.java +++ b/briar-android/src/org/briarproject/android/BriarService.java @@ -180,7 +180,7 @@ public class BriarService extends Service { /** Starts the shutdown process. */ public void shutdown() { - stopSelf(); // This will call onActivityDestroy() + stopSelf(); // This will call onDestroy() } public class BriarBinder extends Binder { diff --git a/briar-android/src/org/briarproject/android/controller/BriarController.java b/briar-android/src/org/briarproject/android/controller/BriarController.java index 342e19359..2ed024ee9 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarController.java +++ b/briar-android/src/org/briarproject/android/controller/BriarController.java @@ -8,8 +8,6 @@ public interface BriarController extends ActivityLifecycleController { void startAndBindService(); - void unbindService(); - boolean encryptionKey(); void signOut(ResultHandler eventHandler); diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java index 59ed95d3b..b959d66e8 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java @@ -45,6 +45,7 @@ public class BriarControllerImp implements BriarController { @Override @CallSuper public void onActivityCreate() { + LOG.info("onActivityCreate : " + databaseConfig.getEncryptionKey()); if (databaseConfig.getEncryptionKey() != null) startAndBindService(); } @@ -97,7 +98,7 @@ public class BriarControllerImp implements BriarController { }.start(); } - public void unbindService() { + private void unbindService() { if (bound) activity.unbindService(serviceConnection); } From aa3ef896f5c0f375e44b2260579e26866a3ad0c8 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Tue, 26 Apr 2016 12:21:14 +0200 Subject: [PATCH 11/19] further polish --- .../src/org/briarproject/android/BriarFragmentActivity.java | 3 +-- .../briarproject/android/controller/BriarControllerImp.java | 1 - .../android/introduction/IntroductionMessageFragment.java | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java index 28f992326..00fe0f39a 100644 --- a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java +++ b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java @@ -49,8 +49,7 @@ public abstract class BriarFragmentActivity extends BriarActivity { exiting. This models the typical Google navigation behaviour such as in Gmail/Inbox. */ - // FIXME -// startFragment(ContactListFragment.newInstance()); + startFragment(activityComponent.newContactListFragment()); } else { super.onBackPressed(); diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java index b959d66e8..9e7cadeae 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java @@ -45,7 +45,6 @@ public class BriarControllerImp implements BriarController { @Override @CallSuper public void onActivityCreate() { - LOG.info("onActivityCreate : " + databaseConfig.getEncryptionKey()); if (databaseConfig.getEncryptionKey() != null) startAndBindService(); } diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java index ed9c7b3c7..48f0726c0 100644 --- a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java +++ b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java @@ -52,7 +52,7 @@ public class IntroductionMessageFragment extends BaseFragment { Bundle args = new Bundle(); args.putInt(CONTACT_ID_1, contactId1); args.putInt(CONTACT_ID_2, contactId2); - this.setArguments(args); + setArguments(args); } @Inject From adb7d37f863cafbd77c9f7d0aa3f330340db2bf5 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Thu, 28 Apr 2016 15:28:35 +0200 Subject: [PATCH 12/19] implementing robolectric and mockito --- briar-android/build.gradle | 27 +- briar-android/proguard-rules.txt | 3 + .../briarproject/android/ActivityModule.java | 17 +- .../briarproject/android/BaseActivity.java | 7 +- .../briarproject/android/SetupActivity.java | 5 +- .../system/AndroidSeedProvider.java | 4 + .../IntroductionIntegrationTest.java | 859 ++++++++++++++++++ .../IntroductionIntegrationTestComponent.java | 80 ++ .../MessageSizeIntegrationTest.java | 90 ++ .../MessageSizeIntegrationTestComponent.java | 37 + .../SimplexMessagingIntegrationTest.java | 193 ++++ ...plexMessagingIntegrationTestComponent.java | 74 ++ .../briarproject/SyncIntegrationTest.java | 169 ++++ .../SyncIntegrationTestComponent.java | 21 + .../activity/SetupActivityTest.java | 69 ++ .../activity/TestActivityModule.java | 19 + .../controller/SetupControllerTest.java | 17 + .../system/LinuxSeedProvider.java | 6 +- 18 files changed, 1681 insertions(+), 16 deletions(-) create mode 100644 briar-android/test/java/briarproject/IntroductionIntegrationTest.java create mode 100644 briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java create mode 100644 briar-android/test/java/briarproject/MessageSizeIntegrationTest.java create mode 100644 briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java create mode 100644 briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java create mode 100644 briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java create mode 100644 briar-android/test/java/briarproject/SyncIntegrationTest.java create mode 100644 briar-android/test/java/briarproject/SyncIntegrationTestComponent.java create mode 100644 briar-android/test/java/briarproject/activity/SetupActivityTest.java create mode 100644 briar-android/test/java/briarproject/activity/TestActivityModule.java create mode 100644 briar-android/test/java/briarproject/controller/SetupControllerTest.java diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 6ff778d86..815c8de62 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -8,6 +8,7 @@ apply plugin: 'de.undercouch.download' repositories { jcenter() + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } } dependencies { @@ -44,6 +45,18 @@ dependencies { compile 'com.google.zxing:core:3.2.1' apt 'com.google.dagger:dagger-compiler:2.0.2' provided 'javax.annotation:jsr250-api:1.0' + + testCompile 'junit:junit:4.12' + testCompile 'net.jodah:concurrentunit:0.4.2' + testApt 'com.google.dagger:dagger-compiler:2.4' + testCompile project(path: ':briar-tests') + testCompile 'org.robolectric:robolectric:3.1-SNAPSHOT' + testCompile 'org.mockito:mockito-core:1.10.19' + + androidTestCompile 'org.robolectric:robolectric:3.0' + androidTestCompile 'org.mockito:mockito-core:1.10.19' + androidTestApt 'com.google.dagger:dagger-compiler:2.4' + androidTestCompile 'junit:junit:4.12' } dependencyVerification { @@ -81,7 +94,19 @@ android { } // Move the tests to tests/java, tests/res, etc... - instrumentTest.setRoot('tests') + //instrumentTest.setRoot('tests') +// unitTest.setRoot('tests') + + androidTest.setRoot('androidTest') + androidTest { + java.srcDirs = ['androidTest/java'] + } + + test.setRoot('test') + test { + java.srcDirs = ['test/java'] + } + // Move the build types to build-types/ // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... diff --git a/briar-android/proguard-rules.txt b/briar-android/proguard-rules.txt index 48d785a43..df28bc507 100644 --- a/briar-android/proguard-rules.txt +++ b/briar-android/proguard-rules.txt @@ -48,6 +48,9 @@ -keep class roboguice.** { *; } -keep class dagger.** { *; } -keep class com.google.** { *; } +-keep class javax.** { *; } +-keep class org.eclipse.** { *; } +-keep class com.squareup.** { *; } -dontwarn org.h2.** -dontnote org.h2.** diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 33accc970..70d3b00ab 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -54,34 +54,33 @@ public class ActivityModule { @ActivityScope @Provides - SetupController provideSetupController( - SetupControllerImp setupControllerImp) { - return setupControllerImp; + protected SetupController provideSetupController() { + return new SetupControllerImp(); } @ActivityScope @Provides - ConfigController provideConfigController( + protected ConfigController provideConfigController( ConfigControllerImp configControllerImp) { return configControllerImp; } @ActivityScope @Provides - SharedPreferences provideSharedPreferences(Activity activity) { + protected SharedPreferences provideSharedPreferences(Activity activity) { return activity.getSharedPreferences("db", Context.MODE_PRIVATE); } @ActivityScope @Provides - PasswordController providePasswordController( + protected PasswordController providePasswordController( PasswordControllerImp passwordControllerImp) { return passwordControllerImp; } @ActivityScope @Provides - BriarController provideBriarController( + protected BriarController provideBriarController( BriarControllerImp briarControllerImp) { activity.addLifecycleController(briarControllerImp); return briarControllerImp; @@ -89,7 +88,7 @@ public class ActivityModule { @ActivityScope @Provides - NavDrawerController provideNavDrawerController( + protected NavDrawerController provideNavDrawerController( NavDrawerControllerImp navDrawerControllerImp) { activity.addLifecycleController(navDrawerControllerImp); if (activity instanceof TransportStateListener) { @@ -101,7 +100,7 @@ public class ActivityModule { @ActivityScope @Provides - BriarServiceConnection provideBriarServiceConnection() { + protected BriarServiceConnection provideBriarServiceConnection() { return new BriarServiceConnection(); } diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index e14eb2963..fa2e68d6b 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -38,7 +38,7 @@ public abstract class BaseActivity extends AppCompatActivity { activityComponent = DaggerActivityComponent.builder() .androidComponent(applicationComponent) - .activityModule(new ActivityModule(this)) + .activityModule(getActivityModule()) .build(); injectActivity(activityComponent); @@ -48,6 +48,11 @@ public abstract class BaseActivity extends AppCompatActivity { } } + // This exists to make test overrides easier + protected ActivityModule getActivityModule() { + return new ActivityModule(this); + } + @Override protected void onResume() { super.onResume(); diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index f54d1e861..c3cb01cb3 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -27,8 +27,6 @@ import javax.inject.Inject; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; -import static android.view.WindowManager.LayoutParams.FLAG_SECURE; -import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; @@ -66,7 +64,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, createAccountButton = (Button) findViewById(R.id.create_account); progress = (ProgressBar) findViewById(R.id.progress_wheel); - if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); +// if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); TextWatcher tw = new TextWatcher() { @Override @@ -125,6 +123,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { hideSoftKeyboard(v); + return true; } diff --git a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java index c15e0b411..749d1c68b 100644 --- a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java +++ b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java @@ -8,6 +8,7 @@ import android.provider.Settings; import java.io.DataOutputStream; import java.io.IOException; +import java.util.logging.Logger; import javax.inject.Inject; @@ -15,6 +16,9 @@ import static android.provider.Settings.Secure.ANDROID_ID; class AndroidSeedProvider extends LinuxSeedProvider { + private static final Logger LOG = + Logger.getLogger(LinuxSeedProvider.class.getName()); + private final Context appContext; @Inject diff --git a/briar-android/test/java/briarproject/IntroductionIntegrationTest.java b/briar-android/test/java/briarproject/IntroductionIntegrationTest.java new file mode 100644 index 000000000..e92b54546 --- /dev/null +++ b/briar-android/test/java/briarproject/IntroductionIntegrationTest.java @@ -0,0 +1,859 @@ +package briarproject; + +import net.jodah.concurrentunit.Waiter; + +import org.briarproject.BriarTestCase; +import org.briarproject.TestDatabaseModule; +import org.briarproject.TestUtils; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.IntroductionAbortedEvent; +import org.briarproject.api.event.IntroductionRequestReceivedEvent; +import org.briarproject.api.event.IntroductionResponseReceivedEvent; +import org.briarproject.api.event.IntroductionSucceededEvent; +import org.briarproject.api.event.MessageValidatedEvent; +import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.api.introduction.IntroductionManager; +import org.briarproject.api.introduction.IntroductionRequest; +import org.briarproject.api.introduction.SessionId; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.properties.TransportProperties; +import org.briarproject.api.properties.TransportPropertyManager; +import org.briarproject.api.sync.SyncSession; +import org.briarproject.api.sync.SyncSessionFactory; +import org.briarproject.api.system.Clock; +import org.briarproject.contact.ContactModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.introduction.IntroductionModule; +import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.properties.PropertiesModule; +import org.briarproject.sync.SyncModule; +import org.briarproject.transport.TransportModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.concurrent.TimeoutException; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import static org.briarproject.TestPluginsModule.MAX_LATENCY; +import static org.briarproject.TestPluginsModule.TRANSPORT_ID; +import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class IntroductionIntegrationTest extends BriarTestCase { + + LifecycleManager lifecycleManager0, lifecycleManager1, lifecycleManager2; + SyncSessionFactory sync0, sync1, sync2; + ContactManager contactManager0, contactManager1, contactManager2; + ContactId contactId0, contactId1, contactId2; + IdentityManager identityManager0, identityManager1, identityManager2; + LocalAuthor author0, author1, author2; + + @Inject + Clock clock; + @Inject + AuthorFactory authorFactory; + + // objects accessed from background threads need to be volatile + private volatile IntroductionManager introductionManager0; + private volatile IntroductionManager introductionManager1; + private volatile IntroductionManager introductionManager2; + private volatile Waiter eventWaiter; + private volatile Waiter msgWaiter; + + private final File testDir = TestUtils.getTestDirectory(); + private final SecretKey master = TestUtils.getSecretKey(); + private final int TIMEOUT = 15000; + private final String INTRODUCER = "Introducer"; + private final String INTRODUCEE1 = "Introducee1"; + private final String INTRODUCEE2 = "Introducee2"; + + private static final Logger LOG = + Logger.getLogger(IntroductionIntegrationTest.class.getName()); + + private IntroductionIntegrationTestComponent t0, t1, t2; + + @Before + public void setUp() { + IntroductionIntegrationTestComponent component = + DaggerIntroductionIntegrationTestComponent.builder().build(); + component.inject(this); + injectEagerSingletons(component); + + assertTrue(testDir.mkdirs()); + File t0Dir = new File(testDir, INTRODUCER); + t0 = DaggerIntroductionIntegrationTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(t0Dir)).build(); + injectEagerSingletons(t0); + File t1Dir = new File(testDir, INTRODUCEE1); + t1 = DaggerIntroductionIntegrationTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(t1Dir)).build(); + injectEagerSingletons(t1); + File t2Dir = new File(testDir, INTRODUCEE2); + t2 = DaggerIntroductionIntegrationTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(t2Dir)).build(); + injectEagerSingletons(t2); + + identityManager0 = t0.getIdentityManager(); + identityManager1 = t1.getIdentityManager(); + identityManager2 = t2.getIdentityManager(); + contactManager0 = t0.getContactManager(); + contactManager1 = t1.getContactManager(); + contactManager2 = t2.getContactManager(); + introductionManager0 = t0.getIntroductionManager(); + introductionManager1 = t1.getIntroductionManager(); + introductionManager2 = t2.getIntroductionManager(); + sync0 = t0.getSyncSessionFactory(); + sync1 = t1.getSyncSessionFactory(); + sync2 = t2.getSyncSessionFactory(); + + // initialize waiters fresh for each test + eventWaiter = new Waiter(); + msgWaiter = new Waiter(); + } + + @Test + public void testIntroductionSession() throws Exception { + startLifecycles(); + try { + // Add Identities + addDefaultIdentities(); + + // Add Transport Properties + addTransportProperties(); + + // Add introducees as contacts + contactId1 = contactManager0.addContact(author1, + author0.getId(), master, clock.currentTimeMillis(), true, + true + ); + contactId2 = contactManager0.addContact(author2, + author0.getId(), master, clock.currentTimeMillis(), true, + true + ); + // Add introducer back + contactId0 = contactManager1.addContact(author0, + author1.getId(), master, clock.currentTimeMillis(), true, + true + ); + ContactId contactId02 = contactManager2.addContact(author0, + author2.getId(), master, clock.currentTimeMillis(), true, + true + ); + assertTrue(contactId0.equals(contactId02)); + + // listen to events + IntroducerListener listener0 = new IntroducerListener(); + t0.getEventBus().addListener(listener0); + IntroduceeListener listener1 = new IntroduceeListener(1, true); + t1.getEventBus().addListener(listener1); + IntroduceeListener listener2 = new IntroduceeListener(2, true); + t2.getEventBus().addListener(listener2); + + // make introduction + long time = clock.currentTimeMillis(); + Contact introducee1 = contactManager0.getContact(contactId1); + Contact introducee2 = contactManager0.getContact(contactId2); + introductionManager0 + .makeIntroduction(introducee1, introducee2, "Hi!", time); + + // sync first request message + deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener1.requestReceived); + + // sync second request message + deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener2.requestReceived); + + // sync first response + deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response1Received); + + // sync second response + deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response2Received); + + // sync forwarded responses to introducees + deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1"); + deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2"); + + // sync first ACK and its forward + deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); + deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2"); + + // sync second ACK and its forward + deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); + deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 2"); + + // wait for introduction to succeed + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener1.succeeded); + assertTrue(listener2.succeeded); + + assertTrue(contactManager1 + .contactExists(author2.getId(), author1.getId())); + assertTrue(contactManager2 + .contactExists(author1.getId(), author2.getId())); + + assertDefaultUiMessages(); + } finally { + stopLifecycles(); + } + } + + @Test + public void testIntroductionSessionFirstDecline() throws Exception { + startLifecycles(); + try { + // Add Identities + addDefaultIdentities(); + + // Add Transport Properties + addTransportProperties(); + + // Add introducees as contacts + contactId1 = contactManager0.addContact(author1, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + contactId2 = contactManager0.addContact(author2, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + // Add introducer back + contactId0 = contactManager1.addContact(author0, author1.getId(), + master, clock.currentTimeMillis(), true, true + ); + ContactId contactId02 = contactManager2.addContact(author0, + author2.getId(), master, clock.currentTimeMillis(), true, + true + ); + assertTrue(contactId0.equals(contactId02)); + + // listen to events + IntroducerListener listener0 = new IntroducerListener(); + t0.getEventBus().addListener(listener0); + IntroduceeListener listener1 = new IntroduceeListener(1, false); + t1.getEventBus().addListener(listener1); + IntroduceeListener listener2 = new IntroduceeListener(2, true); + t2.getEventBus().addListener(listener2); + + // make introduction + long time = clock.currentTimeMillis(); + Contact introducee1 = contactManager0.getContact(contactId1); + Contact introducee2 = contactManager0.getContact(contactId2); + introductionManager0 + .makeIntroduction(introducee1, introducee2, null, time); + + // sync request messages + deliverMessage(sync0, contactId0, sync1, contactId1); + deliverMessage(sync0, contactId0, sync2, contactId2); + + // wait for requests to arrive + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener1.requestReceived); + assertTrue(listener2.requestReceived); + + // sync first response + deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response1Received); + + // sync second response + deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response2Received); + + // sync first forwarded response + deliverMessage(sync0, contactId0, sync2, contactId2); + + // note how the introducer does not forward the second response, + // because after the first decline the protocol finished + + assertFalse(listener1.succeeded); + assertFalse(listener2.succeeded); + + assertFalse(contactManager1 + .contactExists(author2.getId(), author1.getId())); + assertFalse(contactManager2 + .contactExists(author1.getId(), author2.getId())); + + assertEquals(2, + introductionManager0.getIntroductionMessages(contactId1) + .size()); + assertEquals(2, + introductionManager0.getIntroductionMessages(contactId2) + .size()); + assertEquals(2, + introductionManager1.getIntroductionMessages(contactId0) + .size()); + // introducee2 should also have the decline response of introducee1 + assertEquals(3, + introductionManager2.getIntroductionMessages(contactId0) + .size()); + } finally { + stopLifecycles(); + } + } + + @Test + public void testIntroductionSessionSecondDecline() throws Exception { + startLifecycles(); + try { + // Add Identities + addDefaultIdentities(); + + // Add Transport Properties + addTransportProperties(); + + // Add introducees as contacts + contactId1 = contactManager0.addContact(author1, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + contactId2 = contactManager0.addContact(author2, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + // Add introducer back + contactId0 = contactManager1.addContact(author0, author1.getId(), + master, clock.currentTimeMillis(), false, true + ); + ContactId contactId02 = contactManager2.addContact(author0, + author2.getId(), master, clock.currentTimeMillis(), false, + true + ); + assertTrue(contactId0.equals(contactId02)); + + // listen to events + IntroducerListener listener0 = new IntroducerListener(); + t0.getEventBus().addListener(listener0); + IntroduceeListener listener1 = new IntroduceeListener(1, true); + t1.getEventBus().addListener(listener1); + IntroduceeListener listener2 = new IntroduceeListener(2, false); + t2.getEventBus().addListener(listener2); + + // make introduction + long time = clock.currentTimeMillis(); + Contact introducee1 = contactManager0.getContact(contactId1); + Contact introducee2 = contactManager0.getContact(contactId2); + introductionManager0 + .makeIntroduction(introducee1, introducee2, null, time); + + // sync request messages + deliverMessage(sync0, contactId0, sync1, contactId1); + deliverMessage(sync0, contactId0, sync2, contactId2); + + // wait for requests to arrive + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener1.requestReceived); + assertTrue(listener2.requestReceived); + + // sync first response + deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response1Received); + + // sync second response + deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response2Received); + + // sync both forwarded response + deliverMessage(sync0, contactId0, sync2, contactId2); + deliverMessage(sync0, contactId0, sync1, contactId1); + + assertFalse(contactManager1 + .contactExists(author2.getId(), author1.getId())); + assertFalse(contactManager2 + .contactExists(author1.getId(), author2.getId())); + + assertEquals(2, + introductionManager0.getIntroductionMessages(contactId1) + .size()); + assertEquals(2, + introductionManager0.getIntroductionMessages(contactId2) + .size()); + // introducee1 also sees the decline response from introducee2 + assertEquals(3, + introductionManager1.getIntroductionMessages(contactId0) + .size()); + assertEquals(2, + introductionManager2.getIntroductionMessages(contactId0) + .size()); + } finally { + stopLifecycles(); + } + } + + @Test + public void testIntroductionSessionDelayedFirstDecline() throws Exception { + startLifecycles(); + try { + // Add Identities + addDefaultIdentities(); + + // Add Transport Properties + addTransportProperties(); + + // Add introducees as contacts + contactId1 = contactManager0.addContact(author1, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + contactId2 = contactManager0.addContact(author2, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + // Add introducer back + contactId0 = contactManager1.addContact(author0, author1.getId(), + master, clock.currentTimeMillis(), false, true + ); + ContactId contactId02 = contactManager2.addContact(author0, + author2.getId(), master, clock.currentTimeMillis(), false, + true + ); + assertTrue(contactId0.equals(contactId02)); + + // listen to events + IntroducerListener listener0 = new IntroducerListener(); + t0.getEventBus().addListener(listener0); + IntroduceeListener listener1 = new IntroduceeListener(1, false); + t1.getEventBus().addListener(listener1); + IntroduceeListener listener2 = new IntroduceeListener(2, false); + t2.getEventBus().addListener(listener2); + + // make introduction + long time = clock.currentTimeMillis(); + Contact introducee1 = contactManager0.getContact(contactId1); + Contact introducee2 = contactManager0.getContact(contactId2); + introductionManager0 + .makeIntroduction(introducee1, introducee2, null, time); + + // sync request messages + deliverMessage(sync0, contactId0, sync1, contactId1); + deliverMessage(sync0, contactId0, sync2, contactId2); + + // wait for requests to arrive + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener1.requestReceived); + assertTrue(listener2.requestReceived); + + // sync first response + deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response1Received); + + // sync second response + deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response2Received); + + // sync first forwarded response + deliverMessage(sync0, contactId0, sync2, contactId2); + + // note how the second response will not be forwarded anymore + + assertFalse(contactManager1 + .contactExists(author2.getId(), author1.getId())); + assertFalse(contactManager2 + .contactExists(author1.getId(), author2.getId())); + + // since introducee2 was already in FINISHED state when + // introducee1's response arrived, she ignores and deletes it + assertDefaultUiMessages(); + } finally { + stopLifecycles(); + } + } + + @Test + public void testIntroductionToSameContact() throws Exception { + startLifecycles(); + try { + // Add Identities + addDefaultIdentities(); + + // Add Transport Properties + addTransportProperties(); + + // Add introducee as contact + contactId1 = contactManager0.addContact(author1, author0.getId(), + master, clock.currentTimeMillis(), true, true + ); + // Add introducer back + contactId0 = contactManager1.addContact(author0, author1.getId(), + master, clock.currentTimeMillis(), true, true + ); + + // listen to events + IntroducerListener listener0 = new IntroducerListener(); + t0.getEventBus().addListener(listener0); + IntroduceeListener listener1 = new IntroduceeListener(1, true); + t1.getEventBus().addListener(listener1); + + // make introduction + long time = clock.currentTimeMillis(); + Contact introducee1 = contactManager0.getContact(contactId1); + introductionManager0 + .makeIntroduction(introducee1, introducee1, null, time); + + // sync request messages + deliverMessage(sync0, contactId0, sync1, contactId1); + + // we should not get any event, because the request will be discarded + assertFalse(listener1.requestReceived); + + // make really sure we don't have that request + assertTrue(introductionManager1.getIntroductionMessages(contactId0) + .isEmpty()); + } finally { + stopLifecycles(); + } + } + + @Test + public void testIntroductionToIdentitiesOfSameContact() throws Exception { + startLifecycles(); + try { + // Add Identities + author0 = authorFactory.createLocalAuthor(INTRODUCER, + TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), + TestUtils.getRandomBytes(123)); + identityManager0.addLocalAuthor(author0); + author1 = authorFactory.createLocalAuthor(INTRODUCEE1, + TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), + TestUtils.getRandomBytes(123)); + identityManager1.addLocalAuthor(author1); + author2 = authorFactory.createLocalAuthor(INTRODUCEE2, + TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), + TestUtils.getRandomBytes(123)); + identityManager1.addLocalAuthor(author2); + + // Add Transport Properties + addTransportProperties(); + + // Add introducees' authors as contacts + contactId1 = contactManager0.addContact(author1, + author0.getId(), master, clock.currentTimeMillis(), true, + true + ); + contactId2 = contactManager0.addContact(author2, + author0.getId(), master, clock.currentTimeMillis(), true, + true + ); + // Add introducer back + contactId0 = null; + ContactId contactId01 = contactManager1.addContact(author0, + author1.getId(), master, clock.currentTimeMillis(), false, + true + ); + ContactId contactId02 = contactManager1.addContact(author0, + author2.getId(), master, clock.currentTimeMillis(), false, + true + ); + + // listen to events + IntroducerListener listener0 = new IntroducerListener(); + t0.getEventBus().addListener(listener0); + IntroduceeListener listener1 = new IntroduceeListener(1, true); + t1.getEventBus().addListener(listener1); + + // make introduction + long time = clock.currentTimeMillis(); + Contact introducee1 = contactManager0.getContact(contactId1); + Contact introducee2 = contactManager0.getContact(contactId2); + introductionManager0 + .makeIntroduction(introducee1, introducee2, "Hi!", time); + + // sync request messages + deliverMessage(sync0, contactId01, sync1, contactId1); + deliverMessage(sync0, contactId02, sync1, contactId2); + + // wait for request to arrive + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener1.requestReceived); + + // sync responses + deliverMessage(sync1, contactId1, sync0, contactId01); + deliverMessage(sync1, contactId2, sync0, contactId02); + + // wait for two responses to arrive + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener0.response1Received); + assertTrue(listener0.response2Received); + + // sync forwarded responses to introducees + deliverMessage(sync0, contactId01, sync1, contactId1); + deliverMessage(sync0, contactId02, sync1, contactId2); + + // wait for "both" introducees to abort session + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener1.aborted); + + // sync abort message + deliverMessage(sync1, contactId1, sync0, contactId01); + deliverMessage(sync1, contactId2, sync0, contactId02); + + // wait for introducer to abort session (gets event twice) + eventWaiter.await(TIMEOUT, 2); + assertTrue(listener0.aborted); + + assertFalse(contactManager1 + .contactExists(author1.getId(), author2.getId())); + assertFalse(contactManager1 + .contactExists(author2.getId(), author1.getId())); + + assertEquals(2, introductionManager0.getIntroductionMessages( + contactId1).size()); + assertEquals(2, introductionManager0.getIntroductionMessages( + contactId2).size()); + assertEquals(2, introductionManager1.getIntroductionMessages( + contactId01).size()); + assertEquals(2, introductionManager1.getIntroductionMessages( + contactId02).size()); + } finally { + stopLifecycles(); + } + } + + // TODO add a test for faking responses when #256 is implemented + + @After + public void tearDown() throws InterruptedException { + TestUtils.deleteTestDirectory(testDir); + } + + private void startLifecycles() throws InterruptedException { + // Start the lifecycle manager and wait for it to finish + lifecycleManager0 = t0.getLifecycleManager(); + lifecycleManager1 = t1.getLifecycleManager(); + lifecycleManager2 = t2.getLifecycleManager(); + lifecycleManager0.startServices(); + lifecycleManager1.startServices(); + lifecycleManager2.startServices(); + lifecycleManager0.waitForStartup(); + lifecycleManager1.waitForStartup(); + lifecycleManager2.waitForStartup(); + } + + private void stopLifecycles() throws InterruptedException { + // Clean up + lifecycleManager0.stopServices(); + lifecycleManager1.stopServices(); + lifecycleManager2.stopServices(); + lifecycleManager0.waitForShutdown(); + lifecycleManager1.waitForShutdown(); + lifecycleManager2.waitForShutdown(); + } + + private void addTransportProperties() throws DbException { + TransportPropertyManager tpm0 = t0.getTransportPropertyManager(); + TransportPropertyManager tpm1 = t1.getTransportPropertyManager(); + TransportPropertyManager tpm2 = t2.getTransportPropertyManager(); + + TransportProperties tp = new TransportProperties( + Collections.singletonMap("key", "value")); + tpm0.mergeLocalProperties(TRANSPORT_ID, tp); + tpm1.mergeLocalProperties(TRANSPORT_ID, tp); + tpm2.mergeLocalProperties(TRANSPORT_ID, tp); + } + + private void addDefaultIdentities() throws DbException { + author0 = authorFactory.createLocalAuthor(INTRODUCER, + TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), + TestUtils.getRandomBytes(123)); + identityManager0.addLocalAuthor(author0); + author1 = authorFactory.createLocalAuthor(INTRODUCEE1, + TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), + TestUtils.getRandomBytes(123)); + identityManager1.addLocalAuthor(author1); + author2 = authorFactory.createLocalAuthor(INTRODUCEE2, + TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), + TestUtils.getRandomBytes(123)); + identityManager2.addLocalAuthor(author2); + } + + private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId, + SyncSessionFactory toSync, ContactId toId) + throws IOException, TimeoutException { + deliverMessage(fromSync, fromId, toSync, toId, null); + } + + private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId, + SyncSessionFactory toSync, ContactId toId, String debug) + throws IOException, TimeoutException { + + if (debug != null) LOG.info("TEST: Sending message from " + debug); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + // Create an outgoing sync session + SyncSession sessionFrom = + fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out); + // Write whatever needs to be written + sessionFrom.run(); + out.close(); + + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + // Create an incoming sync session + SyncSession sessionTo = toSync.createIncomingSession(fromId, in); + // Read whatever needs to be read + sessionTo.run(); + in.close(); + + // wait for message to actually arrive + msgWaiter.await(TIMEOUT, 1); + } + + private void assertDefaultUiMessages() throws DbException { + assertEquals(2, introductionManager0.getIntroductionMessages( + contactId1).size()); + assertEquals(2, introductionManager0.getIntroductionMessages( + contactId2).size()); + assertEquals(2, introductionManager1.getIntroductionMessages( + contactId0).size()); + assertEquals(2, introductionManager2.getIntroductionMessages( + contactId0).size()); + } + + private class IntroduceeListener implements EventListener { + + public volatile boolean requestReceived = false; + public volatile boolean succeeded = false; + public volatile boolean aborted = false; + + private final int introducee; + private final boolean accept; + + IntroduceeListener(int introducee, boolean accept) { + this.introducee = introducee; + this.accept = accept; + } + + public void eventOccurred(Event e) { + if (e instanceof MessageValidatedEvent) { + MessageValidatedEvent event = (MessageValidatedEvent) e; + if (event.getClientId() + .equals(introductionManager0.getClientId()) && + !event.isLocal()) { + LOG.info("TEST: Introducee" + introducee + + " received message in group " + + ((MessageValidatedEvent) e).getMessage() + .getGroupId().hashCode()); + msgWaiter.resume(); + } + } else if (e instanceof IntroductionRequestReceivedEvent) { + IntroductionRequestReceivedEvent introEvent = + ((IntroductionRequestReceivedEvent) e); + requestReceived = true; + IntroductionRequest ir = introEvent.getIntroductionRequest(); + ContactId contactId = introEvent.getContactId(); + SessionId sessionId = ir.getSessionId(); + long time = clock.currentTimeMillis(); + try { + if (introducee == 1) { + if (accept) { + introductionManager1 + .acceptIntroduction(contactId, sessionId, + time); + } else { + introductionManager1 + .declineIntroduction(contactId, sessionId, + time); + } + } else if (introducee == 2) { + if (accept) { + introductionManager2 + .acceptIntroduction(contactId, sessionId, + time); + } else { + introductionManager2 + .declineIntroduction(contactId, sessionId, + time); + } + } + } catch (DbException exception) { + eventWaiter.rethrow(exception); + } catch (IOException exception) { + eventWaiter.rethrow(exception); + } finally { + eventWaiter.resume(); + } + } else if (e instanceof IntroductionSucceededEvent) { + succeeded = true; + Contact contact = ((IntroductionSucceededEvent) e).getContact(); + eventWaiter.assertFalse(contact.getId().equals(contactId0)); + eventWaiter.assertTrue(contact.isActive()); + eventWaiter.resume(); + } else if (e instanceof IntroductionAbortedEvent) { + aborted = true; + eventWaiter.resume(); + } + } + } + + private class IntroducerListener implements EventListener { + + public volatile boolean response1Received = false; + public volatile boolean response2Received = false; + public volatile boolean aborted = false; + + public void eventOccurred(Event e) { + if (e instanceof MessageValidatedEvent) { + MessageValidatedEvent event = (MessageValidatedEvent) e; + if (event.getClientId() + .equals(introductionManager0.getClientId()) && + !event.isLocal()) { + LOG.info("TEST: Introducer received message in group " + + ((MessageValidatedEvent) e).getMessage() + .getGroupId().hashCode()); + msgWaiter.resume(); + } + } else if (e instanceof IntroductionResponseReceivedEvent) { + ContactId c = + ((IntroductionResponseReceivedEvent) e).getContactId(); + try { + if (c.equals(contactId1)) { + response1Received = true; + } else if (c.equals(contactId2)) { + response2Received = true; + } + } finally { + eventWaiter.resume(); + } + } else if (e instanceof IntroductionAbortedEvent) { + aborted = true; + eventWaiter.resume(); + } + } + } + + private void injectEagerSingletons( + IntroductionIntegrationTestComponent component) { + + component.inject(new LifecycleModule.EagerSingletons()); + component.inject(new LifecycleModule.EagerSingletons()); + component.inject(new IntroductionModule.EagerSingletons()); + component.inject(new CryptoModule.EagerSingletons()); + component.inject(new ContactModule.EagerSingletons()); + component.inject(new TransportModule.EagerSingletons()); + component.inject(new SyncModule.EagerSingletons()); + component.inject(new PropertiesModule.EagerSingletons()); + } + +} diff --git a/briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java b/briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java new file mode 100644 index 000000000..d86b50d7c --- /dev/null +++ b/briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java @@ -0,0 +1,80 @@ +package briarproject; + +import org.briarproject.TestDatabaseModule; +import org.briarproject.TestPluginsModule; +import org.briarproject.TestSystemModule; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.introduction.IntroductionManager; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.properties.TransportPropertyManager; +import org.briarproject.api.sync.SyncSessionFactory; +import org.briarproject.clients.ClientsModule; +import org.briarproject.contact.ContactModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.data.DataModule; +import org.briarproject.db.DatabaseModule; +import org.briarproject.event.EventModule; +import org.briarproject.identity.IdentityModule; +import org.briarproject.introduction.IntroductionModule; +import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.properties.PropertiesModule; +import org.briarproject.sync.SyncModule; +import org.briarproject.transport.TransportModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + TestSystemModule.class, + TestDatabaseModule.class, + TestPluginsModule.class, + LifecycleModule.class, + IntroductionModule.class, + DatabaseModule.class, + CryptoModule.class, + EventModule.class, + ContactModule.class, + IdentityModule.class, + TransportModule.class, + ClientsModule.class, + SyncModule.class, + DataModule.class, + PropertiesModule.class +}) +public interface IntroductionIntegrationTestComponent { + + void inject(IntroductionIntegrationTest testCase); + + void inject(ContactModule.EagerSingletons init); + + void inject(CryptoModule.EagerSingletons init); + + void inject(IntroductionModule.EagerSingletons init); + + void inject(LifecycleModule.EagerSingletons init); + + void inject(PropertiesModule.EagerSingletons init); + + void inject(SyncModule.EagerSingletons init); + + void inject(TransportModule.EagerSingletons init); + + LifecycleManager getLifecycleManager(); + + EventBus getEventBus(); + + IdentityManager getIdentityManager(); + + ContactManager getContactManager(); + + IntroductionManager getIntroductionManager(); + + TransportPropertyManager getTransportPropertyManager(); + + SyncSessionFactory getSyncSessionFactory(); + +} diff --git a/briar-android/test/java/briarproject/MessageSizeIntegrationTest.java b/briar-android/test/java/briarproject/MessageSizeIntegrationTest.java new file mode 100644 index 000000000..d46c26f43 --- /dev/null +++ b/briar-android/test/java/briarproject/MessageSizeIntegrationTest.java @@ -0,0 +1,90 @@ +package briarproject; + +import org.briarproject.BriarTestCase; +import org.briarproject.TestUtils; +import org.briarproject.api.UniqueId; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.PrivateKey; +import org.briarproject.api.forum.ForumConstants; +import org.briarproject.api.forum.ForumPost; +import org.briarproject.api.forum.ForumPostFactory; +import org.briarproject.api.identity.Author; +import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.messaging.MessagingConstants; +import org.briarproject.api.messaging.PrivateMessage; +import org.briarproject.api.messaging.PrivateMessageFactory; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.MessageId; +import org.junit.Test; + +import javax.inject.Inject; + +import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH; +import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; +import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH; +import static org.briarproject.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH; +import static org.junit.Assert.assertTrue; + +public class MessageSizeIntegrationTest extends BriarTestCase { + + @Inject + CryptoComponent crypto; + @Inject + AuthorFactory authorFactory; + @Inject + PrivateMessageFactory privateMessageFactory; + @Inject + ForumPostFactory forumPostFactory; + + public MessageSizeIntegrationTest() throws Exception { + MessageSizeIntegrationTestComponent component = + DaggerMessageSizeIntegrationTestComponent.builder().build(); + component.inject(this); + } + + @Test + public void testPrivateMessageFitsIntoPacket() throws Exception { + // Create a maximum-length private message + GroupId groupId = new GroupId(TestUtils.getRandomId()); + long timestamp = Long.MAX_VALUE; + MessageId parent = new MessageId(TestUtils.getRandomId()); + String contentType = TestUtils.getRandomString( + MessagingConstants.MAX_CONTENT_TYPE_LENGTH); + byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]; + PrivateMessage message = privateMessageFactory.createPrivateMessage( + groupId, timestamp, parent, contentType, body); + // Check the size of the serialised message + int length = message.getMessage().getRaw().length; + assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH + + MessagingConstants.MAX_CONTENT_TYPE_LENGTH + + MAX_PRIVATE_MESSAGE_BODY_LENGTH); + assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH); + } + + @Test + public void testForumPostFitsIntoPacket() throws Exception { + // Create a maximum-length author + String authorName = TestUtils.getRandomString( + MAX_AUTHOR_NAME_LENGTH); + byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH]; + Author author = authorFactory.createAuthor(authorName, authorPublic); + // Create a maximum-length forum post + GroupId groupId = new GroupId(TestUtils.getRandomId()); + long timestamp = Long.MAX_VALUE; + MessageId parent = new MessageId(TestUtils.getRandomId()); + String contentType = TestUtils.getRandomString( + ForumConstants.MAX_CONTENT_TYPE_LENGTH); + byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH]; + PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate(); + ForumPost post = forumPostFactory.createPseudonymousPost(groupId, + timestamp, parent, author, contentType, body, privateKey); + // Check the size of the serialised message + int length = post.getMessage().getRaw().length; + assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH + + MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH + + ForumConstants.MAX_CONTENT_TYPE_LENGTH + + MAX_FORUM_POST_BODY_LENGTH); + assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH); + } +} diff --git a/briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java b/briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java new file mode 100644 index 000000000..9f112fb6b --- /dev/null +++ b/briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java @@ -0,0 +1,37 @@ +package briarproject; + +import org.briarproject.TestDatabaseModule; +import org.briarproject.TestLifecycleModule; +import org.briarproject.TestSystemModule; +import org.briarproject.clients.ClientsModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.data.DataModule; +import org.briarproject.db.DatabaseModule; +import org.briarproject.event.EventModule; +import org.briarproject.forum.ForumModule; +import org.briarproject.identity.IdentityModule; +import org.briarproject.messaging.MessagingModule; +import org.briarproject.sync.SyncModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + TestDatabaseModule.class, + TestLifecycleModule.class, + TestSystemModule.class, + ClientsModule.class, + CryptoModule.class, + DataModule.class, + DatabaseModule.class, + EventModule.class, + ForumModule.class, + IdentityModule.class, + MessagingModule.class, + SyncModule.class +}) +public interface MessageSizeIntegrationTestComponent { + void inject(MessageSizeIntegrationTest testCase); +} diff --git a/briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java b/briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java new file mode 100644 index 000000000..53e7d03a3 --- /dev/null +++ b/briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java @@ -0,0 +1,193 @@ +package briarproject; + +import org.briarproject.BriarTestCase; +import org.briarproject.TestDatabaseModule; +import org.briarproject.TestUtils; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.MessageAddedEvent; +import org.briarproject.api.identity.Author; +import org.briarproject.api.identity.AuthorId; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.messaging.MessagingManager; +import org.briarproject.api.messaging.PrivateMessage; +import org.briarproject.api.messaging.PrivateMessageFactory; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.SyncSession; +import org.briarproject.api.sync.SyncSessionFactory; +import org.briarproject.api.transport.KeyManager; +import org.briarproject.api.transport.StreamContext; +import org.briarproject.api.transport.StreamReaderFactory; +import org.briarproject.api.transport.StreamWriterFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; + +import static org.briarproject.TestPluginsModule.MAX_LATENCY; +import static org.briarproject.TestPluginsModule.TRANSPORT_ID; +import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; +import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class SimplexMessagingIntegrationTest extends BriarTestCase { + + private final File testDir = TestUtils.getTestDirectory(); + private final File aliceDir = new File(testDir, "alice"); + private final File bobDir = new File(testDir, "bob"); + private final SecretKey master = TestUtils.getSecretKey(); + private final long timestamp = System.currentTimeMillis(); + private final AuthorId aliceId = new AuthorId(TestUtils.getRandomId()); + private final AuthorId bobId = new AuthorId(TestUtils.getRandomId()); + + private SimplexMessagingIntegrationTestComponent alice, bob; + + @Before + public void setUp() { + assertTrue(testDir.mkdirs()); + alice = DaggerSimplexMessagingIntegrationTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(aliceDir)).build(); + bob = DaggerSimplexMessagingIntegrationTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(bobDir)).build(); + } + + @Test + public void testWriteAndRead() throws Exception { + read(write()); + } + + private byte[] write() throws Exception { + // Instantiate Alice's services + LifecycleManager lifecycleManager = alice.getLifecycleManager(); + IdentityManager identityManager = alice.getIdentityManager(); + ContactManager contactManager = alice.getContactManager(); + MessagingManager messagingManager = alice.getMessagingManager(); + KeyManager keyManager = alice.getKeyManager(); + PrivateMessageFactory privateMessageFactory = + alice.getPrivateMessageFactory(); + StreamWriterFactory streamWriterFactory = + alice.getStreamWriterFactory(); + SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory(); + + // Start the lifecycle manager + lifecycleManager.startServices(); + lifecycleManager.waitForStartup(); + // Add an identity for Alice + LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice", + new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); + identityManager.addLocalAuthor(aliceAuthor); + // Add Bob as a contact + Author bobAuthor = new Author(bobId, "Bob", + new byte[MAX_PUBLIC_KEY_LENGTH]); + ContactId contactId = contactManager.addContact(bobAuthor, aliceId, + master, timestamp, true, true); + + // Send Bob a message + GroupId groupId = messagingManager.getConversationId(contactId); + byte[] body = "Hi Bob!".getBytes("UTF-8"); + PrivateMessage message = privateMessageFactory.createPrivateMessage( + groupId, timestamp, null, "text/plain", body); + messagingManager.addLocalMessage(message); + // Get a stream context + StreamContext ctx = keyManager.getStreamContext(contactId, + TRANSPORT_ID); + assertNotNull(ctx); + // Create a stream writer + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStream streamWriter = streamWriterFactory.createStreamWriter( + out, ctx); + // Create an outgoing sync session + SyncSession session = syncSessionFactory.createSimplexOutgoingSession( + contactId, MAX_LATENCY, streamWriter); + // Write whatever needs to be written + session.run(); + streamWriter.close(); + + // Clean up + lifecycleManager.stopServices(); + lifecycleManager.waitForShutdown(); + + // Return the contents of the stream + return out.toByteArray(); + } + + private void read(byte[] stream) throws Exception { + // Instantiate Bob's services + LifecycleManager lifecycleManager = bob.getLifecycleManager(); + IdentityManager identityManager = bob.getIdentityManager(); + ContactManager contactManager = bob.getContactManager(); + KeyManager keyManager = bob.getKeyManager(); + StreamReaderFactory streamReaderFactory = bob.getStreamReaderFactory(); + SyncSessionFactory syncSessionFactory = bob.getSyncSessionFactory(); + // Bob needs a MessagingManager even though we're not using it directly + bob.getMessagingManager(); + + // Start the lifecyle manager + lifecycleManager.startServices(); + lifecycleManager.waitForStartup(); + // Add an identity for Bob + LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob", + new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); + identityManager.addLocalAuthor(bobAuthor); + // Add Alice as a contact + Author aliceAuthor = new Author(aliceId, "Alice", + new byte[MAX_PUBLIC_KEY_LENGTH]); + ContactId contactId = contactManager.addContact(aliceAuthor, bobId, + master, timestamp, false, true); + + // Set up an event listener + MessageListener listener = new MessageListener(); + bob.getEventBus().addListener(listener); + // 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); + StreamContext ctx = keyManager.getStreamContext(TRANSPORT_ID, tag); + assertNotNull(ctx); + // Create a stream reader + InputStream streamReader = streamReaderFactory.createStreamReader( + in, ctx); + // Create an incoming sync session + SyncSession session = syncSessionFactory.createIncomingSession( + contactId, streamReader); + // No messages should have been added yet + assertFalse(listener.messageAdded); + // Read whatever needs to be read + session.run(); + streamReader.close(); + // The private message from Alice should have been added + assertTrue(listener.messageAdded); + + // Clean up + lifecycleManager.stopServices(); + lifecycleManager.waitForShutdown(); + } + + @After + public void tearDown() { + TestUtils.deleteTestDirectory(testDir); + } + + private static class MessageListener implements EventListener { + + private volatile boolean messageAdded = false; + + public void eventOccurred(Event e) { + if (e instanceof MessageAddedEvent) messageAdded = true; + } + } +} diff --git a/briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java b/briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java new file mode 100644 index 000000000..7691b8192 --- /dev/null +++ b/briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java @@ -0,0 +1,74 @@ +package briarproject; + +import org.briarproject.TestDatabaseModule; +import org.briarproject.TestPluginsModule; +import org.briarproject.TestSystemModule; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.messaging.MessagingManager; +import org.briarproject.api.messaging.PrivateMessageFactory; +import org.briarproject.api.sync.SyncSessionFactory; +import org.briarproject.api.transport.KeyManager; +import org.briarproject.api.transport.StreamReaderFactory; +import org.briarproject.api.transport.StreamWriterFactory; +import org.briarproject.clients.ClientsModule; +import org.briarproject.contact.ContactModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.data.DataModule; +import org.briarproject.db.DatabaseModule; +import org.briarproject.event.EventModule; +import org.briarproject.identity.IdentityModule; +import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.messaging.MessagingModule; +import org.briarproject.plugins.PluginsModule; +import org.briarproject.sync.SyncModule; +import org.briarproject.transport.TransportModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + TestDatabaseModule.class, + TestPluginsModule.class, + TestSystemModule.class, + ClientsModule.class, + ContactModule.class, + CryptoModule.class, + DataModule.class, + DatabaseModule.class, + EventModule.class, + IdentityModule.class, + LifecycleModule.class, + MessagingModule.class, + PluginsModule.class, + SyncModule.class, + TransportModule.class +}) +public interface SimplexMessagingIntegrationTestComponent { + + void inject(SimplexMessagingIntegrationTest testCase); + + 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/test/java/briarproject/SyncIntegrationTest.java b/briar-android/test/java/briarproject/SyncIntegrationTest.java new file mode 100644 index 000000000..8d5dabfc3 --- /dev/null +++ b/briar-android/test/java/briarproject/SyncIntegrationTest.java @@ -0,0 +1,169 @@ +package briarproject; + +import org.briarproject.BriarTestCase; +import org.briarproject.TestUtils; +import org.briarproject.api.TransportId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.api.sync.Ack; +import org.briarproject.api.sync.ClientId; +import org.briarproject.api.sync.Group; +import org.briarproject.api.sync.GroupFactory; +import org.briarproject.api.sync.Message; +import org.briarproject.api.sync.MessageFactory; +import org.briarproject.api.sync.MessageId; +import org.briarproject.api.sync.Offer; +import org.briarproject.api.sync.PacketReader; +import org.briarproject.api.sync.PacketReaderFactory; +import org.briarproject.api.sync.PacketWriter; +import org.briarproject.api.sync.PacketWriterFactory; +import org.briarproject.api.sync.Request; +import org.briarproject.api.transport.StreamContext; +import org.briarproject.api.transport.StreamReaderFactory; +import org.briarproject.api.transport.StreamWriterFactory; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collection; + +import javax.inject.Inject; + +import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH; +import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class SyncIntegrationTest extends BriarTestCase { + + @Inject + GroupFactory groupFactory; + @Inject + MessageFactory messageFactory; + @Inject + StreamReaderFactory streamReaderFactory; + @Inject + StreamWriterFactory streamWriterFactory; + @Inject + PacketReaderFactory packetReaderFactory; + @Inject + PacketWriterFactory packetWriterFactory; + @Inject + CryptoComponent crypto; + + private final ContactId contactId; + private final TransportId transportId; + private final SecretKey tagKey, headerKey; + private final long streamNumber; + private final Message message, message1; + private final Collection messageIds; + + public SyncIntegrationTest() throws Exception { + + SyncIntegrationTestComponent component = + DaggerSyncIntegrationTestComponent.builder().build(); + component.inject(this); + + contactId = new ContactId(234); + transportId = new TransportId("id"); + // Create the transport keys + tagKey = TestUtils.getSecretKey(); + headerKey = TestUtils.getSecretKey(); + streamNumber = 123; + // Create a group + ClientId clientId = new ClientId(TestUtils.getRandomId()); + byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH]; + Group group = groupFactory.createGroup(clientId, descriptor); + // Add two messages to the group + long timestamp = System.currentTimeMillis(); + byte[] body = "Hello world".getBytes("UTF-8"); + message = messageFactory.createMessage(group.getId(), timestamp, body); + message1 = messageFactory.createMessage(group.getId(), timestamp, body); + messageIds = Arrays.asList(message.getId(), message1.getId()); + } + + @Test + public void testWriteAndRead() throws Exception { + read(write()); + } + + private byte[] write() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamContext ctx = new StreamContext(contactId, transportId, tagKey, + headerKey, streamNumber); + OutputStream streamWriter = streamWriterFactory.createStreamWriter(out, + ctx); + PacketWriter packetWriter = packetWriterFactory.createPacketWriter( + streamWriter); + + packetWriter.writeAck(new Ack(messageIds)); + packetWriter.writeMessage(message.getRaw()); + packetWriter.writeMessage(message1.getRaw()); + packetWriter.writeOffer(new Offer(messageIds)); + packetWriter.writeRequest(new Request(messageIds)); + + streamWriter.flush(); + return out.toByteArray(); + } + + private void read(byte[] connectionData) throws Exception { + // Calculate the expected tag + byte[] expectedTag = new byte[TAG_LENGTH]; + crypto.encodeTag(expectedTag, tagKey, streamNumber); + + // Read the tag + InputStream in = new ByteArrayInputStream(connectionData); + byte[] tag = new byte[TAG_LENGTH]; + assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH)); + assertArrayEquals(expectedTag, tag); + + // Create the readers + StreamContext ctx = new StreamContext(contactId, transportId, tagKey, + headerKey, 0); + InputStream streamReader = streamReaderFactory.createStreamReader(in, + ctx); + PacketReader packetReader = packetReaderFactory.createPacketReader( + streamReader); + + // Read the ack + assertTrue(packetReader.hasAck()); + Ack a = packetReader.readAck(); + assertEquals(messageIds, a.getMessageIds()); + + // Read the messages + assertTrue(packetReader.hasMessage()); + Message m = packetReader.readMessage(); + checkMessageEquality(message, m); + assertTrue(packetReader.hasMessage()); + m = packetReader.readMessage(); + checkMessageEquality(message1, m); + assertFalse(packetReader.hasMessage()); + + // Read the offer + assertTrue(packetReader.hasOffer()); + Offer o = packetReader.readOffer(); + assertEquals(messageIds, o.getMessageIds()); + + // Read the request + assertTrue(packetReader.hasRequest()); + Request req = packetReader.readRequest(); + assertEquals(messageIds, req.getMessageIds()); + + in.close(); + } + + private void checkMessageEquality(Message m1, Message m2) { + assertArrayEquals(m1.getId().getBytes(), m2.getId().getBytes()); + assertArrayEquals(m1.getGroupId().getBytes(), + m2.getGroupId().getBytes()); + assertEquals(m1.getTimestamp(), m2.getTimestamp()); + assertEquals(m1.getLength(), m2.getLength()); + assertArrayEquals(m1.getRaw(), m2.getRaw()); + } +} diff --git a/briar-android/test/java/briarproject/SyncIntegrationTestComponent.java b/briar-android/test/java/briarproject/SyncIntegrationTestComponent.java new file mode 100644 index 000000000..ad3d4dfde --- /dev/null +++ b/briar-android/test/java/briarproject/SyncIntegrationTestComponent.java @@ -0,0 +1,21 @@ +package briarproject; + +import org.briarproject.TestSystemModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.sync.SyncModule; +import org.briarproject.transport.TransportModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + TestSystemModule.class, + CryptoModule.class, + SyncModule.class, + TransportModule.class +}) +public interface SyncIntegrationTestComponent { + void inject(SyncIntegrationTest testCase); +} diff --git a/briar-android/test/java/briarproject/activity/SetupActivityTest.java b/briar-android/test/java/briarproject/activity/SetupActivityTest.java new file mode 100644 index 000000000..a730cf91f --- /dev/null +++ b/briar-android/test/java/briarproject/activity/SetupActivityTest.java @@ -0,0 +1,69 @@ +package briarproject.activity; + +import android.support.design.widget.TextInputLayout; +import android.widget.Button; +import android.widget.EditText; + +import org.briarproject.BuildConfig; +import org.briarproject.R; +import org.briarproject.android.ActivityModule; +import org.briarproject.android.SetupActivity; +import org.briarproject.android.util.StrengthMeter; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class, sdk = 22) +public class SetupActivityTest { + + private SetupActivity setupActivity; + TextInputLayout nicknameEntryWrapper; + TextInputLayout passwordEntryWrapper; + TextInputLayout passwordConfirmationWrapper; + EditText nicknameEntry; + EditText passwordEntry; + EditText passwordConfirmation; + StrengthMeter strengthMeter; + Button createAccountButton; + + class TestSetupActivity extends SetupActivity { + + @Override + protected ActivityModule getActivityModule() { + return super.getActivityModule(); + } + } + + @Before + public void setUp() { + setupActivity = Robolectric.setupActivity(SetupActivity.class); + nicknameEntryWrapper = (TextInputLayout) setupActivity + .findViewById(R.id.nickname_entry_wrapper); + passwordEntryWrapper = (TextInputLayout) setupActivity + .findViewById(R.id.password_entry_wrapper); + passwordConfirmationWrapper = (TextInputLayout) setupActivity + .findViewById(R.id.password_confirm_wrapper); + nicknameEntry = + (EditText) setupActivity.findViewById(R.id.nickname_entry); + passwordEntry = + (EditText) setupActivity.findViewById(R.id.password_entry); + passwordConfirmation = + (EditText) setupActivity.findViewById(R.id.password_confirm); + strengthMeter = + (StrengthMeter) setupActivity.findViewById(R.id.strength_meter); + createAccountButton = + (Button) setupActivity.findViewById(R.id.create_account); + + } + + @Test + public void test() { + + + + } +} diff --git a/briar-android/test/java/briarproject/activity/TestActivityModule.java b/briar-android/test/java/briarproject/activity/TestActivityModule.java new file mode 100644 index 000000000..e5eba02f2 --- /dev/null +++ b/briar-android/test/java/briarproject/activity/TestActivityModule.java @@ -0,0 +1,19 @@ +package briarproject.activity; + +import org.briarproject.android.ActivityModule; +import org.briarproject.android.BaseActivity; + +public class TestActivityModule extends ActivityModule { + + public TestActivityModule(BaseActivity activity) { + super(activity); + } + + + /* + @Override + protected SetupController provideSetupController( + SetupControllerImp setupControllerImp) { + } + */ +} diff --git a/briar-android/test/java/briarproject/controller/SetupControllerTest.java b/briar-android/test/java/briarproject/controller/SetupControllerTest.java new file mode 100644 index 000000000..8564a7393 --- /dev/null +++ b/briar-android/test/java/briarproject/controller/SetupControllerTest.java @@ -0,0 +1,17 @@ +package briarproject.controller; + +import org.briarproject.BriarTestCase; +import org.briarproject.android.controller.SetupController; +import org.junit.Before; + +import javax.inject.Inject; + +public class SetupControllerTest extends BriarTestCase { + + @Inject + SetupController setupController; + + @Before public void setUp() { + + } +} diff --git a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java index 58b22d32a..730beef97 100644 --- a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java +++ b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java @@ -1,6 +1,6 @@ package org.briarproject.system; -import static java.util.logging.Level.WARNING; +import org.briarproject.api.system.SeedProvider; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -13,7 +13,7 @@ import java.util.Collections; import java.util.List; import java.util.logging.Logger; -import org.briarproject.api.system.SeedProvider; +import static java.util.logging.Level.WARNING; class LinuxSeedProvider implements SeedProvider { @@ -43,6 +43,8 @@ class LinuxSeedProvider implements SeedProvider { } catch (IOException e) { // On some devices /dev/urandom isn't writable - this isn't fatal if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + } catch (NullPointerException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } // Read the seed from the pool try { From 8bb1d444c6a9ee0c22acbbff059688f3a87ef52c Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 29 Apr 2016 11:47:50 +0200 Subject: [PATCH 13/19] interlude --- briar-android/proguard-rules.txt | 18 ++++++-- .../briarproject/android/ActivityModule.java | 8 ++-- .../briarproject/android/SetupActivity.java | 4 +- .../android/util/StrengthMeter.java | 14 ++++--- .../activity/SetupActivityTest.java | 42 +++++++++++++++++-- .../activity/TestActivityModule.java | 19 --------- .../controller/SetupControllerTest.java | 2 + 7 files changed, 72 insertions(+), 35 deletions(-) delete mode 100644 briar-android/test/java/briarproject/activity/TestActivityModule.java diff --git a/briar-android/proguard-rules.txt b/briar-android/proguard-rules.txt index df28bc507..8ff4600e0 100644 --- a/briar-android/proguard-rules.txt +++ b/briar-android/proguard-rules.txt @@ -3,6 +3,7 @@ -dontpreverify -dontobfuscate -verbose +-useuniqueclassmembernames -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # For comfortability in case we do obfuscate # -renamesourcefileattribute SourceFile @@ -48,9 +49,20 @@ -keep class roboguice.** { *; } -keep class dagger.** { *; } -keep class com.google.** { *; } --keep class javax.** { *; } --keep class org.eclipse.** { *; } --keep class com.squareup.** { *; } + +-dontwarn org.hamcrest.** +-dontwarn com.squareup.** +-dontwarn com.google.android.** + +-keep class com.google.android.** { + *; +} +-keep class com.google.common.** { + *; +} +-keep class org.hamcrest.** { + *; +} -dontwarn org.h2.** -dontnote org.h2.** diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 70d3b00ab..36c31ef98 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -54,8 +54,9 @@ public class ActivityModule { @ActivityScope @Provides - protected SetupController provideSetupController() { - return new SetupControllerImp(); + protected SetupController provideSetupController( + SetupControllerImp setupControllerImp) { + return setupControllerImp; } @ActivityScope @@ -147,7 +148,8 @@ public class ActivityModule { @Provides @Named("IntroductionMessageFragment") IntroductionMessageFragment provideIntroductionMessageFragment() { - IntroductionMessageFragment fragment = new IntroductionMessageFragment(); + IntroductionMessageFragment fragment = + new IntroductionMessageFragment(); fragment.setArguments(new Bundle()); return fragment; } diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index c3cb01cb3..a08d23be1 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -27,6 +27,8 @@ import javax.inject.Inject; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; +import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; +import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; @@ -64,7 +66,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, createAccountButton = (Button) findViewById(R.id.create_account); progress = (ProgressBar) findViewById(R.id.progress_wheel); -// if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); + if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); TextWatcher tw = new TextWatcher() { @Override diff --git a/briar-android/src/org/briarproject/android/util/StrengthMeter.java b/briar-android/src/org/briarproject/android/util/StrengthMeter.java index eee1e5473..83fb20b8f 100644 --- a/briar-android/src/org/briarproject/android/util/StrengthMeter.java +++ b/briar-android/src/org/briarproject/android/util/StrengthMeter.java @@ -23,11 +23,11 @@ import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; public class StrengthMeter extends ProgressBar { private static final int MAX = 100; - private static final int RED = Color.rgb(255, 0, 0); - private static final int ORANGE = Color.rgb(255, 160, 0); - private static final int YELLOW = Color.rgb(255, 255, 0); - private static final int LIME = Color.rgb(180, 255, 0); - private static final int GREEN = Color.rgb(0, 255, 0); + public static final int RED = Color.rgb(255, 0, 0); + public static final int ORANGE = Color.rgb(255, 160, 0); + public static final int YELLOW = Color.rgb(255, 255, 0); + public static final int LIME = Color.rgb(180, 255, 0); + public static final int GREEN = Color.rgb(0, 255, 0); private final ShapeDrawable bar; @@ -57,6 +57,10 @@ public class StrengthMeter extends ProgressBar { return MAX; } + public int getColor() { + return bar.getPaint().getColor(); + } + public void setStrength(float strength) { if (strength < 0 || strength > 1) throw new IllegalArgumentException(); int colour; diff --git a/briar-android/test/java/briarproject/activity/SetupActivityTest.java b/briar-android/test/java/briarproject/activity/SetupActivityTest.java index a730cf91f..86a640d27 100644 --- a/briar-android/test/java/briarproject/activity/SetupActivityTest.java +++ b/briar-android/test/java/briarproject/activity/SetupActivityTest.java @@ -4,20 +4,29 @@ import android.support.design.widget.TextInputLayout; import android.widget.Button; import android.widget.EditText; +import com.google.common.base.Strings; + import org.briarproject.BuildConfig; import org.briarproject.R; import org.briarproject.android.ActivityModule; import org.briarproject.android.SetupActivity; +import org.briarproject.android.controller.SetupController; +import org.briarproject.android.controller.SetupControllerImp; import org.briarproject.android.util.StrengthMeter; +import org.briarproject.api.crypto.PasswordStrengthEstimator; +import org.briarproject.api.identity.AuthorConstants; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.robolectric.Robolectric; import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; +import static junit.framework.Assert.assertEquals; + @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 22) +@Config(constants = BuildConfig.class, sdk = 21) public class SetupActivityTest { private SetupActivity setupActivity; @@ -34,7 +43,22 @@ public class SetupActivityTest { @Override protected ActivityModule getActivityModule() { - return super.getActivityModule(); + return new ActivityModule(this) { + + @Override + protected SetupController provideSetupController( + SetupControllerImp setupControllerImp) { + SetupController setupController = + Mockito.mock(SetupControllerImp.class); + Mockito.when( + setupController.estimatePasswordStrength("strong")) + .thenReturn(PasswordStrengthEstimator.STRONG); +// Mockito.when( +// setupController.estimatePasswordStrength("qstrong")) +// .thenReturn(PasswordStrengthEstimator.QUITE_STRONG); + return setupController; + } + }; } } @@ -57,13 +81,23 @@ public class SetupActivityTest { (StrengthMeter) setupActivity.findViewById(R.id.strength_meter); createAccountButton = (Button) setupActivity.findViewById(R.id.create_account); - } @Test public void test() { + String longNick = + Strings.padEnd("*", AuthorConstants.MAX_AUTHOR_NAME_LENGTH + 1, + '*'); + nicknameEntry.setText(longNick); + assertEquals(nicknameEntryWrapper.getError(), + setupActivity.getString(R.string.name_too_long)); + passwordEntry.setText("strong"); + assertEquals(strengthMeter.getProgress(), + strengthMeter.getMax() * PasswordStrengthEstimator.STRONG); - +// passwordEntry.setText("strong"); +// assertEquals(StrengthMeter.GREEN, strengthMeter.getColor()); +// setupActivity. } } diff --git a/briar-android/test/java/briarproject/activity/TestActivityModule.java b/briar-android/test/java/briarproject/activity/TestActivityModule.java deleted file mode 100644 index e5eba02f2..000000000 --- a/briar-android/test/java/briarproject/activity/TestActivityModule.java +++ /dev/null @@ -1,19 +0,0 @@ -package briarproject.activity; - -import org.briarproject.android.ActivityModule; -import org.briarproject.android.BaseActivity; - -public class TestActivityModule extends ActivityModule { - - public TestActivityModule(BaseActivity activity) { - super(activity); - } - - - /* - @Override - protected SetupController provideSetupController( - SetupControllerImp setupControllerImp) { - } - */ -} diff --git a/briar-android/test/java/briarproject/controller/SetupControllerTest.java b/briar-android/test/java/briarproject/controller/SetupControllerTest.java index 8564a7393..85bcfe809 100644 --- a/briar-android/test/java/briarproject/controller/SetupControllerTest.java +++ b/briar-android/test/java/briarproject/controller/SetupControllerTest.java @@ -8,6 +8,8 @@ import javax.inject.Inject; public class SetupControllerTest extends BriarTestCase { + + @Inject SetupController setupController; From 80f79d9ee0038ae6e6f46c1ef15cfb5b5895b22e Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Tue, 3 May 2016 01:12:14 +0200 Subject: [PATCH 14/19] finished Activity mock --- .../briarproject/android/SetupActivity.java | 2 +- .../android/net/http/AndroidHttpClient.java | 7 ++ .../activity/MockedSetupActivity.java | 85 ++++++++++++++ .../activity/SetupActivityTest.java | 105 ++++++++++++------ 4 files changed, 161 insertions(+), 38 deletions(-) create mode 100644 briar-android/test/java/android/net/http/AndroidHttpClient.java create mode 100644 briar-android/test/java/briarproject/activity/MockedSetupActivity.java diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index a08d23be1..1b101d2e0 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -27,8 +27,8 @@ import javax.inject.Inject; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; -import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; +import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; diff --git a/briar-android/test/java/android/net/http/AndroidHttpClient.java b/briar-android/test/java/android/net/http/AndroidHttpClient.java new file mode 100644 index 000000000..f2cf7a346 --- /dev/null +++ b/briar-android/test/java/android/net/http/AndroidHttpClient.java @@ -0,0 +1,7 @@ +package android.net.http; + +// This class is here to fix an issue with Robolectric. +// https://github.com/robolectric/robolectric/issues/1862 +// TODO Check if this class can be removed on next Robolectric update +public class AndroidHttpClient { +} \ No newline at end of file diff --git a/briar-android/test/java/briarproject/activity/MockedSetupActivity.java b/briar-android/test/java/briarproject/activity/MockedSetupActivity.java new file mode 100644 index 000000000..77a830f32 --- /dev/null +++ b/briar-android/test/java/briarproject/activity/MockedSetupActivity.java @@ -0,0 +1,85 @@ +package briarproject.activity; + +import org.briarproject.android.ActivityModule; +import org.briarproject.android.SetupActivity; +import org.briarproject.android.controller.SetupController; +import org.briarproject.android.controller.SetupControllerImp; +import org.briarproject.android.controller.handler.ResultHandler; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import java.util.logging.Logger; + +import static org.briarproject.api.crypto.PasswordStrengthEstimator.NONE; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_STRONG; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_WEAK; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.STRONG; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; + +public class MockedSetupActivity extends SetupActivity { + + private static final Logger LOG = + Logger.getLogger(MockedSetupActivity.class.getName()); + + final static String STRONG_PASS = "strong"; + final static String QSTRONG_PASS = "qstrong"; + final static String QWEAK_PASS = "qweak"; + final static String WEAK_PASS = "weak"; + final static String NO_PASS = "none"; + + @Override + protected ActivityModule getActivityModule() { + return new ActivityModule(this) { + + @Override + protected SetupController provideSetupController( + SetupControllerImp setupControllerImp) { + SetupController setupController = + Mockito.mock(SetupControllerImp.class); + + Mockito.doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) + throws Throwable { + ((ResultHandler) invocation.getArguments()[2]) + .onResult(1L); + return null; + } + }).when(setupController) + .createIdentity(anyString(), anyString(), + (ResultHandler) any()); + Mockito.when( + setupController + .estimatePasswordStrength(anyString())) + .thenAnswer(new Answer() { + @Override + public Float answer( + InvocationOnMock invocation) + throws Throwable { + String p = (String) invocation + .getArguments()[0]; + LOG.info("p = " + p); + if (p.equals(STRONG_PASS)) { + return STRONG; + } else if (p.equals(QSTRONG_PASS)) { + return QUITE_STRONG; + } else if (p.equals(QWEAK_PASS)) { + return QUITE_WEAK; + } else if (p.equals(WEAK_PASS)) { + return WEAK; + } else if (p.equals(NO_PASS)) { + return NONE; + } else { + return STRONG; + } + } + }); + + return setupController; + } + }; + } +} diff --git a/briar-android/test/java/briarproject/activity/SetupActivityTest.java b/briar-android/test/java/briarproject/activity/SetupActivityTest.java index 86a640d27..1317c6180 100644 --- a/briar-android/test/java/briarproject/activity/SetupActivityTest.java +++ b/briar-android/test/java/briarproject/activity/SetupActivityTest.java @@ -1,5 +1,6 @@ package briarproject.activity; +import android.content.Intent; import android.support.design.widget.TextInputLayout; import android.widget.Button; import android.widget.EditText; @@ -8,27 +9,47 @@ import com.google.common.base.Strings; import org.briarproject.BuildConfig; import org.briarproject.R; -import org.briarproject.android.ActivityModule; +import org.briarproject.android.NavDrawerActivity; import org.briarproject.android.SetupActivity; -import org.briarproject.android.controller.SetupController; -import org.briarproject.android.controller.SetupControllerImp; import org.briarproject.android.util.StrengthMeter; -import org.briarproject.api.crypto.PasswordStrengthEstimator; import org.briarproject.api.identity.AuthorConstants; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import org.robolectric.Robolectric; import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowActivity; +import java.util.logging.Logger; + +import static briarproject.activity.MockedSetupActivity.NO_PASS; +import static briarproject.activity.MockedSetupActivity.QSTRONG_PASS; +import static briarproject.activity.MockedSetupActivity.QWEAK_PASS; +import static briarproject.activity.MockedSetupActivity.STRONG_PASS; +import static briarproject.activity.MockedSetupActivity.WEAK_PASS; import static junit.framework.Assert.assertEquals; +import static org.briarproject.android.util.StrengthMeter.GREEN; +import static org.briarproject.android.util.StrengthMeter.LIME; +import static org.briarproject.android.util.StrengthMeter.ORANGE; +import static org.briarproject.android.util.StrengthMeter.RED; +import static org.briarproject.android.util.StrengthMeter.YELLOW; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.NONE; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_STRONG; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_WEAK; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.STRONG; +import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; +import static org.junit.Assert.assertNotEquals; +import static org.robolectric.Shadows.shadowOf; @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class SetupActivityTest { + private static final Logger LOG = + Logger.getLogger(SetupActivityTest.class.getName()); + + private SetupActivity setupActivity; TextInputLayout nicknameEntryWrapper; TextInputLayout passwordEntryWrapper; @@ -39,32 +60,9 @@ public class SetupActivityTest { StrengthMeter strengthMeter; Button createAccountButton; - class TestSetupActivity extends SetupActivity { - - @Override - protected ActivityModule getActivityModule() { - return new ActivityModule(this) { - - @Override - protected SetupController provideSetupController( - SetupControllerImp setupControllerImp) { - SetupController setupController = - Mockito.mock(SetupControllerImp.class); - Mockito.when( - setupController.estimatePasswordStrength("strong")) - .thenReturn(PasswordStrengthEstimator.STRONG); -// Mockito.when( -// setupController.estimatePasswordStrength("qstrong")) -// .thenReturn(PasswordStrengthEstimator.QUITE_STRONG); - return setupController; - } - }; - } - } - @Before public void setUp() { - setupActivity = Robolectric.setupActivity(SetupActivity.class); + setupActivity = Robolectric.setupActivity(MockedSetupActivity.class); nicknameEntryWrapper = (TextInputLayout) setupActivity .findViewById(R.id.nickname_entry_wrapper); passwordEntryWrapper = (TextInputLayout) setupActivity @@ -83,21 +81,54 @@ public class SetupActivityTest { (Button) setupActivity.findViewById(R.id.create_account); } + private void testStrengthMeter(String pass, float strength, int color) { + passwordEntry.setText(pass); + assertEquals(strengthMeter.getProgress(), + (int) (strengthMeter.getMax() * strength)); + assertEquals(color, strengthMeter.getColor()); + } + @Test - public void test() { + public void testUI() { + // Nick String longNick = Strings.padEnd("*", AuthorConstants.MAX_AUTHOR_NAME_LENGTH + 1, '*'); nicknameEntry.setText(longNick); assertEquals(nicknameEntryWrapper.getError(), setupActivity.getString(R.string.name_too_long)); + assertEquals(createAccountButton.isEnabled(), false); + // strength estimator + testStrengthMeter(STRONG_PASS, STRONG, GREEN); + assertEquals(createAccountButton.isEnabled(), false); + testStrengthMeter(QSTRONG_PASS, QUITE_STRONG, LIME); + assertEquals(createAccountButton.isEnabled(), false); + testStrengthMeter(QWEAK_PASS, QUITE_WEAK, YELLOW); + assertEquals(createAccountButton.isEnabled(), false); + testStrengthMeter(WEAK_PASS, WEAK, ORANGE); + assertEquals(createAccountButton.isEnabled(), false); + testStrengthMeter(NO_PASS, NONE, RED); + assertEquals(createAccountButton.isEnabled(), false); - passwordEntry.setText("strong"); - assertEquals(strengthMeter.getProgress(), - strengthMeter.getMax() * PasswordStrengthEstimator.STRONG); - -// passwordEntry.setText("strong"); -// assertEquals(StrengthMeter.GREEN, strengthMeter.getColor()); -// setupActivity. + // pass confirmation + nicknameEntry.setText("nick.nickerton"); + passwordEntry.setText("really.safe.password"); + passwordConfirmation.setText("really.safe.pass"); + assertEquals(createAccountButton.isEnabled(), false); + assertEquals(passwordConfirmationWrapper.getError(), + setupActivity.getString(R.string.passwords_do_not_match)); + passwordEntry.setText("really.safe.pass"); + passwordConfirmation.setText("really.safe.pass"); + assertNotEquals(passwordConfirmationWrapper.getError(), + setupActivity.getString(R.string.passwords_do_not_match)); + assertEquals(createAccountButton.isEnabled(), true); + // confirm correct Activity started + createAccountButton.performClick(); + assertEquals(setupActivity.isFinishing(), true); + ShadowActivity shadowActivity = shadowOf(setupActivity); + Intent intent = shadowActivity.peekNextStartedActivity(); + assertEquals(intent.getComponent().getClassName(), + NavDrawerActivity.class.getName()); } + } From f855c9ea282a5e0cab15281f2495bc0b6eb6d201 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Wed, 4 May 2016 21:48:13 +0200 Subject: [PATCH 15/19] Finished unit tests for SetupActivity and its Controller --- briar-android/build.gradle | 3 + .../briarproject/android/SetupActivity.java | 2 +- .../controller/SetupControllerImp.java | 8 + .../system/AndroidSeedProvider.java | 7 +- .../activity/MockedSetupActivity.java | 85 -------- .../activity/SetupActivityTest.java | 184 +++++++++++++----- .../activity/TestSetupActivity.java | 20 ++ .../controller/SetupControllerTest.java | 19 -- .../system/LinuxSeedProvider.java | 2 - 9 files changed, 176 insertions(+), 154 deletions(-) delete mode 100644 briar-android/test/java/briarproject/activity/MockedSetupActivity.java create mode 100644 briar-android/test/java/briarproject/activity/TestSetupActivity.java delete mode 100644 briar-android/test/java/briarproject/controller/SetupControllerTest.java diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 815c8de62..51b2584e0 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -105,6 +105,9 @@ android { test.setRoot('test') test { java.srcDirs = ['test/java'] + testOptions { + unitTests.returnDefaultValues = true + } } diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index 1b101d2e0..13bb49f4b 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -36,7 +36,7 @@ public class SetupActivity extends BaseActivity implements OnClickListener, OnEditorActionListener { @Inject - SetupController setupController; + protected SetupController setupController; TextInputLayout nicknameEntryWrapper; TextInputLayout passwordEntryWrapper; diff --git a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java index 61a933e67..22eeeb84f 100644 --- a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java @@ -84,15 +84,23 @@ public class SetupControllerImp implements SetupController { @Override public void createIdentity(final String nickname, final String password, final ResultHandler resultHandler) { + LOG.info("createIdentity called"); cryptoExecutor.execute(new Runnable() { public void run() { + LOG.info("createIdentity running"); SecretKey key = crypto.generateSecretKey(); + LOG.info("createIdentity 1"); databaseConfig.setEncryptionKey(key); + LOG.info("createIdentity 2"); String hex = encryptDatabaseKey(key, password); + LOG.info("createIdentity 3"); storeEncryptedDatabaseKey(hex); + LOG.info("createIdentity 4"); final LocalAuthor localAuthor = createLocalAuthor(nickname); + LOG.info("createIdentity 5"); long handle = referenceManager.putReference(localAuthor, LocalAuthor.class); + LOG.info("createIdentity 6"); resultHandler.onResult(handle); } }); diff --git a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java index 749d1c68b..1b51be767 100644 --- a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java +++ b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java @@ -34,7 +34,10 @@ class AndroidSeedProvider extends LinuxSeedProvider { if (Build.FINGERPRINT != null) out.writeUTF(Build.FINGERPRINT); if (Build.SERIAL != null) out.writeUTF(Build.SERIAL); ContentResolver contentResolver = appContext.getContentResolver(); - out.writeUTF(Settings.Secure.getString(contentResolver, ANDROID_ID)); - super.writeToEntropyPool(out); + String str = Settings.Secure.getString(contentResolver, ANDROID_ID); + if (str != null) { + out.writeUTF(str); + super.writeToEntropyPool(out); + } } } diff --git a/briar-android/test/java/briarproject/activity/MockedSetupActivity.java b/briar-android/test/java/briarproject/activity/MockedSetupActivity.java deleted file mode 100644 index 77a830f32..000000000 --- a/briar-android/test/java/briarproject/activity/MockedSetupActivity.java +++ /dev/null @@ -1,85 +0,0 @@ -package briarproject.activity; - -import org.briarproject.android.ActivityModule; -import org.briarproject.android.SetupActivity; -import org.briarproject.android.controller.SetupController; -import org.briarproject.android.controller.SetupControllerImp; -import org.briarproject.android.controller.handler.ResultHandler; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.util.logging.Logger; - -import static org.briarproject.api.crypto.PasswordStrengthEstimator.NONE; -import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_STRONG; -import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_WEAK; -import static org.briarproject.api.crypto.PasswordStrengthEstimator.STRONG; -import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; - -public class MockedSetupActivity extends SetupActivity { - - private static final Logger LOG = - Logger.getLogger(MockedSetupActivity.class.getName()); - - final static String STRONG_PASS = "strong"; - final static String QSTRONG_PASS = "qstrong"; - final static String QWEAK_PASS = "qweak"; - final static String WEAK_PASS = "weak"; - final static String NO_PASS = "none"; - - @Override - protected ActivityModule getActivityModule() { - return new ActivityModule(this) { - - @Override - protected SetupController provideSetupController( - SetupControllerImp setupControllerImp) { - SetupController setupController = - Mockito.mock(SetupControllerImp.class); - - Mockito.doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocation) - throws Throwable { - ((ResultHandler) invocation.getArguments()[2]) - .onResult(1L); - return null; - } - }).when(setupController) - .createIdentity(anyString(), anyString(), - (ResultHandler) any()); - Mockito.when( - setupController - .estimatePasswordStrength(anyString())) - .thenAnswer(new Answer() { - @Override - public Float answer( - InvocationOnMock invocation) - throws Throwable { - String p = (String) invocation - .getArguments()[0]; - LOG.info("p = " + p); - if (p.equals(STRONG_PASS)) { - return STRONG; - } else if (p.equals(QSTRONG_PASS)) { - return QUITE_STRONG; - } else if (p.equals(QWEAK_PASS)) { - return QUITE_WEAK; - } else if (p.equals(WEAK_PASS)) { - return WEAK; - } else if (p.equals(NO_PASS)) { - return NONE; - } else { - return STRONG; - } - } - }); - - return setupController; - } - }; - } -} diff --git a/briar-android/test/java/briarproject/activity/SetupActivityTest.java b/briar-android/test/java/briarproject/activity/SetupActivityTest.java index 1317c6180..586cec989 100644 --- a/briar-android/test/java/briarproject/activity/SetupActivityTest.java +++ b/briar-android/test/java/briarproject/activity/SetupActivityTest.java @@ -1,6 +1,8 @@ package briarproject.activity; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.support.design.widget.TextInputLayout; import android.widget.Button; import android.widget.EditText; @@ -10,47 +12,45 @@ import com.google.common.base.Strings; import org.briarproject.BuildConfig; import org.briarproject.R; import org.briarproject.android.NavDrawerActivity; -import org.briarproject.android.SetupActivity; +import org.briarproject.android.controller.SetupController; +import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.android.util.StrengthMeter; import org.briarproject.api.identity.AuthorConstants; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowActivity; -import java.util.logging.Logger; - -import static briarproject.activity.MockedSetupActivity.NO_PASS; -import static briarproject.activity.MockedSetupActivity.QSTRONG_PASS; -import static briarproject.activity.MockedSetupActivity.QWEAK_PASS; -import static briarproject.activity.MockedSetupActivity.STRONG_PASS; -import static briarproject.activity.MockedSetupActivity.WEAK_PASS; import static junit.framework.Assert.assertEquals; -import static org.briarproject.android.util.StrengthMeter.GREEN; -import static org.briarproject.android.util.StrengthMeter.LIME; -import static org.briarproject.android.util.StrengthMeter.ORANGE; -import static org.briarproject.android.util.StrengthMeter.RED; -import static org.briarproject.android.util.StrengthMeter.YELLOW; import static org.briarproject.api.crypto.PasswordStrengthEstimator.NONE; import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_STRONG; import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_WEAK; import static org.briarproject.api.crypto.PasswordStrengthEstimator.STRONG; import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK; -import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class SetupActivityTest { - private static final Logger LOG = - Logger.getLogger(SetupActivityTest.class.getName()); - - - private SetupActivity setupActivity; + TestSetupActivity setupActivity; TextInputLayout nicknameEntryWrapper; TextInputLayout passwordEntryWrapper; TextInputLayout passwordConfirmationWrapper; @@ -60,9 +60,15 @@ public class SetupActivityTest { StrengthMeter strengthMeter; Button createAccountButton; + @Mock + SetupController setupController; + @Captor + ArgumentCaptor> resultCaptor; + @Before public void setUp() { - setupActivity = Robolectric.setupActivity(MockedSetupActivity.class); + MockitoAnnotations.initMocks(this); + setupActivity = Robolectric.setupActivity(TestSetupActivity.class); nicknameEntryWrapper = (TextInputLayout) setupActivity .findViewById(R.id.nickname_entry_wrapper); passwordEntryWrapper = (TextInputLayout) setupActivity @@ -89,46 +95,134 @@ public class SetupActivityTest { } @Test - public void testUI() { - // Nick - String longNick = - Strings.padEnd("*", AuthorConstants.MAX_AUTHOR_NAME_LENGTH + 1, - '*'); - nicknameEntry.setText(longNick); - assertEquals(nicknameEntryWrapper.getError(), - setupActivity.getString(R.string.name_too_long)); - assertEquals(createAccountButton.isEnabled(), false); - // strength estimator - testStrengthMeter(STRONG_PASS, STRONG, GREEN); - assertEquals(createAccountButton.isEnabled(), false); - testStrengthMeter(QSTRONG_PASS, QUITE_STRONG, LIME); - assertEquals(createAccountButton.isEnabled(), false); - testStrengthMeter(QWEAK_PASS, QUITE_WEAK, YELLOW); - assertEquals(createAccountButton.isEnabled(), false); - testStrengthMeter(WEAK_PASS, WEAK, ORANGE); - assertEquals(createAccountButton.isEnabled(), false); - testStrengthMeter(NO_PASS, NONE, RED); - assertEquals(createAccountButton.isEnabled(), false); - - // pass confirmation - nicknameEntry.setText("nick.nickerton"); + public void testPasswordMatchUI() { + // Password mismatch passwordEntry.setText("really.safe.password"); passwordConfirmation.setText("really.safe.pass"); assertEquals(createAccountButton.isEnabled(), false); assertEquals(passwordConfirmationWrapper.getError(), setupActivity.getString(R.string.passwords_do_not_match)); + // Button enabled passwordEntry.setText("really.safe.pass"); passwordConfirmation.setText("really.safe.pass"); - assertNotEquals(passwordConfirmationWrapper.getError(), + // Confirm that the password mismatch error message is not visible + Assert.assertNotEquals(passwordConfirmationWrapper.getError(), setupActivity.getString(R.string.passwords_do_not_match)); + // Nick has not been set, expect the button to be disabled + assertEquals(createAccountButton.isEnabled(), false); + } + + @Test + public void testCreateAccountUI() { + + SetupController mockedController = this.setupController; + setupActivity.setController(mockedController); + // Mock strong password strength answer + when(mockedController.estimatePasswordStrength(anyString())).thenReturn( + STRONG); + String safePass = "really.safe.password"; + String nick = "nick.nickerton"; + passwordEntry.setText(safePass); + passwordConfirmation.setText(safePass); + nicknameEntry.setText(nick); + // Confirm that the create account button is clickable assertEquals(createAccountButton.isEnabled(), true); - // confirm correct Activity started createAccountButton.performClick(); + // Verify that the controller's method was called with the correct + // params and get the callback + verify(mockedController, times(1)) + .createIdentity(eq(nick), eq(safePass), resultCaptor.capture()); + // execute the callback + resultCaptor.getValue().onResult(1L); assertEquals(setupActivity.isFinishing(), true); + // Confirm that the correct Activity has been started ShadowActivity shadowActivity = shadowOf(setupActivity); Intent intent = shadowActivity.peekNextStartedActivity(); assertEquals(intent.getComponent().getClassName(), NavDrawerActivity.class.getName()); } + @Test + public void testNickUI() { + Assert.assertNotNull(setupActivity); + String longNick = + Strings.padEnd("*", AuthorConstants.MAX_AUTHOR_NAME_LENGTH + 1, + '*'); + nicknameEntry.setText(longNick); + // Password should be too long + assertEquals(nicknameEntryWrapper.getError(), + setupActivity.getString(R.string.name_too_long)); + } + + @Test + public void testAccountCreation() { + SetupController controller = setupActivity.getController(); + // mock a resulthandler + ResultHandler resultHandler = + (ResultHandler) mock(ResultHandler.class); + controller + .createIdentity("nick", "some.strong.pass", resultHandler); + // blocking verification call with timeout that waits until the mocked + // result gets called with handle 0L, the expected value + verify(resultHandler, timeout(2000).times(1)).onResult(0L); + SharedPreferences prefs = + setupActivity.getSharedPreferences("db", Context.MODE_PRIVATE); + // Confirm database key + assertTrue(prefs.contains("key")); + // Note that Robolectric uses its own persistant storage that it + // wipes clean after each test run, no need to clean up manually. + } + + @Test + public void testStrengthMeter() { + SetupController controller = setupActivity.getController(); + + String strongPass = "very.strong.password.123"; + String weakPass = "we"; + String quiteStrongPass = "quite.strong"; + + float val = controller.estimatePasswordStrength(strongPass); + assertTrue(val == STRONG); + val = controller.estimatePasswordStrength(weakPass); + assertTrue(val < WEAK && val > NONE); + val = controller.estimatePasswordStrength(quiteStrongPass); + assertTrue(val < STRONG && val > QUITE_WEAK); + } + + @Test + public void testStrengthMeterUI() { + Assert.assertNotNull(setupActivity); + // replace the setup controller with our mocked copy + SetupController mockedController = this.setupController; + setupActivity.setController(mockedController); + // Mock answers for UI testing only + when(mockedController.estimatePasswordStrength("strong")).thenReturn( + STRONG); + when(mockedController.estimatePasswordStrength("qstring")).thenReturn( + QUITE_STRONG); + when(mockedController.estimatePasswordStrength("qweak")).thenReturn( + QUITE_WEAK); + when(mockedController.estimatePasswordStrength("weak")).thenReturn( + WEAK); + when(mockedController.estimatePasswordStrength("empty")).thenReturn( + NONE); + // Test the meters progress and color for several values + testStrengthMeter("strong", STRONG, StrengthMeter.GREEN); + Mockito.verify(mockedController, Mockito.times(1)) + .estimatePasswordStrength(eq("strong")); + testStrengthMeter("qstring", QUITE_STRONG, StrengthMeter.LIME); + Mockito.verify(mockedController, Mockito.times(1)) + .estimatePasswordStrength(eq("qstring")); + testStrengthMeter("qweak", QUITE_WEAK, StrengthMeter.YELLOW); + Mockito.verify(mockedController, Mockito.times(1)) + .estimatePasswordStrength(eq("qweak")); + testStrengthMeter("weak", WEAK, StrengthMeter.ORANGE); + Mockito.verify(mockedController, Mockito.times(1)) + .estimatePasswordStrength(eq("weak")); + // Not sure this should be the correct behaviour on an empty input ? + testStrengthMeter("empty", NONE, StrengthMeter.RED); + Mockito.verify(mockedController, Mockito.times(1)) + .estimatePasswordStrength(eq("empty")); + } + } diff --git a/briar-android/test/java/briarproject/activity/TestSetupActivity.java b/briar-android/test/java/briarproject/activity/TestSetupActivity.java new file mode 100644 index 000000000..923372a49 --- /dev/null +++ b/briar-android/test/java/briarproject/activity/TestSetupActivity.java @@ -0,0 +1,20 @@ +package briarproject.activity; + +import org.briarproject.android.SetupActivity; +import org.briarproject.android.controller.SetupController; + +/** + * This class exposes the SetupController and offers the possibility to + * override it. + */ +public class TestSetupActivity extends SetupActivity { + + public SetupController getController() { + return this.setupController; + } + + public void setController(SetupController setupController) { + this.setupController = setupController; + } + +} diff --git a/briar-android/test/java/briarproject/controller/SetupControllerTest.java b/briar-android/test/java/briarproject/controller/SetupControllerTest.java deleted file mode 100644 index 85bcfe809..000000000 --- a/briar-android/test/java/briarproject/controller/SetupControllerTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package briarproject.controller; - -import org.briarproject.BriarTestCase; -import org.briarproject.android.controller.SetupController; -import org.junit.Before; - -import javax.inject.Inject; - -public class SetupControllerTest extends BriarTestCase { - - - - @Inject - SetupController setupController; - - @Before public void setUp() { - - } -} diff --git a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java index 730beef97..6481b4a5f 100644 --- a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java +++ b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java @@ -43,8 +43,6 @@ class LinuxSeedProvider implements SeedProvider { } catch (IOException e) { // On some devices /dev/urandom isn't writable - this isn't fatal if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } catch (NullPointerException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } // Read the seed from the pool try { From 64d1e25ad77df5c24f10ec6e33c5d110e583af22 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Fri, 6 May 2016 11:01:59 +0200 Subject: [PATCH 16/19] cleanup --- briar-android/AndroidManifest.xml | 2 +- briar-android/build.gradle | 6 +- .../android/ActivityComponent.java | 2 - .../android/AndroidComponent.java | 12 + .../android/BriarApplication.java | 58 +- .../android/BriarApplicationImp.java | 56 ++ .../android/DevReportActivity.java | 1 + .../android/SplashScreenActivity.java | 3 + .../android/contact/ContactListFragment.java | 4 - .../controller/SetupControllerImp.java | 8 - .../android/forum/ForumListFragment.java | 15 - .../android/fragment/BaseFragment.java | 3 - .../android/panic/PanicResponderActivity.java | 4 + .../util/BriarReportSenderFactory.java | 1 + .../IntroductionIntegrationTest.java | 859 ------------------ .../IntroductionIntegrationTestComponent.java | 80 -- .../MessageSizeIntegrationTest.java | 90 -- .../MessageSizeIntegrationTestComponent.java | 37 - .../SimplexMessagingIntegrationTest.java | 193 ---- ...plexMessagingIntegrationTestComponent.java | 74 -- .../briarproject/SyncIntegrationTest.java | 169 ---- .../SyncIntegrationTestComponent.java | 21 - .../activity/SetupActivityTest.java | 3 +- .../activity/TestBriarApplicationImp.java | 43 + .../system/LinuxSeedProvider.java | 3 - 25 files changed, 132 insertions(+), 1615 deletions(-) create mode 100644 briar-android/src/org/briarproject/android/BriarApplicationImp.java delete mode 100644 briar-android/test/java/briarproject/IntroductionIntegrationTest.java delete mode 100644 briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java delete mode 100644 briar-android/test/java/briarproject/MessageSizeIntegrationTest.java delete mode 100644 briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java delete mode 100644 briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java delete mode 100644 briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java delete mode 100644 briar-android/test/java/briarproject/SyncIntegrationTest.java delete mode 100644 briar-android/test/java/briarproject/SyncIntegrationTestComponent.java create mode 100644 briar-android/test/java/briarproject/activity/TestBriarApplicationImp.java diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index 10b50aa4d..92ae565c5 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -29,7 +29,7 @@ resultHandler) { - LOG.info("createIdentity called"); cryptoExecutor.execute(new Runnable() { public void run() { - LOG.info("createIdentity running"); SecretKey key = crypto.generateSecretKey(); - LOG.info("createIdentity 1"); databaseConfig.setEncryptionKey(key); - LOG.info("createIdentity 2"); String hex = encryptDatabaseKey(key, password); - LOG.info("createIdentity 3"); storeEncryptedDatabaseKey(hex); - LOG.info("createIdentity 4"); final LocalAuthor localAuthor = createLocalAuthor(nickname); - LOG.info("createIdentity 5"); long handle = referenceManager.putReference(localAuthor, LocalAuthor.class); - LOG.info("createIdentity 6"); resultHandler.onResult(handle); } }); diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index a6ba633f7..012999093 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -51,16 +51,6 @@ public class ForumListFragment extends BaseEventFragment implements private static final Logger LOG = Logger.getLogger(ForumListFragment.class.getName()); - /* - public static ForumListFragment newInstance() { - - Bundle args = new Bundle(); - - ForumListFragment fragment = new ForumListFragment(); - fragment.setArguments(args); - return fragment; - } - */ private BriarRecyclerView list; private ForumListAdapter adapter; @@ -107,11 +97,6 @@ public class ForumListFragment extends BaseEventFragment implements return TAG; } -// @Override -// public void injectActivity(ActivityComponent component) { -// component.inject(this); -// } - @Override public void onResume() { super.onResume(); diff --git a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java index 34e00e0c3..96efaad58 100644 --- a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java +++ b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java @@ -4,9 +4,6 @@ import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; -import org.briarproject.android.AndroidComponent; -import org.briarproject.android.BriarApplication; - public abstract class BaseFragment extends Fragment { public abstract String getUniqueTag(); diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java index bdb037785..0b08f7f5a 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -9,6 +9,7 @@ import android.support.v7.preference.PreferenceManager; import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; +import org.briarproject.android.api.AndroidExecutor; import org.briarproject.android.controller.ConfigController; import org.briarproject.android.util.AndroidUtils; import org.iilab.IilabEngineeringRSA2048Pin; @@ -22,6 +23,7 @@ import info.guardianproject.panic.Panic; import info.guardianproject.panic.PanicResponder; 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_PURGE; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_UNINSTALL; @@ -31,6 +33,8 @@ public class PanicResponderActivity extends BriarActivity { private static final Logger LOG = Logger.getLogger(PanicResponderActivity.class.getName()); @Inject protected ConfigController configController; + @Inject + protected AndroidExecutor androidExecutor; @Override public void onCreate(Bundle savedInstanceState) { diff --git a/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java b/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java index 6dc106f74..73108ae4a 100644 --- a/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java +++ b/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java @@ -7,6 +7,7 @@ import org.acra.config.ACRAConfiguration; import org.acra.sender.ReportSender; import org.acra.sender.ReportSenderFactory; import org.briarproject.android.BriarApplication; +import org.briarproject.android.BriarApplicationImp; public class BriarReportSenderFactory implements ReportSenderFactory { @NonNull diff --git a/briar-android/test/java/briarproject/IntroductionIntegrationTest.java b/briar-android/test/java/briarproject/IntroductionIntegrationTest.java deleted file mode 100644 index e92b54546..000000000 --- a/briar-android/test/java/briarproject/IntroductionIntegrationTest.java +++ /dev/null @@ -1,859 +0,0 @@ -package briarproject; - -import net.jodah.concurrentunit.Waiter; - -import org.briarproject.BriarTestCase; -import org.briarproject.TestDatabaseModule; -import org.briarproject.TestUtils; -import org.briarproject.api.contact.Contact; -import org.briarproject.api.contact.ContactId; -import org.briarproject.api.contact.ContactManager; -import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.db.DbException; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.IntroductionAbortedEvent; -import org.briarproject.api.event.IntroductionRequestReceivedEvent; -import org.briarproject.api.event.IntroductionResponseReceivedEvent; -import org.briarproject.api.event.IntroductionSucceededEvent; -import org.briarproject.api.event.MessageValidatedEvent; -import org.briarproject.api.identity.AuthorFactory; -import org.briarproject.api.identity.IdentityManager; -import org.briarproject.api.identity.LocalAuthor; -import org.briarproject.api.introduction.IntroductionManager; -import org.briarproject.api.introduction.IntroductionRequest; -import org.briarproject.api.introduction.SessionId; -import org.briarproject.api.lifecycle.LifecycleManager; -import org.briarproject.api.properties.TransportProperties; -import org.briarproject.api.properties.TransportPropertyManager; -import org.briarproject.api.sync.SyncSession; -import org.briarproject.api.sync.SyncSessionFactory; -import org.briarproject.api.system.Clock; -import org.briarproject.contact.ContactModule; -import org.briarproject.crypto.CryptoModule; -import org.briarproject.introduction.IntroductionModule; -import org.briarproject.lifecycle.LifecycleModule; -import org.briarproject.properties.PropertiesModule; -import org.briarproject.sync.SyncModule; -import org.briarproject.transport.TransportModule; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.concurrent.TimeoutException; -import java.util.logging.Logger; - -import javax.inject.Inject; - -import static org.briarproject.TestPluginsModule.MAX_LATENCY; -import static org.briarproject.TestPluginsModule.TRANSPORT_ID; -import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class IntroductionIntegrationTest extends BriarTestCase { - - LifecycleManager lifecycleManager0, lifecycleManager1, lifecycleManager2; - SyncSessionFactory sync0, sync1, sync2; - ContactManager contactManager0, contactManager1, contactManager2; - ContactId contactId0, contactId1, contactId2; - IdentityManager identityManager0, identityManager1, identityManager2; - LocalAuthor author0, author1, author2; - - @Inject - Clock clock; - @Inject - AuthorFactory authorFactory; - - // objects accessed from background threads need to be volatile - private volatile IntroductionManager introductionManager0; - private volatile IntroductionManager introductionManager1; - private volatile IntroductionManager introductionManager2; - private volatile Waiter eventWaiter; - private volatile Waiter msgWaiter; - - private final File testDir = TestUtils.getTestDirectory(); - private final SecretKey master = TestUtils.getSecretKey(); - private final int TIMEOUT = 15000; - private final String INTRODUCER = "Introducer"; - private final String INTRODUCEE1 = "Introducee1"; - private final String INTRODUCEE2 = "Introducee2"; - - private static final Logger LOG = - Logger.getLogger(IntroductionIntegrationTest.class.getName()); - - private IntroductionIntegrationTestComponent t0, t1, t2; - - @Before - public void setUp() { - IntroductionIntegrationTestComponent component = - DaggerIntroductionIntegrationTestComponent.builder().build(); - component.inject(this); - injectEagerSingletons(component); - - assertTrue(testDir.mkdirs()); - File t0Dir = new File(testDir, INTRODUCER); - t0 = DaggerIntroductionIntegrationTestComponent.builder() - .testDatabaseModule(new TestDatabaseModule(t0Dir)).build(); - injectEagerSingletons(t0); - File t1Dir = new File(testDir, INTRODUCEE1); - t1 = DaggerIntroductionIntegrationTestComponent.builder() - .testDatabaseModule(new TestDatabaseModule(t1Dir)).build(); - injectEagerSingletons(t1); - File t2Dir = new File(testDir, INTRODUCEE2); - t2 = DaggerIntroductionIntegrationTestComponent.builder() - .testDatabaseModule(new TestDatabaseModule(t2Dir)).build(); - injectEagerSingletons(t2); - - identityManager0 = t0.getIdentityManager(); - identityManager1 = t1.getIdentityManager(); - identityManager2 = t2.getIdentityManager(); - contactManager0 = t0.getContactManager(); - contactManager1 = t1.getContactManager(); - contactManager2 = t2.getContactManager(); - introductionManager0 = t0.getIntroductionManager(); - introductionManager1 = t1.getIntroductionManager(); - introductionManager2 = t2.getIntroductionManager(); - sync0 = t0.getSyncSessionFactory(); - sync1 = t1.getSyncSessionFactory(); - sync2 = t2.getSyncSessionFactory(); - - // initialize waiters fresh for each test - eventWaiter = new Waiter(); - msgWaiter = new Waiter(); - } - - @Test - public void testIntroductionSession() throws Exception { - startLifecycles(); - try { - // Add Identities - addDefaultIdentities(); - - // Add Transport Properties - addTransportProperties(); - - // Add introducees as contacts - contactId1 = contactManager0.addContact(author1, - author0.getId(), master, clock.currentTimeMillis(), true, - true - ); - contactId2 = contactManager0.addContact(author2, - author0.getId(), master, clock.currentTimeMillis(), true, - true - ); - // Add introducer back - contactId0 = contactManager1.addContact(author0, - author1.getId(), master, clock.currentTimeMillis(), true, - true - ); - ContactId contactId02 = contactManager2.addContact(author0, - author2.getId(), master, clock.currentTimeMillis(), true, - true - ); - assertTrue(contactId0.equals(contactId02)); - - // listen to events - IntroducerListener listener0 = new IntroducerListener(); - t0.getEventBus().addListener(listener0); - IntroduceeListener listener1 = new IntroduceeListener(1, true); - t1.getEventBus().addListener(listener1); - IntroduceeListener listener2 = new IntroduceeListener(2, true); - t2.getEventBus().addListener(listener2); - - // make introduction - long time = clock.currentTimeMillis(); - Contact introducee1 = contactManager0.getContact(contactId1); - Contact introducee2 = contactManager0.getContact(contactId2); - introductionManager0 - .makeIntroduction(introducee1, introducee2, "Hi!", time); - - // sync first request message - deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener1.requestReceived); - - // sync second request message - deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener2.requestReceived); - - // sync first response - deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response1Received); - - // sync second response - deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response2Received); - - // sync forwarded responses to introducees - deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1"); - deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2"); - - // sync first ACK and its forward - deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); - deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2"); - - // sync second ACK and its forward - deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); - deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 2"); - - // wait for introduction to succeed - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener1.succeeded); - assertTrue(listener2.succeeded); - - assertTrue(contactManager1 - .contactExists(author2.getId(), author1.getId())); - assertTrue(contactManager2 - .contactExists(author1.getId(), author2.getId())); - - assertDefaultUiMessages(); - } finally { - stopLifecycles(); - } - } - - @Test - public void testIntroductionSessionFirstDecline() throws Exception { - startLifecycles(); - try { - // Add Identities - addDefaultIdentities(); - - // Add Transport Properties - addTransportProperties(); - - // Add introducees as contacts - contactId1 = contactManager0.addContact(author1, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - contactId2 = contactManager0.addContact(author2, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - // Add introducer back - contactId0 = contactManager1.addContact(author0, author1.getId(), - master, clock.currentTimeMillis(), true, true - ); - ContactId contactId02 = contactManager2.addContact(author0, - author2.getId(), master, clock.currentTimeMillis(), true, - true - ); - assertTrue(contactId0.equals(contactId02)); - - // listen to events - IntroducerListener listener0 = new IntroducerListener(); - t0.getEventBus().addListener(listener0); - IntroduceeListener listener1 = new IntroduceeListener(1, false); - t1.getEventBus().addListener(listener1); - IntroduceeListener listener2 = new IntroduceeListener(2, true); - t2.getEventBus().addListener(listener2); - - // make introduction - long time = clock.currentTimeMillis(); - Contact introducee1 = contactManager0.getContact(contactId1); - Contact introducee2 = contactManager0.getContact(contactId2); - introductionManager0 - .makeIntroduction(introducee1, introducee2, null, time); - - // sync request messages - deliverMessage(sync0, contactId0, sync1, contactId1); - deliverMessage(sync0, contactId0, sync2, contactId2); - - // wait for requests to arrive - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener1.requestReceived); - assertTrue(listener2.requestReceived); - - // sync first response - deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response1Received); - - // sync second response - deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response2Received); - - // sync first forwarded response - deliverMessage(sync0, contactId0, sync2, contactId2); - - // note how the introducer does not forward the second response, - // because after the first decline the protocol finished - - assertFalse(listener1.succeeded); - assertFalse(listener2.succeeded); - - assertFalse(contactManager1 - .contactExists(author2.getId(), author1.getId())); - assertFalse(contactManager2 - .contactExists(author1.getId(), author2.getId())); - - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId1) - .size()); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId2) - .size()); - assertEquals(2, - introductionManager1.getIntroductionMessages(contactId0) - .size()); - // introducee2 should also have the decline response of introducee1 - assertEquals(3, - introductionManager2.getIntroductionMessages(contactId0) - .size()); - } finally { - stopLifecycles(); - } - } - - @Test - public void testIntroductionSessionSecondDecline() throws Exception { - startLifecycles(); - try { - // Add Identities - addDefaultIdentities(); - - // Add Transport Properties - addTransportProperties(); - - // Add introducees as contacts - contactId1 = contactManager0.addContact(author1, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - contactId2 = contactManager0.addContact(author2, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - // Add introducer back - contactId0 = contactManager1.addContact(author0, author1.getId(), - master, clock.currentTimeMillis(), false, true - ); - ContactId contactId02 = contactManager2.addContact(author0, - author2.getId(), master, clock.currentTimeMillis(), false, - true - ); - assertTrue(contactId0.equals(contactId02)); - - // listen to events - IntroducerListener listener0 = new IntroducerListener(); - t0.getEventBus().addListener(listener0); - IntroduceeListener listener1 = new IntroduceeListener(1, true); - t1.getEventBus().addListener(listener1); - IntroduceeListener listener2 = new IntroduceeListener(2, false); - t2.getEventBus().addListener(listener2); - - // make introduction - long time = clock.currentTimeMillis(); - Contact introducee1 = contactManager0.getContact(contactId1); - Contact introducee2 = contactManager0.getContact(contactId2); - introductionManager0 - .makeIntroduction(introducee1, introducee2, null, time); - - // sync request messages - deliverMessage(sync0, contactId0, sync1, contactId1); - deliverMessage(sync0, contactId0, sync2, contactId2); - - // wait for requests to arrive - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener1.requestReceived); - assertTrue(listener2.requestReceived); - - // sync first response - deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response1Received); - - // sync second response - deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response2Received); - - // sync both forwarded response - deliverMessage(sync0, contactId0, sync2, contactId2); - deliverMessage(sync0, contactId0, sync1, contactId1); - - assertFalse(contactManager1 - .contactExists(author2.getId(), author1.getId())); - assertFalse(contactManager2 - .contactExists(author1.getId(), author2.getId())); - - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId1) - .size()); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId2) - .size()); - // introducee1 also sees the decline response from introducee2 - assertEquals(3, - introductionManager1.getIntroductionMessages(contactId0) - .size()); - assertEquals(2, - introductionManager2.getIntroductionMessages(contactId0) - .size()); - } finally { - stopLifecycles(); - } - } - - @Test - public void testIntroductionSessionDelayedFirstDecline() throws Exception { - startLifecycles(); - try { - // Add Identities - addDefaultIdentities(); - - // Add Transport Properties - addTransportProperties(); - - // Add introducees as contacts - contactId1 = contactManager0.addContact(author1, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - contactId2 = contactManager0.addContact(author2, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - // Add introducer back - contactId0 = contactManager1.addContact(author0, author1.getId(), - master, clock.currentTimeMillis(), false, true - ); - ContactId contactId02 = contactManager2.addContact(author0, - author2.getId(), master, clock.currentTimeMillis(), false, - true - ); - assertTrue(contactId0.equals(contactId02)); - - // listen to events - IntroducerListener listener0 = new IntroducerListener(); - t0.getEventBus().addListener(listener0); - IntroduceeListener listener1 = new IntroduceeListener(1, false); - t1.getEventBus().addListener(listener1); - IntroduceeListener listener2 = new IntroduceeListener(2, false); - t2.getEventBus().addListener(listener2); - - // make introduction - long time = clock.currentTimeMillis(); - Contact introducee1 = contactManager0.getContact(contactId1); - Contact introducee2 = contactManager0.getContact(contactId2); - introductionManager0 - .makeIntroduction(introducee1, introducee2, null, time); - - // sync request messages - deliverMessage(sync0, contactId0, sync1, contactId1); - deliverMessage(sync0, contactId0, sync2, contactId2); - - // wait for requests to arrive - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener1.requestReceived); - assertTrue(listener2.requestReceived); - - // sync first response - deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response1Received); - - // sync second response - deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0"); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener0.response2Received); - - // sync first forwarded response - deliverMessage(sync0, contactId0, sync2, contactId2); - - // note how the second response will not be forwarded anymore - - assertFalse(contactManager1 - .contactExists(author2.getId(), author1.getId())); - assertFalse(contactManager2 - .contactExists(author1.getId(), author2.getId())); - - // since introducee2 was already in FINISHED state when - // introducee1's response arrived, she ignores and deletes it - assertDefaultUiMessages(); - } finally { - stopLifecycles(); - } - } - - @Test - public void testIntroductionToSameContact() throws Exception { - startLifecycles(); - try { - // Add Identities - addDefaultIdentities(); - - // Add Transport Properties - addTransportProperties(); - - // Add introducee as contact - contactId1 = contactManager0.addContact(author1, author0.getId(), - master, clock.currentTimeMillis(), true, true - ); - // Add introducer back - contactId0 = contactManager1.addContact(author0, author1.getId(), - master, clock.currentTimeMillis(), true, true - ); - - // listen to events - IntroducerListener listener0 = new IntroducerListener(); - t0.getEventBus().addListener(listener0); - IntroduceeListener listener1 = new IntroduceeListener(1, true); - t1.getEventBus().addListener(listener1); - - // make introduction - long time = clock.currentTimeMillis(); - Contact introducee1 = contactManager0.getContact(contactId1); - introductionManager0 - .makeIntroduction(introducee1, introducee1, null, time); - - // sync request messages - deliverMessage(sync0, contactId0, sync1, contactId1); - - // we should not get any event, because the request will be discarded - assertFalse(listener1.requestReceived); - - // make really sure we don't have that request - assertTrue(introductionManager1.getIntroductionMessages(contactId0) - .isEmpty()); - } finally { - stopLifecycles(); - } - } - - @Test - public void testIntroductionToIdentitiesOfSameContact() throws Exception { - startLifecycles(); - try { - // Add Identities - author0 = authorFactory.createLocalAuthor(INTRODUCER, - TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - TestUtils.getRandomBytes(123)); - identityManager0.addLocalAuthor(author0); - author1 = authorFactory.createLocalAuthor(INTRODUCEE1, - TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - TestUtils.getRandomBytes(123)); - identityManager1.addLocalAuthor(author1); - author2 = authorFactory.createLocalAuthor(INTRODUCEE2, - TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - TestUtils.getRandomBytes(123)); - identityManager1.addLocalAuthor(author2); - - // Add Transport Properties - addTransportProperties(); - - // Add introducees' authors as contacts - contactId1 = contactManager0.addContact(author1, - author0.getId(), master, clock.currentTimeMillis(), true, - true - ); - contactId2 = contactManager0.addContact(author2, - author0.getId(), master, clock.currentTimeMillis(), true, - true - ); - // Add introducer back - contactId0 = null; - ContactId contactId01 = contactManager1.addContact(author0, - author1.getId(), master, clock.currentTimeMillis(), false, - true - ); - ContactId contactId02 = contactManager1.addContact(author0, - author2.getId(), master, clock.currentTimeMillis(), false, - true - ); - - // listen to events - IntroducerListener listener0 = new IntroducerListener(); - t0.getEventBus().addListener(listener0); - IntroduceeListener listener1 = new IntroduceeListener(1, true); - t1.getEventBus().addListener(listener1); - - // make introduction - long time = clock.currentTimeMillis(); - Contact introducee1 = contactManager0.getContact(contactId1); - Contact introducee2 = contactManager0.getContact(contactId2); - introductionManager0 - .makeIntroduction(introducee1, introducee2, "Hi!", time); - - // sync request messages - deliverMessage(sync0, contactId01, sync1, contactId1); - deliverMessage(sync0, contactId02, sync1, contactId2); - - // wait for request to arrive - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener1.requestReceived); - - // sync responses - deliverMessage(sync1, contactId1, sync0, contactId01); - deliverMessage(sync1, contactId2, sync0, contactId02); - - // wait for two responses to arrive - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener0.response1Received); - assertTrue(listener0.response2Received); - - // sync forwarded responses to introducees - deliverMessage(sync0, contactId01, sync1, contactId1); - deliverMessage(sync0, contactId02, sync1, contactId2); - - // wait for "both" introducees to abort session - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener1.aborted); - - // sync abort message - deliverMessage(sync1, contactId1, sync0, contactId01); - deliverMessage(sync1, contactId2, sync0, contactId02); - - // wait for introducer to abort session (gets event twice) - eventWaiter.await(TIMEOUT, 2); - assertTrue(listener0.aborted); - - assertFalse(contactManager1 - .contactExists(author1.getId(), author2.getId())); - assertFalse(contactManager1 - .contactExists(author2.getId(), author1.getId())); - - assertEquals(2, introductionManager0.getIntroductionMessages( - contactId1).size()); - assertEquals(2, introductionManager0.getIntroductionMessages( - contactId2).size()); - assertEquals(2, introductionManager1.getIntroductionMessages( - contactId01).size()); - assertEquals(2, introductionManager1.getIntroductionMessages( - contactId02).size()); - } finally { - stopLifecycles(); - } - } - - // TODO add a test for faking responses when #256 is implemented - - @After - public void tearDown() throws InterruptedException { - TestUtils.deleteTestDirectory(testDir); - } - - private void startLifecycles() throws InterruptedException { - // Start the lifecycle manager and wait for it to finish - lifecycleManager0 = t0.getLifecycleManager(); - lifecycleManager1 = t1.getLifecycleManager(); - lifecycleManager2 = t2.getLifecycleManager(); - lifecycleManager0.startServices(); - lifecycleManager1.startServices(); - lifecycleManager2.startServices(); - lifecycleManager0.waitForStartup(); - lifecycleManager1.waitForStartup(); - lifecycleManager2.waitForStartup(); - } - - private void stopLifecycles() throws InterruptedException { - // Clean up - lifecycleManager0.stopServices(); - lifecycleManager1.stopServices(); - lifecycleManager2.stopServices(); - lifecycleManager0.waitForShutdown(); - lifecycleManager1.waitForShutdown(); - lifecycleManager2.waitForShutdown(); - } - - private void addTransportProperties() throws DbException { - TransportPropertyManager tpm0 = t0.getTransportPropertyManager(); - TransportPropertyManager tpm1 = t1.getTransportPropertyManager(); - TransportPropertyManager tpm2 = t2.getTransportPropertyManager(); - - TransportProperties tp = new TransportProperties( - Collections.singletonMap("key", "value")); - tpm0.mergeLocalProperties(TRANSPORT_ID, tp); - tpm1.mergeLocalProperties(TRANSPORT_ID, tp); - tpm2.mergeLocalProperties(TRANSPORT_ID, tp); - } - - private void addDefaultIdentities() throws DbException { - author0 = authorFactory.createLocalAuthor(INTRODUCER, - TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - TestUtils.getRandomBytes(123)); - identityManager0.addLocalAuthor(author0); - author1 = authorFactory.createLocalAuthor(INTRODUCEE1, - TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - TestUtils.getRandomBytes(123)); - identityManager1.addLocalAuthor(author1); - author2 = authorFactory.createLocalAuthor(INTRODUCEE2, - TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - TestUtils.getRandomBytes(123)); - identityManager2.addLocalAuthor(author2); - } - - private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId, - SyncSessionFactory toSync, ContactId toId) - throws IOException, TimeoutException { - deliverMessage(fromSync, fromId, toSync, toId, null); - } - - private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId, - SyncSessionFactory toSync, ContactId toId, String debug) - throws IOException, TimeoutException { - - if (debug != null) LOG.info("TEST: Sending message from " + debug); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - // Create an outgoing sync session - SyncSession sessionFrom = - fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out); - // Write whatever needs to be written - sessionFrom.run(); - out.close(); - - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - // Create an incoming sync session - SyncSession sessionTo = toSync.createIncomingSession(fromId, in); - // Read whatever needs to be read - sessionTo.run(); - in.close(); - - // wait for message to actually arrive - msgWaiter.await(TIMEOUT, 1); - } - - private void assertDefaultUiMessages() throws DbException { - assertEquals(2, introductionManager0.getIntroductionMessages( - contactId1).size()); - assertEquals(2, introductionManager0.getIntroductionMessages( - contactId2).size()); - assertEquals(2, introductionManager1.getIntroductionMessages( - contactId0).size()); - assertEquals(2, introductionManager2.getIntroductionMessages( - contactId0).size()); - } - - private class IntroduceeListener implements EventListener { - - public volatile boolean requestReceived = false; - public volatile boolean succeeded = false; - public volatile boolean aborted = false; - - private final int introducee; - private final boolean accept; - - IntroduceeListener(int introducee, boolean accept) { - this.introducee = introducee; - this.accept = accept; - } - - public void eventOccurred(Event e) { - if (e instanceof MessageValidatedEvent) { - MessageValidatedEvent event = (MessageValidatedEvent) e; - if (event.getClientId() - .equals(introductionManager0.getClientId()) && - !event.isLocal()) { - LOG.info("TEST: Introducee" + introducee + - " received message in group " + - ((MessageValidatedEvent) e).getMessage() - .getGroupId().hashCode()); - msgWaiter.resume(); - } - } else if (e instanceof IntroductionRequestReceivedEvent) { - IntroductionRequestReceivedEvent introEvent = - ((IntroductionRequestReceivedEvent) e); - requestReceived = true; - IntroductionRequest ir = introEvent.getIntroductionRequest(); - ContactId contactId = introEvent.getContactId(); - SessionId sessionId = ir.getSessionId(); - long time = clock.currentTimeMillis(); - try { - if (introducee == 1) { - if (accept) { - introductionManager1 - .acceptIntroduction(contactId, sessionId, - time); - } else { - introductionManager1 - .declineIntroduction(contactId, sessionId, - time); - } - } else if (introducee == 2) { - if (accept) { - introductionManager2 - .acceptIntroduction(contactId, sessionId, - time); - } else { - introductionManager2 - .declineIntroduction(contactId, sessionId, - time); - } - } - } catch (DbException exception) { - eventWaiter.rethrow(exception); - } catch (IOException exception) { - eventWaiter.rethrow(exception); - } finally { - eventWaiter.resume(); - } - } else if (e instanceof IntroductionSucceededEvent) { - succeeded = true; - Contact contact = ((IntroductionSucceededEvent) e).getContact(); - eventWaiter.assertFalse(contact.getId().equals(contactId0)); - eventWaiter.assertTrue(contact.isActive()); - eventWaiter.resume(); - } else if (e instanceof IntroductionAbortedEvent) { - aborted = true; - eventWaiter.resume(); - } - } - } - - private class IntroducerListener implements EventListener { - - public volatile boolean response1Received = false; - public volatile boolean response2Received = false; - public volatile boolean aborted = false; - - public void eventOccurred(Event e) { - if (e instanceof MessageValidatedEvent) { - MessageValidatedEvent event = (MessageValidatedEvent) e; - if (event.getClientId() - .equals(introductionManager0.getClientId()) && - !event.isLocal()) { - LOG.info("TEST: Introducer received message in group " + - ((MessageValidatedEvent) e).getMessage() - .getGroupId().hashCode()); - msgWaiter.resume(); - } - } else if (e instanceof IntroductionResponseReceivedEvent) { - ContactId c = - ((IntroductionResponseReceivedEvent) e).getContactId(); - try { - if (c.equals(contactId1)) { - response1Received = true; - } else if (c.equals(contactId2)) { - response2Received = true; - } - } finally { - eventWaiter.resume(); - } - } else if (e instanceof IntroductionAbortedEvent) { - aborted = true; - eventWaiter.resume(); - } - } - } - - private void injectEagerSingletons( - IntroductionIntegrationTestComponent component) { - - component.inject(new LifecycleModule.EagerSingletons()); - component.inject(new LifecycleModule.EagerSingletons()); - component.inject(new IntroductionModule.EagerSingletons()); - component.inject(new CryptoModule.EagerSingletons()); - component.inject(new ContactModule.EagerSingletons()); - component.inject(new TransportModule.EagerSingletons()); - component.inject(new SyncModule.EagerSingletons()); - component.inject(new PropertiesModule.EagerSingletons()); - } - -} diff --git a/briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java b/briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java deleted file mode 100644 index d86b50d7c..000000000 --- a/briar-android/test/java/briarproject/IntroductionIntegrationTestComponent.java +++ /dev/null @@ -1,80 +0,0 @@ -package briarproject; - -import org.briarproject.TestDatabaseModule; -import org.briarproject.TestPluginsModule; -import org.briarproject.TestSystemModule; -import org.briarproject.api.contact.ContactManager; -import org.briarproject.api.event.EventBus; -import org.briarproject.api.identity.IdentityManager; -import org.briarproject.api.introduction.IntroductionManager; -import org.briarproject.api.lifecycle.LifecycleManager; -import org.briarproject.api.properties.TransportPropertyManager; -import org.briarproject.api.sync.SyncSessionFactory; -import org.briarproject.clients.ClientsModule; -import org.briarproject.contact.ContactModule; -import org.briarproject.crypto.CryptoModule; -import org.briarproject.data.DataModule; -import org.briarproject.db.DatabaseModule; -import org.briarproject.event.EventModule; -import org.briarproject.identity.IdentityModule; -import org.briarproject.introduction.IntroductionModule; -import org.briarproject.lifecycle.LifecycleModule; -import org.briarproject.properties.PropertiesModule; -import org.briarproject.sync.SyncModule; -import org.briarproject.transport.TransportModule; - -import javax.inject.Singleton; - -import dagger.Component; - -@Singleton -@Component(modules = { - TestSystemModule.class, - TestDatabaseModule.class, - TestPluginsModule.class, - LifecycleModule.class, - IntroductionModule.class, - DatabaseModule.class, - CryptoModule.class, - EventModule.class, - ContactModule.class, - IdentityModule.class, - TransportModule.class, - ClientsModule.class, - SyncModule.class, - DataModule.class, - PropertiesModule.class -}) -public interface IntroductionIntegrationTestComponent { - - void inject(IntroductionIntegrationTest testCase); - - void inject(ContactModule.EagerSingletons init); - - void inject(CryptoModule.EagerSingletons init); - - void inject(IntroductionModule.EagerSingletons init); - - void inject(LifecycleModule.EagerSingletons init); - - void inject(PropertiesModule.EagerSingletons init); - - void inject(SyncModule.EagerSingletons init); - - void inject(TransportModule.EagerSingletons init); - - LifecycleManager getLifecycleManager(); - - EventBus getEventBus(); - - IdentityManager getIdentityManager(); - - ContactManager getContactManager(); - - IntroductionManager getIntroductionManager(); - - TransportPropertyManager getTransportPropertyManager(); - - SyncSessionFactory getSyncSessionFactory(); - -} diff --git a/briar-android/test/java/briarproject/MessageSizeIntegrationTest.java b/briar-android/test/java/briarproject/MessageSizeIntegrationTest.java deleted file mode 100644 index d46c26f43..000000000 --- a/briar-android/test/java/briarproject/MessageSizeIntegrationTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package briarproject; - -import org.briarproject.BriarTestCase; -import org.briarproject.TestUtils; -import org.briarproject.api.UniqueId; -import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.PrivateKey; -import org.briarproject.api.forum.ForumConstants; -import org.briarproject.api.forum.ForumPost; -import org.briarproject.api.forum.ForumPostFactory; -import org.briarproject.api.identity.Author; -import org.briarproject.api.identity.AuthorFactory; -import org.briarproject.api.messaging.MessagingConstants; -import org.briarproject.api.messaging.PrivateMessage; -import org.briarproject.api.messaging.PrivateMessageFactory; -import org.briarproject.api.sync.GroupId; -import org.briarproject.api.sync.MessageId; -import org.junit.Test; - -import javax.inject.Inject; - -import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH; -import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; -import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH; -import static org.briarproject.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH; -import static org.junit.Assert.assertTrue; - -public class MessageSizeIntegrationTest extends BriarTestCase { - - @Inject - CryptoComponent crypto; - @Inject - AuthorFactory authorFactory; - @Inject - PrivateMessageFactory privateMessageFactory; - @Inject - ForumPostFactory forumPostFactory; - - public MessageSizeIntegrationTest() throws Exception { - MessageSizeIntegrationTestComponent component = - DaggerMessageSizeIntegrationTestComponent.builder().build(); - component.inject(this); - } - - @Test - public void testPrivateMessageFitsIntoPacket() throws Exception { - // Create a maximum-length private message - GroupId groupId = new GroupId(TestUtils.getRandomId()); - long timestamp = Long.MAX_VALUE; - MessageId parent = new MessageId(TestUtils.getRandomId()); - String contentType = TestUtils.getRandomString( - MessagingConstants.MAX_CONTENT_TYPE_LENGTH); - byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]; - PrivateMessage message = privateMessageFactory.createPrivateMessage( - groupId, timestamp, parent, contentType, body); - // Check the size of the serialised message - int length = message.getMessage().getRaw().length; - assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH - + MessagingConstants.MAX_CONTENT_TYPE_LENGTH - + MAX_PRIVATE_MESSAGE_BODY_LENGTH); - assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH); - } - - @Test - public void testForumPostFitsIntoPacket() throws Exception { - // Create a maximum-length author - String authorName = TestUtils.getRandomString( - MAX_AUTHOR_NAME_LENGTH); - byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH]; - Author author = authorFactory.createAuthor(authorName, authorPublic); - // Create a maximum-length forum post - GroupId groupId = new GroupId(TestUtils.getRandomId()); - long timestamp = Long.MAX_VALUE; - MessageId parent = new MessageId(TestUtils.getRandomId()); - String contentType = TestUtils.getRandomString( - ForumConstants.MAX_CONTENT_TYPE_LENGTH); - byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH]; - PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate(); - ForumPost post = forumPostFactory.createPseudonymousPost(groupId, - timestamp, parent, author, contentType, body, privateKey); - // Check the size of the serialised message - int length = post.getMessage().getRaw().length; - assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH - + MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH - + ForumConstants.MAX_CONTENT_TYPE_LENGTH - + MAX_FORUM_POST_BODY_LENGTH); - assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH); - } -} diff --git a/briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java b/briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java deleted file mode 100644 index 9f112fb6b..000000000 --- a/briar-android/test/java/briarproject/MessageSizeIntegrationTestComponent.java +++ /dev/null @@ -1,37 +0,0 @@ -package briarproject; - -import org.briarproject.TestDatabaseModule; -import org.briarproject.TestLifecycleModule; -import org.briarproject.TestSystemModule; -import org.briarproject.clients.ClientsModule; -import org.briarproject.crypto.CryptoModule; -import org.briarproject.data.DataModule; -import org.briarproject.db.DatabaseModule; -import org.briarproject.event.EventModule; -import org.briarproject.forum.ForumModule; -import org.briarproject.identity.IdentityModule; -import org.briarproject.messaging.MessagingModule; -import org.briarproject.sync.SyncModule; - -import javax.inject.Singleton; - -import dagger.Component; - -@Singleton -@Component(modules = { - TestDatabaseModule.class, - TestLifecycleModule.class, - TestSystemModule.class, - ClientsModule.class, - CryptoModule.class, - DataModule.class, - DatabaseModule.class, - EventModule.class, - ForumModule.class, - IdentityModule.class, - MessagingModule.class, - SyncModule.class -}) -public interface MessageSizeIntegrationTestComponent { - void inject(MessageSizeIntegrationTest testCase); -} diff --git a/briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java b/briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java deleted file mode 100644 index 53e7d03a3..000000000 --- a/briar-android/test/java/briarproject/SimplexMessagingIntegrationTest.java +++ /dev/null @@ -1,193 +0,0 @@ -package briarproject; - -import org.briarproject.BriarTestCase; -import org.briarproject.TestDatabaseModule; -import org.briarproject.TestUtils; -import org.briarproject.api.contact.ContactId; -import org.briarproject.api.contact.ContactManager; -import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.MessageAddedEvent; -import org.briarproject.api.identity.Author; -import org.briarproject.api.identity.AuthorId; -import org.briarproject.api.identity.IdentityManager; -import org.briarproject.api.identity.LocalAuthor; -import org.briarproject.api.lifecycle.LifecycleManager; -import org.briarproject.api.messaging.MessagingManager; -import org.briarproject.api.messaging.PrivateMessage; -import org.briarproject.api.messaging.PrivateMessageFactory; -import org.briarproject.api.sync.GroupId; -import org.briarproject.api.sync.SyncSession; -import org.briarproject.api.sync.SyncSessionFactory; -import org.briarproject.api.transport.KeyManager; -import org.briarproject.api.transport.StreamContext; -import org.briarproject.api.transport.StreamReaderFactory; -import org.briarproject.api.transport.StreamWriterFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; - -import static org.briarproject.TestPluginsModule.MAX_LATENCY; -import static org.briarproject.TestPluginsModule.TRANSPORT_ID; -import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; -import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class SimplexMessagingIntegrationTest extends BriarTestCase { - - private final File testDir = TestUtils.getTestDirectory(); - private final File aliceDir = new File(testDir, "alice"); - private final File bobDir = new File(testDir, "bob"); - private final SecretKey master = TestUtils.getSecretKey(); - private final long timestamp = System.currentTimeMillis(); - private final AuthorId aliceId = new AuthorId(TestUtils.getRandomId()); - private final AuthorId bobId = new AuthorId(TestUtils.getRandomId()); - - private SimplexMessagingIntegrationTestComponent alice, bob; - - @Before - public void setUp() { - assertTrue(testDir.mkdirs()); - alice = DaggerSimplexMessagingIntegrationTestComponent.builder() - .testDatabaseModule(new TestDatabaseModule(aliceDir)).build(); - bob = DaggerSimplexMessagingIntegrationTestComponent.builder() - .testDatabaseModule(new TestDatabaseModule(bobDir)).build(); - } - - @Test - public void testWriteAndRead() throws Exception { - read(write()); - } - - private byte[] write() throws Exception { - // Instantiate Alice's services - LifecycleManager lifecycleManager = alice.getLifecycleManager(); - IdentityManager identityManager = alice.getIdentityManager(); - ContactManager contactManager = alice.getContactManager(); - MessagingManager messagingManager = alice.getMessagingManager(); - KeyManager keyManager = alice.getKeyManager(); - PrivateMessageFactory privateMessageFactory = - alice.getPrivateMessageFactory(); - StreamWriterFactory streamWriterFactory = - alice.getStreamWriterFactory(); - SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory(); - - // Start the lifecycle manager - lifecycleManager.startServices(); - lifecycleManager.waitForStartup(); - // Add an identity for Alice - LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice", - new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); - identityManager.addLocalAuthor(aliceAuthor); - // Add Bob as a contact - Author bobAuthor = new Author(bobId, "Bob", - new byte[MAX_PUBLIC_KEY_LENGTH]); - ContactId contactId = contactManager.addContact(bobAuthor, aliceId, - master, timestamp, true, true); - - // Send Bob a message - GroupId groupId = messagingManager.getConversationId(contactId); - byte[] body = "Hi Bob!".getBytes("UTF-8"); - PrivateMessage message = privateMessageFactory.createPrivateMessage( - groupId, timestamp, null, "text/plain", body); - messagingManager.addLocalMessage(message); - // Get a stream context - StreamContext ctx = keyManager.getStreamContext(contactId, - TRANSPORT_ID); - assertNotNull(ctx); - // Create a stream writer - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutputStream streamWriter = streamWriterFactory.createStreamWriter( - out, ctx); - // Create an outgoing sync session - SyncSession session = syncSessionFactory.createSimplexOutgoingSession( - contactId, MAX_LATENCY, streamWriter); - // Write whatever needs to be written - session.run(); - streamWriter.close(); - - // Clean up - lifecycleManager.stopServices(); - lifecycleManager.waitForShutdown(); - - // Return the contents of the stream - return out.toByteArray(); - } - - private void read(byte[] stream) throws Exception { - // Instantiate Bob's services - LifecycleManager lifecycleManager = bob.getLifecycleManager(); - IdentityManager identityManager = bob.getIdentityManager(); - ContactManager contactManager = bob.getContactManager(); - KeyManager keyManager = bob.getKeyManager(); - StreamReaderFactory streamReaderFactory = bob.getStreamReaderFactory(); - SyncSessionFactory syncSessionFactory = bob.getSyncSessionFactory(); - // Bob needs a MessagingManager even though we're not using it directly - bob.getMessagingManager(); - - // Start the lifecyle manager - lifecycleManager.startServices(); - lifecycleManager.waitForStartup(); - // Add an identity for Bob - LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob", - new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); - identityManager.addLocalAuthor(bobAuthor); - // Add Alice as a contact - Author aliceAuthor = new Author(aliceId, "Alice", - new byte[MAX_PUBLIC_KEY_LENGTH]); - ContactId contactId = contactManager.addContact(aliceAuthor, bobId, - master, timestamp, false, true); - - // Set up an event listener - MessageListener listener = new MessageListener(); - bob.getEventBus().addListener(listener); - // 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); - StreamContext ctx = keyManager.getStreamContext(TRANSPORT_ID, tag); - assertNotNull(ctx); - // Create a stream reader - InputStream streamReader = streamReaderFactory.createStreamReader( - in, ctx); - // Create an incoming sync session - SyncSession session = syncSessionFactory.createIncomingSession( - contactId, streamReader); - // No messages should have been added yet - assertFalse(listener.messageAdded); - // Read whatever needs to be read - session.run(); - streamReader.close(); - // The private message from Alice should have been added - assertTrue(listener.messageAdded); - - // Clean up - lifecycleManager.stopServices(); - lifecycleManager.waitForShutdown(); - } - - @After - public void tearDown() { - TestUtils.deleteTestDirectory(testDir); - } - - private static class MessageListener implements EventListener { - - private volatile boolean messageAdded = false; - - public void eventOccurred(Event e) { - if (e instanceof MessageAddedEvent) messageAdded = true; - } - } -} diff --git a/briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java b/briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java deleted file mode 100644 index 7691b8192..000000000 --- a/briar-android/test/java/briarproject/SimplexMessagingIntegrationTestComponent.java +++ /dev/null @@ -1,74 +0,0 @@ -package briarproject; - -import org.briarproject.TestDatabaseModule; -import org.briarproject.TestPluginsModule; -import org.briarproject.TestSystemModule; -import org.briarproject.api.contact.ContactManager; -import org.briarproject.api.event.EventBus; -import org.briarproject.api.identity.IdentityManager; -import org.briarproject.api.lifecycle.LifecycleManager; -import org.briarproject.api.messaging.MessagingManager; -import org.briarproject.api.messaging.PrivateMessageFactory; -import org.briarproject.api.sync.SyncSessionFactory; -import org.briarproject.api.transport.KeyManager; -import org.briarproject.api.transport.StreamReaderFactory; -import org.briarproject.api.transport.StreamWriterFactory; -import org.briarproject.clients.ClientsModule; -import org.briarproject.contact.ContactModule; -import org.briarproject.crypto.CryptoModule; -import org.briarproject.data.DataModule; -import org.briarproject.db.DatabaseModule; -import org.briarproject.event.EventModule; -import org.briarproject.identity.IdentityModule; -import org.briarproject.lifecycle.LifecycleModule; -import org.briarproject.messaging.MessagingModule; -import org.briarproject.plugins.PluginsModule; -import org.briarproject.sync.SyncModule; -import org.briarproject.transport.TransportModule; - -import javax.inject.Singleton; - -import dagger.Component; - -@Singleton -@Component(modules = { - TestDatabaseModule.class, - TestPluginsModule.class, - TestSystemModule.class, - ClientsModule.class, - ContactModule.class, - CryptoModule.class, - DataModule.class, - DatabaseModule.class, - EventModule.class, - IdentityModule.class, - LifecycleModule.class, - MessagingModule.class, - PluginsModule.class, - SyncModule.class, - TransportModule.class -}) -public interface SimplexMessagingIntegrationTestComponent { - - void inject(SimplexMessagingIntegrationTest testCase); - - 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/test/java/briarproject/SyncIntegrationTest.java b/briar-android/test/java/briarproject/SyncIntegrationTest.java deleted file mode 100644 index 8d5dabfc3..000000000 --- a/briar-android/test/java/briarproject/SyncIntegrationTest.java +++ /dev/null @@ -1,169 +0,0 @@ -package briarproject; - -import org.briarproject.BriarTestCase; -import org.briarproject.TestUtils; -import org.briarproject.api.TransportId; -import org.briarproject.api.contact.ContactId; -import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.sync.Ack; -import org.briarproject.api.sync.ClientId; -import org.briarproject.api.sync.Group; -import org.briarproject.api.sync.GroupFactory; -import org.briarproject.api.sync.Message; -import org.briarproject.api.sync.MessageFactory; -import org.briarproject.api.sync.MessageId; -import org.briarproject.api.sync.Offer; -import org.briarproject.api.sync.PacketReader; -import org.briarproject.api.sync.PacketReaderFactory; -import org.briarproject.api.sync.PacketWriter; -import org.briarproject.api.sync.PacketWriterFactory; -import org.briarproject.api.sync.Request; -import org.briarproject.api.transport.StreamContext; -import org.briarproject.api.transport.StreamReaderFactory; -import org.briarproject.api.transport.StreamWriterFactory; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Collection; - -import javax.inject.Inject; - -import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH; -import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class SyncIntegrationTest extends BriarTestCase { - - @Inject - GroupFactory groupFactory; - @Inject - MessageFactory messageFactory; - @Inject - StreamReaderFactory streamReaderFactory; - @Inject - StreamWriterFactory streamWriterFactory; - @Inject - PacketReaderFactory packetReaderFactory; - @Inject - PacketWriterFactory packetWriterFactory; - @Inject - CryptoComponent crypto; - - private final ContactId contactId; - private final TransportId transportId; - private final SecretKey tagKey, headerKey; - private final long streamNumber; - private final Message message, message1; - private final Collection messageIds; - - public SyncIntegrationTest() throws Exception { - - SyncIntegrationTestComponent component = - DaggerSyncIntegrationTestComponent.builder().build(); - component.inject(this); - - contactId = new ContactId(234); - transportId = new TransportId("id"); - // Create the transport keys - tagKey = TestUtils.getSecretKey(); - headerKey = TestUtils.getSecretKey(); - streamNumber = 123; - // Create a group - ClientId clientId = new ClientId(TestUtils.getRandomId()); - byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH]; - Group group = groupFactory.createGroup(clientId, descriptor); - // Add two messages to the group - long timestamp = System.currentTimeMillis(); - byte[] body = "Hello world".getBytes("UTF-8"); - message = messageFactory.createMessage(group.getId(), timestamp, body); - message1 = messageFactory.createMessage(group.getId(), timestamp, body); - messageIds = Arrays.asList(message.getId(), message1.getId()); - } - - @Test - public void testWriteAndRead() throws Exception { - read(write()); - } - - private byte[] write() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - StreamContext ctx = new StreamContext(contactId, transportId, tagKey, - headerKey, streamNumber); - OutputStream streamWriter = streamWriterFactory.createStreamWriter(out, - ctx); - PacketWriter packetWriter = packetWriterFactory.createPacketWriter( - streamWriter); - - packetWriter.writeAck(new Ack(messageIds)); - packetWriter.writeMessage(message.getRaw()); - packetWriter.writeMessage(message1.getRaw()); - packetWriter.writeOffer(new Offer(messageIds)); - packetWriter.writeRequest(new Request(messageIds)); - - streamWriter.flush(); - return out.toByteArray(); - } - - private void read(byte[] connectionData) throws Exception { - // Calculate the expected tag - byte[] expectedTag = new byte[TAG_LENGTH]; - crypto.encodeTag(expectedTag, tagKey, streamNumber); - - // Read the tag - InputStream in = new ByteArrayInputStream(connectionData); - byte[] tag = new byte[TAG_LENGTH]; - assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH)); - assertArrayEquals(expectedTag, tag); - - // Create the readers - StreamContext ctx = new StreamContext(contactId, transportId, tagKey, - headerKey, 0); - InputStream streamReader = streamReaderFactory.createStreamReader(in, - ctx); - PacketReader packetReader = packetReaderFactory.createPacketReader( - streamReader); - - // Read the ack - assertTrue(packetReader.hasAck()); - Ack a = packetReader.readAck(); - assertEquals(messageIds, a.getMessageIds()); - - // Read the messages - assertTrue(packetReader.hasMessage()); - Message m = packetReader.readMessage(); - checkMessageEquality(message, m); - assertTrue(packetReader.hasMessage()); - m = packetReader.readMessage(); - checkMessageEquality(message1, m); - assertFalse(packetReader.hasMessage()); - - // Read the offer - assertTrue(packetReader.hasOffer()); - Offer o = packetReader.readOffer(); - assertEquals(messageIds, o.getMessageIds()); - - // Read the request - assertTrue(packetReader.hasRequest()); - Request req = packetReader.readRequest(); - assertEquals(messageIds, req.getMessageIds()); - - in.close(); - } - - private void checkMessageEquality(Message m1, Message m2) { - assertArrayEquals(m1.getId().getBytes(), m2.getId().getBytes()); - assertArrayEquals(m1.getGroupId().getBytes(), - m2.getGroupId().getBytes()); - assertEquals(m1.getTimestamp(), m2.getTimestamp()); - assertEquals(m1.getLength(), m2.getLength()); - assertArrayEquals(m1.getRaw(), m2.getRaw()); - } -} diff --git a/briar-android/test/java/briarproject/SyncIntegrationTestComponent.java b/briar-android/test/java/briarproject/SyncIntegrationTestComponent.java deleted file mode 100644 index ad3d4dfde..000000000 --- a/briar-android/test/java/briarproject/SyncIntegrationTestComponent.java +++ /dev/null @@ -1,21 +0,0 @@ -package briarproject; - -import org.briarproject.TestSystemModule; -import org.briarproject.crypto.CryptoModule; -import org.briarproject.sync.SyncModule; -import org.briarproject.transport.TransportModule; - -import javax.inject.Singleton; - -import dagger.Component; - -@Singleton -@Component(modules = { - TestSystemModule.class, - CryptoModule.class, - SyncModule.class, - TransportModule.class -}) -public interface SyncIntegrationTestComponent { - void inject(SyncIntegrationTest testCase); -} diff --git a/briar-android/test/java/briarproject/activity/SetupActivityTest.java b/briar-android/test/java/briarproject/activity/SetupActivityTest.java index 586cec989..5adf7483d 100644 --- a/briar-android/test/java/briarproject/activity/SetupActivityTest.java +++ b/briar-android/test/java/briarproject/activity/SetupActivityTest.java @@ -47,7 +47,8 @@ import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) +@Config(constants = BuildConfig.class, sdk = 21, + application = TestBriarApplicationImp.class) public class SetupActivityTest { TestSetupActivity setupActivity; diff --git a/briar-android/test/java/briarproject/activity/TestBriarApplicationImp.java b/briar-android/test/java/briarproject/activity/TestBriarApplicationImp.java new file mode 100644 index 000000000..8e29d9efd --- /dev/null +++ b/briar-android/test/java/briarproject/activity/TestBriarApplicationImp.java @@ -0,0 +1,43 @@ +package briarproject.activity; + +import android.app.Application; + +import org.briarproject.CoreModule; +import org.briarproject.android.AndroidComponent; +import org.briarproject.android.AndroidEagerSingletons; +import org.briarproject.android.AppModule; +import org.briarproject.android.BriarApplication; +import org.briarproject.android.DaggerAndroidComponent; + +import java.util.logging.Logger; + +/** + * This Class only exists to get around ACRA + */ +public class TestBriarApplicationImp extends Application implements + BriarApplication{ + + private static final Logger LOG = + Logger.getLogger(TestBriarApplicationImp.class.getName()); + + private AndroidComponent applicationComponent; + + @Override + public void onCreate() { + super.onCreate(); + LOG.info("Created"); + + applicationComponent = DaggerAndroidComponent.builder() + .appModule(new AppModule(this)) + .build(); + + // We need to load the eager singletons directly after making the + // dependency graphs + CoreModule.initEagerSingletons(applicationComponent); + AndroidEagerSingletons.initEagerSingletons(applicationComponent); + } + + public AndroidComponent getApplicationComponent() { + return applicationComponent; + } +} diff --git a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java index 6481b4a5f..d4bc00b5d 100644 --- a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java +++ b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java @@ -17,9 +17,6 @@ import static java.util.logging.Level.WARNING; class LinuxSeedProvider implements SeedProvider { - private static final Logger LOG = - Logger.getLogger(LinuxSeedProvider.class.getName()); - private final String outputFile, inputFile; LinuxSeedProvider() { From d4232b6a018f4b0ae5521d849009b3229e725e03 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Mon, 9 May 2016 14:08:24 +0200 Subject: [PATCH 17/19] cleanup --- briar-core/src/org/briarproject/system/LinuxSeedProvider.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java index d4bc00b5d..6481b4a5f 100644 --- a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java +++ b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java @@ -17,6 +17,9 @@ import static java.util.logging.Level.WARNING; class LinuxSeedProvider implements SeedProvider { + private static final Logger LOG = + Logger.getLogger(LinuxSeedProvider.class.getName()); + private final String outputFile, inputFile; LinuxSeedProvider() { From c93e78f178321c8ce8ebff0f9e72a273a8eaa254 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Wed, 11 May 2016 11:40:49 +0200 Subject: [PATCH 18/19] modifications based on Akwizgran's comments --- briar-android/AndroidManifest.xml | 2 +- briar-android/build.gradle | 4 --- briar-android/proguard-rules.txt | 14 ---------- .../briarproject/android/ActivityModule.java | 28 +++++++++---------- .../briarproject/android/BriarActivity.java | 10 ++----- ...tionImp.java => BriarApplicationImpl.java} | 4 +-- .../android/NavDrawerActivity.java | 20 +++++-------- .../android/SplashScreenActivity.java | 1 + .../android/controller/BriarController.java | 2 +- ...ollerImp.java => BriarControllerImpl.java} | 8 +++--- ...llerImp.java => ConfigControllerImpl.java} | 4 +-- .../controller/NavDrawerController.java | 7 ++--- ...rImp.java => NavDrawerControllerImpl.java} | 16 +++++------ ...erImp.java => PasswordControllerImpl.java} | 8 ++++-- ...ollerImp.java => SetupControllerImpl.java} | 8 +++--- .../android/panic/PanicResponderActivity.java | 1 + .../util/BriarReportSenderFactory.java | 1 - .../system/AndroidSeedProvider.java | 2 +- .../activity/SetupActivityTest.java | 4 +-- 19 files changed, 57 insertions(+), 87 deletions(-) rename briar-android/src/org/briarproject/android/{BriarApplicationImp.java => BriarApplicationImpl.java} (91%) rename briar-android/src/org/briarproject/android/controller/{BriarControllerImp.java => BriarControllerImpl.java} (93%) rename briar-android/src/org/briarproject/android/controller/{ConfigControllerImp.java => ConfigControllerImpl.java} (88%) rename briar-android/src/org/briarproject/android/controller/{NavDrawerControllerImp.java => NavDrawerControllerImpl.java} (88%) rename briar-android/src/org/briarproject/android/controller/{PasswordControllerImp.java => PasswordControllerImpl.java} (83%) rename briar-android/src/org/briarproject/android/controller/{SetupControllerImp.java => SetupControllerImpl.java} (93%) diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index 92ae565c5..6901075a3 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -29,7 +29,7 @@ (this) { + new UiResultHandler(this) { @Override public void onResultUi(Void result) { hideLoadingScreen(); } - - @Override - public void onExceptionUi(DbException exception) { - - } }); } @@ -245,21 +239,21 @@ public class NavDrawerActivity extends BriarFragmentActivity implements Transport tor = new Transport(); tor.id = new TransportId("tor"); - tor.enabled = controller.transportRunning(tor.id); + tor.enabled = controller.isTransportRunning(tor.id); tor.iconId = R.drawable.transport_tor; tor.textId = R.string.transport_tor; transports.add(tor); Transport bt = new Transport(); bt.id = new TransportId("bt"); - bt.enabled = controller.transportRunning(bt.id); + bt.enabled = controller.isTransportRunning(bt.id); bt.iconId = R.drawable.transport_bt; bt.textId = R.string.transport_bt; transports.add(bt); Transport lan = new Transport(); lan.id = new TransportId("lan"); - lan.enabled = controller.transportRunning(lan.id); + lan.enabled = controller.isTransportRunning(lan.id); lan.iconId = R.drawable.transport_lan; lan.textId = R.string.transport_lan; transports.add(lan); @@ -326,7 +320,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements private void updateTransports() { if (transports == null || transportsAdapter == null) return; for (Transport t : transports) { - t.enabled = controller.transportRunning(t.id); + t.enabled = controller.isTransportRunning(t.id); } transportsAdapter.notifyDataSetChanged(); } diff --git a/briar-android/src/org/briarproject/android/SplashScreenActivity.java b/briar-android/src/org/briarproject/android/SplashScreenActivity.java index e2b8dcc8b..e4ff0b941 100644 --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -69,6 +69,7 @@ public class SplashScreenActivity extends BaseActivity { startActivity(new Intent(this, NavDrawerActivity.class)); } else { configController.clearPrefs(); + // TODO replace this static call with a controller method AndroidUtils.deleteAppData(this); startActivity(new Intent(this, SetupActivity.class)); } diff --git a/briar-android/src/org/briarproject/android/controller/BriarController.java b/briar-android/src/org/briarproject/android/controller/BriarController.java index 2ed024ee9..4be89b108 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarController.java +++ b/briar-android/src/org/briarproject/android/controller/BriarController.java @@ -8,7 +8,7 @@ public interface BriarController extends ActivityLifecycleController { void startAndBindService(); - boolean encryptionKey(); + boolean hasEncryptionKey(); void signOut(ResultHandler eventHandler); } diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java similarity index 93% rename from briar-android/src/org/briarproject/android/controller/BriarControllerImp.java rename to briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java index 9e7cadeae..fd24291c7 100644 --- a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java @@ -17,10 +17,10 @@ import java.util.logging.Logger; import javax.inject.Inject; -public class BriarControllerImp implements BriarController { +public class BriarControllerImpl implements BriarController { private static final Logger LOG = - Logger.getLogger(BriarControllerImp.class.getName()); + Logger.getLogger(BriarControllerImpl.class.getName()); @Inject protected BriarServiceConnection serviceConnection; @@ -38,7 +38,7 @@ public class BriarControllerImp implements BriarController { private boolean bound = false; @Inject - public BriarControllerImp() { + public BriarControllerImpl() { } @@ -71,7 +71,7 @@ public class BriarControllerImp implements BriarController { } @Override - public boolean encryptionKey() { + public boolean hasEncryptionKey() { return databaseConfig.getEncryptionKey() != null; } diff --git a/briar-android/src/org/briarproject/android/controller/ConfigControllerImp.java b/briar-android/src/org/briarproject/android/controller/ConfigControllerImpl.java similarity index 88% rename from briar-android/src/org/briarproject/android/controller/ConfigControllerImp.java rename to briar-android/src/org/briarproject/android/controller/ConfigControllerImpl.java index d37ab8f1b..b823b98e2 100644 --- a/briar-android/src/org/briarproject/android/controller/ConfigControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/ConfigControllerImpl.java @@ -6,7 +6,7 @@ import org.briarproject.api.db.DatabaseConfig; import javax.inject.Inject; -public class ConfigControllerImp implements ConfigController { +public class ConfigControllerImpl implements ConfigController { private final static String PREF_DB_KEY = "key"; @@ -16,7 +16,7 @@ public class ConfigControllerImp implements ConfigController { protected volatile DatabaseConfig databaseConfig; @Inject - public ConfigControllerImp() { + public ConfigControllerImpl() { } diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java index 2669cc455..56d48b1ca 100644 --- a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java @@ -1,17 +1,16 @@ package org.briarproject.android.controller; -import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.api.TransportId; -import org.briarproject.api.db.DbException; import org.briarproject.api.identity.LocalAuthor; public interface NavDrawerController extends BriarController { void setTransportListener(TransportStateListener transportListener); - boolean transportRunning(TransportId transportId); + boolean isTransportRunning(TransportId transportId); void storeLocalAuthor(LocalAuthor author, - ResultExceptionHandler resultHandler); + UiResultHandler resultHandler); LocalAuthor removeAuthorHandle(long handle); } diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java similarity index 88% rename from briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java rename to briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java index 0a5d2c865..4be03f949 100644 --- a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java @@ -3,7 +3,7 @@ package org.briarproject.android.controller; import android.app.Activity; import org.briarproject.android.api.ReferenceManager; -import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.api.TransportId; import org.briarproject.api.db.DbException; import org.briarproject.api.event.Event; @@ -25,11 +25,11 @@ import javax.inject.Inject; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -public class NavDrawerControllerImp extends BriarControllerImp +public class NavDrawerControllerImpl extends BriarControllerImpl implements NavDrawerController, EventListener { private static final Logger LOG = - Logger.getLogger(NavDrawerControllerImp.class.getName()); + Logger.getLogger(NavDrawerControllerImpl.class.getName()); @Inject protected ReferenceManager referenceManager; @@ -38,7 +38,7 @@ public class NavDrawerControllerImp extends BriarControllerImp @Inject protected PluginManager pluginManager; @Inject - protected volatile EventBus eventBus; + protected EventBus eventBus; @Inject protected Activity activity; @@ -47,7 +47,7 @@ public class NavDrawerControllerImp extends BriarControllerImp private TransportStateListener transportStateListener; @Inject - public NavDrawerControllerImp() { + public NavDrawerControllerImpl() { } @@ -103,15 +103,14 @@ public class NavDrawerControllerImp extends BriarControllerImp } @Override - public boolean transportRunning(TransportId transportId) { + public boolean isTransportRunning(TransportId transportId) { Plugin plugin = pluginManager.getPlugin(transportId); return plugin != null && plugin.isRunning(); } @Override public void storeLocalAuthor(final LocalAuthor author, - final ResultExceptionHandler resultHandler) { - + final UiResultHandler resultHandler) { runOnDbThread(new Runnable() { public void run() { try { @@ -124,7 +123,6 @@ public class NavDrawerControllerImp extends BriarControllerImp } catch (final DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - resultHandler.onException(e); } } }); diff --git a/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java b/briar-android/src/org/briarproject/android/controller/PasswordControllerImpl.java similarity index 83% rename from briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java rename to briar-android/src/org/briarproject/android/controller/PasswordControllerImpl.java index 8a85fc51b..12f7e4240 100644 --- a/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/PasswordControllerImpl.java @@ -12,7 +12,7 @@ import java.util.concurrent.Executor; import javax.inject.Inject; -public class PasswordControllerImp extends ConfigControllerImp +public class PasswordControllerImpl extends ConfigControllerImpl implements PasswordController { @Inject @@ -24,7 +24,7 @@ public class PasswordControllerImp extends ConfigControllerImp protected Activity activity; @Inject - public PasswordControllerImp() { + public PasswordControllerImpl() { } @@ -47,6 +47,8 @@ public class PasswordControllerImp extends ConfigControllerImp private byte[] getEncryptedKey() { String hex = getEncryptedDatabaseKey(); - return hex == null ? null : StringUtils.fromHexString(hex); + if (hex == null) + throw new IllegalStateException("Encrypted database key is null."); + return StringUtils.fromHexString(hex); } } diff --git a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java b/briar-android/src/org/briarproject/android/controller/SetupControllerImpl.java similarity index 93% rename from briar-android/src/org/briarproject/android/controller/SetupControllerImp.java rename to briar-android/src/org/briarproject/android/controller/SetupControllerImpl.java index 61a933e67..29bed6d19 100644 --- a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java +++ b/briar-android/src/org/briarproject/android/controller/SetupControllerImpl.java @@ -22,10 +22,10 @@ import javax.inject.Inject; import static java.util.logging.Level.INFO; -public class SetupControllerImp implements SetupController { +public class SetupControllerImpl implements SetupController { private static final Logger LOG = - Logger.getLogger(SetupControllerImp.class.getName()); + Logger.getLogger(SetupControllerImpl.class.getName()); private final static String PREF_DB_KEY = "key"; @@ -50,7 +50,7 @@ public class SetupControllerImp implements SetupController { protected SharedPreferences briarPrefs; @Inject - public SetupControllerImp() { + public SetupControllerImpl() { } @@ -90,7 +90,7 @@ public class SetupControllerImp implements SetupController { databaseConfig.setEncryptionKey(key); String hex = encryptDatabaseKey(key, password); storeEncryptedDatabaseKey(hex); - final LocalAuthor localAuthor = createLocalAuthor(nickname); + LocalAuthor localAuthor = createLocalAuthor(nickname); long handle = referenceManager.putReference(localAuthor, LocalAuthor.class); resultHandler.onResult(handle); diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java index 0b08f7f5a..fbe549e6e 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -112,6 +112,7 @@ public class PanicResponderActivity extends BriarActivity { public void run() { configController.clearPrefs(); // TODO somehow delete/shred the database more thoroughly + // TODO replace this static call with a controller method AndroidUtils.deleteAppData(PanicResponderActivity.this); PanicResponder.deleteAllAppData(PanicResponderActivity.this); diff --git a/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java b/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java index 73108ae4a..6dc106f74 100644 --- a/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java +++ b/briar-android/src/org/briarproject/android/util/BriarReportSenderFactory.java @@ -7,7 +7,6 @@ import org.acra.config.ACRAConfiguration; import org.acra.sender.ReportSender; import org.acra.sender.ReportSenderFactory; import org.briarproject.android.BriarApplication; -import org.briarproject.android.BriarApplicationImp; public class BriarReportSenderFactory implements ReportSenderFactory { @NonNull diff --git a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java index 1b51be767..59c7a6e3a 100644 --- a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java +++ b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java @@ -37,7 +37,7 @@ class AndroidSeedProvider extends LinuxSeedProvider { String str = Settings.Secure.getString(contentResolver, ANDROID_ID); if (str != null) { out.writeUTF(str); - super.writeToEntropyPool(out); } + super.writeToEntropyPool(out); } } diff --git a/briar-android/test/java/briarproject/activity/SetupActivityTest.java b/briar-android/test/java/briarproject/activity/SetupActivityTest.java index 5adf7483d..b58d033b2 100644 --- a/briar-android/test/java/briarproject/activity/SetupActivityTest.java +++ b/briar-android/test/java/briarproject/activity/SetupActivityTest.java @@ -144,13 +144,13 @@ public class SetupActivityTest { } @Test - public void testNickUI() { + public void testNicknameUI() { Assert.assertNotNull(setupActivity); String longNick = Strings.padEnd("*", AuthorConstants.MAX_AUTHOR_NAME_LENGTH + 1, '*'); nicknameEntry.setText(longNick); - // Password should be too long + // Nickname should be too long assertEquals(nicknameEntryWrapper.getError(), setupActivity.getString(R.string.name_too_long)); } From f81c8fcbd0c5b2a573e1b2ce220e6b6ce57eff75 Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson Date: Wed, 11 May 2016 12:22:53 +0200 Subject: [PATCH 19/19] rebased with master --- .../android/ActivityComponent.java | 22 +++++++---- .../briarproject/android/ActivityModule.java | 38 ++++++++++++++----- .../android/AndroidComponent.java | 6 --- .../forum/ContactSelectorFragment.java | 20 ++++------ .../android/forum/ShareForumActivity.java | 9 +++-- .../forum/ShareForumMessageFragment.java | 23 ++++------- 6 files changed, 63 insertions(+), 55 deletions(-) diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java index fcfd11761..529bbf7ba 100644 --- a/briar-android/src/org/briarproject/android/ActivityComponent.java +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -2,24 +2,21 @@ package org.briarproject.android; import android.app.Activity; -import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; import org.briarproject.android.forum.AvailableForumsActivity; +import org.briarproject.android.forum.ContactSelectorFragment; import org.briarproject.android.forum.CreateForumActivity; import org.briarproject.android.forum.ForumActivity; -import org.briarproject.android.forum.ForumListFragment; import org.briarproject.android.forum.ReadForumPostActivity; import org.briarproject.android.forum.ShareForumActivity; +import org.briarproject.android.forum.ShareForumMessageFragment; import org.briarproject.android.forum.WriteForumPostActivity; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.identity.CreateIdentityActivity; -import org.briarproject.android.introduction.ContactChooserFragment; import org.briarproject.android.introduction.IntroductionActivity; import org.briarproject.android.introduction.IntroductionMessageFragment; import org.briarproject.android.invitation.AddContactActivity; -import org.briarproject.android.keyagreement.ChooseIdentityFragment; import org.briarproject.android.keyagreement.KeyAgreementActivity; -import org.briarproject.android.keyagreement.ShowQrCodeFragment; import org.briarproject.android.panic.PanicPreferencesActivity; import org.briarproject.android.panic.PanicResponderActivity; @@ -67,19 +64,22 @@ public interface ActivityComponent { void inject(SettingsActivity activity); + /* void inject(ContactListFragment fragment); void inject(ForumListFragment fragment); - void inject(ChooseIdentityFragment fragment); - void inject(ShowQrCodeFragment fragment); + */ void inject(IntroductionActivity activity); + /* void inject(ContactChooserFragment fragment); - void inject(IntroductionMessageFragment fragment); + void inject(introductionmessagefragment fragment); + + */ @Named("ContactListFragment") BaseFragment newContactListFragment(); @@ -96,6 +96,12 @@ public interface ActivityComponent { @Named("ContactChooserFragment") BaseFragment newContactChooserFragment(); + @Named("ContactSelectorFragment") + ContactSelectorFragment newContactSelectorFragment(); + + @Named("ShareForumMessageFragment") + ShareForumMessageFragment newShareForumMessageFragment(); + @Named("IntroductionMessageFragment") IntroductionMessageFragment newIntroductionMessageFragment(); } diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 0b8b20298..1ed65e9be 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -8,17 +8,19 @@ import android.os.Bundle; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.controller.BriarController; import org.briarproject.android.controller.BriarControllerImpl; -import org.briarproject.android.controller.NavDrawerController; -import org.briarproject.android.controller.NavDrawerControllerImpl; -import org.briarproject.android.controller.PasswordControllerImpl; -import org.briarproject.android.controller.SetupControllerImpl; -import org.briarproject.android.controller.TransportStateListener; -import org.briarproject.android.forum.ForumListFragment; -import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.android.controller.PasswordController; -import org.briarproject.android.controller.SetupController; import org.briarproject.android.controller.ConfigController; import org.briarproject.android.controller.ConfigControllerImpl; +import org.briarproject.android.controller.NavDrawerController; +import org.briarproject.android.controller.NavDrawerControllerImpl; +import org.briarproject.android.controller.PasswordController; +import org.briarproject.android.controller.PasswordControllerImpl; +import org.briarproject.android.controller.SetupController; +import org.briarproject.android.controller.SetupControllerImpl; +import org.briarproject.android.controller.TransportStateListener; +import org.briarproject.android.forum.ContactSelectorFragment; +import org.briarproject.android.forum.ForumListFragment; +import org.briarproject.android.forum.ShareForumMessageFragment; +import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.introduction.ContactChooserFragment; import org.briarproject.android.introduction.IntroductionMessageFragment; import org.briarproject.android.keyagreement.ChooseIdentityFragment; @@ -29,7 +31,7 @@ import javax.inject.Named; import dagger.Module; import dagger.Provides; -import static org.briarproject.android.BriarService.*; +import static org.briarproject.android.BriarService.BriarServiceConnection; @Module public class ActivityModule { @@ -145,6 +147,22 @@ public class ActivityModule { return fragment; } + @Provides + @Named("ContactSelectorFragment") + ContactSelectorFragment provideContactSelectorFragment() { + ContactSelectorFragment fragment = new ContactSelectorFragment(); + fragment.setArguments(new Bundle()); + return fragment; + } + + @Provides + @Named("ShareForumMessageFragment") + ShareForumMessageFragment provideShareForumMessageFragment() { + ShareForumMessageFragment fragment = new ShareForumMessageFragment(); + fragment.setArguments(new Bundle()); + return fragment; + } + @Provides @Named("IntroductionMessageFragment") IntroductionMessageFragment provideIntroductionMessageFragment() { diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 57e584e3c..ba2578add 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -108,15 +108,9 @@ public interface AndroidComponent extends CoreEagerSingletons { AndroidExecutor androidExecutor(); - void inject(BriarService activity); - @IoExecutor Executor ioExecutor(); - void inject(ContactChooserFragment fragment); - - void inject(IntroductionMessageFragment fragment); - void inject(DevReportActivity devReportActivity); void inject(BriarService activity); diff --git a/briar-android/src/org/briarproject/android/forum/ContactSelectorFragment.java b/briar-android/src/org/briarproject/android/forum/ContactSelectorFragment.java index 73de55ec1..cd5ff9bcf 100644 --- a/briar-android/src/org/briarproject/android/forum/ContactSelectorFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ContactSelectorFragment.java @@ -13,7 +13,6 @@ import android.view.View; import android.view.ViewGroup; import org.briarproject.R; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.contact.BaseContactListAdapter; import org.briarproject.android.contact.ContactListItem; import org.briarproject.android.fragment.BaseFragment; @@ -63,13 +62,15 @@ public class ContactSelectorFragment extends BaseFragment implements @Inject protected volatile ForumSharingManager forumSharingManager; - public static ContactSelectorFragment newInstance(GroupId groupId) { - Bundle args = new Bundle(); - args.putByteArray(GROUP_ID, groupId.getBytes()); + public void initBundle(GroupId groupId) { + Bundle bundle = new Bundle(); + bundle.putByteArray(GROUP_ID, groupId.getBytes()); + setArguments(bundle); + } + + @Inject + public ContactSelectorFragment() { - ContactSelectorFragment fragment = new ContactSelectorFragment(); - fragment.setArguments(args); - return fragment; } @Override @@ -83,11 +84,6 @@ public class ContactSelectorFragment extends BaseFragment implements } } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java b/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java index 75a0bc676..81bcdf8cd 100644 --- a/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ShareForumActivity.java @@ -6,7 +6,6 @@ import android.view.View; import org.briarproject.R; import org.briarproject.android.ActivityComponent; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.api.contact.ContactId; @@ -34,7 +33,8 @@ public class ShareForumActivity extends BriarActivity implements if (savedInstanceState == null) { ContactSelectorFragment contactSelectorFragment = - ContactSelectorFragment.newInstance(groupId); + activityComponent.newContactSelectorFragment(); + contactSelectorFragment.initBundle(groupId); getSupportFragmentManager().beginTransaction() .add(R.id.shareForumContainer, contactSelectorFragment) .commit(); @@ -42,7 +42,7 @@ public class ShareForumActivity extends BriarActivity implements } @Override - public void injectActivity(AndroidComponent component) { + public void injectActivity(ActivityComponent component) { component.inject(this); } @@ -50,7 +50,8 @@ public class ShareForumActivity extends BriarActivity implements Collection contacts) { ShareForumMessageFragment messageFragment = - ShareForumMessageFragment.newInstance(groupId, contacts); + activityComponent.newShareForumMessageFragment(); + messageFragment.initBundle(groupId, contacts); getSupportFragmentManager().beginTransaction() .setCustomAnimations(android.R.anim.fade_in, diff --git a/briar-android/src/org/briarproject/android/forum/ShareForumMessageFragment.java b/briar-android/src/org/briarproject/android/forum/ShareForumMessageFragment.java index 7ed79d67c..ab2586666 100644 --- a/briar-android/src/org/briarproject/android/forum/ShareForumMessageFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ShareForumMessageFragment.java @@ -13,7 +13,6 @@ import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.api.contact.ContactId; import org.briarproject.api.db.DbException; @@ -45,17 +44,16 @@ public class ShareForumMessageFragment extends BaseFragment { private volatile GroupId groupId; private volatile Collection contacts; - public static ShareForumMessageFragment newInstance(GroupId groupId, - Collection contacts) { + public void initBundle(GroupId groupId, Collection contacts) { + Bundle bundle = new Bundle(); + bundle.putByteArray(GROUP_ID, groupId.getBytes()); + bundle.putIntegerArrayList(CONTACTS, getContactsFromIds(contacts)); + setArguments(bundle); + } - ShareForumMessageFragment f = new ShareForumMessageFragment(); + @Inject + public ShareForumMessageFragment() { - Bundle args = new Bundle(); - args.putByteArray(GROUP_ID, groupId.getBytes()); - args.putIntegerArrayList(CONTACTS, getContactsFromIds(contacts)); - f.setArguments(args); - - return f; } @Override @@ -69,11 +67,6 @@ public class ShareForumMessageFragment extends BaseFragment { } } - @Override - public void injectActivity(AndroidComponent component) { - component.inject(this); - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {