diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java index 784fff21d..d2c88aebb 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java @@ -45,7 +45,11 @@ public interface MailboxManager { /** * Unpairs the owner's mailbox and tries to wipe it. * As this makes a network call, it should be run on the {@link IoExecutor}. + * + * @return true if we could wipe the mailbox, false if we couldn't. + * It is advised to inform the user to wipe the mailbox themselves, + * if we failed to wipe it. */ @IoExecutor - void unPair() throws DbException; + boolean unPair() throws DbException; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java index 63c494f03..0ecaffbea 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java @@ -7,6 +7,7 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFileId; import org.briarproject.bramble.api.mailbox.MailboxFolderId; import org.briarproject.bramble.api.mailbox.MailboxProperties; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.io.File; import java.io.IOException; @@ -16,6 +17,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; +@NotNullByDefault interface MailboxApi { /** diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java index d17401559..da8d8d47d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java @@ -102,6 +102,7 @@ class MailboxManagerImpl implements MailboxManager { try { MailboxProperties props = db.transactionWithNullableResult(true, mailboxSettingsManager::getOwnMailboxProperties); + if (props == null) throw new DbException(); success = api.checkStatus(props); } catch (DbException e) { logException(LOG, WARNING, e); @@ -132,17 +133,24 @@ class MailboxManagerImpl implements MailboxManager { } @Override - public void unPair() throws DbException { + public boolean unPair() throws DbException { MailboxProperties properties = db.transactionWithNullableResult(true, mailboxSettingsManager::getOwnMailboxProperties); + if (properties == null) { + // no more mailbox, that's strange but possible if called in quick + // succession, so let's return true this time + return true; + } + boolean wasWiped; try { api.wipeMailbox(properties); + wasWiped = true; } catch (IOException | MailboxApi.ApiException e) { - // We wipe on a best-effort basis. - // If we can't do it, we still unpair. logException(LOG, WARNING, e); + wasWiped = false; } db.transaction(false, mailboxSettingsManager::removeOwnMailboxProperties); + return wasWiped; } } 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 8c5f16b32..528de5886 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 @@ -11,10 +11,12 @@ import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.fragment.FinalFragment; +import org.briarproject.briar.android.view.BlankFragment; import javax.inject.Inject; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; @@ -68,6 +70,9 @@ public class MailboxActivity extends BriarActivity { onCameraError(); } else if (state instanceof MailboxState.IsPaired) { onIsPaired(((MailboxState.IsPaired) state).isOnline); + } else if (state instanceof MailboxState.WasUnpaired) { + MailboxState.WasUnpaired s = (MailboxState.WasUnpaired) state; + onUnPaired(s.tellUserToWipeMailbox); } else { throw new AssertionError("Unknown state: " + state); } @@ -190,4 +195,22 @@ public class MailboxActivity extends BriarActivity { showFragment(getSupportFragmentManager(), f, tag, false); } + private void onUnPaired(boolean tellUserToWipeMailbox) { + if (tellUserToWipeMailbox) { + showFragment(getSupportFragmentManager(), new BlankFragment(), + BlankFragment.TAG); + AlertDialog.Builder builder = + new AlertDialog.Builder(this, R.style.BriarDialogTheme); + builder.setTitle(R.string.mailbox_status_unlink_no_wipe_title); + builder.setMessage(R.string.mailbox_status_unlink_no_wipe_message); + builder.setNeutralButton(R.string.got_it, + (dialog, which) -> dialog.cancel()); + builder.setOnCancelListener( + dialog -> supportFinishAfterTransition()); + builder.show(); + } else { + supportFinishAfterTransition(); + } + } + } 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 4fcfdaf6a..774f2c795 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 @@ -35,4 +35,12 @@ class MailboxState { } } + static class WasUnpaired extends MailboxState { + final boolean tellUserToWipeMailbox; + + WasUnpaired(boolean tellUserToWipeMailbox) { + this.tellUserToWipeMailbox = tellUserToWipeMailbox; + } + } + } 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 eeacb180e..0d61bfab5 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 @@ -225,8 +225,8 @@ class MailboxViewModel extends DbViewModel void unlink() { ioExecutor.execute(() -> { try { - mailboxManager.unPair(); - pairingState.postEvent(new MailboxState.NotSetup()); + boolean wasWiped = mailboxManager.unPair(); + pairingState.postEvent(new MailboxState.WasUnpaired(!wasWiped)); } catch (DbException e) { handleException(e); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/BlankFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/view/BlankFragment.java new file mode 100644 index 000000000..6014e8994 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/BlankFragment.java @@ -0,0 +1,12 @@ +package org.briarproject.briar.android.view; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; + +import androidx.fragment.app.Fragment; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class BlankFragment extends Fragment { + public static final String TAG = BlankFragment.class.getName(); +} diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index ad98a1a7d..2dfca0d34 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -654,6 +654,8 @@ Unlink mailbox? Are you sure you want to unlink your Mailbox? If you unlink your Mailbox, you won\'t be able to receive messages while Briar is offline. + Your Mailbox has been unlinked + Next time you have access to your Mailbox device, please open the Mailbox app and tap the \"Unlink\" button to complete the process.\n\nIf you no longer have access to your Mailbox device, don\'t worry. Your data is encrypted so it will remain secure even if you don\'t complete the process. Disappearing messages