mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Compare commits
1 Commits
misc-code-
...
725-result
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71d8947265 |
@@ -2,12 +2,16 @@ package org.briarproject.android;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.CallSuper;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
import org.briarproject.android.controller.ActivityLifecycleController;
|
import org.briarproject.android.controller.ActivityLifecycleController;
|
||||||
|
import org.briarproject.android.controller.handler.ContextResultHandler;
|
||||||
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
import org.briarproject.android.forum.ForumModule;
|
import org.briarproject.android.forum.ForumModule;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -18,12 +22,14 @@ import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
|
|||||||
import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS;
|
import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS;
|
||||||
|
|
||||||
public abstract class BaseActivity extends AppCompatActivity
|
public abstract class BaseActivity extends AppCompatActivity
|
||||||
implements DestroyableContext {
|
implements DestroyableContext, DestroyableContextManager {
|
||||||
|
|
||||||
protected ActivityComponent activityComponent;
|
protected ActivityComponent activityComponent;
|
||||||
|
|
||||||
private final List<ActivityLifecycleController> lifecycleControllers =
|
private final List<ActivityLifecycleController> lifecycleControllers =
|
||||||
new ArrayList<>();
|
new ArrayList<>();
|
||||||
|
private List<ContextResultHandler> contextResultHandlers =
|
||||||
|
new ArrayList<>();
|
||||||
private boolean destroyed = false;
|
private boolean destroyed = false;
|
||||||
|
|
||||||
public abstract void injectActivity(ActivityComponent component);
|
public abstract void injectActivity(ActivityComponent component);
|
||||||
@@ -32,6 +38,7 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
lifecycleControllers.add(alc);
|
lifecycleControllers.add(alc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -52,6 +59,39 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
for (ActivityLifecycleController alc : lifecycleControllers) {
|
for (ActivityLifecycleController alc : lifecycleControllers) {
|
||||||
alc.onActivityCreate(this);
|
alc.onActivityCreate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getLastCustomNonConfigurationInstance() != null) {
|
||||||
|
contextResultHandlers =
|
||||||
|
(List<ContextResultHandler>) getLastCustomNonConfigurationInstance();
|
||||||
|
for (ContextResultHandler crh : contextResultHandlers)
|
||||||
|
crh.setDestroyableContextManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
public void addContextResultHandler(ContextResultHandler crh) {
|
||||||
|
contextResultHandlers.add(crh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
public void removeContextResultHandler(String tag) {
|
||||||
|
List<ContextResultHandler> handlersToRemove = new ArrayList<>();
|
||||||
|
for (ContextResultHandler crh : contextResultHandlers) {
|
||||||
|
if (crh.getTag().equals(tag))
|
||||||
|
contextResultHandlers.remove(crh);
|
||||||
|
handlersToRemove.add(crh);
|
||||||
|
}
|
||||||
|
contextResultHandlers.removeAll(handlersToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
public boolean containsContextResultHandler(String tag) {
|
||||||
|
for (ContextResultHandler crh : contextResultHandlers) {
|
||||||
|
if (crh.getTag().equals(tag)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActivityComponent getActivityComponent() {
|
public ActivityComponent getActivityComponent() {
|
||||||
@@ -67,6 +107,12 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
return new ForumModule();
|
return new ForumModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
@Override
|
||||||
|
public Object onRetainCustomNonConfigurationInstance() {
|
||||||
|
return contextResultHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
@@ -87,6 +133,9 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
destroyed = true;
|
destroyed = true;
|
||||||
|
for (ContextResultHandler crh : contextResultHandlers) {
|
||||||
|
crh.setDestroyableContextManager(null);
|
||||||
|
}
|
||||||
for (ActivityLifecycleController alc : lifecycleControllers) {
|
for (ActivityLifecycleController alc : lifecycleControllers) {
|
||||||
alc.onActivityDestroy();
|
alc.onActivityDestroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package org.briarproject.android;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.briarproject.android.controller.BriarController;
|
import org.briarproject.android.controller.BriarController;
|
||||||
import org.briarproject.android.controller.DbController;
|
import org.briarproject.android.controller.DbController;
|
||||||
import org.briarproject.android.controller.handler.UiResultHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextResultHandler;
|
||||||
import org.briarproject.android.panic.ExitActivity;
|
import org.briarproject.android.panic.ExitActivity;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -28,6 +30,8 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
|
|
||||||
public static final int REQUEST_PASSWORD = 1;
|
public static final int REQUEST_PASSWORD = 1;
|
||||||
|
|
||||||
|
protected static final String TAG_SIGN_OUT = "briar.SIGN_OUT";
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BriarActivity.class.getName());
|
Logger.getLogger(BriarActivity.class.getName());
|
||||||
|
|
||||||
@@ -58,13 +62,18 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void signOut(final boolean removeFromRecentApps) {
|
protected void signOut(final boolean removeFromRecentApps) {
|
||||||
briarController.signOut(new UiResultHandler<Void>(this) {
|
briarController
|
||||||
@Override
|
.signOut(new UiContextResultHandler<Void>(this, TAG_SIGN_OUT) {
|
||||||
public void onResultUi(Void result) {
|
@Override
|
||||||
if (removeFromRecentApps) startExitActivity();
|
public void onResultUi(@NonNull Void result,
|
||||||
else finishAndExit();
|
@NonNull DestroyableContextManager context) {
|
||||||
}
|
if (removeFromRecentApps) {
|
||||||
});
|
((BriarActivity) context).startExitActivity();
|
||||||
|
} else {
|
||||||
|
((BriarActivity)context).finishAndExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void signOut() {
|
protected void signOut() {
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ import android.widget.Toast;
|
|||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.controller.PasswordController;
|
import org.briarproject.android.controller.PasswordController;
|
||||||
import org.briarproject.android.controller.SetupController;
|
import org.briarproject.android.controller.SetupController;
|
||||||
import org.briarproject.android.controller.handler.UiResultHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextResultHandler;
|
||||||
import org.briarproject.android.util.AndroidUtils;
|
import org.briarproject.android.util.AndroidUtils;
|
||||||
import org.briarproject.android.util.StrengthMeter;
|
import org.briarproject.android.util.StrengthMeter;
|
||||||
|
|
||||||
@@ -32,6 +33,8 @@ public class ChangePasswordActivity extends BaseActivity
|
|||||||
implements OnClickListener,
|
implements OnClickListener,
|
||||||
OnEditorActionListener {
|
OnEditorActionListener {
|
||||||
|
|
||||||
|
private static final String TAG_PASSWORD_CHANGE = "briar.PASSWORD_CHANGE";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected PasswordController passwordController;
|
protected PasswordController passwordController;
|
||||||
@Inject
|
@Inject
|
||||||
@@ -91,6 +94,11 @@ public class ChangePasswordActivity extends BaseActivity
|
|||||||
newPasswordConfirmation.addTextChangedListener(tw);
|
newPasswordConfirmation.addTextChangedListener(tw);
|
||||||
newPasswordConfirmation.setOnEditorActionListener(this);
|
newPasswordConfirmation.setOnEditorActionListener(this);
|
||||||
changePasswordButton.setOnClickListener(this);
|
changePasswordButton.setOnClickListener(this);
|
||||||
|
|
||||||
|
if (containsContextResultHandler(TAG_PASSWORD_CHANGE)) {
|
||||||
|
changePasswordButton.setVisibility(INVISIBLE);
|
||||||
|
progress.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,22 +139,27 @@ public class ChangePasswordActivity extends BaseActivity
|
|||||||
// Replace the button with a progress bar
|
// Replace the button with a progress bar
|
||||||
changePasswordButton.setVisibility(INVISIBLE);
|
changePasswordButton.setVisibility(INVISIBLE);
|
||||||
progress.setVisibility(VISIBLE);
|
progress.setVisibility(VISIBLE);
|
||||||
|
|
||||||
passwordController.changePassword(currentPassword.getText().toString(),
|
passwordController.changePassword(currentPassword.getText().toString(),
|
||||||
newPassword.getText().toString(),
|
newPassword.getText().toString(),
|
||||||
new UiResultHandler<Boolean>(this) {
|
new UiContextResultHandler<Boolean>(this, TAG_PASSWORD_CHANGE) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(@NonNull Boolean result) {
|
public void onResultUi(@NonNull Boolean result,
|
||||||
|
@NonNull DestroyableContextManager context) {
|
||||||
|
ChangePasswordActivity cpa =
|
||||||
|
(ChangePasswordActivity) getContextManager();
|
||||||
if (result) {
|
if (result) {
|
||||||
Toast.makeText(ChangePasswordActivity.this,
|
Toast.makeText(cpa, R.string.password_changed,
|
||||||
R.string.password_changed,
|
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.LENGTH_LONG).show();
|
||||||
setResult(RESULT_OK);
|
cpa.setResult(RESULT_OK);
|
||||||
finish();
|
cpa.finish();
|
||||||
} else {
|
} else {
|
||||||
tryAgain();
|
cpa.tryAgain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryAgain() {
|
private void tryAgain() {
|
||||||
|
|||||||
@@ -129,6 +129,12 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
|
|||||||
if (getIntent() != null) {
|
if (getIntent() != null) {
|
||||||
onNewIntent(getIntent());
|
onNewIntent(getIntent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (containsContextResultHandler(TAG_SIGN_OUT)) {
|
||||||
|
// User is signing out of Briar and rotated the device before the
|
||||||
|
// operation could finish, restore the UI state
|
||||||
|
showLoadingScreen(true, R.string.progress_title_logout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void welcomeMessageCheck() {
|
private void welcomeMessageCheck() {
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ import android.widget.TextView.OnEditorActionListener;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.controller.PasswordController;
|
import org.briarproject.android.controller.PasswordController;
|
||||||
import org.briarproject.android.controller.handler.UiResultHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextResultHandler;
|
||||||
import org.briarproject.android.util.AndroidUtils;
|
import org.briarproject.android.util.AndroidUtils;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_MAIN;
|
import static android.content.Intent.ACTION_MAIN;
|
||||||
@@ -30,6 +33,11 @@ import static android.view.View.VISIBLE;
|
|||||||
|
|
||||||
public class PasswordActivity extends BaseActivity {
|
public class PasswordActivity extends BaseActivity {
|
||||||
|
|
||||||
|
private static final String TAG_PASSWORD = "briar.PASSWORD";
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(NavDrawerActivity.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected PasswordController passwordController;
|
protected PasswordController passwordController;
|
||||||
|
|
||||||
@@ -77,6 +85,12 @@ public class PasswordActivity extends BaseActivity {
|
|||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (containsContextResultHandler(TAG_PASSWORD)) {
|
||||||
|
signInButton.setVisibility(INVISIBLE);
|
||||||
|
progress.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.info("not tryAgain() " + this.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -125,21 +139,28 @@ public class PasswordActivity extends BaseActivity {
|
|||||||
hideSoftKeyboard(password);
|
hideSoftKeyboard(password);
|
||||||
signInButton.setVisibility(INVISIBLE);
|
signInButton.setVisibility(INVISIBLE);
|
||||||
progress.setVisibility(VISIBLE);
|
progress.setVisibility(VISIBLE);
|
||||||
passwordController.validatePassword(password.getText().toString(),
|
|
||||||
new UiResultHandler<Boolean>(this) {
|
UiContextResultHandler<Boolean> crh =
|
||||||
|
new UiContextResultHandler<Boolean>(this, TAG_PASSWORD) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(@NonNull Boolean result) {
|
public void onResultUi(@NonNull Boolean result,
|
||||||
|
@NonNull DestroyableContextManager context) {
|
||||||
|
PasswordActivity pa =
|
||||||
|
((PasswordActivity) getContextManager());
|
||||||
if (result) {
|
if (result) {
|
||||||
setResult(RESULT_OK);
|
pa.setResult(RESULT_OK);
|
||||||
finish();
|
pa.finish();
|
||||||
} else {
|
} else {
|
||||||
tryAgain();
|
pa.tryAgain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
};
|
||||||
|
passwordController.validatePassword(password.getText().toString(), crh);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryAgain() {
|
private void tryAgain() {
|
||||||
|
LOG.info("tryAgain() " + this.hashCode());
|
||||||
AndroidUtils.setError(input, getString(R.string.try_again), true);
|
AndroidUtils.setError(input, getString(R.string.try_again), true);
|
||||||
signInButton.setVisibility(VISIBLE);
|
signInButton.setVisibility(VISIBLE);
|
||||||
progress.setVisibility(INVISIBLE);
|
progress.setVisibility(INVISIBLE);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.android;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.design.widget.TextInputLayout;
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
@@ -16,7 +17,8 @@ import android.widget.TextView.OnEditorActionListener;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.controller.SetupController;
|
import org.briarproject.android.controller.SetupController;
|
||||||
import org.briarproject.android.controller.handler.UiResultHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextResultHandler;
|
||||||
import org.briarproject.android.util.AndroidUtils;
|
import org.briarproject.android.util.AndroidUtils;
|
||||||
import org.briarproject.android.util.StrengthMeter;
|
import org.briarproject.android.util.StrengthMeter;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
@@ -33,6 +35,8 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENG
|
|||||||
public class SetupActivity extends BaseActivity implements OnClickListener,
|
public class SetupActivity extends BaseActivity implements OnClickListener,
|
||||||
OnEditorActionListener {
|
OnEditorActionListener {
|
||||||
|
|
||||||
|
protected static final String TAG_SETUP = "briar.SETUP";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected SetupController setupController;
|
protected SetupController setupController;
|
||||||
|
|
||||||
@@ -87,6 +91,14 @@ public class SetupActivity extends BaseActivity implements OnClickListener,
|
|||||||
passwordConfirmation.addTextChangedListener(tw);
|
passwordConfirmation.addTextChangedListener(tw);
|
||||||
passwordConfirmation.setOnEditorActionListener(this);
|
passwordConfirmation.setOnEditorActionListener(this);
|
||||||
createAccountButton.setOnClickListener(this);
|
createAccountButton.setOnClickListener(this);
|
||||||
|
|
||||||
|
if (containsContextResultHandler(TAG_SETUP)) {
|
||||||
|
// Activity has been re-created due to an orientation change,
|
||||||
|
// update the result handler with the current context and restore
|
||||||
|
// the UI state
|
||||||
|
createAccountButton.setVisibility(INVISIBLE);
|
||||||
|
progress.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -135,13 +147,16 @@ public class SetupActivity extends BaseActivity implements OnClickListener,
|
|||||||
String nickname = nicknameEntry.getText().toString();
|
String nickname = nicknameEntry.getText().toString();
|
||||||
String password = passwordEntry.getText().toString();
|
String password = passwordEntry.getText().toString();
|
||||||
|
|
||||||
setupController.storeAuthorInfo(nickname, password,
|
setupController
|
||||||
new UiResultHandler<Void>(this) {
|
.storeAuthorInfo(nickname, password,
|
||||||
@Override
|
new UiContextResultHandler<Void>(this, TAG_SETUP) {
|
||||||
public void onResultUi(Void result) {
|
@Override
|
||||||
showMain();
|
public void onResultUi(@NonNull Void result,
|
||||||
}
|
@NonNull DestroyableContextManager context) {
|
||||||
});
|
((SetupActivity)context).showMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showMain() {
|
private void showMain() {
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public class BriarControllerImpl implements BriarController {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
// Wait for the service to finish starting up
|
// Wait for the service to finish starting up
|
||||||
IBinder binder = serviceConnection.waitForBinder();
|
IBinder binder = serviceConnection.waitForBinder();
|
||||||
BriarService service =
|
BriarService service =
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.briarproject.android.controller.handler;
|
||||||
|
|
||||||
|
public interface ContextResultHandler<R> extends ResultHandler<R> {
|
||||||
|
void setDestroyableContextManager(DestroyableContextManager listener);
|
||||||
|
String getTag();
|
||||||
|
DestroyableContextManager getContextManager();
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.briarproject.android.controller.handler;
|
||||||
|
|
||||||
|
import org.briarproject.android.DestroyableContext;
|
||||||
|
|
||||||
|
public interface DestroyableContextManager extends DestroyableContext {
|
||||||
|
|
||||||
|
void addContextResultHandler(ContextResultHandler crh);
|
||||||
|
|
||||||
|
void removeContextResultHandler(String tag);
|
||||||
|
|
||||||
|
boolean containsContextResultHandler(String tag);
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package org.briarproject.android.controller.handler;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class defines a result handler with a callback that runs on the UI thread
|
||||||
|
* and is retained when orientation changes occur. It ensures that the callback
|
||||||
|
* is always run in the latest context.
|
||||||
|
* <p>
|
||||||
|
* Note that this event handler should be used carefully with callbacks that
|
||||||
|
* depend on global variables as those variables might be destroyed or lose their
|
||||||
|
* state during the orientation change.
|
||||||
|
*
|
||||||
|
* @param <R> The result's object type
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public abstract class UiContextExceptionResultHandler<R, E extends Exception>
|
||||||
|
extends UiContextResultHandler<R>
|
||||||
|
implements ResultExceptionHandler<R, E> {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private E exception;
|
||||||
|
|
||||||
|
protected UiContextExceptionResultHandler(
|
||||||
|
DestroyableContextManager listener, String tag) {
|
||||||
|
super(listener, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDestroyableContextManager(
|
||||||
|
DestroyableContextManager listener) {
|
||||||
|
boolean isSwitchingFromNullToNonNull =
|
||||||
|
this.listener == null && listener != null;
|
||||||
|
super.setDestroyableContextManager(listener);
|
||||||
|
if (isSwitchingFromNullToNonNull)
|
||||||
|
runException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onException(final E exception) {
|
||||||
|
this.exception = exception;
|
||||||
|
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
runException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
private void runException() {
|
||||||
|
if (exception != null && listener != null) {
|
||||||
|
onExceptionUi(exception, listener);
|
||||||
|
listener.removeContextResultHandler(getTag());
|
||||||
|
exception = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
public abstract void onExceptionUi(E exception,
|
||||||
|
DestroyableContextManager context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package org.briarproject.android.controller.handler;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class defines a result handler with a callback that runs on the UI thread
|
||||||
|
* and is retained when orientation changes occur. It ensures that the callback
|
||||||
|
* is always run in the latest context.
|
||||||
|
* <p>
|
||||||
|
* Note that this event handler should be used carefully with callbacks that
|
||||||
|
* depend on global variables as those variables might be destroyed or lose their
|
||||||
|
* state during the orientation change.
|
||||||
|
*
|
||||||
|
* @param <R> The result's object type
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public abstract class UiContextResultHandler<R>
|
||||||
|
implements ContextResultHandler<R> {
|
||||||
|
|
||||||
|
private final String tag;
|
||||||
|
protected DestroyableContextManager listener;
|
||||||
|
@Nullable
|
||||||
|
private R result;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
protected UiContextResultHandler(DestroyableContextManager listener,
|
||||||
|
String tag) {
|
||||||
|
this.listener = listener;
|
||||||
|
this.tag = tag;
|
||||||
|
listener.addContextResultHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@Override
|
||||||
|
public void setDestroyableContextManager(
|
||||||
|
DestroyableContextManager listener) {
|
||||||
|
// Check if the listener is switching from null to non null
|
||||||
|
boolean isSwitchingFromNullToNonNull =
|
||||||
|
this.listener == null && listener != null;
|
||||||
|
this.listener = listener;
|
||||||
|
if (isSwitchingFromNullToNonNull)
|
||||||
|
runResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DestroyableContextManager getContextManager() {
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(final R result) {
|
||||||
|
this.result = result;
|
||||||
|
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
runResult();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
private void runResult() {
|
||||||
|
if (result != null && listener != null) {
|
||||||
|
onResultUi(result, listener);
|
||||||
|
listener.removeContextResultHandler(tag);
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
public abstract void onResultUi(R result,
|
||||||
|
DestroyableContextManager context);
|
||||||
|
}
|
||||||
@@ -18,7 +18,8 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextExceptionResultHandler;
|
||||||
import org.briarproject.android.sharing.ForumSharingStatusActivity;
|
import org.briarproject.android.sharing.ForumSharingStatusActivity;
|
||||||
import org.briarproject.android.sharing.ShareForumActivity;
|
import org.briarproject.android.sharing.ShareForumActivity;
|
||||||
import org.briarproject.android.threaded.ThreadItemAdapter;
|
import org.briarproject.android.threaded.ThreadItemAdapter;
|
||||||
@@ -44,6 +45,7 @@ public class ForumActivity extends
|
|||||||
ThreadListActivity<Forum, ThreadItemAdapter<ForumItem>, ForumItem, ForumPostHeader> {
|
ThreadListActivity<Forum, ThreadItemAdapter<ForumItem>, ForumItem, ForumPostHeader> {
|
||||||
|
|
||||||
private static final int REQUEST_FORUM_SHARED = 3;
|
private static final int REQUEST_FORUM_SHARED = 3;
|
||||||
|
private static final String TAG_FORUM = "briar.FORUM";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ForumController forumController;
|
ForumController forumController;
|
||||||
@@ -168,19 +170,22 @@ public class ForumActivity extends
|
|||||||
|
|
||||||
private void deleteForum() {
|
private void deleteForum() {
|
||||||
forumController.deleteNamedGroup(
|
forumController.deleteNamedGroup(
|
||||||
new UiResultExceptionHandler<Void, DbException>(this) {
|
new UiContextExceptionResultHandler<Void, DbException>(this,
|
||||||
|
TAG_FORUM) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(Void v) {
|
public void onResultUi(Void result,
|
||||||
Toast.makeText(ForumActivity.this,
|
DestroyableContextManager context) {
|
||||||
|
Toast.makeText((ForumActivity)context,
|
||||||
R.string.forum_left_toast, LENGTH_SHORT).show();
|
R.string.forum_left_toast, LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception,
|
||||||
// TODO proper error handling
|
DestroyableContextManager context) {
|
||||||
finish();
|
((ForumActivity)context).finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ package org.briarproject.android.privategroup.creation;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.contactselection.ContactSelectorActivity;
|
import org.briarproject.android.contactselection.ContactSelectorActivity;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextExceptionResultHandler;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
@@ -21,6 +22,8 @@ import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_
|
|||||||
public abstract class BaseGroupInviteActivity
|
public abstract class BaseGroupInviteActivity
|
||||||
extends ContactSelectorActivity implements MessageFragmentListener {
|
extends ContactSelectorActivity implements MessageFragmentListener {
|
||||||
|
|
||||||
|
private static final String TAG_GROUP_INVITEE = "briar.GROUP_INVITEE";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateGroupController controller;
|
CreateGroupController controller;
|
||||||
|
|
||||||
@@ -43,19 +46,26 @@ public abstract class BaseGroupInviteActivity
|
|||||||
public boolean onButtonClick(@NotNull String message) {
|
public boolean onButtonClick(@NotNull String message) {
|
||||||
if (groupId == null)
|
if (groupId == null)
|
||||||
throw new IllegalStateException("GroupId was not initialized");
|
throw new IllegalStateException("GroupId was not initialized");
|
||||||
|
|
||||||
controller.sendInvitation(groupId, contacts, message,
|
controller.sendInvitation(groupId, contacts, message,
|
||||||
new UiResultExceptionHandler<Void, DbException>(this) {
|
new UiContextExceptionResultHandler<Void, DbException>(this,
|
||||||
|
TAG_GROUP_INVITEE) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(Void result) {
|
public void onExceptionUi(DbException exception,
|
||||||
setResult(RESULT_OK);
|
DestroyableContextManager context) {
|
||||||
supportFinishAfterTransition();
|
((BaseGroupInviteActivity) context)
|
||||||
|
.setResult(RESULT_CANCELED);
|
||||||
|
((BaseGroupInviteActivity) context)
|
||||||
|
.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onResultUi(Void result,
|
||||||
// TODO proper error handling
|
DestroyableContextManager context) {
|
||||||
setResult(RESULT_CANCELED);
|
((BaseGroupInviteActivity) context)
|
||||||
finish();
|
.setResult(RESULT_OK);
|
||||||
|
((BaseGroupInviteActivity) context)
|
||||||
|
.supportFinishAfterTransition();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import android.support.v4.app.ActivityOptionsCompat;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.DestroyableContextManager;
|
||||||
|
import org.briarproject.android.controller.handler.UiContextExceptionResultHandler;
|
||||||
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
@@ -18,6 +19,8 @@ import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
|||||||
public class CreateGroupActivity extends BaseGroupInviteActivity implements
|
public class CreateGroupActivity extends BaseGroupInviteActivity implements
|
||||||
CreateGroupListener, MessageFragmentListener {
|
CreateGroupListener, MessageFragmentListener {
|
||||||
|
|
||||||
|
private static final String TAG_CREATE_GROUP = "briar.CREATE_GROUP";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectActivity(ActivityComponent component) {
|
public void injectActivity(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -49,17 +52,20 @@ public class CreateGroupActivity extends BaseGroupInviteActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public void onGroupNameChosen(String name) {
|
public void onGroupNameChosen(String name) {
|
||||||
controller.createGroup(name,
|
controller.createGroup(name,
|
||||||
new UiResultExceptionHandler<GroupId, DbException>(this) {
|
new UiContextExceptionResultHandler<GroupId, DbException>(this,
|
||||||
|
TAG_CREATE_GROUP) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(GroupId g) {
|
public void onExceptionUi(DbException exception,
|
||||||
groupId = g;
|
DestroyableContextManager context) {
|
||||||
switchToContactSelectorFragment(g);
|
((CreateGroupActivity) context).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onResultUi(GroupId g,
|
||||||
// TODO proper error handling
|
DestroyableContextManager context) {
|
||||||
finish();
|
((CreateGroupActivity) context).groupId = g;
|
||||||
|
((CreateGroupActivity) context)
|
||||||
|
.switchToContactSelectorFragment(g);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user