diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2015-01-18 12:52:17 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2015-01-18 12:52:17 +0100 |
commit | fe238450f161a503d61c5ae59ecdd82c60c0e9ec (patch) | |
tree | 075ac1aa9b90d6895505d203a806d262bc41f273 /app/src/main/java/io/trygvis/android | |
parent | f3288422d8dec949fcad33a84e413d8aa45f4500 (diff) | |
download | io.trygvis.soilmoisture-android-fe238450f161a503d61c5ae59ecdd82c60c0e9ec.tar.gz io.trygvis.soilmoisture-android-fe238450f161a503d61c5ae59ecdd82c60c0e9ec.tar.bz2 io.trygvis.soilmoisture-android-fe238450f161a503d61c5ae59ecdd82c60c0e9ec.tar.xz io.trygvis.soilmoisture-android-fe238450f161a503d61c5ae59ecdd82c60c0e9ec.zip |
BtPromise: Adding a distinction between successful and failure.1.0
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.
Diffstat (limited to 'app/src/main/java/io/trygvis/android')
4 files changed, 106 insertions, 56 deletions
diff --git a/app/src/main/java/io/trygvis/android/Optional.java b/app/src/main/java/io/trygvis/android/Optional.java new file mode 100644 index 0000000..616f9a7 --- /dev/null +++ b/app/src/main/java/io/trygvis/android/Optional.java @@ -0,0 +1,45 @@ +package io.trygvis.android; + +public final class Optional<T> { + private final T value; + + public Optional(T value) { + this.value = value; + } + + public T get() { + if (value == null) { + throw new IllegalStateException("get() on empty"); + } + + return value; + } + + public boolean isPresent() { + return value != null; + } + + public void ifPresent(Consumer<T> consumer) { + if (value == null) { + return; + } + + consumer.accept(value); + } + + public static <T> Optional<T> of(T t) { + if (t == null) { + throw new IllegalArgumentException("t can't be null"); + } + + return new Optional<>(t); + } + + public static <T> Optional<T> empty() { + return new Optional<>(null); + } + + public static <T> Optional<T> ofNullable(T t) { + return t != null ? of(t) : empty(); + } +} 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<A> { private final static String TAG = BtDevice.class.getSimpleName(); @@ -90,22 +91,10 @@ public class BtDevice<A> { 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(). + * <p> + * Services will be discovered. */ public synchronized void withConnection(BtPromise promise) { if (callback != null) { @@ -124,22 +113,26 @@ public class BtDevice<A> { 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<A> { } 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<Object, PromiseResult> callback) { + public synchronized BtPromise onDirect(Function<BluetoothGatt, PromiseResult> 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 |