From e809aaa93252f5192b23f047ede5bde4d53acdd6 Mon Sep 17 00:00:00 2001
From: Ernir Erlingsson <ernir@ymirmobile.com>
Date: Tue, 26 Apr 2016 10:59:58 +0200
Subject: [PATCH] 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          | 22 +++++--------
 .../invitation/AddContactActivity.java        |  3 +-
 .../introduction/IntroductionModule.java      |  4 +--
 27 files changed, 186 insertions(+), 160 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 ca2e8b3340..37fd1f17cd 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 33e291abc3..33accc9702 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 c5396da798..623aba6e55 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 7e1b7165a7..6ae3eb8c20 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 9bd1e27dbf..fca3fd12d5 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<Void, RuntimeException>() {
+		briarController.signOut(new UiResultHandler<Void>(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 8545044851..49fb824c2f 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<Void, DbException>() {
+				new UiResultExceptionHandler<Void, DbException>(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 9f004527a6..346b2f2cd9 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<Boolean, EncryptedKeyNullException>() {
+		passwordController.validatePassword(password.getText().toString(),
+				new UiResultHandler<Boolean>(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 1aaba344c0..f54d1e861a 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<Long, RuntimeException>() {
+				new UiResultHandler<Long>(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 edb035cb32..342e19359b 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<Void, RuntimeException> eventHandler);
+	void signOut(ResultHandler<Void> eventHandler);
 }
diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImp.java
index 789b27af46..59ed95d3b0 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<Void, RuntimeException> eventHandler) {
+	public void signOut(final ResultHandler<Void> 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 3da38efa49..0000000000
--- 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 13dfbcc29d..2669cc4551 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<Void, DbException> resultHandler);
+			ResultExceptionHandler<Void, DbException> 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 f6b76c543c..0a5d2c8655 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<Void, DbException> resultHandler) {
+			final ResultExceptionHandler<Void, DbException> 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 b40ddb6703..bf1c9b230e 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<Boolean, EncryptedKeyNullException> resultHandler);
+			ResultHandler<Boolean> resultHandler);
 }
diff --git a/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java b/briar-android/src/org/briarproject/android/controller/PasswordControllerImp.java
index ed86bb9bd1..8a85fc51be 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<Boolean, EncryptedKeyNullException> resultHandler) {
+			final ResultHandler<Boolean> 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<Boolean, EncryptedKeyNullException> 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 5f98763aae..0000000000
--- a/briar-android/src/org/briarproject/android/controller/ResultHandler.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.briarproject.android.controller;
-
-public interface ResultHandler<R, E> {
-	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 884706c3f9..476db0f5e8 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<Long, RuntimeException> resultHandler);
+			ResultHandler<Long> resultHandler);
 }
diff --git a/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java b/briar-android/src/org/briarproject/android/controller/SetupControllerImp.java
index 312502f422..61a933e677 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<Long, RuntimeException> resultHandler) {
+			final ResultHandler<Long> 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<Long, RuntimeException> 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 0000000000..5d3cb03010
--- /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<R, E extends Exception> {
+	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 0000000000..55516f9422
--- /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<R> {
+	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 0000000000..7d9c08f4fb
--- /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<R, E extends Exception>
+		implements ResultExceptionHandler<R, E> {
+
+	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 0000000000..1998060a5c
--- /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<R> implements ResultHandler<R> {
+
+	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 11e30d6356..7b1bcbb5cb 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 2faee1a8ab..79d511291f 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 ed0547da4e..ed9c7b3c77 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);
+		this.setArguments(args);
+	}
+
+	@Inject
+	public IntroductionMessageFragment() {
 
-		return f;
 	}
 
+
 	@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 332efc6555..acd8d36a14 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 9e51aca734..4ea0ac6c3b 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,
-- 
GitLab