From 17a1f7227c8c3872fce7bbcc2f5cd46540f9ac52 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 11 Jan 2015 12:28:55 +0100 Subject: o Reading values from the soil sensor. o Rewrote the database schema to match the new device+sensors model. o Storing samples in the database. o To be able to reuse BT callbacks, added a way to always to directly to the next step instead of waiting for an event. --- .../main/java/io/trygvis/android/bt/BtPromise.java | 179 ++++++++++++++------- 1 file changed, 124 insertions(+), 55 deletions(-) (limited to 'app/src/main/java/io/trygvis/android/bt/BtPromise.java') 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 55b6315..6af62c0 100644 --- a/app/src/main/java/io/trygvis/android/bt/BtPromise.java +++ b/app/src/main/java/io/trygvis/android/bt/BtPromise.java @@ -10,9 +10,11 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.Queue; import io.trygvis.android.F2; +import io.trygvis.android.F3; import io.trygvis.android.Function; import static io.trygvis.android.bt.BtPromise.EventType.onCharacteristicChanged; @@ -21,6 +23,7 @@ import static io.trygvis.android.bt.BtPromise.EventType.onCharacteristicWrite; import static io.trygvis.android.bt.BtPromise.EventType.onConnectionStateChange; import static io.trygvis.android.bt.BtPromise.EventType.onDescriptorRead; import static io.trygvis.android.bt.BtPromise.EventType.onDescriptorWrite; +import static io.trygvis.android.bt.BtPromise.EventType.onDirect; import static io.trygvis.android.bt.BtPromise.EventType.onFailure; import static io.trygvis.android.bt.BtPromise.EventType.onFinally; import static io.trygvis.android.bt.BtPromise.EventType.onReliableWriteCompleted; @@ -28,20 +31,48 @@ import static io.trygvis.android.bt.BtPromise.EventType.onServicesDiscovered; public class BtPromise { private final static String TAG = BtPromise.class.getSimpleName(); - private final Queue actionQ = new ArrayDeque<>(); + private final List actionQ = new ArrayList<>(); private final Queue failureQ = new ArrayDeque<>(); private final Queue finallyQ = new ArrayDeque<>(); - public static final PromiseResult continueDownChain = new Continue(); - public static final PromiseResult doneWithChain = new Done(); + private static final PromiseResult waitForNextEvent = new WaitForNextEvent(); + private static final PromiseResult stop = new Stop(); - public abstract static class PromiseResult { + private Boolean stopOnFailure; + + public static class PromiseResult { + private PromiseResult() { + } + + public static PromiseResult waitForNextEvent() { + return waitForNextEvent; + } + + public static PromiseResult continueDirectly(Object value) { + return new ContinueDirectly(value); + } + + public static PromiseResult stop() { + return stop; + } + + public static PromiseResult detour(BtPromise promise) { + return new Detour(promise); + } } - private static class Continue extends PromiseResult { + private static class WaitForNextEvent extends PromiseResult { } - private static class Done extends PromiseResult { + 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 Detour extends PromiseResult { @@ -52,18 +83,32 @@ public class BtPromise { } } - public synchronized BtPromise onConnectionStateChange(F2 callback) { - actionQ.add(new BtCallback("onConnectionStateChange") { + private boolean stopOnFailure() { + if(stopOnFailure != null) { + boolean b = stopOnFailure; + stopOnFailure = null; + return b; + } + return false; + } + + public BtPromise ignoreFailureForNext() { + stopOnFailure = true; + return this; + } + + public synchronized BtPromise onConnectionStateChange(F3 callback) { + actionQ.add(new BtCallback(stopOnFailure(), "onConnectionStateChange") { @Override - public PromiseResult onConnectionStateChange(BluetoothGatt gatt, int newState) { - return callback.apply(gatt, newState); + public PromiseResult onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + return callback.apply(gatt, status,newState); } }); return this; } public synchronized BtPromise onServicesDiscovered(Function callback) { - actionQ.add(new BtCallback("onServicesDiscovered") { + actionQ.add(new BtCallback(stopOnFailure(), "onServicesDiscovered") { @Override public PromiseResult onServicesDiscovered(BluetoothGatt gatt) { return callback.apply(gatt); @@ -73,7 +118,7 @@ public class BtPromise { } public synchronized BtPromise onCharacteristicRead(F2 callback) { - actionQ.add(new BtCallback("onCharacteristicRead") { + actionQ.add(new BtCallback(stopOnFailure(), "onCharacteristicRead") { @Override public PromiseResult onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { return callback.apply(gatt, characteristic); @@ -83,7 +128,7 @@ public class BtPromise { } public synchronized BtPromise onCharacteristicWrite(F2 callback) { - actionQ.add(new BtCallback("onCharacteristicWrite") { + actionQ.add(new BtCallback(stopOnFailure(), "onCharacteristicWrite") { @Override public PromiseResult onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { return callback.apply(gatt, characteristic); @@ -93,7 +138,7 @@ public class BtPromise { } public synchronized BtPromise onCharacteristicChanged(F2 callback) { - actionQ.add(new BtCallback("onCharacteristicChanged") { + actionQ.add(new BtCallback(stopOnFailure(), "onCharacteristicChanged") { @Override public PromiseResult onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { return callback.apply(gatt, characteristic); @@ -103,7 +148,7 @@ public class BtPromise { } public synchronized BtPromise onDescriptorRead(F2 callback) { - actionQ.add(new BtCallback("onDescriptorRead") { + actionQ.add(new BtCallback(stopOnFailure(), "onDescriptorRead") { @Override public PromiseResult onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor) { return callback.apply(gatt, descriptor); @@ -113,7 +158,7 @@ public class BtPromise { } public synchronized BtPromise onDescriptorWrite(F2 callback) { - actionQ.add(new BtCallback("onDescriptorWrite") { + actionQ.add(new BtCallback(stopOnFailure(), "onDescriptorWrite") { @Override public PromiseResult onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor) { return callback.apply(gatt, descriptor); @@ -123,7 +168,7 @@ public class BtPromise { } public synchronized BtPromise onReliableWriteCompleted(Function callback) { - actionQ.add(new BtCallback("onReliableWriteCompleted") { + actionQ.add(new BtCallback(stopOnFailure(), "onReliableWriteCompleted") { @Override public PromiseResult onReliableWriteCompleted(BluetoothGatt gatt) { return callback.apply(gatt); @@ -133,7 +178,7 @@ public class BtPromise { } public synchronized BtPromise onReadRemoteRssi(F2 callback) { - actionQ.add(new BtCallback("onReadRemoteRssi") { + actionQ.add(new BtCallback(stopOnFailure(), "onReadRemoteRssi") { @Override public PromiseResult onReadRemoteRssi(BluetoothGatt gatt, int rssi) { return callback.apply(gatt, rssi); @@ -142,8 +187,18 @@ public class BtPromise { return this; } + public synchronized BtPromise onDirect(Function callback) { + actionQ.add(new BtCallback(stopOnFailure(), "onDirect") { + @Override + public PromiseResult onDirect(Object value) { + return callback.apply(value); + } + }); + return this; + } + public synchronized BtPromise onFailure(Runnable callback) { - failureQ.add(new BtCallback("onFailure") { + failureQ.add(new BtCallback(stopOnFailure(), "onFailure") { @Override public void onFailure() { callback.run(); @@ -153,7 +208,7 @@ public class BtPromise { } public synchronized BtPromise onFinally(Runnable callback) { - finallyQ.add(new BtCallback("finally") { + finallyQ.add(new BtCallback(stopOnFailure(), "finally") { @Override public void onFinally() { callback.run(); @@ -180,12 +235,8 @@ public class BtPromise { return s.toString(); } - BtBluetoothGattCallback asCallback() { - return new BtBluetoothGattCallback(actionQ, failureQ, finallyQ); - } - - public PromiseResult toDetour() { - return new Detour(this); + BtBluetoothGattCallback asCallback(String address) { + return new BtBluetoothGattCallback(address, actionQ, failureQ, finallyQ); } enum EventType { @@ -200,16 +251,18 @@ public class BtPromise { onReadRemoteRssi, + onDirect, onFailure, onFinally, } private static PromiseResult callCallback(EventType key, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, - BluetoothGattDescriptor descriptor, int newState, BtCallback btCallback) { + BluetoothGattDescriptor descriptor, int status, int newState, + BtCallback btCallback, Object value) { switch (key) { case onConnectionStateChange: - return btCallback.onConnectionStateChange(gatt, newState); + return btCallback.onConnectionStateChange(gatt, status, newState); case onServicesDiscovered: return btCallback.onServicesDiscovered(gatt); case onCharacteristicRead: @@ -225,6 +278,8 @@ public class BtPromise { case onReliableWriteCompleted: return btCallback.onReliableWriteCompleted(gatt); + case onDirect: + return btCallback.onDirect(value); case onFailure: btCallback.onFailure(); return null; @@ -239,23 +294,27 @@ public class BtPromise { static class BtBluetoothGattCallback extends BluetoothGattCallback { - private ArrayDeque actionQ; + private final String address; + private List actionQ; + private ListIterator it; private ArrayDeque failureQ; ArrayDeque finallyQ; -// private ArrayDeque initialActionQ; private List events = new ArrayList<>(); - private BtBluetoothGattCallback(Queue actionQ, Queue failureQ, Queue finallyQ) { - this.actionQ = new ArrayDeque<>(actionQ); + private BtBluetoothGattCallback(String address, List actionQ, Queue failureQ, Queue finallyQ) { + this.address = address; + this.actionQ = new ArrayList<>(actionQ); this.failureQ = new ArrayDeque<>(failureQ); this.finallyQ = new ArrayDeque<>(finallyQ); + this.it = actionQ.listIterator(); } - void onEvent(EventType key, String values, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor, int status, int newState) { + void onEvent(EventType key, String values, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, + BluetoothGattDescriptor descriptor, int status, int newState, Object value) { boolean success = status == BluetoothGatt.GATT_SUCCESS; events.add(key + "(" + values + "), success=" + success); - Log.i(TAG, key + "(" + values + "), success=" + success); + Log.i(TAG, "event: " + key + "(" + values + "), success=" + success); if (!success) { doFailure(); @@ -264,31 +323,33 @@ public class BtPromise { BtCallback btCallback; synchronized (this) { - if (actionQ.isEmpty()) { + if (!it.hasNext()) { Log.d(TAG, "All Bluetooth actions are done"); doFinally(); return; } + btCallback = it.next(); + Log.i(TAG, "Executing bt action: " + btCallback.name); try { Thread.sleep(1000); } catch (InterruptedException e) { // ignore } - btCallback = actionQ.remove(); - Log.i(TAG, "Executing bt action: " + btCallback.name); } try { - PromiseResult result = callCallback(key, gatt, characteristic, descriptor, newState, btCallback); + PromiseResult result = callCallback(key, gatt, characteristic, descriptor, status, newState, btCallback, + value); - if (result instanceof Done) { - Log.i(TAG, "The chain is done."); + if (result instanceof Stop) { + Log.i(TAG, "The chain want to stop."); doFinally(); } else if (result instanceof Detour) { Log.i(TAG, "Adding detour"); BtPromise promise = ((Detour) result).promise; + events.add("detour " + promise.actionQ.size()); if (!promise.failureQ.isEmpty()) { Log.i(TAG, "Ignoring " + promise.failureQ.size() + " items from the failure Q"); } @@ -296,12 +357,19 @@ public class BtPromise { Log.i(TAG, "Ignoring " + promise.finallyQ.size() + " items from the finally Q"); } - for (BtCallback callback : promise.actionQ) { - actionQ.addFirst(callback); + synchronized (this) { + for (BtCallback cb : promise.actionQ) { + it.add(cb); + } } + } else if (result instanceof ContinueDirectly) { + value = ((ContinueDirectly) result).value; + onEvent(onDirect, "value=" + value, null, null, null, BluetoothGatt.GATT_SUCCESS, 0, + value); + return; } - if (actionQ.isEmpty()) { + if (!it.hasNext()) { Log.i(TAG, "The queue is empty"); } } catch (NotOverriddenException e) { @@ -313,14 +381,15 @@ public class BtPromise { private void doFailure() { StringBuilder msg = new StringBuilder(); + msg.append("Address: ").append(address).append("\n"); msg.append("Expected events: \n"); for (BtCallback cb : actionQ) { - msg.append(" ").append(cb.name).append("\n"); + msg.append("- ").append(cb.name).append("\n"); } msg.append("Actual events: \n"); for (String event : events) { - msg.append(" ").append(event).append("\n"); + msg.append("- ").append(event).append("\n"); } Log.w(TAG, msg.toString()); @@ -329,7 +398,7 @@ public class BtPromise { for (BtCallback callback = failureQ.poll(); callback != null; callback = failureQ.poll()) { try { - callCallback(onFailure, null, null, null, 0, callback); + callCallback(onFailure, null, null, null, 0, 0, callback, null); } catch (NotOverriddenException e) { return; } @@ -345,7 +414,7 @@ public class BtPromise { for (BtCallback callback = finallyQ.poll(); callback != null; callback = finallyQ.poll()) { try { - callCallback(onFinally, null, null, null, 0, callback); + callCallback(onFinally, null, null, null, 0, 0, callback, null); } catch (NotOverriddenException e) { return; } @@ -358,42 +427,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); + onEvent(onConnectionStateChange, "status=" + status + ", newState=" + newState, gatt, null, null, status, newState, null); } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { - onEvent(onServicesDiscovered, "status=" + status, gatt, null, null, status, 9); + onEvent(onServicesDiscovered, "status=" + status, gatt, null, null, status, 9, null); } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - onEvent(onCharacteristicRead, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0); + onEvent(onCharacteristicRead, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0, null); } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - onEvent(onCharacteristicWrite, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0); + onEvent(onCharacteristicWrite, "status=" + status + ", characteristic=" + characteristic.getUuid(), gatt, characteristic, null, status, 0, null); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { - onEvent(onCharacteristicChanged, "characteristic=" + characteristic.getUuid(), gatt, characteristic, null, BluetoothGatt.GATT_SUCCESS, 0); + onEvent(onCharacteristicChanged, "characteristic=" + characteristic.getUuid(), gatt, characteristic, null, BluetoothGatt.GATT_SUCCESS, 0, null); } @Override public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { - onEvent(onDescriptorRead, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0); + onEvent(onDescriptorRead, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0, null); } @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { - onEvent(onDescriptorWrite, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0); + onEvent(onDescriptorWrite, "status=" + status + ", descriptor=" + descriptor.getUuid(), gatt, null, descriptor, status, 0, null); } @Override public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { - onEvent(onReliableWriteCompleted, "status=" + status, gatt, null, null, status, 0); + onEvent(onReliableWriteCompleted, "status=" + status, gatt, null, null, status, 0, null); } @Override -- cgit v1.2.3