From 9ddec991ed38a7e623fc787c55707738dadfd7d6 Mon Sep 17 00:00:00 2001
From: Ben <ben@unknown4cedfb3732c9.localdomain>
Date: Wed, 4 Jul 2018 13:53:04 +0200
Subject: [PATCH] Refactor Mailbox Exchange task (merge into
 ContactExchangeTask to avoid redundancy)

---
 .../api/contact/ContactExchangeTask.java      |   5 -
 .../api/contact/MailboxExchangeTask.java      |   8 -
 .../contact/ContactExchangeTaskImpl.java      |  81 ++++-
 .../bramble/contact/ContactModule.java        |   7 -
 .../contact/MailboxExchangeTaskImpl.java      | 332 ------------------
 .../briar/android/AndroidComponent.java       |   3 -
 .../keyagreement/MailboxExchangeActivity.java |   4 +-
 7 files changed, 72 insertions(+), 368 deletions(-)
 delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/contact/MailboxExchangeTask.java
 delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/contact/MailboxExchangeTaskImpl.java

diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactExchangeTask.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactExchangeTask.java
index ab9daacc9..6e8dbd8cf 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactExchangeTask.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactExchangeTask.java
@@ -16,11 +16,6 @@ import java.util.Map;
 @NotNullByDefault
 public interface ContactExchangeTask {
 
-	/**
-	 * The current version of the contact exchange protocol.
-	 */
-	byte PROTOCOL_VERSION = 1;
-
 	/**
 	 * Label for deriving Alice's header key from the master secret.
 	 */
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/MailboxExchangeTask.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/MailboxExchangeTask.java
deleted file mode 100644
index 7d7f60b9b..000000000
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/MailboxExchangeTask.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.briarproject.bramble.api.contact;
-
-public interface MailboxExchangeTask extends ContactExchangeTask {
-		/**
-		 * The current version of the contact exchange protocol.
-		 */
-		byte PROTOCOL_VERSION = 2;
-}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java
index 16bdc9ec5..784e27968 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java
@@ -43,8 +43,13 @@ import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
+
 import static java.util.logging.Level.WARNING;
+import static org.briarproject.bramble.api.contact.ContactTypes.CONTACT;
+import static org.briarproject.bramble.api.contact.ContactTypes.MAILBOX_OWNER;
+import static org.briarproject.bramble.api.contact.ContactTypes.PRIVATE_MAILBOX;
 import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
+import static org.briarproject.bramble.api.contact.RecordTypes.MAILBOX_INFO;
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
 import static org.briarproject.bramble.util.LogUtils.logException;
 import static org.briarproject.bramble.util.ValidationUtils.checkLength;
@@ -60,6 +65,14 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 	private static final String SIGNING_LABEL_EXCHANGE =
 			"org.briarproject.briar.contact/EXCHANGE";
 
+	/**
+	 * The version of the contact exchange protocol. Note: For backwards compatibility,
+	 * the normal contact exchange is version 1, and 2 for Mailbox related exchanges
+	 * Version 2 introduces a new field to the record, which indicates the contact type
+	 */
+	byte PROTOCOL_VERSION;
+	byte RECORD_TYPE;
+
 	private final DatabaseComponent db;
 	private final ClientHelper clientHelper;
 	private final RecordReaderFactory recordReaderFactory;
@@ -106,6 +119,15 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 			LocalAuthor localAuthor, SecretKey masterSecret,
 			DuplexTransportConnection conn, TransportId transportId,
 			boolean alice, int localType, int remoteType) {
+
+		if (remoteType == CONTACT) {
+			PROTOCOL_VERSION = 1;
+			RECORD_TYPE = CONTACT_INFO;
+		} else {
+			PROTOCOL_VERSION = 2;
+			RECORD_TYPE = MAILBOX_INFO;
+		}
+
 		this.listener = listener;
 		this.localAuthor = localAuthor;
 		this.conn = conn;
@@ -161,7 +183,8 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 				streamWriterFactory.createContactExchangeStreamWriter(out,
 						alice ? aliceHeaderKey : bobHeaderKey);
 		RecordWriter recordWriter =
-				recordWriterFactory.createRecordWriter(streamWriter.getOutputStream());
+				recordWriterFactory
+						.createRecordWriter(streamWriter.getOutputStream());
 
 		// Derive the nonces to be signed
 		byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret,
@@ -259,8 +282,13 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 			long timestamp) throws IOException {
 		BdfList authorList = clientHelper.toList(author);
 		BdfDictionary props = clientHelper.toDictionary(properties);
-		BdfList payload = BdfList.of(authorList, props, signature, timestamp);
-		recordWriter.writeRecord(new Record(PROTOCOL_VERSION, CONTACT_INFO,
+		BdfList payload;
+		if (PROTOCOL_VERSION >= 2){
+			payload = BdfList.of(authorList, props, signature, timestamp, localType);
+		} else {
+			payload = BdfList.of(authorList, props, signature, timestamp);
+		}
+		recordWriter.writeRecord(new Record(PROTOCOL_VERSION, RECORD_TYPE,
 				clientHelper.toByteArray(payload)));
 		LOG.info("Sent contact info");
 	}
@@ -272,10 +300,14 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 			record = recordReader.readRecord();
 			if (record.getProtocolVersion() != PROTOCOL_VERSION)
 				throw new FormatException();
-		} while (record.getRecordType() != CONTACT_INFO);
+		} while (record.getRecordType() != RECORD_TYPE);
 		LOG.info("Received contact info");
 		BdfList payload = clientHelper.toList(record.getPayload());
