mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 19:59:05 +01:00
Compare commits
2 Commits
sqlite-jdb
...
1712-motor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9e4ffa841 | ||
|
|
027329ddd6 |
@@ -24,6 +24,7 @@ import java.util.concurrent.Executor;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.os.Build.BRAND;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -81,8 +82,12 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
|
// On Motorola devices, don't try to open multiple connections - the
|
||||||
|
// Bluetooth stack can't handle it
|
||||||
|
// TODO: Narrow this down to specific models/versions if possible
|
||||||
|
boolean singleConnection = "motorola".equalsIgnoreCase(BRAND);
|
||||||
BluetoothConnectionLimiter connectionLimiter =
|
BluetoothConnectionLimiter connectionLimiter =
|
||||||
new BluetoothConnectionLimiterImpl(eventBus);
|
new BluetoothConnectionLimiterImpl(eventBus, singleConnection);
|
||||||
BluetoothConnectionFactory<BluetoothSocket> connectionFactory =
|
BluetoothConnectionFactory<BluetoothSocket> connectionFactory =
|
||||||
new AndroidBluetoothConnectionFactory(connectionLimiter,
|
new AndroidBluetoothConnectionFactory(connectionLimiter,
|
||||||
wakeLockManager, timeoutMonitor);
|
wakeLockManager, timeoutMonitor);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public abstract class AbstractDuplexTransportConnection
|
|||||||
private final Writer writer;
|
private final Writer writer;
|
||||||
private final AtomicBoolean halfClosed, closed;
|
private final AtomicBoolean halfClosed, closed;
|
||||||
|
|
||||||
|
private volatile boolean markedForClose = false;
|
||||||
|
|
||||||
protected AbstractDuplexTransportConnection(Plugin plugin) {
|
protected AbstractDuplexTransportConnection(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
reader = new Reader();
|
reader = new Reader();
|
||||||
@@ -52,6 +54,16 @@ public abstract class AbstractDuplexTransportConnection
|
|||||||
return remote;
|
return remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMarkedForClose() {
|
||||||
|
return markedForClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markForClose() {
|
||||||
|
markedForClose = true;
|
||||||
|
}
|
||||||
|
|
||||||
private class Reader implements TransportConnectionReader {
|
private class Reader implements TransportConnectionReader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.api.plugin.duplex;
|
package org.briarproject.bramble.api.plugin.duplex;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.plugin.ConnectionHandler;
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
@@ -30,4 +31,17 @@ public interface DuplexTransportConnection {
|
|||||||
* the remote peer.
|
* the remote peer.
|
||||||
*/
|
*/
|
||||||
TransportProperties getRemoteProperties();
|
TransportProperties getRemoteProperties();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the connection should be closed immediately without
|
||||||
|
* sending anything.
|
||||||
|
*/
|
||||||
|
boolean isMarkedForClose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this method before the connection is passed to its
|
||||||
|
* {@link ConnectionHandler} if the connection should be closed immediately
|
||||||
|
* without sending anything.
|
||||||
|
*/
|
||||||
|
void markForClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ abstract class DuplexSyncConnection extends SyncConnection
|
|||||||
|
|
||||||
final Executor ioExecutor;
|
final Executor ioExecutor;
|
||||||
final TransportId transportId;
|
final TransportId transportId;
|
||||||
|
final DuplexTransportConnection connection;
|
||||||
final TransportConnectionReader reader;
|
final TransportConnectionReader reader;
|
||||||
final TransportConnectionWriter writer;
|
final TransportConnectionWriter writer;
|
||||||
final TransportProperties remote;
|
final TransportProperties remote;
|
||||||
@@ -80,6 +81,7 @@ abstract class DuplexSyncConnection extends SyncConnection
|
|||||||
transportPropertyManager);
|
transportPropertyManager);
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.transportId = transportId;
|
this.transportId = transportId;
|
||||||
|
this.connection = connection;
|
||||||
reader = connection.getReader();
|
reader = connection.getReader();
|
||||||
writer = connection.getWriter();
|
writer = connection.getWriter();
|
||||||
remote = connection.getRemoteProperties();
|
remote = connection.getRemoteProperties();
|
||||||
@@ -96,6 +98,13 @@ abstract class DuplexSyncConnection extends SyncConnection
|
|||||||
disposeOnError(writer);
|
disposeOnError(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closeOutgoingStream(StreamContext ctx, TransportConnectionWriter w)
|
||||||
|
throws IOException {
|
||||||
|
StreamWriter streamWriter = streamWriterFactory.createStreamWriter(
|
||||||
|
w.getOutputStream(), ctx);
|
||||||
|
streamWriter.sendEndOfStream();
|
||||||
|
}
|
||||||
|
|
||||||
SyncSession createDuplexOutgoingSession(StreamContext ctx,
|
SyncSession createDuplexOutgoingSession(StreamContext ctx,
|
||||||
TransportConnectionWriter w, @Nullable Priority priority)
|
TransportConnectionWriter w, @Nullable Priority priority)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|||||||
@@ -93,10 +93,16 @@ class IncomingDuplexSyncConnection extends DuplexSyncConnection
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// Create and run the outgoing session
|
if (connection.isMarkedForClose()) {
|
||||||
SyncSession out = createDuplexOutgoingSession(ctx, writer, null);
|
// Close the outgoing stream without sending anything
|
||||||
setOutgoingSession(out);
|
closeOutgoingStream(ctx, writer);
|
||||||
out.run();
|
} else {
|
||||||
|
// Create and run the outgoing session
|
||||||
|
SyncSession out =
|
||||||
|
createDuplexOutgoingSession(ctx, writer, null);
|
||||||
|
setOutgoingSession(out);
|
||||||
|
out.run();
|
||||||
|
}
|
||||||
writer.dispose(false);
|
writer.dispose(false);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
|
|||||||
@@ -65,11 +65,16 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
|
|||||||
Priority priority = generatePriority();
|
Priority priority = generatePriority();
|
||||||
ioExecutor.execute(() -> runIncomingSession(priority));
|
ioExecutor.execute(() -> runIncomingSession(priority));
|
||||||
try {
|
try {
|
||||||
// Create and run the outgoing session
|
if (connection.isMarkedForClose()) {
|
||||||
SyncSession out =
|
// Close the outgoing stream without sending anything
|
||||||
createDuplexOutgoingSession(ctx, writer, priority);
|
closeOutgoingStream(ctx, writer);
|
||||||
setOutgoingSession(out);
|
} else {
|
||||||
out.run();
|
// Create and run the outgoing session
|
||||||
|
SyncSession out =
|
||||||
|
createDuplexOutgoingSession(ctx, writer, priority);
|
||||||
|
setOutgoingSession(out);
|
||||||
|
out.run();
|
||||||
|
}
|
||||||
writer.dispose(false);
|
writer.dispose(false);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ interface BluetoothConnectionLimiter {
|
|||||||
boolean canOpenContactConnection();
|
boolean canOpenContactConnection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Informs the limiter that the given connection has been opened.
|
* Informs the limiter that the given connection has been opened. If the
|
||||||
|
* connection is above the limit it will be
|
||||||
|
* {@link DuplexTransportConnection#markForClose() marked for close}.
|
||||||
*/
|
*/
|
||||||
void connectionOpened(DuplexTransportConnection conn);
|
void connectionOpened(DuplexTransportConnection conn);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
|
|||||||
getLogger(BluetoothConnectionLimiterImpl.class.getName());
|
getLogger(BluetoothConnectionLimiterImpl.class.getName());
|
||||||
|
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
private final boolean singleConnection;
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
@@ -32,8 +33,10 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
|
|||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private boolean keyAgreementInProgress = false;
|
private boolean keyAgreementInProgress = false;
|
||||||
|
|
||||||
BluetoothConnectionLimiterImpl(EventBus eventBus) {
|
BluetoothConnectionLimiterImpl(EventBus eventBus,
|
||||||
|
boolean singleConnection) {
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
|
this.singleConnection = singleConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,6 +62,9 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
|
|||||||
if (keyAgreementInProgress) {
|
if (keyAgreementInProgress) {
|
||||||
LOG.info("Can't open contact connection during key agreement");
|
LOG.info("Can't open contact connection during key agreement");
|
||||||
return false;
|
return false;
|
||||||
|
} else if (singleConnection && !connections.isEmpty()) {
|
||||||
|
LOG.info("Can't open contact connection due to limit");
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Can open contact connection");
|
LOG.info("Can open contact connection");
|
||||||
return true;
|
return true;
|
||||||
@@ -68,12 +74,18 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connectionOpened(DuplexTransportConnection conn) {
|
public void connectionOpened(DuplexTransportConnection conn) {
|
||||||
|
boolean shouldClose = false;
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
connections.add(conn);
|
connections.add(conn);
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Connection opened, " + connections.size() + " open");
|
LOG.info("Connection opened, " + connections.size() + " open");
|
||||||
}
|
}
|
||||||
|
if (singleConnection && connections.size() > 1) {
|
||||||
|
LOG.info("Marking connection for close");
|
||||||
|
shouldClose = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (shouldClose) conn.markForClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -43,6 +43,15 @@ public class TestDuplexTransportConnection
|
|||||||
return new TransportProperties();
|
return new TransportProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMarkedForClose() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markForClose() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a pair of TestDuplexTransportConnections that are
|
* Creates and returns a pair of TestDuplexTransportConnections that are
|
||||||
* connected to each other.
|
* connected to each other.
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
@Override
|
@Override
|
||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
BluetoothConnectionLimiter connectionLimiter =
|
BluetoothConnectionLimiter connectionLimiter =
|
||||||
new BluetoothConnectionLimiterImpl(eventBus);
|
new BluetoothConnectionLimiterImpl(eventBus, false);
|
||||||
BluetoothConnectionFactory<StreamConnection> connectionFactory =
|
BluetoothConnectionFactory<StreamConnection> connectionFactory =
|
||||||
new JavaBluetoothConnectionFactory(connectionLimiter,
|
new JavaBluetoothConnectionFactory(connectionLimiter,
|
||||||
timeoutMonitor);
|
timeoutMonitor);
|
||||||
|
|||||||
Reference in New Issue
Block a user