diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java index 8581da441..8e129e2fe 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java @@ -1,59 +1,25 @@ package org.briarproject.bramble.api.mailbox; -import javax.annotation.Nullable; - public abstract class MailboxPairingState { - /** - * The QR code payload that was scanned by the user. - * This is null if the code should not be re-used anymore in this state. - */ - @Nullable - public final String qrCodePayload; - - MailboxPairingState(@Nullable String qrCodePayload) { - this.qrCodePayload = qrCodePayload; - } - public static class QrCodeReceived extends MailboxPairingState { - public QrCodeReceived(String qrCodePayload) { - super(qrCodePayload); - } } public static class Pairing extends MailboxPairingState { - public Pairing(String qrCodePayload) { - super(qrCodePayload); - } } public static class Paired extends MailboxPairingState { - public Paired() { - super(null); - } } public static class InvalidQrCode extends MailboxPairingState { - public InvalidQrCode() { - super(null); - } } public static class MailboxAlreadyPaired extends MailboxPairingState { - public MailboxAlreadyPaired() { - super(null); - } } public static class ConnectionError extends MailboxPairingState { - public ConnectionError(String qrCodePayload) { - super(qrCodePayload); - } } public static class UnexpectedError extends MailboxPairingState { - public UnexpectedError(String qrCodePayload) { - super(qrCodePayload); - } } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java index 03f36d2f7..32ad7d727 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java @@ -71,7 +71,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { this.clock = clock; this.api = api; this.mailboxSettingsManager = mailboxSettingsManager; - state = new MailboxPairingState.QrCodeReceived(payload); + state = new MailboxPairingState.QrCodeReceived(); } @Override @@ -100,15 +100,15 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { } catch (MailboxAlreadyPairedException e) { onMailboxError(e, new MailboxPairingState.MailboxAlreadyPaired()); } catch (IOException e) { - onMailboxError(e, new MailboxPairingState.ConnectionError(payload)); + onMailboxError(e, new MailboxPairingState.ConnectionError()); } catch (ApiException | DbException e) { - onMailboxError(e, new MailboxPairingState.UnexpectedError(payload)); + onMailboxError(e, new MailboxPairingState.UnexpectedError()); } } private void pairMailbox() throws IOException, ApiException, DbException { MailboxProperties mailboxProperties = decodeQrCodePayload(payload); - setState(new MailboxPairingState.Pairing(payload)); + setState(new MailboxPairingState.Pairing()); MailboxAuthToken ownerToken = api.setup(mailboxProperties); MailboxProperties ownerProperties = new MailboxProperties( mailboxProperties.getBaseUrl(), ownerToken, true); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index ed72e1849..0fe7c4876 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -49,6 +49,7 @@ import org.briarproject.briar.android.mailbox.MailboxScanFragment; import org.briarproject.briar.android.mailbox.MailboxStatusFragment; import org.briarproject.briar.android.mailbox.OfflineFragment; import org.briarproject.briar.android.mailbox.SetupDownloadFragment; +import org.briarproject.briar.android.mailbox.SetupIntroFragment; import org.briarproject.briar.android.removabledrive.ChooserFragment; import org.briarproject.briar.android.removabledrive.ReceiveFragment; import org.briarproject.briar.android.removabledrive.SendFragment; @@ -245,6 +246,8 @@ public interface AndroidComponent void inject(BluetoothIntroFragment bluetoothIntroFragment); + void inject(SetupIntroFragment setupIntroFragment); + void inject(SetupDownloadFragment setupDownloadFragment); void inject(MailboxScanFragment mailboxScanFragment); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/ErrorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/ErrorFragment.java index 769f9493e..ffc37c11a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/ErrorFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/ErrorFragment.java @@ -59,10 +59,7 @@ public class ErrorFragment extends FinalFragment { // Do not hijack back button events, but let the activity process them onBackPressedCallback.remove(); buttonView.setText(R.string.try_again_button); - buttonView.setOnClickListener(view -> { - getParentFragmentManager().popBackStackImmediate(); - viewModel.tryAgainAfterError(); - }); + buttonView.setOnClickListener(view -> viewModel.showDownloadFragment()); return v; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java index d163a3768..df58ace2d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java @@ -54,6 +54,8 @@ public class MailboxActivity extends BriarActivity { viewModel.getState().observeEvent(this, state -> { if (state instanceof MailboxState.NotSetup) { onNotSetup(); + } else if (state instanceof MailboxState.ShowDownload) { + onShowDownload(); } else if (state instanceof MailboxState.ScanningQrCode) { onScanningQrCode(); } else if (state instanceof MailboxState.Pairing) { @@ -62,6 +64,8 @@ public class MailboxActivity extends BriarActivity { onMailboxPairingStateChanged(s); } else if (state instanceof MailboxState.OfflineWhenPairing) { onOffline(); + } else if (state instanceof MailboxState.CameraError) { + onCameraError(); } else if (state instanceof MailboxState.IsPaired) { onIsPaired(); } else { @@ -99,32 +103,38 @@ public class MailboxActivity extends BriarActivity { .commit(); } - private void onScanningQrCode() { + private void onShowDownload() { FragmentManager fm = getSupportFragmentManager(); - if (fm.findFragmentByTag(MailboxScanFragment.TAG) != null) { - // if the scanner is already on the back stack, pop back to it + if (fm.findFragmentByTag(SetupDownloadFragment.TAG) != null) { + // if the fragment is already on the back stack, pop back to it // instead of adding it to the stack again - fm.popBackStackImmediate(MailboxScanFragment.TAG, 0); + fm.popBackStackImmediate(SetupDownloadFragment.TAG, 0); } else { - showFragment(fm, new MailboxScanFragment(), - MailboxScanFragment.TAG); + showFragment(fm, new SetupDownloadFragment(), + SetupDownloadFragment.TAG); } } + private void onScanningQrCode() { + showFragment(getSupportFragmentManager(), new MailboxScanFragment(), + MailboxScanFragment.TAG); + } + private void onMailboxPairingStateChanged(MailboxPairingState s) { progressBar.setVisibility(INVISIBLE); FragmentManager fm = getSupportFragmentManager(); + if (fm.getBackStackEntryCount() == 0) { + // We re-launched into an existing state, + // need to re-populate the back stack. + onNotSetup(); + onShowDownload(); + } Fragment f; String tag; if (s instanceof MailboxPairingState.QrCodeReceived) { - // ignore, showing yet another progress fragment messes with back stack - return; + f = new MailboxConnectingFragment(); + tag = MailboxConnectingFragment.TAG; } else if (s instanceof MailboxPairingState.Pairing) { - if (fm.getBackStackEntryCount() == 0) { - // We re-launched into an existing state, - // need to re-populate the back stack. - repopulateBackStack(); - } f = new MailboxConnectingFragment(); tag = MailboxConnectingFragment.TAG; } else if (s instanceof MailboxPairingState.InvalidQrCode) { @@ -164,18 +174,17 @@ public class MailboxActivity extends BriarActivity { OfflineFragment.TAG); } + private void onCameraError() { + Fragment f = ErrorFragment.newInstance( + R.string.mailbox_setup_camera_error_title, + R.string.mailbox_setup_camera_error_description); + showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG); + } + private void onIsPaired() { progressBar.setVisibility(INVISIBLE); showFragment(getSupportFragmentManager(), new MailboxStatusFragment(), MailboxStatusFragment.TAG, false); } - private void repopulateBackStack() { - FragmentManager fm = getSupportFragmentManager(); - onNotSetup(); - showFragment(fm, new SetupDownloadFragment(), - SetupDownloadFragment.TAG); - onScanningQrCode(); - } - } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxScanFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxScanFragment.java index 335fd90f8..80afa4863 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxScanFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxScanFragment.java @@ -94,7 +94,7 @@ public class MailboxScanFragment extends Fragment { logException(LOG, WARNING, e); Toast.makeText(requireContext(), R.string.camera_error, LENGTH_LONG).show(); - requireActivity().getSupportFragmentManager().popBackStack(); + viewModel.onCameraError(); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxState.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxState.java index 4e384ffa0..7d2ef097e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxState.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxState.java @@ -3,13 +3,14 @@ package org.briarproject.briar.android.mailbox; import org.briarproject.bramble.api.mailbox.MailboxPairingState; import org.briarproject.bramble.api.mailbox.MailboxStatus; -import androidx.annotation.Nullable; - class MailboxState { static class NotSetup extends MailboxState { } + static class ShowDownload extends MailboxState { + } + static class ScanningQrCode extends MailboxState { } @@ -19,24 +20,12 @@ class MailboxState { Pairing(MailboxPairingState pairingState) { this.pairingState = pairingState; } - - @Nullable - String getQrCodePayload() { - return pairingState.qrCodePayload; - } } static class OfflineWhenPairing extends MailboxState { - @Nullable - final String qrCodePayload; + } - OfflineWhenPairing(@Nullable String qrCodePayload) { - this.qrCodePayload = qrCodePayload; - } - - OfflineWhenPairing() { - this(null); - } + static class CameraError extends MailboxState { } static class IsPaired extends MailboxState { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java index 0c98a82fc..2a8e15a6b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java @@ -33,7 +33,6 @@ import androidx.annotation.AnyThread; import androidx.annotation.Nullable; import androidx.annotation.UiThread; -import static java.util.Objects.requireNonNull; import static java.util.logging.Level.INFO; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; @@ -110,6 +109,11 @@ class MailboxViewModel extends DbViewModel } } + @UiThread + void onCameraError() { + state.setEvent(new MailboxState.CameraError()); + } + @Override @IoExecutor public void onQrCodeDecoded(Result result) { @@ -123,7 +127,7 @@ class MailboxViewModel extends DbViewModel pairingTask = mailboxManager.startPairingTask(qrCodePayload); pairingTask.addObserver(this); } else { - state.postEvent(new MailboxState.OfflineWhenPairing(qrCodePayload)); + state.postEvent(new MailboxState.OfflineWhenPairing()); } } @@ -143,26 +147,8 @@ class MailboxViewModel extends DbViewModel } @UiThread - void tryAgainWhenOffline() { - MailboxState.OfflineWhenPairing offline = - (MailboxState.OfflineWhenPairing) requireNonNull( - state.getLastValue()); - if (offline.qrCodePayload == null) { - onScanButtonClicked(); - } else { - onQrCodePayloadReceived(offline.qrCodePayload); - } - } - - @UiThread - void tryAgainAfterError() { - MailboxState.Pairing pairing = (MailboxState.Pairing) - requireNonNull(state.getLastValue()); - if (pairing.getQrCodePayload() == null) { - onScanButtonClicked(); - } else { - onQrCodePayloadReceived(pairing.getQrCodePayload()); - } + void showDownloadFragment() { + state.setEvent(new MailboxState.ShowDownload()); } @UiThread diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/OfflineFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/OfflineFragment.java index fba30ccf6..99ae679be 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/OfflineFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/OfflineFragment.java @@ -62,10 +62,7 @@ public class OfflineFragment extends Fragment { startActivity(i); }); buttonView = v.findViewById(R.id.button); - buttonView.setOnClickListener(view -> { - getParentFragmentManager().popBackStackImmediate(); - viewModel.tryAgainWhenOffline(); - }); + buttonView.setOnClickListener(view -> viewModel.showDownloadFragment()); return v; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/SetupIntroFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/SetupIntroFragment.java index 8ba22a04c..febe902a4 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/SetupIntroFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/SetupIntroFragment.java @@ -1,5 +1,6 @@ package org.briarproject.briar.android.mailbox; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -11,12 +12,15 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.briar.R; +import javax.inject.Inject; + import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; import static android.view.View.FOCUS_DOWN; -import static org.briarproject.briar.android.util.UiUtils.showFragment; +import static org.briarproject.briar.android.AppModule.getAndroidComponent; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -24,8 +28,22 @@ public class SetupIntroFragment extends Fragment { static final String TAG = SetupIntroFragment.class.getName(); + @Inject + ViewModelProvider.Factory viewModelFactory; + + private MailboxViewModel viewModel; + private ScrollView scrollView; + @Override + public void onAttach(Context context) { + super.onAttach(context); + FragmentActivity activity = requireActivity(); + getAndroidComponent(activity).inject(this); + viewModel = new ViewModelProvider(activity, viewModelFactory) + .get(MailboxViewModel.class); + } + @Nullable @Override public View onCreateView(LayoutInflater inflater, @@ -35,11 +53,7 @@ public class SetupIntroFragment extends Fragment { container, false); scrollView = v.findViewById(R.id.scrollView); Button button = v.findViewById(R.id.continueButton); - button.setOnClickListener(view -> { - FragmentManager fm = getParentFragmentManager(); - Fragment f = new SetupDownloadFragment(); - showFragment(fm, f, SetupDownloadFragment.TAG); - }); + button.setOnClickListener(view -> viewModel.showDownloadFragment()); return v; } diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 38b7c848f..fd79a88d7 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -631,6 +631,8 @@ Ensure that both devices are connected to the internet and try again. Mailbox error Please send feedback (with anonymous data) via the Briar app if the issue persists. + @string/camera_error + Could not access camera. Try again, maybe after rebooting device. Connected Your Mailbox has been successfully linked with Briar.\n \nKeep your Mailbox connected to power and Wi-Fi so it\'s always online.