-		checkSize(payload, 4);
+		if (PROTOCOL_VERSION >= 2) {
+			checkSize(payload, 5);
+		} else {
+			checkSize(payload, 4);
+		}
 		Author author = clientHelper.parseAndValidateAuthor(payload.getList(0));
 		BdfDictionary props = payload.getDictionary(1);
 		Map<TransportId, TransportProperties> properties =
@@ -284,7 +316,13 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 		checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
 		long timestamp = payload.getLong(3);
 		if (timestamp < 0) throw new FormatException();
-		return new ContactInfo(author, properties, signature, timestamp, remoteType);
+		if (PROTOCOL_VERSION >= 2){
+			int type = payload.getLong(4).intValue();
+			if(type != remoteType)
+				throw new AssertionError();
+		}
+		return new ContactInfo(author, properties, signature, timestamp,
+				remoteType);
 	}
 
 	private ContactId addContact(Author remoteAuthor, long timestamp,
@@ -293,11 +331,32 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 		ContactId contactId;
 		Transaction txn = db.startTransaction(false);
 		try {
-			contactId = contactManager.addContact(txn, remoteAuthor,
-					localAuthor.getId(), masterSecret, timestamp, alice,
-					true, true);
-			transportPropertyManager.addRemoteProperties(txn, contactId,
-					remoteProperties);
+			switch (remoteType) {
+				case CONTACT:
+					contactId = contactManager.addContact(txn, remoteAuthor,
+							localAuthor.getId(), masterSecret, timestamp, alice,
+							true, true);
+					transportPropertyManager.addRemoteProperties(txn, contactId,
+							remoteProperties);
+					break;
+				case MAILBOX_OWNER:
+					contactId =
+							contactManager.addMailboxOwner(txn, remoteAuthor,
+									localAuthor.getId(), masterSecret,
+									timestamp, alice);
+					break;
+				case PRIVATE_MAILBOX:
+					contactId =
+							contactManager.addPrivateMailbox(txn, remoteAuthor,
+									localAuthor.getId(), masterSecret,
+									timestamp, alice);
+					transportPropertyManager.addRemoteProperties(txn, contactId,
+							remoteProperties);
+					break;
+				default:
+					throw new RuntimeException("Invalid remote contact type");
+			}
+
 			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactModule.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactModule.java
index 3599ade1c..2cb610972 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactModule.java
@@ -2,7 +2,6 @@ package org.briarproject.bramble.contact;
 
 import org.briarproject.bramble.api.contact.ContactExchangeTask;
 import org.briarproject.bramble.api.contact.ContactManager;
-import org.briarproject.bramble.api.contact.MailboxExchangeTask;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -29,10 +28,4 @@ public class ContactModule {
 			ContactExchangeTaskImpl contactExchangeTask) {
 		return contactExchangeTask;
 	}
-
-	@Provides
-	MailboxExchangeTask provideMailboxExchangeTask(
-			MailboxExchangeTaskImpl mailboxExchangeTask) {
-		return mailboxExchangeTask;
-	}
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/MailboxExchangeTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/MailboxExchangeTaskImpl.java
deleted file mode 100644
index 7d09cb6e6..000000000
--- a/bramble-core/src/main/java/org/briarproject/bramble/contact/MailboxExchangeTaskImpl.java
+++ /dev/null
@@ -1,332 +0,0 @@
-package org.briarproject.bramble.contact;
-
-import org.briarproject.bramble.api.FormatException;
-import org.briarproject.bramble.api.client.ClientHelper;
-import org.briarproject.bramble.api.contact.ContactExchangeListener;
-import org.briarproject.bramble.api.contact.ContactId;
-import org.briarproject.bramble.api.contact.ContactManager;
-import org.briarproject.bramble.api.contact.MailboxExchangeTask;
-import org.briarproject.bramble.api.crypto.CryptoComponent;
-import org.briarproject.bramble.api.crypto.SecretKey;
-import org.briarproject.bramble.api.data.BdfDictionary;
-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.DbException;
-import org.briarproject.bramble.api.db.Transaction;
-import org.briarproject.bramble.api.identity.Author;
-import org.briarproject.bramble.api.identity.LocalAuthor;
-import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
-import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
-import org.briarproject.bramble.api.plugin.ConnectionManager;
-import org.briarproject.bramble.api.plugin.TransportId;
-import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
-import org.briarproject.bramble.api.properties.TransportProperties;
-import org.briarproject.bramble.api.properties.TransportPropertyManager;
-import org.briarproject.bramble.api.record.Record;
-import org.briarproject.bramble.api.record.RecordReader;
-import org.briarproject.bramble.api.record.RecordReaderFactory;
-import org.briarproject.bramble.api.record.RecordWriter;
-import org.briarproject.bramble.api.record.RecordWriterFactory;
-import org.briarproject.bramble.api.system.Clock;
-import org.briarproject.bramble.api.transport.StreamReaderFactory;
-import org.briarproject.bramble.api.transport.StreamWriter;
-import org.briarproject.bramble.api.transport.StreamWriterFactory;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.GeneralSecurityException;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import javax.inject.Inject;
-
-import static java.util.logging.Level.WARNING;
-import static org.briarproject.bramble.api.contact.ContactTypes.MAILBOX_OWNER;
-import static org.briarproject.bramble.api.contact.RecordTypes.MAILBOX_INFO;
-import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
-import static org.briarproject.bramble.util.LogUtils.logException;
-import static org.briarproject.bramble.util.ValidationUtils.checkLength;
-import static org.briarproject.bramble.util.ValidationUtils.checkSize;
-
-@MethodsNotNullByDefault
-@ParametersNotNullByDefault
-class MailboxExchangeTaskImpl extends Thread implements MailboxExchangeTask {
-	private static final Logger LOG =
-			Logger.getLogger(MailboxExchangeTaskImpl.class.getName());
-
-	private static final String SIGNING_LABEL_EXCHANGE =
-			"org.briarproject.briar.contact/EXCHANGE";
-
-	private final DatabaseComponent db;
-	private final ClientHelper clientHelper;
-	private final RecordReaderFactory recordReaderFactory;
-	private final RecordWriterFactory recordWriterFactory;
-	private final Clock clock;
-	private final ConnectionManager connectionManager;
-	private final ContactManager contactManager;
-	private final TransportPropertyManager transportPropertyManager;
-	private final CryptoComponent crypto;
-	private final StreamReaderFactory streamReaderFactory;
-	private final StreamWriterFactory streamWriterFactory;
-
-	private volatile ContactExchangeListener listener;
-	private volatile LocalAuthor localAuthor;
-	private volatile DuplexTransportConnection conn;
-	private volatile TransportId transportId;
-	private volatile SecretKey masterSecret;
-	private volatile boolean alice;
-	private volatile int localType, remoteType;
-
-	@Inject
-	MailboxExchangeTaskImpl(DatabaseComponent db, ClientHelper clientHelper,
-			RecordReaderFactory recordReaderFactory,
-			RecordWriterFactory recordWriterFactory, Clock clock,
-			ConnectionManager connectionManager, ContactManager contactManager,
-			TransportPropertyManager transportPropertyManager,
-			CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
-			StreamWriterFactory streamWriterFactory) {
-		this.db = db;
-		this.clientHelper = clientHelper;
-		this.recordReaderFactory = recordReaderFactory;
-		this.recordWriterFactory = recordWriterFactory;
-		this.clock = clock;
-		this.connectionManager = connectionManager;
-		this.contactManager = contactManager;
-		this.transportPropertyManager = transportPropertyManager;
-		this.crypto = crypto;
-		this.streamReaderFactory = streamReaderFactory;
-		this.streamWriterFactory = streamWriterFactory;
-	}
-
-	@Override
-	public void startExchange(ContactExchangeListener listener,
-			LocalAuthor localAuthor, SecretKey masterSecret,
-			DuplexTransportConnection conn, TransportId transportId,
-			boolean alice, int localType, int remoteType) {
-		this.listener = listener;
-		this.localAuthor = localAuthor;
-		this.conn = conn;
-		this.transportId = transportId;
-		this.masterSecret = masterSecret;
-		this.alice = alice;
-		this.localType = localType;
-		this.remoteType = remoteType;
-		start();
-
-	}
-
-	@Override
-	public void run() {
-		// Get the transport connection's input and output streams
-		InputStream in;
-		OutputStream out;
-		try {
-			in = conn.getReader().getInputStream();
-			out = conn.getWriter().getOutputStream();
-		} catch (IOException e) {
-			logException(LOG, WARNING, e);
-			listener.contactExchangeFailed();
-			tryToClose(conn);
-			return;
-		}
-
-		// Get the local transport properties
-		Map<TransportId, TransportProperties> localProperties;
-		try {
-			localProperties = transportPropertyManager.getLocalProperties();
-		} catch (DbException e) {
-			logException(LOG, WARNING, e);
-			listener.contactExchangeFailed();
-			tryToClose(conn);
-			return;
-		}
-
-		// Derive the header keys for the transport streams
-		SecretKey aliceHeaderKey = crypto.deriveKey(ALICE_KEY_LABEL,
-				masterSecret, new byte[] {PROTOCOL_VERSION});
-		SecretKey bobHeaderKey = crypto.deriveKey(BOB_KEY_LABEL, masterSecret,
-				new byte[] {PROTOCOL_VERSION});
-
-		// Create the readers
-		InputStream streamReader =
-				streamReaderFactory.createContactExchangeStreamReader(in,
-						alice ? bobHeaderKey : aliceHeaderKey);
-		RecordReader recordReader =
-				recordReaderFactory.createRecordReader(streamReader);
-
-		// Create the writers
-		StreamWriter streamWriter =
-				streamWriterFactory.createContactExchangeStreamWriter(out,
-						alice ? aliceHeaderKey : bobHeaderKey);
-		RecordWriter recordWriter =
-				recordWriterFactory
-						.createRecordWriter(streamWriter.getOutputStream());
-
-		// Derive the nonces to be signed
-		byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret,
-				new byte[] {PROTOCOL_VERSION});
-		byte[] bobNonce = crypto.mac(BOB_NONCE_LABEL, masterSecret,
-				new byte[] {PROTOCOL_VERSION});
-		byte[] localNonce = alice ? aliceNonce : bobNonce;
-		byte[] remoteNonce = alice ? bobNonce : aliceNonce;
-
-		// Sign the nonce
-		byte[] localSignature = sign(localAuthor, localNonce);
-
-		// Exchange contact info
-		long localTimestamp = clock.currentTimeMillis();
-		ContactInfo remoteInfo;
-		try {
-			if (alice) {
-				sendContactInfo(recordWriter, localAuthor, localProperties,
-						localSignature, localTimestamp);
-				recordWriter.flush();
-				remoteInfo = receiveContactInfo(recordReader);
-			} else {
-				remoteInfo = receiveContactInfo(recordReader);
-				sendContactInfo(recordWriter, localAuthor, localProperties,
-						localSignature, localTimestamp);
-				recordWriter.flush();
-			}
-			// Send EOF on the outgoing stream
-			streamWriter.sendEndOfStream();
-			// Skip any remaining records from the incoming stream
-			try {
-				while (true) recordReader.readRecord();
-			} catch (EOFException expected) {
-				LOG.info("End of stream");
-			}
-		} catch (IOException e) {
-			logException(LOG, WARNING, e);
-			listener.contactExchangeFailed();
-			tryToClose(conn);
-			return;
-		}
-
-		// Verify the contact's signature
-		if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
-			LOG.warning("Invalid signature");
-			listener.contactExchangeFailed();
-			tryToClose(conn);
-			return;
-		}
-
-		// The agreed timestamp is the minimum of the peers' timestamps
-		long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
-
-		try {
-			ContactId contactId;
-			// Add the Contact/Repeater
-			contactId = addContact(remoteInfo.author, timestamp,
-					remoteInfo.properties);
-
-			// Reuse the connection as a transport connection
-			connectionManager.manageOutgoingConnection(contactId, transportId,
-					conn);
-			// Pseudonym exchange succeeded
-			LOG.info("Pseudonym exchange succeeded");
-			listener.contactExchangeSucceeded(remoteInfo.author);
-		} catch (ContactExistsException e) {
-			logException(LOG, WARNING, e);
-			tryToClose(conn);
-			listener.duplicateContact(remoteInfo.author);
-		} catch (DbException e) {
-			logException(LOG, WARNING, e);
-			tryToClose(conn);
-			listener.contactExchangeFailed();
-		}
-	}
-
-	private byte[] sign(LocalAuthor author, byte[] nonce) {
-		try {
-			return crypto.sign(SIGNING_LABEL_EXCHANGE, nonce,
-					author.getPrivateKey());
-		} catch (GeneralSecurityException e) {
-			throw new AssertionError();
-		}
-	}
-
-	private boolean verify(Author author, byte[] nonce, byte[] signature) {
-		try {
-			return crypto.verifySignature(signature, SIGNING_LABEL_EXCHANGE,
-					nonce, author.getPublicKey());
-		} catch (GeneralSecurityException e) {
-			return false;
-		}
-	}
-
-	private void sendContactInfo(RecordWriter recordWriter, Author author,
-			Map<TransportId, TransportProperties> properties, byte[] signature,
-			long timestamp) throws IOException {
-		BdfList authorList = clientHelper.toList(author);
-		BdfDictionary props = clientHelper.toDictionary(properties);
-		BdfList payload = BdfList.of(authorList, props, signature, timestamp, localType);
-		recordWriter.writeRecord(new Record(PROTOCOL_VERSION, MAILBOX_INFO,
-				clientHelper.toByteArray(payload)));
-		LOG.info("Sent repeater info");
-	}
-
-	private ContactInfo receiveContactInfo(RecordReader recordReader)
-			throws IOException {
-		Record record;
-		do {
-			record = recordReader.readRecord();
-			if (record.getProtocolVersion() != PROTOCOL_VERSION)
-				throw new FormatException();
-		} while (record.getRecordType() != MAILBOX_INFO);
-		LOG.info("Received contact info");
-		BdfList payload = clientHelper.toList(record.getPayload());
-		checkSize(payload, 5);
-		Author author = clientHelper.parseAndValidateAuthor(payload.getList(0));
-		BdfDictionary props = payload.getDictionary(1);
-		Map<TransportId, TransportProperties> properties =
-				clientHelper.parseAndValidateTransportPropertiesMap(props);
-		byte[] signature = payload.getRaw(2);
-		checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
-		long timestamp = payload.getLong(3);
-		if (timestamp < 0) throw new FormatException();
-		int type = payload.getLong(4).intValue();
-		if(type != remoteType)
-			throw new AssertionError();
-		return new ContactInfo(author, properties, signature, timestamp, type);
-	}
-
-	private ContactId addContact(Author remoteAuthor, long timestamp,
-			Map<TransportId, TransportProperties> remoteProperties)
-			throws DbException {
-		ContactId contactId;
-		Transaction txn = db.startTransaction(false);
-		try {
-			if (remoteType == MAILBOX_OWNER) {
-				contactId = contactManager.addMailboxOwner(txn, remoteAuthor,
-						localAuthor.getId(), masterSecret, timestamp, alice);
-				//TODO: Do we need transport properties here? (Repeater will not contact the Owner)
-			} else {
-				contactId = contactManager.addPrivateMailbox(txn, remoteAuthor,
-						localAuthor.getId(), masterSecret, timestamp, alice);
-				transportPropertyManager.addRemoteProperties(txn, contactId,
-						remoteProperties);
-			}
-
-			db.commitTransaction(txn);
-		} finally {
-			db.endTransaction(txn);
-		}
-		return contactId;
-	}
-
-	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);
-		}
-	}
-
-
-}
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 9c140a021..778a6f2b9 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
@@ -7,7 +7,6 @@ import org.briarproject.bramble.BrambleCoreEagerSingletons;
 import org.briarproject.bramble.BrambleCoreModule;
 import org.briarproject.bramble.api.contact.ContactExchangeTask;
 import org.briarproject.bramble.api.contact.ContactManager;
