From 5f880d3816526157c5d411896707b971af48212b Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Mon, 12 Jan 2015 22:47:57 +0100 Subject: o Major refactoring of the BT promise. --- .../main/java/io/trygvis/android/bt/BtDevice.java | 150 ++++++++++++++++++--- 1 file changed, 133 insertions(+), 17 deletions(-) (limited to 'app/src/main/java/io/trygvis/android/bt/BtDevice.java') diff --git a/app/src/main/java/io/trygvis/android/bt/BtDevice.java b/app/src/main/java/io/trygvis/android/bt/BtDevice.java index d8dfefc..2a4a5d8 100644 --- a/app/src/main/java/io/trygvis/android/bt/BtDevice.java +++ b/app/src/main/java/io/trygvis/android/bt/BtDevice.java @@ -3,11 +3,16 @@ package io.trygvis.android.bt; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import java.util.Date; +import static io.trygvis.android.bt.BtPromise.PromiseResult.detour; +import static io.trygvis.android.bt.BtPromise.PromiseResult.stop; + public class BtDevice> { private final static String TAG = BtDevice.class.getSimpleName(); @@ -23,6 +28,7 @@ public class BtDevice> { private final Date firstSeen; private Date lastSeen; private boolean connected; + private final WrappingBluetoothGattCallback wrappingCallback = new WrappingBluetoothGattCallback(); public static interface BtDeviceWrapper> { BtDevice getBtDevice(); @@ -83,27 +89,69 @@ public class BtDevice> { this.lastSeen = lastSeen; } - public synchronized boolean connect(BtPromise executor) { - Log.i(TAG, "connect(), address=" + bluetoothDevice.getAddress()); - BluetoothGattCallback callback = executor.asCallback(bluetoothDevice.getAddress()); - gatt = bluetoothDevice.connectGatt(btService, false, new WrappingBluetoothGattCallback(callback) { - @Override - public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { - BtDevice.this.connected = newState == BluetoothGatt.STATE_CONNECTED; - - super.onConnectionStateChange(gatt, status, newState); - } - }); - return true; - } +// public synchronized boolean connect(BtPromise executor) { +// Log.i(TAG, "connect(), address=" + bluetoothDevice.getAddress()); +// BluetoothGattCallback callback = executor.asCallback(bluetoothDevice.getAddress()); +// gatt = bluetoothDevice.connectGatt(btService, false, new WrappingBluetoothGattCallback(callback) { +// @Override +// public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { +// BtDevice.this.connected = newState == BluetoothGatt.STATE_CONNECTED; +// +// super.onConnectionStateChange(gatt, status, newState); +// } +// }); +// return true; +// } + + private BluetoothGattCallback callback; + + public synchronized void withConnection(BtPromise promise) { + if (callback != null) { + throw new RuntimeException("The current callback is not done."); + } - public synchronized void disconnect() { - if (gatt != null) { - gatt.disconnect(); - gatt = null; + Log.i(TAG, "withConnection(), address=" + bluetoothDevice.getAddress() + ", connected: " + (gatt != null)); + + if (gatt == null) { + callback = new BtPromise(). + ignoreFailureForNext(). + onConnectionStateChange((gatt, status, newState) -> { + Log.i(TAG, "defaultConnectCallback: status=" + status + ", newState=" + newState); + String address = gatt.getDevice().getAddress(); + //noinspection SimplifiableIfStatement + if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) { + Log.i(TAG, "Connected to " + address); + return detour(promise); + } else { + Log.i(TAG, "Could not connect to " + address + ", trying again"); + + return detour(new BtPromise().onConnectionStateChange((gatt2, status2, newState2) -> { + if (status2 == BluetoothGatt.GATT_SUCCESS && newState2 == BluetoothGatt.STATE_CONNECTED) { + Log.i(TAG, "Connected to " + address); + return detour(promise); + } + + Log.i(TAG, "Could still not connect to " + address + ", failing."); + + return stop(); + })); + } + }). + asCallback(bluetoothDevice.getAddress()); + } else { + callback = promise.asCallback(bluetoothDevice.getAddress()); } + + gatt = bluetoothDevice.connectGatt(btService, false, wrappingCallback); } +// public synchronized void disconnect() { +// if (gatt != null) { +// gatt.disconnect(); +// gatt = null; +// } +// } + public boolean connected() { return connected; } @@ -131,4 +179,72 @@ public class BtDevice> { public int hashCode() { return getAddress().hashCode(); } + + private class WrappingBluetoothGattCallback extends BluetoothGattCallback { + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + BtDevice.this.connected = newState == BluetoothGatt.STATE_CONNECTED; + + if (callback != null) { + callback.onConnectionStateChange(gatt, status, newState); + } + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (callback != null) { + callback.onServicesDiscovered(gatt, status); + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if (callback != null) { + callback.onCharacteristicRead(gatt, characteristic, status); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if (callback != null) { + callback.onCharacteristicWrite(gatt, characteristic, status); + } + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + if (callback != null) { + callback.onCharacteristicChanged(gatt, characteristic); + } + } + + @Override + public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + if (callback != null) { + callback.onDescriptorRead(gatt, descriptor, status); + } + } + + @Override + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + if (callback != null) { + callback.onDescriptorWrite(gatt, descriptor, status); + } + } + + @Override + public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { + if (callback != null) { + callback.onReliableWriteCompleted(gatt, status); + } + } + + @Override + public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { + if (callback != null) { + callback.onReadRemoteRssi(gatt, rssi, status); + } + } + } } -- cgit v1.2.3