mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Use new MailboxManager in Android UI
This commit is contained in:
@@ -5,6 +5,8 @@ import android.view.MenuItem;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Pairing;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
@@ -20,6 +22,7 @@ import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static org.briarproject.briar.android.util.UiUtils.showFragment;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -55,14 +58,14 @@ public class MailboxActivity extends BriarActivity {
|
||||
onNotSetup();
|
||||
} else if (state instanceof MailboxState.ScanningQrCode) {
|
||||
onScanningQrCode();
|
||||
} else if (state instanceof MailboxState.SettingUp) {
|
||||
onCodeScanned();
|
||||
} else if (state instanceof MailboxState.QrCodeWrong) {
|
||||
onQrCodeWrong();
|
||||
} else if (state instanceof MailboxState.OfflineInSetup) {
|
||||
} else if (state instanceof MailboxState.Pairing) {
|
||||
MailboxPairingState s =
|
||||
((MailboxState.Pairing) state).pairingState;
|
||||
onMailboxPairingStateChanged(s);
|
||||
} else if (state instanceof MailboxState.OfflineWhenPairing) {
|
||||
onOffline();
|
||||
} else if (state instanceof MailboxState.IsSetup) {
|
||||
onIsSetup(((MailboxState.IsSetup) state).mailboxStatus);
|
||||
} else if (state instanceof MailboxState.IsPaired) {
|
||||
onIsPaired(((MailboxState.IsPaired) state).mailboxStatus);
|
||||
} else {
|
||||
throw new AssertionError("Unknown state: " + state);
|
||||
}
|
||||
@@ -80,9 +83,10 @@ public class MailboxActivity extends BriarActivity {
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (viewModel.getState()
|
||||
.getLastValue() instanceof MailboxState.SettingUp) {
|
||||
// don't go back in flow if we are already setting up mailbox
|
||||
MailboxState s = viewModel.getState().getLastValue();
|
||||
if (s instanceof MailboxState.Pairing &&
|
||||
((MailboxState.Pairing) s).pairingState instanceof Pairing) {
|
||||
// don't go back in flow if we are already pairing with the mailbox
|
||||
supportFinishAfterTransition();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
@@ -102,17 +106,43 @@ public class MailboxActivity extends BriarActivity {
|
||||
MailboxScanFragment.TAG);
|
||||
}
|
||||
|
||||
private void onCodeScanned() {
|
||||
showFragment(getSupportFragmentManager(),
|
||||
new MailboxConnectingFragment(),
|
||||
MailboxConnectingFragment.TAG, false);
|
||||
}
|
||||
|
||||
private void onQrCodeWrong() {
|
||||
Fragment f = ErrorFragment.newInstance(
|
||||
R.string.mailbox_setup_qr_code_wrong_title,
|
||||
R.string.mailbox_setup_qr_code_wrong_description);
|
||||
showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG);
|
||||
private void onMailboxPairingStateChanged(MailboxPairingState s) {
|
||||
progressBar.setVisibility(INVISIBLE);
|
||||
Fragment f;
|
||||
String tag;
|
||||
boolean addToBackStack = true;
|
||||
if (s instanceof MailboxPairingState.QrCodeReceived) {
|
||||
// ignore, showing yet another progress fragment messes with back stack
|
||||
return;
|
||||
} else if (s instanceof MailboxPairingState.Pairing) {
|
||||
f = new MailboxConnectingFragment();
|
||||
tag = MailboxConnectingFragment.TAG;
|
||||
addToBackStack = false;
|
||||
} else if (s instanceof MailboxPairingState.InvalidQrCode) {
|
||||
f = ErrorFragment.newInstance(
|
||||
R.string.mailbox_setup_qr_code_wrong_title,
|
||||
R.string.mailbox_setup_qr_code_wrong_description);
|
||||
tag = ErrorFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.MailboxAlreadyPaired) {
|
||||
// TODO
|
||||
Toast.makeText(this, "MailboxAlreadyPaired", LENGTH_LONG).show();
|
||||
return;
|
||||
} else if (s instanceof MailboxPairingState.ConnectionError) {
|
||||
// TODO
|
||||
Toast.makeText(this, "Connection Error", LENGTH_LONG).show();
|
||||
return;
|
||||
} else if (s instanceof MailboxPairingState.AssertionError) {
|
||||
// TODO
|
||||
Toast.makeText(this, "Connection Error", LENGTH_LONG).show();
|
||||
return;
|
||||
} else if (s instanceof MailboxPairingState.Paired) {
|
||||
// TODO
|
||||
Toast.makeText(this, "Connection Error", LENGTH_LONG).show();
|
||||
return;
|
||||
} else {
|
||||
throw new IllegalStateException("Unhandled state: " + s.getClass());
|
||||
}
|
||||
showFragment(getSupportFragmentManager(), f, tag, addToBackStack);
|
||||
}
|
||||
|
||||
private void onOffline() {
|
||||
@@ -120,9 +150,10 @@ public class MailboxActivity extends BriarActivity {
|
||||
OfflineFragment.TAG);
|
||||
}
|
||||
|
||||
private void onIsSetup(MailboxStatus mailboxStatus) {
|
||||
private void onIsPaired(MailboxStatus mailboxStatus) {
|
||||
progressBar.setVisibility(INVISIBLE);
|
||||
// TODO
|
||||
Toast.makeText(this, "NOT IMPLEMENTED", Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(this, "NOT IMPLEMENTED", LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.briarproject.briar.android.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -13,29 +13,31 @@ class MailboxState {
|
||||
static class ScanningQrCode extends MailboxState {
|
||||
}
|
||||
|
||||
static class SettingUp extends MailboxState {
|
||||
static class Pairing extends MailboxState {
|
||||
final MailboxPairingState pairingState;
|
||||
|
||||
Pairing(MailboxPairingState pairingState) {
|
||||
this.pairingState = pairingState;
|
||||
}
|
||||
}
|
||||
|
||||
static class QrCodeWrong extends MailboxState {
|
||||
}
|
||||
|
||||
static class OfflineInSetup extends MailboxState {
|
||||
static class OfflineWhenPairing extends MailboxState {
|
||||
@Nullable
|
||||
final MailboxProperties mailboxProperties;
|
||||
final String qrCodePayload;
|
||||
|
||||
OfflineInSetup(@Nullable MailboxProperties mailboxProperties) {
|
||||
this.mailboxProperties = mailboxProperties;
|
||||
OfflineWhenPairing(@Nullable String qrCodePayload) {
|
||||
this.qrCodePayload = qrCodePayload;
|
||||
}
|
||||
|
||||
OfflineInSetup() {
|
||||
OfflineWhenPairing() {
|
||||
this(null);
|
||||
}
|
||||
}
|
||||
|
||||
static class IsSetup extends MailboxState {
|
||||
static class IsPaired extends MailboxState {
|
||||
final MailboxStatus mailboxStatus;
|
||||
|
||||
IsSetup(MailboxStatus mailboxStatus) {
|
||||
IsPaired(MailboxStatus mailboxStatus) {
|
||||
this.mailboxStatus = mailboxStatus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,14 @@ import android.app.Application;
|
||||
|
||||
import com.google.zxing.Result;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.Consumer;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.TransactionManager;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.Plugin;
|
||||
@@ -25,38 +24,34 @@ import org.briarproject.briar.android.viewmodel.DbViewModel;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||
|
||||
@NotNullByDefault
|
||||
class MailboxViewModel extends DbViewModel
|
||||
implements QrCodeDecoder.ResultCallback {
|
||||
implements QrCodeDecoder.ResultCallback, Consumer<MailboxPairingState> {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(MailboxViewModel.class.getName());
|
||||
|
||||
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
private static final int VERSION_REQUIRED = 32;
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final QrCodeDecoder qrCodeDecoder;
|
||||
private final PluginManager pluginManager;
|
||||
private final MailboxSettingsManager mailboxSettingsManager;
|
||||
private final MailboxManager mailboxManager;
|
||||
|
||||
private final MutableLiveEvent<MailboxState> state =
|
||||
new MutableLiveEvent<>();
|
||||
@Nullable
|
||||
private MailboxPairingTask pairingTask = null;
|
||||
|
||||
@Inject
|
||||
MailboxViewModel(
|
||||
@@ -66,29 +61,43 @@ class MailboxViewModel extends DbViewModel
|
||||
TransactionManager db,
|
||||
AndroidExecutor androidExecutor,
|
||||
@IoExecutor Executor ioExecutor,
|
||||
CryptoComponent crypto,
|
||||
PluginManager pluginManager,
|
||||
MailboxSettingsManager mailboxSettingsManager) {
|
||||
MailboxManager mailboxManager) {
|
||||
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||
this.crypto = crypto;
|
||||
this.pluginManager = pluginManager;
|
||||
this.mailboxSettingsManager = mailboxSettingsManager;
|
||||
this.mailboxManager = mailboxManager;
|
||||
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
||||
checkIfSetup();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
MailboxPairingTask task = pairingTask;
|
||||
if (task != null) {
|
||||
task.removeObserver(this);
|
||||
pairingTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void checkIfSetup() {
|
||||
runOnDbThread(true, txn -> {
|
||||
MailboxProperties props =
|
||||
mailboxSettingsManager.getOwnMailboxProperties(txn);
|
||||
if (props == null) state.postEvent(new NotSetup());
|
||||
else {
|
||||
MailboxStatus mailboxStatus =
|
||||
mailboxSettingsManager.getOwnMailboxStatus(txn);
|
||||
state.postEvent(new MailboxState.IsSetup(mailboxStatus));
|
||||
}
|
||||
}, this::handleException);
|
||||
MailboxPairingTask task = mailboxManager.getCurrentPairingTask();
|
||||
if (task == null) {
|
||||
runOnDbThread(true, txn -> {
|
||||
boolean isPaired = mailboxManager.isPaired(txn);
|
||||
if (isPaired) {
|
||||
MailboxStatus mailboxStatus =
|
||||
mailboxManager.getMailboxStatus(txn);
|
||||
state.postEvent(new MailboxState.IsPaired(mailboxStatus));
|
||||
} else {
|
||||
state.postEvent(new NotSetup());
|
||||
}
|
||||
}, this::handleException);
|
||||
} else {
|
||||
task.addObserver(this);
|
||||
pairingTask = task;
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -96,7 +105,7 @@ class MailboxViewModel extends DbViewModel
|
||||
if (isTorActive()) {
|
||||
state.setEvent(new MailboxState.ScanningQrCode());
|
||||
} else {
|
||||
state.setEvent(new MailboxState.OfflineInSetup());
|
||||
state.setEvent(new MailboxState.OfflineWhenPairing());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,53 +113,25 @@ class MailboxViewModel extends DbViewModel
|
||||
@IoExecutor
|
||||
public void onQrCodeDecoded(Result result) {
|
||||
LOG.info("Got result from decoder");
|
||||
MailboxProperties properties;
|
||||
try {
|
||||
properties = decodeQrCode(result.getText());
|
||||
} catch (FormatException e) {
|
||||
state.postEvent(new MailboxState.QrCodeWrong());
|
||||
return;
|
||||
}
|
||||
onMailboxPropertiesReceived(properties);
|
||||
onQrCodePayloadReceived(result.getText());
|
||||
}
|
||||
|
||||
@IoExecutor
|
||||
// TODO move this into core #2168
|
||||
private MailboxProperties decodeQrCode(String payload)
|
||||
throws FormatException {
|
||||
byte[] bytes = payload.getBytes(ISO_8859_1);
|
||||
if (bytes.length != 65) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("QR code length is not 65: " + bytes.length);
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
int version = bytes[0] & 0xFF;
|
||||
if (version != VERSION_REQUIRED) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("QR code has not version " + VERSION_REQUIRED +
|
||||
": " + version);
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
LOG.info("QR code is valid");
|
||||
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
|
||||
String onionAddress = crypto.encodeOnionAddress(onionPubKey);
|
||||
byte[] tokenBytes = Arrays.copyOfRange(bytes, 33, 65);
|
||||
MailboxAuthToken setupToken = new MailboxAuthToken(tokenBytes);
|
||||
return new MailboxProperties(onionAddress, setupToken, true);
|
||||
}
|
||||
|
||||
private void onMailboxPropertiesReceived(MailboxProperties properties) {
|
||||
@AnyThread
|
||||
private void onQrCodePayloadReceived(String qrCodePayload) {
|
||||
if (isTorActive()) {
|
||||
// TODO pass props to core #2168
|
||||
state.postEvent(new MailboxState.SettingUp());
|
||||
pairingTask = mailboxManager.startPairingTask(qrCodePayload);
|
||||
pairingTask.addObserver(this);
|
||||
} else {
|
||||
state.postEvent(new MailboxState.OfflineInSetup(properties));
|
||||
state.postEvent(new MailboxState.OfflineWhenPairing(qrCodePayload));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO ideally also move this into core #2168
|
||||
@UiThread
|
||||
@Override
|
||||
public void accept(MailboxPairingState mailboxPairingState) {
|
||||
state.setEvent(new MailboxState.Pairing(mailboxPairingState));
|
||||
}
|
||||
|
||||
private boolean isTorActive() {
|
||||
Plugin plugin = pluginManager.getPlugin(TorConstants.ID);
|
||||
return plugin != null && plugin.getState() == ACTIVE;
|
||||
@@ -158,13 +139,13 @@ class MailboxViewModel extends DbViewModel
|
||||
|
||||
@UiThread
|
||||
void tryAgainWhenOffline() {
|
||||
MailboxState.OfflineInSetup offline =
|
||||
(MailboxState.OfflineInSetup) requireNonNull(
|
||||
MailboxState.OfflineWhenPairing offline =
|
||||
(MailboxState.OfflineWhenPairing) requireNonNull(
|
||||
state.getLastValue());
|
||||
if (offline.mailboxProperties == null) {
|
||||
if (offline.qrCodePayload == null) {
|
||||
onScanButtonClicked();
|
||||
} else {
|
||||
onMailboxPropertiesReceived(offline.mailboxProperties);
|
||||
onQrCodePayloadReceived(offline.qrCodePayload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user