From fe238450f161a503d61c5ae59ecdd82c60c0e9ec Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 18 Jan 2015 12:52:17 +0100 Subject: BtPromise: Adding a distinction between successful and failure. o Chain can now call fail() instead of stop() to signal failure. o The finally handlers can be changed to get this info later. o Should probably make all callbacks take the BtDevice as a callback instead of BluetoothGatt and make the gatt instance available through the device. This way state can be kept in the device's tag. BtPromise: always discover services when operating inside a connection. --- .../java/io/trygvis/android/bt/BtCallback.java | 2 +- .../main/java/io/trygvis/android/bt/BtDevice.java | 35 ++++------ .../main/java/io/trygvis/android/bt/BtPromise.java | 80 +++++++++++++--------- 3 files changed, 61 insertions(+), 56 deletions(-) (limited to 'app/src/main/java/io/trygvis/android/bt') diff --git a/app/src/main/java/io/trygvis/android/bt/BtCallback.java b/app/src/main/java/io/trygvis/android/bt/BtCallback.java index 7ff8733..3b1fb10 100644 --- a/app/src/main/java/io/trygvis/android/bt/BtCallback.java +++ b/app/src/main/java/io/trygvis/android/bt/BtCallback.java @@ -51,7 +51,7 @@ public class BtCallback { throw new NotOverriddenException(); } - public PromiseResult onDirect(Object value) { + public PromiseResult onDirect(BluetoothGatt value) { throw new NotOverriddenException(); } 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 6a4d92e..23fd397 100644 --- a/app/src/main/java/io/trygvis/android/bt/BtDevice.java +++ b/app/src/main/java/io/trygvis/android/bt/BtDevice.java @@ -12,7 +12,8 @@ import java.util.Date; import static io.trygvis.android.bt.BtPromise.BtBluetoothGattCallback; import static io.trygvis.android.bt.BtPromise.PromiseResult.detour; -import static io.trygvis.android.bt.BtPromise.PromiseResult.stop; +import static io.trygvis.android.bt.BtPromise.PromiseResult.fail; +import static io.trygvis.android.bt.BtPromise.PromiseResult.waitForNextEvent; public class BtDevice { private final static String TAG = BtDevice.class.getSimpleName(); @@ -90,22 +91,10 @@ 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; -// } - /** * The first handler must handle a onDirect(). + *

