mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 15:19:53 +01:00
Replace events with return value and exceptions.
This commit is contained in:
@@ -1,16 +1,24 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
package org.briarproject.bramble.api.contact;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
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.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface ContactExchangeManager {
|
public interface ContactExchangeManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchanges contact information with a remote peer.
|
* Exchanges contact information with a remote peer.
|
||||||
|
*
|
||||||
|
* @return The contact's pseudonym
|
||||||
|
* @throws ContactExistsException If the contact already exists
|
||||||
*/
|
*/
|
||||||
void exchangeContacts(TransportId t, DuplexTransportConnection conn,
|
Author exchangeContacts(TransportId t, DuplexTransportConnection conn,
|
||||||
SecretKey masterKey, boolean alice);
|
SecretKey masterKey, boolean alice) throws IOException, DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.contact.event;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
public class ContactExchangeFailedEvent extends Event {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private final Author duplicateRemoteAuthor;
|
|
||||||
|
|
||||||
public ContactExchangeFailedEvent(@Nullable Author duplicateRemoteAuthor) {
|
|
||||||
this.duplicateRemoteAuthor = duplicateRemoteAuthor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactExchangeFailedEvent() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Author getDuplicateRemoteAuthor() {
|
|
||||||
return duplicateRemoteAuthor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean wasDuplicateContact() {
|
|
||||||
return duplicateRemoteAuthor != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.contact.event;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
public class ContactExchangeSucceededEvent extends Event {
|
|
||||||
|
|
||||||
private final Author remoteAuthor;
|
|
||||||
|
|
||||||
public ContactExchangeSucceededEvent(Author remoteAuthor) {
|
|
||||||
this.remoteAuthor = remoteAuthor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Author getRemoteAuthor() {
|
|
||||||
return remoteAuthor;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -6,16 +6,12 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
|||||||
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactExchangeFailedEvent;
|
|
||||||
import org.briarproject.bramble.api.contact.event.ContactExchangeSucceededEvent;
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
@@ -46,7 +42,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
|
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||||
@@ -56,7 +51,6 @@ import static org.briarproject.bramble.contact.ContactExchangeConstants.BOB_KEY_
|
|||||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.BOB_NONCE_LABEL;
|
import static org.briarproject.bramble.contact.ContactExchangeConstants.BOB_NONCE_LABEL;
|
||||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
||||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.SIGNING_LABEL;
|
import static org.briarproject.bramble.contact.ContactExchangeConstants.SIGNING_LABEL;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||||
|
|
||||||
@@ -85,7 +79,6 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
private final RecordReaderFactory recordReaderFactory;
|
private final RecordReaderFactory recordReaderFactory;
|
||||||
private final RecordWriterFactory recordWriterFactory;
|
private final RecordWriterFactory recordWriterFactory;
|
||||||
private final EventBus eventBus;
|
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
@@ -98,7 +91,7 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
@Inject
|
@Inject
|
||||||
ContactExchangeManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
|
ContactExchangeManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
RecordReaderFactory recordReaderFactory,
|
RecordReaderFactory recordReaderFactory,
|
||||||
RecordWriterFactory recordWriterFactory, EventBus eventBus,
|
RecordWriterFactory recordWriterFactory,
|
||||||
Clock clock, ConnectionManager connectionManager,
|
Clock clock, ConnectionManager connectionManager,
|
||||||
ContactManager contactManager, IdentityManager identityManager,
|
ContactManager contactManager, IdentityManager identityManager,
|
||||||
TransportPropertyManager transportPropertyManager,
|
TransportPropertyManager transportPropertyManager,
|
||||||
@@ -108,7 +101,6 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
this.recordReaderFactory = recordReaderFactory;
|
this.recordReaderFactory = recordReaderFactory;
|
||||||
this.recordWriterFactory = recordWriterFactory;
|
this.recordWriterFactory = recordWriterFactory;
|
||||||
this.eventBus = eventBus;
|
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -120,33 +112,17 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exchangeContacts(TransportId t, DuplexTransportConnection conn,
|
public Author exchangeContacts(TransportId t,
|
||||||
SecretKey masterKey, boolean alice) {
|
DuplexTransportConnection conn, SecretKey masterKey, boolean alice)
|
||||||
|
throws IOException, DbException {
|
||||||
// Get the transport connection's input and output streams
|
// Get the transport connection's input and output streams
|
||||||
InputStream in;
|
InputStream in = conn.getReader().getInputStream();
|
||||||
OutputStream out;
|
OutputStream out = conn.getWriter().getOutputStream();
|
||||||
try {
|
|
||||||
in = conn.getReader().getInputStream();
|
|
||||||
out = conn.getWriter().getOutputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
tryToClose(conn);
|
|
||||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the local author and transport properties
|
// Get the local author and transport properties
|
||||||
LocalAuthor localAuthor;
|
LocalAuthor localAuthor = identityManager.getLocalAuthor();
|
||||||
Map<TransportId, TransportProperties> localProperties;
|
Map<TransportId, TransportProperties> localProperties =
|
||||||
try {
|
transportPropertyManager.getLocalProperties();
|
||||||
localAuthor = identityManager.getLocalAuthor();
|
|
||||||
localProperties = transportPropertyManager.getLocalProperties();
|
|
||||||
} catch (DbException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
|
||||||
tryToClose(conn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derive the header keys for the transport streams
|
// Derive the header keys for the transport streams
|
||||||
SecretKey aliceHeaderKey = crypto.deriveKey(ALICE_KEY_LABEL, masterKey,
|
SecretKey aliceHeaderKey = crypto.deriveKey(ALICE_KEY_LABEL, masterKey,
|
||||||
@@ -183,58 +159,37 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
// Exchange contact info
|
// Exchange contact info
|
||||||
long localTimestamp = clock.currentTimeMillis();
|
long localTimestamp = clock.currentTimeMillis();
|
||||||
ContactInfo remoteInfo;
|
ContactInfo remoteInfo;
|
||||||
try {
|
if (alice) {
|
||||||
if (alice) {
|
sendContactInfo(recordWriter, localAuthor, localProperties,
|
||||||
sendContactInfo(recordWriter, localAuthor, localProperties,
|
localSignature, localTimestamp);
|
||||||
localSignature, localTimestamp);
|
remoteInfo = receiveContactInfo(recordReader);
|
||||||
remoteInfo = receiveContactInfo(recordReader);
|
} else {
|
||||||
} else {
|
remoteInfo = receiveContactInfo(recordReader);
|
||||||
remoteInfo = receiveContactInfo(recordReader);
|
sendContactInfo(recordWriter, localAuthor, localProperties,
|
||||||
sendContactInfo(recordWriter, localAuthor, localProperties,
|
localSignature, localTimestamp);
|
||||||
localSignature, localTimestamp);
|
|
||||||
}
|
|
||||||
// Send EOF on the outgoing stream
|
|
||||||
streamWriter.sendEndOfStream();
|
|
||||||
// Skip any remaining records from the incoming stream
|
|
||||||
recordReader.readRecord(r -> false, IGNORE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
|
||||||
tryToClose(conn);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
// Send EOF on the outgoing stream
|
||||||
|
streamWriter.sendEndOfStream();
|
||||||
|
// Skip any remaining records from the incoming stream
|
||||||
|
recordReader.readRecord(r -> false, IGNORE);
|
||||||
|
|
||||||
// Verify the contact's signature
|
// Verify the contact's signature
|
||||||
if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
|
if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
|
||||||
LOG.warning("Invalid signature");
|
LOG.warning("Invalid signature");
|
||||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
throw new FormatException();
|
||||||
tryToClose(conn);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The agreed timestamp is the minimum of the peers' timestamps
|
// The agreed timestamp is the minimum of the peers' timestamps
|
||||||
long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
|
long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
|
||||||
|
|
||||||
try {
|
// Add the contact
|
||||||
// Add the contact
|
ContactId contactId = addContact(remoteInfo.author, localAuthor,
|
||||||
ContactId contactId = addContact(remoteInfo.author, localAuthor,
|
masterKey, timestamp, alice, remoteInfo.properties);
|
||||||
masterKey, timestamp, alice, remoteInfo.properties);
|
// Reuse the connection as a transport connection
|
||||||
// Reuse the connection as a transport connection
|
connectionManager.manageOutgoingConnection(contactId, t, conn);
|
||||||
connectionManager.manageOutgoingConnection(contactId, t, conn);
|
// Pseudonym exchange succeeded
|
||||||
// Pseudonym exchange succeeded
|
LOG.info("Pseudonym exchange succeeded");
|
||||||
LOG.info("Pseudonym exchange succeeded");
|
return remoteInfo.author;
|
||||||
eventBus.broadcast(
|
|
||||||
new ContactExchangeSucceededEvent(remoteInfo.author));
|
|
||||||
} catch (ContactExistsException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
tryToClose(conn);
|
|
||||||
eventBus.broadcast(
|
|
||||||
new ContactExchangeFailedEvent(e.getRemoteAuthor()));
|
|
||||||
} catch (DbException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
tryToClose(conn);
|
|
||||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] sign(LocalAuthor author, byte[] nonce) {
|
private byte[] sign(LocalAuthor author, byte[] nonce) {
|
||||||
@@ -298,16 +253,6 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(DuplexTransportConnection conn) {
|
|
||||||
try {
|
|
||||||
LOG.info("Closing connection");
|
|
||||||
conn.getReader().dispose(true, true);
|
|
||||||
conn.getWriter().dispose(true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ContactInfo {
|
private static class ContactInfo {
|
||||||
|
|
||||||
private final Author author;
|
private final Author author;
|
||||||
|
|||||||
@@ -7,58 +7,63 @@ import android.arch.lifecycle.MutableLiveData;
|
|||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactExchangeFailedEvent;
|
|
||||||
import org.briarproject.bramble.api.contact.event.ContactExchangeSucceededEvent;
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
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.util.LogUtils.logException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ContactExchangeViewModel extends AndroidViewModel
|
class ContactExchangeViewModel extends AndroidViewModel {
|
||||||
implements EventListener {
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(ContactExchangeViewModel.class.getName());
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final ContactExchangeManager contactExchangeManager;
|
private final ContactExchangeManager contactExchangeManager;
|
||||||
private final EventBus eventBus;
|
|
||||||
private final MutableLiveData<Boolean> succeeded = new MutableLiveData<>();
|
private final MutableLiveData<Boolean> succeeded = new MutableLiveData<>();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Author remoteAuthor, duplicateAuthor;
|
private volatile Author remoteAuthor, duplicateAuthor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ContactExchangeViewModel(Application app, @IoExecutor Executor ioExecutor,
|
ContactExchangeViewModel(Application app, @IoExecutor Executor ioExecutor,
|
||||||
ContactExchangeManager contactExchangeManager, EventBus eventBus) {
|
ContactExchangeManager contactExchangeManager) {
|
||||||
super(app);
|
super(app);
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.contactExchangeManager = contactExchangeManager;
|
this.contactExchangeManager = contactExchangeManager;
|
||||||
this.eventBus = eventBus;
|
|
||||||
eventBus.addListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCleared() {
|
|
||||||
super.onCleared();
|
|
||||||
eventBus.removeListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void startContactExchange(TransportId t, DuplexTransportConnection conn,
|
void startContactExchange(TransportId t, DuplexTransportConnection conn,
|
||||||
SecretKey masterKey, boolean alice) {
|
SecretKey masterKey, boolean alice) {
|
||||||
ioExecutor.execute(() -> contactExchangeManager.exchangeContacts(t,
|
ioExecutor.execute(() -> {
|
||||||
conn, masterKey, alice));
|
try {
|
||||||
|
remoteAuthor = contactExchangeManager.exchangeContacts(t, conn,
|
||||||
|
masterKey, alice);
|
||||||
|
succeeded.postValue(true);
|
||||||
|
} catch (ContactExistsException e) {
|
||||||
|
duplicateAuthor = e.getRemoteAuthor();
|
||||||
|
succeeded.postValue(false);
|
||||||
|
} catch (DbException | IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
succeeded.postValue(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@@ -76,18 +81,4 @@ class ContactExchangeViewModel extends AndroidViewModel
|
|||||||
LiveData<Boolean> getSucceeded() {
|
LiveData<Boolean> getSucceeded() {
|
||||||
return succeeded;
|
return succeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
|
||||||
if (e instanceof ContactExchangeSucceededEvent) {
|
|
||||||
ContactExchangeSucceededEvent c = (ContactExchangeSucceededEvent) e;
|
|
||||||
remoteAuthor = c.getRemoteAuthor();
|
|
||||||
succeeded.setValue(true);
|
|
||||||
} else if (e instanceof ContactExchangeFailedEvent) {
|
|
||||||
ContactExchangeFailedEvent c = (ContactExchangeFailedEvent) e;
|
|
||||||
if (c.wasDuplicateContact())
|
|
||||||
duplicateAuthor = requireNonNull(c.getDuplicateRemoteAuthor());
|
|
||||||
succeeded.setValue(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user