Make rfcomm connections thread based to prevent blocking calls
Change-Id: I0018c06ac5e100fa6dd00d945690fb39493c658f
Cherry-Pick of: https://android-review.googlesource.com/#/c/231675/
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java
index c362b7e..f25e93e 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java
@@ -62,6 +62,7 @@
private Map<String, BluetoothConnection>
connections = new HashMap<String, BluetoothConnection>();
private BluetoothSocket mCurrentSocket;
+ private ConnectThread mCurrThread;
public BluetoothRfcommFacade(FacadeManager manager) {
super(manager);
@@ -105,22 +106,28 @@
BluetoothSocket mSocket;
BluetoothConnection conn;
mDevice = mBluetoothAdapter.getRemoteDevice(address);
- mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
-
// Register a broadcast receiver to bypass manual confirmation
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
mService.registerReceiver(mPairingReceiver, filter);
-
- // Always cancel discovery because it will slow down a connection.
- mBluetoothAdapter.cancelDiscovery();
- mSocket.connect();
- conn = new BluetoothConnection(mSocket);
- mCurrentSocket = mSocket;
-
+ ConnectThread t = new ConnectThread(mDevice, uuid);
+ t.run();
+ mCurrThread = t;
+ conn = new BluetoothConnection(mCurrThread.getSocket());
+ Log.d("Connection Successful");
mService.unregisterReceiver(mPairingReceiver);
return addConnection(conn);
}
+ @Rpc(description = "Kill thread")
+ public void bluetoothRfcommKillConnThread() {
+ try {
+ mCurrThread.cancel();
+ mCurrThread.join(5000);
+ } catch (InterruptedException e) {
+ Log.e("Interrupted Exception: " + e.toString());
+ }
+ }
+
/**
* Closes an active Rfcomm socket
*/
@@ -170,6 +177,7 @@
BluetoothSocket mSocket = mServerSocket.accept(timeout.intValue());
BluetoothConnection conn = new BluetoothConnection(mSocket, mServerSocket);
mService.unregisterReceiver(mPairingReceiver);
+ mCurrentSocket = mSocket;
return addConnection(conn);
}
@@ -291,8 +299,50 @@
}
connections.clear();
}
+ private class ConnectThread extends Thread {
+ private final BluetoothSocket mmSocket;
+
+ public ConnectThread(BluetoothDevice device, String uuid) {
+ BluetoothSocket tmp = null;
+ try {
+ tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
+ } catch (IOException createSocketException) {
+ Log.e("Failed to create socket: " + createSocketException.toString());
+ }
+ mmSocket = tmp;
+ }
+
+ public void run() {
+ mBluetoothAdapter.cancelDiscovery();
+ try {
+ mmSocket.connect();
+ } catch(IOException connectException) {
+ Log.e("Failed to connect socket: " + connectException.toString());
+ try {
+ mmSocket.close();
+ } catch(IOException closeException){
+ Log.e("Failed to close socket: " + closeException.toString());
+ }
+ return;
+ }
+ }
+
+ public void cancel() {
+ try {
+ mmSocket.close();
+ } catch (IOException e){
+
+ }
+ }
+
+ public BluetoothSocket getSocket() {
+ return mmSocket;
+ }
+ }
+
}
+
class BluetoothConnection {
private BluetoothSocket mSocket;
private BluetoothDevice mDevice;