+ * Services will be discovered. */ public synchronized void withConnection(BtPromise promise) { if (callback != null) { @@ -124,22 +113,26 @@ public class BtDevice { btService.sendBroadcast(btService.createDeviceConnection(address)); if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) { - Log.i(TAG, "Connected to " + address); - return detour(promise); + Log.i(TAG, "Connected to " + address + ", discovering services"); + return gatt.discoverServices() ? waitForNextEvent() : fail(); } 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, "Connected to " + address + ", discovering services"); + return gatt.discoverServices() ? waitForNextEvent() : fail(); } Log.i(TAG, "Could still not connect to " + address + ", failing."); - return stop(); + return fail(); })); } + }). + onServicesDiscovered(gatt -> { + Log.i(TAG, "Services discovered, has " + gatt.getServices().size() + " services"); + return detour(promise); }); } else { newPromise = promise; @@ -157,7 +150,7 @@ public class BtDevice { } else { callback.onEvent(BtPromise.EventType.onDirect, "", gatt, null, null, BluetoothGatt.GATT_SUCCESS, - BluetoothGatt.STATE_CONNECTED, gatt); + BluetoothGatt.STATE_CONNECTED); } } diff --git a/app/src/main/java/io/trygvis/android/bt/BtPromise.java b/app/src/main/java/io/trygvis/android/bt/BtPromise.java index acbed8d..91c0359 100644 --- a/app/src/main/java/io/trygvis/android/bt/BtPromise.java +++ b/app/src/main/java/io/trygvis/android/bt/BtPromise.java @@ -33,6 +33,8 @@ public class BtPromise { private static final PromiseResult waitForNextEvent = new WaitForNextEvent(); private static final PromiseResult stop = new Stop(); + private static final PromiseResult fail = new Fail(); + private static final PromiseResult continueDirectly = new ContinueDirectly(); private Boolean stopOnFailure; @@ -44,14 +46,18 @@ public class BtPromise { return waitForNextEvent; } - public static PromiseResult continueDirectly(Object value) { - return new ContinueDirectly(value); + public static PromiseResult continueDirectly() { + return continueDirectly; } public static PromiseResult stop() { return stop; } + public static PromiseResult fail() { + return fail; + } + public static PromiseResult detour(BtPromise promise) { return new Detour(promise); } @@ -61,16 +67,14 @@ public class BtPromise { } private static class ContinueDirectly extends PromiseResult { - private final Object value; - - private ContinueDirectly(Object value) { - this.value = value; - } } private static class Stop extends PromiseResult { } + private static class Fail extends PromiseResult { + } + private static class Detour extends PromiseResult { final BtPromise promise; @@ -183,10 +187,10 @@ public class BtPromise { return this; } - public synchronized BtPromise onDirect(Function callback) { + public synchronized BtPromise onDirect(Function callback) { actionQ.add(new BtCallback(stopOnFailure(), "onDirect") { @Override - public PromiseResult onDirect(Object value) { + public PromiseResult onDirect(BluetoothGatt value) { return callback.apply(value); } }); @@ -255,7 +259,7 @@ public class BtPromise { private static PromiseResult callCallback(EventType key, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor, int status, int newState, - BtCallback btCallback, Object value) { + BtCallback btCallback) { switch (key) { case onConnectionStateChange: return btCallback.onConnectionStateChange(gatt, status, newState); @@ -275,7 +279,7 @@ public class BtPromise { return btCallback.onReliableWriteCompleted(gatt); case onDirect: - return btCallback.onDirect(value); + return btCallback.onDirect(gatt); case onFailure: btCallback.onFailure(); return null; @@ -306,7 +310,7 @@ public class BtPromise { } void onEvent(EventType key, String values, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, - BluetoothGattDescriptor descriptor, int status, int newState, Object value) { + BluetoothGattDescriptor descriptor, int status, int newState) { boolean success = status == BluetoothGatt.GATT_SUCCESS; events.add(key + "(" + values + "), success=" + success); @@ -317,7 +321,7 @@ public class BtPromise { if (!hasNext()) { Log.d(TAG, "All Bluetooth actions are done, no handler for last event."); - doFinally(); + doFinally(true); return; } @@ -326,7 +330,7 @@ public class BtPromise { if (!success) { if (btCallback.stopOnFailure) { // doFailure(); - doFinally(); + doFinally(false); return; } else { Log.i(TAG, "Last status was a failure, but the callback still want it."); @@ -343,12 +347,18 @@ public class BtPromise { try { Log.i(TAG, "Executing bt action: " + btCallback.name); - PromiseResult result = callCallback(key, gatt, characteristic, descriptor, status, newState, btCallback, - value); + PromiseResult result = callCallback(key, gatt, characteristic, descriptor, status, newState, btCallback + ); if (result instanceof Stop) { Log.i(TAG, "The chain want to stop."); - doFinally(); + doFinally(true); + return; + } + + if (result instanceof Fail) { + Log.i(TAG, "The chain returned fail()."); + doFinally(false); return; } @@ -370,20 +380,18 @@ public class BtPromise { // current stack can continue. actionQ.addAll(currentAction, detour.actionQ); -// failureQ.addAll(detour.failureQ); +// failureQ.addAll(detour.failureQ);B finallyQ.addAll(detour.finallyQ); Log.i(TAG, "hasNext(): " + hasNext()); if (hasNext()) { Log.i(TAG, "next action: " + actionQ.get(currentAction).name); } - result = PromiseResult.continueDirectly(gatt); + result = PromiseResult.continueDirectly(); } if (result instanceof ContinueDirectly) { - value = ((ContinueDirectly) result).value; - onEvent(onDirect, "value=" + value, null, null, null, BluetoothGatt.GATT_SUCCESS, 0, - value); + onEvent(onDirect, "direct", gatt, null, null, BluetoothGatt.GATT_SUCCESS, 0); return; } @@ -394,7 +402,11 @@ public class BtPromise { } catch (NotOverriddenException e) { Log.w(TAG, "Unexpected callback by listener: " + key); // doFailure(); - doFinally(); + doFinally(false); + } catch (Exception e) { + Log.w(TAG, "Exception in callback", e); +// doFailure(); + doFinally(false); } } @@ -442,16 +454,16 @@ public class BtPromise { Log.w(TAG, msg.toString()); } - private void doFinally() { + private void doFinally(boolean success) { showEvents(); actionQ.clear(); - Log.w(TAG, "Executing " + finallyQ.size() + " finally handlers"); + Log.w(TAG, "Executing " + finallyQ.size() + " finally handlers, success=" + success); for (BtCallback callback : finallyQ) { try { - callCallback(onFinally, null, null, null, 0, 0, callback, null); + callCallback(onFinally, null, null, null, 0, 0, callback); } catch (NotOverriddenException e) { return; } @@ -464,42 +476,42 @@ public class BtPromise { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { - onEvent(onConnectionStateChange, "status=" + status + ", newState=" + newState, gatt, null, null, status, newState, null); + onEvent(onConnectionStateChange, "status=" + status + ", newState=" + newState, gatt, null, null, status, newState); } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { - onEvent(onServicesDiscovered, "status=" + status, gatt, null, null, status, 9, null); + onEvent(onServicesDiscovered, "status=" + status, gatt, null, null, status, 9); } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - onEvent(onCharacteristicRead, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0, null); + onEvent(onCharacteristicRead, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0); } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - onEvent(onCharacteristicWrite, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0, null); + onEvent(onCharacteristicWrite, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { - onEvent(onCharacteristicChanged, "characteristic=" + characteristic.getUuid(), gatt, characteristic, null, BluetoothGatt.GATT_SUCCESS, 0, null); + onEvent(onCharacteristicChanged, "characteristic=" + characteristic.getUuid(), gatt, characteristic, null, BluetoothGatt.GATT_SUCCESS, 0); } @Override public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { - onEvent(onDescriptorRead, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0, null); + onEvent(onDescriptorRead, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0); } @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { - onEvent(onDescriptorWrite, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0, null); + onEvent(onDescriptorWrite, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0); } @Override public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { - onEvent(onReliableWriteCompleted, "status=" + status, gatt, null, null, status, 0, null); + onEvent(onReliableWriteCompleted, "status=" + status, gatt, null, null, status, 0); } @Override -- cgit v1.2.3