mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 22:59:54 +01:00
Android Bluetooth plugin binds a socket each time BT is enabled.
Dev task #80.
This commit is contained in:
@@ -68,9 +68,10 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
|
|
||||||
private volatile boolean running = false;
|
private volatile boolean running = false;
|
||||||
private volatile boolean wasDisabled = false;
|
private volatile boolean wasDisabled = false;
|
||||||
|
private volatile BluetoothStateReceiver receiver = null;
|
||||||
private volatile BluetoothServerSocket socket = null;
|
private volatile BluetoothServerSocket socket = null;
|
||||||
|
|
||||||
// Non-null if running has ever been true
|
// Non-null if the plugin started successfully
|
||||||
private volatile BluetoothAdapter adapter = null;
|
private volatile BluetoothAdapter adapter = null;
|
||||||
|
|
||||||
DroidtoothPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor,
|
DroidtoothPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor,
|
||||||
@@ -120,66 +121,56 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
running = true;
|
running = true;
|
||||||
pluginExecutor.execute(new Runnable() {
|
// Listen for changes to the Bluetooth state
|
||||||
public void run() {
|
IntentFilter filter = new IntentFilter(ACTION_STATE_CHANGED);
|
||||||
bind();
|
receiver = new BluetoothStateReceiver();
|
||||||
|
appContext.registerReceiver(receiver, filter);
|
||||||
|
// If Bluetooth is enabled, bind a socket - otherwise enable it
|
||||||
|
if(adapter.isEnabled()) {
|
||||||
|
bind();
|
||||||
|
} else if(callback.getConfig().getBoolean("enable", true)) {
|
||||||
|
if(adapter.enable()) {
|
||||||
|
LOG.info("Enabling Bluetooth");
|
||||||
|
wasDisabled = true;
|
||||||
|
} else {
|
||||||
|
LOG.info("Could not enable Bluetooth");
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
LOG.info("Not enabling Bluetooth");
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bind() {
|
private void bind() {
|
||||||
if(!running) return;
|
pluginExecutor.execute(new Runnable() {
|
||||||
if(!enableBluetooth()) return;
|
public void run() {
|
||||||
if(LOG.isLoggable(INFO))
|
if(!running) return;
|
||||||
LOG.info("Local address " + adapter.getAddress());
|
if(!adapter.isEnabled()) return;
|
||||||
// Advertise the Bluetooth address to contacts
|
if(LOG.isLoggable(INFO))
|
||||||
TransportProperties p = new TransportProperties();
|
LOG.info("Local address " + adapter.getAddress());
|
||||||
p.put("address", adapter.getAddress());
|
// Advertise the Bluetooth address to contacts
|
||||||
callback.mergeLocalProperties(p);
|
TransportProperties p = new TransportProperties();
|
||||||
// Bind a server socket to accept connections from contacts
|
p.put("address", adapter.getAddress());
|
||||||
BluetoothServerSocket ss = null;
|
callback.mergeLocalProperties(p);
|
||||||
try {
|
// Bind a server socket to accept connections from contacts
|
||||||
ss = InsecureBluetooth.listen(adapter, "RFCOMM", getUuid());
|
BluetoothServerSocket ss = null;
|
||||||
} catch(IOException e) {
|
try {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
ss = InsecureBluetooth.listen(adapter, "RFCOMM", getUuid());
|
||||||
tryToClose(ss);
|
} catch(IOException e) {
|
||||||
return;
|
if(LOG.isLoggable(WARNING))
|
||||||
}
|
LOG.log(WARNING, e.toString(), e);
|
||||||
if(!running) {
|
tryToClose(ss);
|
||||||
tryToClose(ss);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if(!running) {
|
||||||
socket = ss;
|
tryToClose(ss);
|
||||||
acceptContactConnections();
|
return;
|
||||||
}
|
}
|
||||||
|
LOG.info("Socket bound");
|
||||||
private boolean enableBluetooth() {
|
socket = ss;
|
||||||
if(adapter.isEnabled()) return true;
|
acceptContactConnections();
|
||||||
if(!callback.getConfig().getBoolean("enable", true)) {
|
|
||||||
LOG.info("Not enabling Bluetooth");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
wasDisabled = true;
|
|
||||||
// Try to enable the adapter and wait for the result
|
|
||||||
LOG.info("Enabling Bluetooth");
|
|
||||||
IntentFilter filter = new IntentFilter(ACTION_STATE_CHANGED);
|
|
||||||
BluetoothStateReceiver receiver = new BluetoothStateReceiver();
|
|
||||||
appContext.registerReceiver(receiver, filter);
|
|
||||||
try {
|
|
||||||
if(adapter.enable()) {
|
|
||||||
boolean enabled = receiver.waitForStateChange();
|
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Enabled: " + enabled);
|
|
||||||
return enabled;
|
|
||||||
} else {
|
|
||||||
LOG.info("Could not enable Bluetooth");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
});
|
||||||
LOG.warning("Interrupted while enabling Bluetooth");
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID getUuid() {
|
private UUID getUuid() {
|
||||||
@@ -204,7 +195,7 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void acceptContactConnections() {
|
private void acceptContactConnections() {
|
||||||
while(true) {
|
while(running) {
|
||||||
BluetoothSocket s;
|
BluetoothSocket s;
|
||||||
try {
|
try {
|
||||||
s = socket.accept();
|
s = socket.accept();
|
||||||
@@ -215,7 +206,6 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callback.incomingConnectionCreated(wrapSocket(s));
|
callback.incomingConnectionCreated(wrapSocket(s));
|
||||||
if(!running) return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,33 +215,17 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
running = false;
|
running = false;
|
||||||
if(socket != null) tryToClose(socket);
|
if(receiver != null) appContext.unregisterReceiver(receiver);
|
||||||
// Disable Bluetooth if we enabled it at any point
|
tryToClose(socket);
|
||||||
if(wasDisabled) disableBluetooth();
|
// Disable Bluetooth if we enabled it and it's still enabled
|
||||||
}
|
if(wasDisabled && adapter.isEnabled()) {
|
||||||
|
if(adapter.disable()) LOG.info("Disabling Bluetooth");
|
||||||
private void disableBluetooth() {
|
else LOG.info("Could not disable Bluetooth");
|
||||||
if(!adapter.isEnabled()) return;
|
|
||||||
// Try to disable the adapter and wait for the result
|
|
||||||
LOG.info("Disabling Bluetooth");
|
|
||||||
IntentFilter filter = new IntentFilter(ACTION_STATE_CHANGED);
|
|
||||||
BluetoothStateReceiver receiver = new BluetoothStateReceiver();
|
|
||||||
appContext.registerReceiver(receiver, filter);
|
|
||||||
try {
|
|
||||||
if(adapter.disable()) {
|
|
||||||
boolean enabled = receiver.waitForStateChange();
|
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Enabled: " + enabled);
|
|
||||||
} else {
|
|
||||||
LOG.info("Could not disable Bluetooth");
|
|
||||||
}
|
|
||||||
} catch(InterruptedException e) {
|
|
||||||
LOG.warning("Interrupted while disabling Bluetooth");
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return running && socket != null;
|
return running && adapter.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldPoll() {
|
public boolean shouldPoll() {
|
||||||
@@ -379,28 +353,18 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BluetoothStateReceiver extends BroadcastReceiver {
|
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
private final CountDownLatch finished = new CountDownLatch(1);
|
|
||||||
|
|
||||||
private volatile boolean enabled = false;
|
|
||||||
|
|
||||||
public void onReceive(Context ctx, Intent intent) {
|
public void onReceive(Context ctx, Intent intent) {
|
||||||
int state = intent.getIntExtra(EXTRA_STATE, 0);
|
int state = intent.getIntExtra(EXTRA_STATE, 0);
|
||||||
if(state == STATE_ON) {
|
if(state == STATE_ON) {
|
||||||
enabled = true;
|
LOG.info("Bluetooth enabled");
|
||||||
ctx.unregisterReceiver(this);
|
bind();
|
||||||
finished.countDown();
|
|
||||||
} else if(state == STATE_OFF) {
|
} else if(state == STATE_OFF) {
|
||||||
ctx.unregisterReceiver(this);
|
LOG.info("Bluetooth disabled");
|
||||||
finished.countDown();
|
tryToClose(socket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean waitForStateChange() throws InterruptedException {
|
|
||||||
finished.await();
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DiscoveryThread extends Thread {
|
private class DiscoveryThread extends Thread {
|
||||||
|
|||||||
Reference in New Issue
Block a user