-import org.briarproject.bramble.api.contact.MailboxExchangeTask;
 import org.briarproject.bramble.api.crypto.CryptoComponent;
 import org.briarproject.bramble.api.crypto.CryptoExecutor;
 import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
@@ -130,8 +129,6 @@ public interface AndroidComponent
 
 	ContactExchangeTask contactExchangeTask();
 
-	MailboxExchangeTask mailboxExchangeTask();
-
 	KeyAgreementTask keyAgreementTask();
 
 	PayloadEncoder payloadEncoder();
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/MailboxExchangeActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/MailboxExchangeActivity.java
index f2764266a..b3f39a560 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/MailboxExchangeActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/MailboxExchangeActivity.java
@@ -5,7 +5,7 @@ import android.support.annotation.UiThread;
 import android.widget.Toast;
 
 import org.briarproject.bramble.api.contact.ContactExchangeListener;
-import org.briarproject.bramble.api.contact.MailboxExchangeTask;
+import org.briarproject.bramble.api.contact.ContactExchangeTask;
 import org.briarproject.bramble.api.db.DbException;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.IdentityManager;
@@ -33,7 +33,7 @@ public class MailboxExchangeActivity extends KeyAgreementActivity implements
 			Logger.getLogger(MailboxExchangeActivity.class.getName());
 
 	@Inject
-	volatile MailboxExchangeTask mailboxExchangeTask;
+	volatile ContactExchangeTask mailboxExchangeTask;
 	@Inject
 	volatile IdentityManager identityManager;
 
-- 
GitLab