Introduce ContactExchangeResult

to include all result information in LiveData
This commit is contained in:
Torsten Grote
2021-02-01 14:01:46 -03:00
parent 94ec22bef8
commit f6b3bde724
4 changed files with 67 additions and 58 deletions

View File

@@ -8,13 +8,10 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
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 javax.annotation.Nullable;
import javax.inject.Inject;
import androidx.annotation.UiThread;
import androidx.lifecycle.ViewModelProvider;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.Objects.requireNonNull;
@@ -23,40 +20,29 @@ import static java.util.Objects.requireNonNull;
@ParametersNotNullByDefault
public class ContactExchangeActivity extends KeyAgreementActivity {
@Inject
ViewModelProvider.Factory viewModelFactory;
private ContactExchangeViewModel viewModel;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
requireNonNull(getSupportActionBar())
.setTitle(R.string.add_contact_title);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(ContactExchangeViewModel.class);
}
private void startContactExchange(KeyAgreementResult result) {
viewModel.getSucceeded().observe(this, succeeded -> {
if (succeeded == null) return;
if (succeeded) {
Author remote = requireNonNull(viewModel.getRemoteAuthor());
contactExchangeSucceeded(remote);
} else {
Author duplicate = viewModel.getDuplicateAuthor();
if (duplicate == null) contactExchangeFailed();
else duplicateContact(duplicate);
}
private void startContactExchange(KeyAgreementResult agreementResult) {
viewModel.getContactExchangeResult().observe(this, result -> {
if (result instanceof ContactExchangeResult.Success) {
Author remoteAuthor =
((ContactExchangeResult.Success) result).remoteAuthor;
contactExchangeSucceeded(remoteAuthor);
} else if (result instanceof ContactExchangeResult.Error) {
Author duplicateAuthor =
((ContactExchangeResult.Error) result).duplicateAuthor;
if (duplicateAuthor == null) contactExchangeFailed();
else duplicateContact(duplicateAuthor);
} else throw new AssertionError();
});
viewModel.startContactExchange(result.getTransportId(),
result.getConnection(), result.getMasterKey(),
result.wasAlice());
viewModel.startContactExchange(agreementResult.getTransportId(),
agreementResult.getConnection(), agreementResult.getMasterKey(),
agreementResult.wasAlice());
}
@UiThread

View File

@@ -0,0 +1,30 @@
package org.briarproject.briar.android.contact.add.nearby;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
abstract class ContactExchangeResult {
static class Success extends ContactExchangeResult {
final Author remoteAuthor;
Success(Author remoteAuthor) {
this.remoteAuthor = remoteAuthor;
}
}
static class Error extends ContactExchangeResult {
@Nullable
final Author duplicateAuthor;
Error(@Nullable Author duplicateAuthor) {
this.duplicateAuthor = duplicateAuthor;
}
}
}

View File

@@ -8,17 +8,17 @@ import org.briarproject.bramble.api.contact.ContactExchangeManager;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeResult.Error;
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeResult.Success;
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import androidx.annotation.UiThread;
@@ -39,10 +39,8 @@ class ContactExchangeViewModel extends AndroidViewModel {
private final Executor ioExecutor;
private final ContactExchangeManager contactExchangeManager;
private final ConnectionManager connectionManager;
private final MutableLiveData<Boolean> succeeded = new MutableLiveData<>();
@Nullable
private volatile Author remoteAuthor, duplicateAuthor;
private final MutableLiveData<ContactExchangeResult> exchangeResult =
new MutableLiveData<>();
@Inject
ContactExchangeViewModel(Application app, @IoExecutor Executor ioExecutor,
@@ -62,18 +60,16 @@ class ContactExchangeViewModel extends AndroidViewModel {
Contact contact = contactExchangeManager.exchangeContacts(conn,
masterKey, alice, true);
// Reuse the connection as a transport connection
connectionManager.manageOutgoingConnection(contact.getId(),
t, conn);
remoteAuthor = contact.getAuthor();
succeeded.postValue(true);
connectionManager
.manageOutgoingConnection(contact.getId(), t, conn);
exchangeResult.postValue(new Success(contact.getAuthor()));
} catch (ContactExistsException e) {
tryToClose(conn);
duplicateAuthor = e.getRemoteAuthor();
succeeded.postValue(false);
exchangeResult.postValue(new Error(e.getRemoteAuthor()));
} catch (DbException | IOException e) {
tryToClose(conn);
logException(LOG, WARNING, e);
succeeded.postValue(false);
exchangeResult.postValue(new Error(null));
}
});
}
@@ -87,19 +83,7 @@ class ContactExchangeViewModel extends AndroidViewModel {
}
}
@UiThread
@Nullable
Author getRemoteAuthor() {
return remoteAuthor;
}
@UiThread
@Nullable
Author getDuplicateAuthor() {
return duplicateAuthor;
}
LiveData<Boolean> getSucceeded() {
return succeeded;
LiveData<ContactExchangeResult> getContactExchangeResult() {
return exchangeResult;
}
}

View File

@@ -22,10 +22,10 @@ import org.briarproject.bramble.api.plugin.event.TransportStateEvent;
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.BaseFragment;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.briar.android.contact.add.nearby.IntroFragment.IntroScreenSeenListener;
import org.briarproject.briar.android.contact.add.nearby.KeyAgreementFragment.KeyAgreementEventListener;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
import java.util.logging.Logger;
@@ -38,6 +38,7 @@ import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.CAMERA;
@@ -97,12 +98,18 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
private static final Logger LOG =
getLogger(KeyAgreementActivity.class.getName());
@Inject
ViewModelProvider.Factory viewModelFactory;
@Inject
EventBus eventBus;
@Inject
PluginManager pluginManager;
protected ContactExchangeViewModel viewModel;
/**
* Set to true in onPostResume() and false in onPause(). This prevents the
* QR code fragment from being shown if onRequestPermissionsResult() is
@@ -140,6 +147,8 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(ContactExchangeViewModel.class);
}
@Override