diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/NewUiResultHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/NewUiResultHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..46d85295c0660a7c3135364c4579e7df5e477b83 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/NewUiResultHandler.java @@ -0,0 +1,60 @@ +package org.briarproject.briar.android.controller.handler; + +import android.os.Binder; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.support.annotation.UiThread; + +public abstract class NewUiResultHandler<R> implements ResultHandler<R> { + + private static final int MESSAGE_POST_RESULT = 1; + private static UiThreadHandler uiHandler; + + // Ui thread handler singleton, used for all result handlers + private static Handler getHandler() { + synchronized (NewUiResultHandler.class) { + if (uiHandler == null) { + uiHandler = new UiThreadHandler(); + } + return uiHandler; + } + } + + private static class UiThreadHandler extends Handler { + + UiThreadHandler() { + super(Looper.getMainLooper()); + } + + @SuppressWarnings("unchecked") + @Override + public void handleMessage(Message msg) { + if (msg.what == MESSAGE_POST_RESULT) { + ResultHandlerResult<?> mhr = (ResultHandlerResult<?>) msg.obj; + mhr.resultHandler.onResultUi(mhr.result); + } + } + } + + private static class ResultHandlerResult<R> { + final NewUiResultHandler resultHandler; + final R result; + + ResultHandlerResult(NewUiResultHandler resultHandler, R result) { + this.resultHandler = resultHandler; + this.result = result; + } + } + + @Override + public void onResult(R result) { + Binder.flushPendingCommands(); + Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, + new ResultHandlerResult<>(this, result)); + message.sendToTarget(); + } + + @UiThread + public abstract void onResultUi(R result); +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java index 3606f077f1428d0199c7f434417d4b65a7d31f32..3f7e933c78c326f877117432390af45bf2256164 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java @@ -3,7 +3,6 @@ package org.briarproject.briar.android.login; 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; @@ -19,7 +18,7 @@ import android.widget.TextView.OnEditorActionListener; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BaseActivity; -import org.briarproject.briar.android.controller.handler.UiResultHandler; +import org.briarproject.briar.android.controller.handler.NewUiResultHandler; import org.briarproject.briar.android.util.UiUtils; import javax.inject.Inject; @@ -39,6 +38,8 @@ public class PasswordActivity extends BaseActivity { private TextInputLayout input; private EditText password; + private PasswordResult passwordResult; + @Override public void onCreate(Bundle state) { super.onCreate(state); @@ -78,6 +79,16 @@ public class PasswordActivity extends BaseActivity { public void afterTextChanged(Editable s) { } }); + + this.passwordResult = + (PasswordResult) getLastCustomNonConfigurationInstance(); + if (passwordResult != null) + passwordResult.setActivity(this); + } + + @Override + public Object onRetainCustomNonConfigurationInstance() { + return passwordResult; } @Override @@ -123,24 +134,21 @@ public class PasswordActivity extends BaseActivity { } private void validatePassword() { + initProgressUiState(); + + passwordResult = new PasswordResult(this); + passwordController.validatePassword(password.getText().toString(), + passwordResult); + } + + public void initProgressUiState() { hideSoftKeyboard(password); signInButton.setVisibility(INVISIBLE); progress.setVisibility(VISIBLE); - passwordController.validatePassword(password.getText().toString(), - new UiResultHandler<Boolean>(this) { - @Override - public void onResultUi(@NonNull Boolean result) { - if (result) { - setResult(RESULT_OK); - finish(); - } else { - tryAgain(); - } - } - }); } private void tryAgain() { + passwordResult = null; UiUtils.setError(input, getString(R.string.try_again), true); signInButton.setVisibility(VISIBLE); progress.setVisibility(INVISIBLE); @@ -149,4 +157,29 @@ public class PasswordActivity extends BaseActivity { // show the keyboard again showSoftKeyboard(password); } + + private static class PasswordResult extends + NewUiResultHandler<Boolean> { + + private PasswordActivity activity; + + PasswordResult(PasswordActivity activity) { + setActivity(activity); + } + + void setActivity(PasswordActivity activity) { + this.activity = activity; + activity.initProgressUiState(); + } + + @Override + public void onResultUi(Boolean result) { + if (result) { + activity.setResult(RESULT_OK); + activity.finish(); + } else { + activity.tryAgain(); + } + } + } }