Disable polling while doing connect-via-BT

This commit is contained in:
Daniel Lublin
2021-05-04 16:45:06 +02:00
parent c647c52638
commit fba028db03
6 changed files with 73 additions and 45 deletions

View File

@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.keyagreement.event;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
/** /**
* An event that is broadcast when a BQP protocol completes. * An event that is broadcast when a BQP protocol begins.
*/ */
public class KeyAgreementStartedEvent extends Event { public class KeyAgreementStartedEvent extends Event {
} }

View File

@@ -473,6 +473,16 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
return discoverSemaphore.availablePermits() == 0; return discoverSemaphore.availablePermits() == 0;
} }
@Override
public void disablePolling() {
connectionLimiter.startLimiting();
}
@Override
public void enablePolling() {
connectionLimiter.endLimiting();
}
@Override @Override
public DuplexTransportConnection discoverAndConnectForSetup(String uuid) { public DuplexTransportConnection discoverAndConnectForSetup(String uuid) {
DuplexTransportConnection conn = discoverAndConnect(uuid); DuplexTransportConnection conn = discoverAndConnect(uuid);
@@ -501,9 +511,9 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
if (s.getNamespace().equals(ID.getString())) if (s.getNamespace().equals(ID.getString()))
ioExecutor.execute(() -> onSettingsUpdated(s.getSettings())); ioExecutor.execute(() -> onSettingsUpdated(s.getSettings()));
} else if (e instanceof KeyAgreementListeningEvent) { } else if (e instanceof KeyAgreementListeningEvent) {
ioExecutor.execute(connectionLimiter::keyAgreementStarted); connectionLimiter.startLimiting();
} else if (e instanceof KeyAgreementStoppedListeningEvent) { } else if (e instanceof KeyAgreementStoppedListeningEvent) {
ioExecutor.execute(connectionLimiter::keyAgreementEnded); connectionLimiter.endLimiting();
} else if (e instanceof RemoteTransportPropertiesUpdatedEvent) { } else if (e instanceof RemoteTransportPropertiesUpdatedEvent) {
RemoteTransportPropertiesUpdatedEvent r = RemoteTransportPropertiesUpdatedEvent r =
(RemoteTransportPropertiesUpdatedEvent) e; (RemoteTransportPropertiesUpdatedEvent) e;

View File

@@ -7,14 +7,15 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
interface BluetoothConnectionLimiter { interface BluetoothConnectionLimiter {
/** /**
* Informs the limiter that key agreement has started. * Tells the limiter to not allow regular polling connections (because we
* are about to do key agreement, or connect via BT for setup).
*/ */
void keyAgreementStarted(); void startLimiting();
/** /**
* Informs the limiter that key agreement has ended. * Tells the limiter to no longer limit regular polling connections.
*/ */
void keyAgreementEnded(); void endLimiting();
/** /**
* Returns true if a contact connection can be opened. This method does not * Returns true if a contact connection can be opened. This method does not

View File

@@ -30,34 +30,37 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
private final List<DuplexTransportConnection> connections = private final List<DuplexTransportConnection> connections =
new LinkedList<>(); new LinkedList<>();
@GuardedBy("lock") @GuardedBy("lock")
private boolean keyAgreementInProgress = false; private int limitingInProgress = 0;
BluetoothConnectionLimiterImpl(EventBus eventBus) { BluetoothConnectionLimiterImpl(EventBus eventBus) {
this.eventBus = eventBus; this.eventBus = eventBus;
} }
@Override @Override
public void keyAgreementStarted() { public void startLimiting() {
synchronized (lock) { synchronized (lock) {
keyAgreementInProgress = true; limitingInProgress++;
} }
LOG.info("Key agreement started"); LOG.info("Limiting started");
eventBus.broadcast(new CloseSyncConnectionsEvent(ID)); eventBus.broadcast(new CloseSyncConnectionsEvent(ID));
} }
@Override @Override
public void keyAgreementEnded() { public void endLimiting() {
synchronized (lock) { synchronized (lock) {
keyAgreementInProgress = false; limitingInProgress--;
if (limitingInProgress < 0) {
throw new IllegalStateException();
}
} }
LOG.info("Key agreement ended"); LOG.info("Limiting ended");
} }
@Override @Override
public boolean canOpenContactConnection() { public boolean canOpenContactConnection() {
synchronized (lock) { synchronized (lock) {
if (keyAgreementInProgress) { if (limitingInProgress > 0) {
LOG.info("Can't open contact connection during key agreement"); LOG.info("Can't open contact connection while limiting");
return false; return false;
} else { } else {
LOG.info("Can open contact connection"); LOG.info("Can open contact connection");

View File

@@ -11,6 +11,10 @@ public interface BluetoothPlugin extends DuplexPlugin {
boolean isDiscovering(); boolean isDiscovering();
void disablePolling();
void enablePolling();
@Nullable @Nullable
DuplexTransportConnection discoverAndConnectForSetup(String uuid); DuplexTransportConnection discoverAndConnectForSetup(String uuid);

View File

@@ -176,6 +176,7 @@ class BluetoothConnecter implements EventListener {
connect(); connect();
} }
@UiThread
@Override @Override
public void eventOccurred(@NonNull Event e) { public void eventOccurred(@NonNull Event e) {
if (e instanceof ConnectionOpenedEvent) { if (e instanceof ConnectionOpenedEvent) {
@@ -192,43 +193,52 @@ class BluetoothConnecter implements EventListener {
} }
private void connect() { private void connect() {
bluetoothPlugin.disablePolling();
pluginManager.setPluginEnabled(ID, true); pluginManager.setPluginEnabled(ID, true);
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
if (!waitForBluetoothActive()) {
showToast(R.string.bt_plugin_status_inactive);
LOG.warning("Bluetooth plugin didn't become active");
return;
}
showToast(R.string.toast_connect_via_bluetooth_start);
eventBus.addListener(this);
try { try {
String uuid = null; if (!waitForBluetoothActive()) {
showToast(R.string.bt_plugin_status_inactive);
LOG.warning("Bluetooth plugin didn't become active");
return;
}
showToast(R.string.toast_connect_via_bluetooth_start);
eventBus.addListener(this);
try { try {
uuid = transportPropertyManager String uuid = null;
.getRemoteProperties(contactId, ID).get(PROP_UUID); try {
} catch (DbException e) { uuid = transportPropertyManager
logException(LOG, WARNING, e); .getRemoteProperties(contactId, ID)
} .get(PROP_UUID);
if (isNullOrEmpty(uuid)) { } catch (DbException e) {
LOG.warning("PROP_UUID missing for contact"); logException(LOG, WARNING, e);
return;
}
DuplexTransportConnection conn = bluetoothPlugin
.discoverAndConnectForSetup(uuid);
if (conn == null) {
if (!isConnectedViaBluetooth(contactId)) {
LOG.warning("Failed to connect");
showToast(R.string.toast_connect_via_bluetooth_error);
} else {
LOG.info("Failed to connect, but contact connected");
} }
return; if (isNullOrEmpty(uuid)) {
LOG.warning("PROP_UUID missing for contact");
return;
}
DuplexTransportConnection conn = bluetoothPlugin
.discoverAndConnectForSetup(uuid);
if (conn == null) {
if (!isConnectedViaBluetooth(contactId)) {
LOG.warning("Failed to connect");
showToast(
R.string.toast_connect_via_bluetooth_error);
} else {
LOG.info(
"Failed to connect, but contact connected");
}
return;
}
connectionManager
.manageOutgoingConnection(contactId, ID, conn);
showToast(R.string.toast_connect_via_bluetooth_success);
} finally {
eventBus.removeListener(this);
} }
connectionManager.manageOutgoingConnection(contactId, ID, conn);
showToast(R.string.toast_connect_via_bluetooth_success);
} finally { } finally {
eventBus.removeListener(this); bluetoothPlugin.enablePolling();
} }
}); });
} }