From d78a6604fd66425752575464805bab0706bf444f Mon Sep 17 00:00:00 2001 From: ameba23 Date: Mon, 26 Apr 2021 12:29:45 +0200 Subject: [PATCH] UI for error and explainer fragments --- .../android/activity/ActivityComponent.java | 3 + .../recover/CustodianReturnShardActivity.java | 46 +++++++++++++--- .../CustodianReturnShardErrorFragment.java | 9 ++- .../CustodianReturnShardViewModel.java | 28 ++++++---- .../OwnerRecoveryModeErrorFragment.java | 55 ++++++++++++++++++- .../recover/OwnerReturnShardActivity.java | 14 +++-- .../OwnerReturnShardSuccessFragment.java | 2 +- .../recover/OwnerReturnShardViewModel.java | 10 ++++ ...ent_recovery_custodian_error_explainer.xml | 2 +- .../fragment_recovery_custodian_explainer.xml | 17 +++++- .../fragment_recovery_owner_explainer.xml | 18 +++++- briar-android/src/main/res/values/strings.xml | 5 +- 12 files changed, 170 insertions(+), 39 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java index d0b7234b9..089038184 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java @@ -88,6 +88,7 @@ import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardA import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardErrorFragment; import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardFragment; import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardSuccessFragment; +import org.briarproject.briar.android.socialbackup.recover.OwnerRecoveryModeErrorFragment; import org.briarproject.briar.android.socialbackup.recover.OwnerRecoveryModeExplainerFragment; import org.briarproject.briar.android.socialbackup.recover.OwnerRecoveryModeMainFragment; import org.briarproject.briar.android.socialbackup.recover.OwnerReturnShardActivity; @@ -302,5 +303,7 @@ public interface ActivityComponent { void inject(OwnerReturnShardSuccessFragment ownerReturnShardSuccessFragment); + void inject(OwnerRecoveryModeErrorFragment ownerRecoveryModeErrorFragment); + void inject(CustodianReturnShardErrorFragment custodianReturnShardErrorFragment); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardActivity.java index 33e82536d..976ed8581 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardActivity.java @@ -21,6 +21,7 @@ import javax.inject.Inject; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; +import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static java.util.logging.Logger.getLogger; import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID; @@ -30,6 +31,7 @@ public class CustodianReturnShardActivity extends BriarActivity private CustodianReturnShardViewModel viewModel; private static final Logger LOG = getLogger(CustodianReturnShardActivity.class.getName()); + private ContactId contactId; @Inject ViewModelProvider.Factory viewModelFactory; @@ -50,35 +52,61 @@ public class CustodianReturnShardActivity extends BriarActivity Intent intent = getIntent(); int id = intent.getIntExtra(CONTACT_ID, -1); if (id == -1) throw new IllegalStateException("No ContactId"); - ContactId contactId = new ContactId(id); + contactId = new ContactId(id); try { viewModel.start(contactId); - } catch (IOException e) { - // TODO improve this - Toast.makeText(this, - "It looks like you are not connected to a Wifi network", - Toast.LENGTH_SHORT).show(); - showNextFragment(new CustodianReturnShardErrorFragment()); - return; +// } catch (IOException e) { +// // TODO improve this +// Toast.makeText(this, +// "It looks like you are not connected to a Wifi network", +// Toast.LENGTH_SHORT).show(); +// showInitialFragment(new CustodianReturnShardErrorFragment()); } catch (DbException e) { Toast.makeText(this, "You do not hold a backup piece for this contact", Toast.LENGTH_SHORT).show(); finish(); } - showInitialFragment(new CustodianRecoveryModeExplainerFragment()); } + showInitialFragment(new CustodianRecoveryModeExplainerFragment()); + + viewModel.getContinueClicked().observeEvent(this, clicked -> { + if (clicked) beginTransfer(); + }); + viewModel.getShowCameraFragment().observeEvent(this, show -> { if (show) showCameraFragment(); }); viewModel.getSuccessDismissed().observeEvent(this, dismissed -> { if (dismissed) finish(); }); + viewModel.getErrorTryAgain().observeEvent(this, tryAgain -> { + if (tryAgain) beginTransfer(); + }); viewModel.getState() .observe(this, this::onReturnShardStateChanged); } + private void beginTransfer() { + try { + viewModel.beginTransfer(); + } catch (IOException e) { + Toast.makeText(this, + "It looks like you are not connected to a Wifi network", + Toast.LENGTH_SHORT).show(); + FragmentManager fm = getSupportFragmentManager(); + if (fm.findFragmentByTag(CustodianReturnShardFragment.TAG) == null) { + BaseFragment f = new CustodianReturnShardErrorFragment(); + fm.beginTransaction() + .replace(R.id.fragmentContainer, f, f.getUniqueTag()) + .addToBackStack(f.getUniqueTag()) + .commit(); + } + } + } + + private void onReturnShardStateChanged(CustodianTask.State state) { if (state instanceof CustodianTask.State.Success) { CustodianReturnShardSuccessFragment fragment = new CustodianReturnShardSuccessFragment(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardErrorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardErrorFragment.java index d0ae28640..5c2b78472 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardErrorFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardErrorFragment.java @@ -41,13 +41,12 @@ public class CustodianReturnShardErrorFragment extends BaseFragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - // TODO change fragment to error - View view = inflater.inflate(R.layout.fragment_recovery_custodian_done, + View view = inflater.inflate(R.layout.fragment_recovery_custodian_error_explainer, container, false); - Button button = view.findViewById(R.id.button); - button.setOnClickListener(e -> viewModel.onErrorCancelled()); - // TODO try again button + button.setOnClickListener(e -> viewModel.onErrorTryAgain()); + // TODO cancel button +// button.setOnClickListener(e -> viewModel.onErrorCancelled()); return view; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardViewModel.java index 9c31b68d3..d68915362 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/CustodianReturnShardViewModel.java @@ -51,9 +51,9 @@ public class CustodianReturnShardViewModel extends AndroidViewModel private final SocialBackupManager socialBackupManager; private final DatabaseComponent db; final QrCodeDecoder qrCodeDecoder; - private boolean wasContinueClicked = false; private boolean qrCodeRead = false; private WifiManager wifiManager; + private final MutableLiveEvent continueClicked = new MutableLiveEvent<>(); private final MutableLiveEvent showCameraFragment = new MutableLiveEvent<>(); private final MutableLiveEvent successDismissed = @@ -111,12 +111,8 @@ public class CustodianReturnShardViewModel extends AndroidViewModel } } - public void start(ContactId contactId) throws DbException, IOException { - InetAddress inetAddress = getWifiIpv4Address(); - LOG.info("Client InetAddress: " + inetAddress); - if (inetAddress == null) - throw new IOException("Cannot get IP on local wifi"); - + public void start(ContactId contactId) throws DbException { + // TODO this should be transactionWithResult db.transaction(false, txn -> { if (!socialBackupManager.amCustodian(txn, contactId)) { throw new DbException(); @@ -124,8 +120,6 @@ public class CustodianReturnShardViewModel extends AndroidViewModel returnShardPayloadBytes = socialBackupManager .getReturnShardPayloadBytes(txn, contactId); }); - task.cancel(); - task.start(this, returnShardPayloadBytes); } @IoExecutor @@ -150,11 +144,21 @@ public class CustodianReturnShardViewModel extends AndroidViewModel } } + public void beginTransfer() throws IOException { + InetAddress inetAddress = getWifiIpv4Address(); + LOG.info("Client InetAddress: " + inetAddress); + if (inetAddress == null) + throw new IOException("Cannot get IP on local wifi"); + + task.cancel(); + task.start(this, returnShardPayloadBytes); + //TODO camera permissions + showCameraFragment.setEvent(true); + } @UiThread public void onContinueClicked() { - wasContinueClicked = true; + continueClicked.setEvent(true); // checkPermissions.setEvent(true); - showCameraFragment.setEvent(true); } @UiThread @@ -201,4 +205,6 @@ public class CustodianReturnShardViewModel extends AndroidViewModel public MutableLiveEvent getErrorTryAgain() { return errorTryAgain; } + + public MutableLiveEvent getContinueClicked() { return continueClicked; } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerRecoveryModeErrorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerRecoveryModeErrorFragment.java index ee522c56a..7c4981266 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerRecoveryModeErrorFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerRecoveryModeErrorFragment.java @@ -1,4 +1,57 @@ package org.briarproject.briar.android.socialbackup.recover; -public class OwnerRecoveryModeErrorFragment { +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; + +import javax.inject.Inject; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class OwnerRecoveryModeErrorFragment extends BaseFragment { + public static final String TAG = + OwnerRecoveryModeErrorFragment.class.getName(); + + @Inject + ViewModelProvider.Factory viewModelFactory; + + private OwnerReturnShardViewModel viewModel; + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) + .get(OwnerReturnShardViewModel.class); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_recovery_custodian_error_explainer, + container, false); + Button button = view.findViewById(R.id.button); + button.setOnClickListener(e -> viewModel.onErrorTryAgain()); + // TODO cancel button +// button.setOnClickListener(e -> viewModel.onErrorCancelled()); + return view; + } + + @Override + public String getUniqueTag() { + return TAG; + } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java index 4ac3ad86a..ac88c52ac 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java @@ -80,6 +80,9 @@ public class OwnerReturnShardActivity extends BaseActivity viewModel.getSuccessDismissed().observeEvent(this, success -> { if (success) onSuccessDismissed(); }); + viewModel.getErrorTryAgain().observeEvent(this, tryAgain -> { + if (tryAgain) onBackPressed(); + }); viewModel.getState() .observe(this, this::onReturnShardStateChanged); } @@ -167,12 +170,11 @@ public class OwnerReturnShardActivity extends BaseActivity } onBackPressed(); } else if (state instanceof SecretOwnerTask.State.Failure) { - // TODO error screen, handle reason - Toast.makeText(this, - "Shard return failed!", - Toast.LENGTH_SHORT).show(); - onBackPressed(); -// showNextFragment(new OwnerRecoveryModeExplainerFragment()); +// Toast.makeText(this, +// "Shard return failed!", +// Toast.LENGTH_SHORT).show(); +// onBackPressed(); + showNextFragment(new OwnerRecoveryModeErrorFragment()); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardSuccessFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardSuccessFragment.java index 92c2ba378..d7707ec94 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardSuccessFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardSuccessFragment.java @@ -38,7 +38,7 @@ public class OwnerReturnShardSuccessFragment extends BaseFragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_recovery_custodian_done, + View view = inflater.inflate(R.layout.fragment_recovery_owner_success, container, false); Button button = view.findViewById(R.id.button); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java index 1ccb763b7..b476cc488 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java @@ -51,6 +51,8 @@ class OwnerReturnShardViewModel extends AndroidViewModel private final SecretOwnerTask task; private final RestoreAccount restoreAccount; + private final MutableLiveEvent errorTryAgain = + new MutableLiveEvent<>(); private final MutableLiveEvent showQrCodeFragment = new MutableLiveEvent<>(); private final MutableLiveEvent successDismissed = new MutableLiveEvent<>(); @@ -158,6 +160,10 @@ class OwnerReturnShardViewModel extends AndroidViewModel }); } + @UiThread + public void onErrorTryAgain() { + errorTryAgain.setEvent(true); + } /** * Set to true in onPostResume() and false in onPause(). This prevents the @@ -236,4 +242,8 @@ class OwnerReturnShardViewModel extends AndroidViewModel public MutableLiveEvent getSuccessDismissed() { return successDismissed; } + + public MutableLiveEvent getErrorTryAgain() { + return errorTryAgain; + } } diff --git a/briar-android/src/main/res/layout/fragment_recovery_custodian_error_explainer.xml b/briar-android/src/main/res/layout/fragment_recovery_custodian_error_explainer.xml index 4f43bd7a3..28a4fe417 100644 --- a/briar-android/src/main/res/layout/fragment_recovery_custodian_error_explainer.xml +++ b/briar-android/src/main/res/layout/fragment_recovery_custodian_error_explainer.xml @@ -31,7 +31,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView1" - app:srcCompat="@drawable/qr_code_error" /> + app:srcCompat="@drawable/qr_code_social_backup_error" /> + app:srcCompat="@drawable/qr_code_social_backup" /> + +