mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Provide earlier feedback in the UI when connecting to a new contact.
Partially addresses issue #3611924.
This commit is contained in:
@@ -57,7 +57,7 @@ implements InvitationListener {
|
||||
private BluetoothWifiStateReceiver receiver = null;
|
||||
private int localInvitationCode = -1, remoteInvitationCode = -1;
|
||||
private int localConfirmationCode = -1, remoteConfirmationCode = -1;
|
||||
private boolean connectionFailed = false;
|
||||
private boolean connected = false, connectionFailed = false;
|
||||
private boolean localCompared = false, remoteCompared = false;
|
||||
private boolean localMatched = false, remoteMatched = false;
|
||||
private String contactName = null;
|
||||
@@ -109,6 +109,7 @@ implements InvitationListener {
|
||||
remoteInvitationCode = s.getRemoteInvitationCode();
|
||||
localConfirmationCode = s.getLocalConfirmationCode();
|
||||
remoteConfirmationCode = s.getRemoteConfirmationCode();
|
||||
connected = s.getConnected();
|
||||
connectionFailed = s.getConnectionFailed();
|
||||
localCompared = s.getLocalCompared();
|
||||
remoteCompared = s.getRemoteCompared();
|
||||
@@ -120,10 +121,12 @@ implements InvitationListener {
|
||||
setView(new NetworkSetupView(this));
|
||||
} else if(remoteInvitationCode == -1) {
|
||||
setView(new InvitationCodeView(this));
|
||||
} else if(localConfirmationCode == -1) {
|
||||
setView(new ConnectionView(this));
|
||||
} else if(connectionFailed) {
|
||||
setView(new ConnectionFailedView(this));
|
||||
} else if(connected && localConfirmationCode == -1) {
|
||||
setView(new ConnectedView(this));
|
||||
} else if(localConfirmationCode == -1) {
|
||||
setView(new ConnectionView(this));
|
||||
} else if(!localCompared) {
|
||||
setView(new ConfirmationCodeView(this));
|
||||
} else if(!remoteCompared) {
|
||||
@@ -296,7 +299,26 @@ implements InvitationListener {
|
||||
return contactName;
|
||||
}
|
||||
|
||||
public void connectionSucceeded(final int localCode, final int remoteCode) {
|
||||
public void connectionSucceeded() {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
connected = true;
|
||||
setView(new ConnectedView(AddContactActivity.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void connectionFailed() {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
connectionFailed = true;
|
||||
setView(new ConnectionFailedView(AddContactActivity.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void keyAgreementSucceeded(final int localCode,
|
||||
final int remoteCode) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
localConfirmationCode = localCode;
|
||||
@@ -306,7 +328,7 @@ implements InvitationListener {
|
||||
});
|
||||
}
|
||||
|
||||
public void connectionFailed() {
|
||||
public void keyAgreementFailed() {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
connectionFailed = true;
|
||||
@@ -390,14 +412,22 @@ implements InvitationListener {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public void connectionSucceeded(int localCode, int remoteCode) {
|
||||
// Wait for remote confirmation to succeed or fail
|
||||
public void connectionSucceeded() {
|
||||
// Wait for key agreement to succeed or fail
|
||||
}
|
||||
|
||||
public void connectionFailed() {
|
||||
referenceManager.removeReference(handle, InvitationTask.class);
|
||||
}
|
||||
|
||||
public void keyAgreementSucceeded(int localCode, int remoteCode) {
|
||||
// Wait for remote confirmation to succeed or fail
|
||||
}
|
||||
|
||||
public void keyAgreementFailed() {
|
||||
referenceManager.removeReference(handle, InvitationTask.class);
|
||||
}
|
||||
|
||||
public void remoteConfirmationSucceeded() {
|
||||
// Wait for the pseudonym exchange to succeed or fail
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class ConnectedView extends AddContactView {
|
||||
|
||||
ConnectedView(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
void populate() {
|
||||
removeAllViews();
|
||||
Context ctx = getContext();
|
||||
LinearLayout innerLayout = new LinearLayout(ctx);
|
||||
innerLayout.setOrientation(HORIZONTAL);
|
||||
innerLayout.setGravity(CENTER);
|
||||
|
||||
ImageView icon = new ImageView(ctx);
|
||||
icon.setImageResource(R.drawable.navigation_accept);
|
||||
innerLayout.addView(icon);
|
||||
|
||||
TextView connected = new TextView(ctx);
|
||||
connected.setTextSize(22);
|
||||
connected.setPadding(10, 10, 10, 10);
|
||||
connected.setText(R.string.connected_to_contact);
|
||||
innerLayout.addView(connected);
|
||||
addView(innerLayout);
|
||||
}
|
||||
}
|
||||
@@ -6,38 +6,42 @@ package net.sf.briar.api.invitation;
|
||||
*/
|
||||
public interface InvitationListener {
|
||||
|
||||
/** Called if a connection is established and key agreement succeeds. */
|
||||
void connectionSucceeded(int localCode, int remoteCode);
|
||||
/** Called if a connection to the remote peer is established. */
|
||||
void connectionSucceeded();
|
||||
|
||||
/**
|
||||
* Called if a connection cannot be established. This indicates that the
|
||||
* protocol has ended unsuccessfully.
|
||||
* Called if a connection to the remote peer cannot be established. This
|
||||
* indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void connectionFailed();
|
||||
|
||||
/** Called if key agreement with the remote peer succeeds. */
|
||||
void keyAgreementSucceeded(int localCode, int remoteCode);
|
||||
|
||||
/**
|
||||
* Informs the local peer that the remote peer's confirmation check
|
||||
* succeeded.
|
||||
* Called if key agreement with the remote peer fails or the connection is
|
||||
* lost. This indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void keyAgreementFailed();
|
||||
|
||||
/** Called if the remote peer's confirmation check succeeds. */
|
||||
void remoteConfirmationSucceeded();
|
||||
|
||||
/**
|
||||
* Informs the local peer that the remote peer's confirmation check did
|
||||
* not succeed, or the connection was lost during confirmation. This
|
||||
* indicates that the protocol has ended unsuccessfully.
|
||||
* Called if remote peer's confirmation check fails or the connection is
|
||||
* lost. This indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void remoteConfirmationFailed();
|
||||
|
||||
/**
|
||||
* Informs the local peer of the name used by the remote peer. Called if
|
||||
* the exchange of pseudonyms succeeds. This indicates that the protocol
|
||||
* has ended successfully.
|
||||
* Called if the exchange of pseudonyms succeeds. This indicates that the
|
||||
* protocol has ended successfully.
|
||||
*/
|
||||
void pseudonymExchangeSucceeded(String remoteName);
|
||||
|
||||
/**
|
||||
* Called if the exchange of pseudonyms fails. This indicates that the
|
||||
* protocol has ended unsuccessfully.
|
||||
* Called if the exchange of pseudonyms fails or the connection is lost.
|
||||
* This indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void pseudonymExchangeFailed();
|
||||
}
|
||||
|
||||
@@ -4,20 +4,21 @@ public class InvitationState {
|
||||
|
||||
private final int localInvitationCode, remoteInvitationCode;
|
||||
private final int localConfirmationCode, remoteConfirmationCode;
|
||||
private final boolean connectionFailed;
|
||||
private final boolean connected, connectionFailed;
|
||||
private final boolean localCompared, remoteCompared;
|
||||
private final boolean localMatched, remoteMatched;
|
||||
private final String contactName;
|
||||
|
||||
public InvitationState(int localInvitationCode, int remoteInvitationCode,
|
||||
int localConfirmationCode, int remoteConfirmationCode,
|
||||
boolean connectionFailed, boolean localCompared,
|
||||
boolean connected, boolean connectionFailed, boolean localCompared,
|
||||
boolean remoteCompared, boolean localMatched,
|
||||
boolean remoteMatched, String contactName) {
|
||||
this.localInvitationCode = localInvitationCode;
|
||||
this.remoteInvitationCode = remoteInvitationCode;
|
||||
this.localConfirmationCode = localConfirmationCode;
|
||||
this.remoteConfirmationCode = remoteConfirmationCode;
|
||||
this.connected = connected;
|
||||
this.connectionFailed = connectionFailed;
|
||||
this.localCompared = localCompared;
|
||||
this.remoteCompared = remoteCompared;
|
||||
@@ -42,6 +43,10 @@ public class InvitationState {
|
||||
return remoteConfirmationCode;
|
||||
}
|
||||
|
||||
public boolean getConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
public boolean getConnectionFailed() {
|
||||
return connectionFailed;
|
||||
}
|
||||
|
||||
@@ -91,10 +91,12 @@ class AliceConnector extends Connector {
|
||||
secret = deriveMasterSecret(hash, key, true);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +104,7 @@ class AliceConnector extends Connector {
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
|
||||
int[] codes = crypto.deriveConfirmationCodes(secret);
|
||||
int aliceCode = codes[0], bobCode = codes[1];
|
||||
group.connectionSucceeded(aliceCode, bobCode);
|
||||
group.keyAgreementSucceeded(aliceCode, bobCode);
|
||||
// Exchange confirmation results
|
||||
try {
|
||||
sendConfirmation(w);
|
||||
|
||||
@@ -91,10 +91,12 @@ class BobConnector extends Connector {
|
||||
secret = deriveMasterSecret(hash, key, false);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +104,7 @@ class BobConnector extends Connector {
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
|
||||
int[] codes = crypto.deriveConfirmationCodes(secret);
|
||||
int aliceCode = codes[0], bobCode = codes[1];
|
||||
group.connectionSucceeded(bobCode, aliceCode);
|
||||
group.keyAgreementSucceeded(bobCode, aliceCode);
|
||||
// Exchange confirmation results
|
||||
try {
|
||||
if(receiveConfirmation(r)) group.remoteConfirmationSucceeded();
|
||||
|
||||
@@ -101,7 +101,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
public synchronized InvitationState addListener(InvitationListener l) {
|
||||
listeners.add(l);
|
||||
return new InvitationState(localInvitationCode, remoteInvitationCode,
|
||||
localConfirmationCode, remoteConfirmationCode,
|
||||
localConfirmationCode, remoteConfirmationCode, connected.get(),
|
||||
connectionFailed, localCompared, remoteCompared, localMatched,
|
||||
remoteMatched, remoteName);
|
||||
}
|
||||
@@ -202,16 +202,24 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
}
|
||||
|
||||
boolean getAndSetConnected() {
|
||||
return connected.getAndSet(true);
|
||||
boolean redundant = connected.getAndSet(true);
|
||||
if(!redundant) {
|
||||
for(InvitationListener l : listeners) l.connectionSucceeded();
|
||||
}
|
||||
return redundant;
|
||||
}
|
||||
|
||||
void connectionSucceeded(int localCode, int remoteCode) {
|
||||
void keyAgreementSucceeded(int localCode, int remoteCode) {
|
||||
synchronized(this) {
|
||||
localConfirmationCode = localCode;
|
||||
remoteConfirmationCode = remoteCode;
|
||||
}
|
||||
for(InvitationListener l : listeners)
|
||||
l.connectionSucceeded(localCode, remoteCode);
|
||||
l.keyAgreementSucceeded(localCode, remoteCode);
|
||||
}
|
||||
|
||||
void keyAgreementFailed() {
|
||||
for(InvitationListener l : listeners) l.keyAgreementFailed();
|
||||
}
|
||||
|
||||
void remoteConfirmationSucceeded() {
|
||||
|
||||
Reference in New Issue
Block a user