aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-01-12 22:47:57 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2015-01-16 22:48:11 +0100
commit5f880d3816526157c5d411896707b971af48212b (patch)
treea9315b7853c2bfc55944537d5890515ce0618746
parent17a1f7227c8c3872fce7bbcc2f5cd46540f9ac52 (diff)
downloadio.trygvis.soilmoisture-android-5f880d3816526157c5d411896707b971af48212b.tar.gz
io.trygvis.soilmoisture-android-5f880d3816526157c5d411896707b971af48212b.tar.bz2
io.trygvis.soilmoisture-android-5f880d3816526157c5d411896707b971af48212b.tar.xz
io.trygvis.soilmoisture-android-5f880d3816526157c5d411896707b971af48212b.zip
o Major refactoring of the BT promise.
-rw-r--r--app/app.iml117
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtCallback.java8
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtDevice.java150
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtPromise.java116
-rw-r--r--app/src/main/java/io/trygvis/android/bt/DefaultBtService.java5
-rw-r--r--app/src/main/java/io/trygvis/android/bt/WrappingBluetoothGattCallback.java60
-rw-r--r--app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java37
7 files changed, 214 insertions, 279 deletions
diff --git a/app/app.iml b/app/app.iml
deleted file mode 100644
index 7d4711d..0000000
--- a/app/app.iml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
- <component name="FacetManager">
- <facet type="android-gradle" name="Android-Gradle">
- <configuration>
- <option name="GRADLE_PROJECT_PATH" value=":app" />
- </configuration>
- </facet>
- <facet type="android" name="Android">
- <configuration>
- <option name="SELECTED_BUILD_VARIANT" value="level18Debug" />
- <option name="ASSEMBLE_TASK_NAME" value="assembleLevel18Debug" />
- <option name="COMPILE_JAVA_TASK_NAME" value="compileLevel18DebugSources" />
- <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleLevel18DebugTest" />
- <option name="SOURCE_GEN_TASK_NAME" value="generateLevel18DebugSources" />
- <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateLevel18DebugTestSources" />
- <option name="ALLOW_USER_CONFIGURATION" value="false" />
- <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
- <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
- <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
- <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
- </configuration>
- </facet>
- </component>
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/intermediates/classes/level18/debug" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/level18/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/level18/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/level18/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/level18/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/level18/debug" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/level18/debug" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/assets" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18Debug/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/level18/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/level18/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/level18/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/level18/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/level18/debug" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/level18/debug" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/assets" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/level18/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/res" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/resources" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/assets" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/aidl" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/jni" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTestLevel18/rs" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
- <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
- <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
- <excludeFolder url="file://$MODULE_DIR$/build/retrolambda" />
- <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
- </content>
- <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" exported="" name="answers-1.0.2" level="project" />
- <orderEntry type="library" exported="" name="flyway-core-3.1" level="project" />
- <orderEntry type="library" exported="" name="fabric-1.0.2" level="project" />
- <orderEntry type="library" exported="" name="sqldroid-1.0.3" level="project" />
- <orderEntry type="library" exported="" name="crashlytics-2.1.0" level="project" />
- <orderEntry type="library" exported="" name="beta-1.0.2" level="project" />
- </component>
-</module>
-
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 71f7d56..7ff8733 100644
--- a/app/src/main/java/io/trygvis/android/bt/BtCallback.java
+++ b/app/src/main/java/io/trygvis/android/bt/BtCallback.java
@@ -62,4 +62,12 @@ public class BtCallback {
public void onFinally() {
throw new NotOverriddenException();
}
+
+ @Override
+ public String toString() {
+ return "BtCallback{" +
+ "name='" + name + '\'' +
+ ", stopOnFailure=" + stopOnFailure +
+ '}';
+ }
}
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<A extends BtDevice.BtDeviceWrapper<A>> {
private final static String TAG = BtDevice.class.getSimpleName();
@@ -23,6 +28,7 @@ public class BtDevice<A extends BtDevice.BtDeviceWrapper<A>> {
private final Date firstSeen;
private Date lastSeen;
private boolean connected;
+ private final WrappingBluetoothGattCallback wrappingCallback = new WrappingBluetoothGattCallback();
public static interface BtDeviceWrapper<A extends BtDevice.BtDeviceWrapper<A>> {
BtDevice<A> getBtDevice();
@@ -83,27 +89,69 @@ public class BtDevice<A extends BtDevice.BtDeviceWrapper<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;
- }
+// 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<A extends BtDevice.BtDeviceWrapper<A>> {
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);
+ }
+ }
+ }
}
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 6af62c0..d4b3b67 100644
--- a/app/src/main/java/io/trygvis/android/bt/BtPromise.java
+++ b/app/src/main/java/io/trygvis/android/bt/BtPromise.java
@@ -6,12 +6,9 @@ import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.util.Log;
-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;
@@ -32,8 +29,8 @@ import static io.trygvis.android.bt.BtPromise.EventType.onServicesDiscovered;
public class BtPromise {
private final static String TAG = BtPromise.class.getSimpleName();
private final List<BtCallback> actionQ = new ArrayList<>();
- private final Queue<BtCallback> failureQ = new ArrayDeque<>();
- private final Queue<BtCallback> finallyQ = new ArrayDeque<>();
+ private final List<BtCallback> failureQ = new ArrayList<>();
+ private final List<BtCallback> finallyQ = new ArrayList<>();
private static final PromiseResult waitForNextEvent = new WaitForNextEvent();
private static final PromiseResult stop = new Stop();
@@ -84,7 +81,7 @@ public class BtPromise {
}
private boolean stopOnFailure() {
- if(stopOnFailure != null) {
+ if (stopOnFailure != null) {
boolean b = stopOnFailure;
stopOnFailure = null;
return b;
@@ -96,12 +93,12 @@ public class BtPromise {
stopOnFailure = true;
return this;
}
-
+
public synchronized BtPromise onConnectionStateChange(F3<BluetoothGatt, Integer, Integer, PromiseResult> callback) {
actionQ.add(new BtCallback(stopOnFailure(), "onConnectionStateChange") {
@Override
public PromiseResult onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
- return callback.apply(gatt, status,newState);
+ return callback.apply(gatt, status, newState);
}
});
return this;
@@ -296,17 +293,17 @@ public class BtPromise {
private final String address;
private List<BtCallback> actionQ;
- private ListIterator<BtCallback> it;
- private ArrayDeque<BtCallback> failureQ;
- ArrayDeque<BtCallback> finallyQ;
+ private int currentAction = 0;
+ private List<BtCallback> failureQ;
+ private List<BtCallback> finallyQ;
private List<String> events = new ArrayList<>();
- private BtBluetoothGattCallback(String address, List<BtCallback> actionQ, Queue<BtCallback> failureQ, Queue<BtCallback> finallyQ) {
+ private BtBluetoothGattCallback(String address, List<BtCallback> actionQ,
+ List<BtCallback> failureQ, List<BtCallback> finallyQ) {
this.address = address;
this.actionQ = new ArrayList<>(actionQ);
- this.failureQ = new ArrayDeque<>(failureQ);
- this.finallyQ = new ArrayDeque<>(finallyQ);
- this.it = actionQ.listIterator();
+ this.failureQ = new ArrayList<>(failureQ);
+ this.finallyQ = new ArrayList<>(finallyQ);
}
void onEvent(EventType key, String values, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
@@ -316,22 +313,28 @@ public class BtPromise {
Log.i(TAG, "event: " + key + "(" + values + "), success=" + success);
- if (!success) {
- doFailure();
- return;
- }
-
BtCallback btCallback;
synchronized (this) {
- if (!it.hasNext()) {
- Log.d(TAG, "All Bluetooth actions are done");
+ if (!hasNext()) {
+ Log.d(TAG, "All Bluetooth actions are done, no handler for last event.");
+ showEvents();
doFinally();
return;
}
- btCallback = it.next();
- Log.i(TAG, "Executing bt action: " + btCallback.name);
+ btCallback = actionQ.get(currentAction++);
+
+ if (!success) {
+ if (btCallback.stopOnFailure) {
+ doFailure();
+ return;
+ } else {
+ Log.i(TAG, "Last status was a failure, but the callback still want it.");
+ }
+ }
+
+ Log.i(TAG, "Graceful sleep" + btCallback.name);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
@@ -340,6 +343,7 @@ public class BtPromise {
}
try {
+ Log.i(TAG, "Executing bt action: " + btCallback.name);
PromiseResult result = callCallback(key, gatt, characteristic, descriptor, status, newState, btCallback,
value);
@@ -347,20 +351,23 @@ public class BtPromise {
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");
- }
- if (!promise.finallyQ.isEmpty()) {
- Log.i(TAG, "Ignoring " + promise.finallyQ.size() + " items from the finally Q");
+ BtPromise detour = ((Detour) result).promise;
+ Log.i(TAG, "Adding detour with " + detour.actionQ.size() + " actions.");
+ events.add("detour, action size=" + detour.actionQ.size() + ", failure size=" +
+ detour.failureQ.size() + ", finally size=" + detour.finallyQ.size());
+
+ Log.i(TAG, "hasNext(): " + hasNext());
+ Log.i(TAG, "currentAction: " + currentAction);
+ if (hasNext()) {
+ Log.i(TAG, "next action: " + actionQ.get(currentAction).name);
}
- synchronized (this) {
- for (BtCallback cb : promise.actionQ) {
- it.add(cb);
- }
+ actionQ.addAll(currentAction, detour.actionQ);
+ failureQ.addAll(detour.failureQ);
+ finallyQ.addAll(detour.finallyQ);
+ Log.i(TAG, "hasNext(): " + hasNext());
+ if (hasNext()) {
+ Log.i(TAG, "next action: " + actionQ.get(currentAction).name);
}
} else if (result instanceof ContinueDirectly) {
value = ((ContinueDirectly) result).value;
@@ -369,8 +376,9 @@ public class BtPromise {
return;
}
- if (!it.hasNext()) {
+ if (!hasNext()) {
Log.i(TAG, "The queue is empty");
+ showEvents();
}
} catch (NotOverriddenException e) {
Log.w(TAG, "Unexpected callback by listener: " + key);
@@ -378,33 +386,37 @@ public class BtPromise {
}
}
+ private boolean hasNext() {
+ return currentAction < actionQ.size();
+ }
+
private void doFailure() {
+ showEvents();
+
+ Log.w(TAG, "Executing " + failureQ.size() + " failure handlers");
+
+ for (BtCallback callback : failureQ) {
+ callCallback(onFailure, null, null, null, 0, 0, callback, null);
+ }
+
+ doFinally();
+ }
+
+ private void showEvents() {
StringBuilder msg = new StringBuilder();
msg.append("Address: ").append(address).append("\n");
- msg.append("Expected events: \n");
+ msg.append("Event handlers: \n");
for (BtCallback cb : actionQ) {
msg.append("- ").append(cb.name).append("\n");
}
- msg.append("Actual events: \n");
+ msg.append("Events received: \n");
for (String event : events) {
msg.append("- ").append(event).append("\n");
}
Log.w(TAG, msg.toString());
-
- Log.w(TAG, "Executing " + failureQ.size() + " failure handlers");
-
- for (BtCallback callback = failureQ.poll(); callback != null; callback = failureQ.poll()) {
- try {
- callCallback(onFailure, null, null, null, 0, 0, callback, null);
- } catch (NotOverriddenException e) {
- return;
- }
- }
-
- doFinally();
}
private void doFinally() {
@@ -412,7 +424,7 @@ public class BtPromise {
Log.w(TAG, "Executing " + finallyQ.size() + " finally handlers");
- for (BtCallback callback = finallyQ.poll(); callback != null; callback = finallyQ.poll()) {
+ for (BtCallback callback : finallyQ) {
try {
callCallback(onFinally, null, null, null, 0, 0, callback, null);
} catch (NotOverriddenException e) {
diff --git a/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java b/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
index cc7d484..718a1cd 100644
--- a/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
+++ b/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
@@ -185,6 +185,11 @@ public class DefaultBtService<A extends BtDevice.BtDeviceWrapper<A>> extends Ser
private BluetoothAdapter.LeScanCallback leScanCallback = (device, rssi, scanRecord) -> {
BtScanResult scanResult = new BtScanResult(scanRecord);
+ if (!device.getAddress().startsWith("FB:")) {
+ Log.w(TAG, "filtering out device: " + device.getAddress());
+ return;
+ }
+
register(device, rssi, scanResult);
};
diff --git a/app/src/main/java/io/trygvis/android/bt/WrappingBluetoothGattCallback.java b/app/src/main/java/io/trygvis/android/bt/WrappingBluetoothGattCallback.java
deleted file mode 100644
index 8d790d1..0000000
--- a/app/src/main/java/io/trygvis/android/bt/WrappingBluetoothGattCallback.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package io.trygvis.android.bt;
-
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-
-class WrappingBluetoothGattCallback extends BluetoothGattCallback {
-
- private final BluetoothGattCallback wrapped;
-
- public WrappingBluetoothGattCallback(BluetoothGattCallback wrapped) {
- this.wrapped = wrapped;
- }
-
- @Override
- public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
- wrapped.onConnectionStateChange(gatt, status, newState);
- }
-
- @Override
- public void onServicesDiscovered(BluetoothGatt gatt, int status) {
- wrapped.onServicesDiscovered(gatt, status);
- }
-
- @Override
- public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
- wrapped.onCharacteristicRead(gatt, characteristic, status);
- }
-
- @Override
- public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
- wrapped.onCharacteristicWrite(gatt, characteristic, status);
- }
-
- @Override
- public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- wrapped.onCharacteristicChanged(gatt, characteristic);
- }
-
- @Override
- public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
- wrapped.onDescriptorRead(gatt, descriptor, status);
- }
-
- @Override
- public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
- wrapped.onDescriptorWrite(gatt, descriptor, status);
- }
-
- @Override
- public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
- wrapped.onReliableWriteCompleted(gatt, status);
- }
-
- @Override
- public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
- wrapped.onReadRemoteRssi(gatt, rssi, status);
- }
-}
diff --git a/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java b/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
index 3ff6e66..174c245 100644
--- a/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
+++ b/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
@@ -30,8 +30,6 @@ import io.trygvis.android.bt.BtService;
import io.trygvis.android.bt.DefaultBtService;
import io.trygvis.bluetooth.TrygvisIoUuids;
-import static io.trygvis.android.bt.BtPromise.PromiseResult.continueDirectly;
-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.waitForNextEvent;
import static io.trygvis.android.bt.BtService.BtServiceListenerBroadcastReceiver;
@@ -117,8 +115,6 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
if (!smDevice.isProbed()) {
Log.i(TAG, "Probing " + address + ", name=" + btDevice.getName());
BtPromise executor = new BtPromise().
- ignoreFailureForNext().
- onConnectionStateChange(DefaultSoilMoistureService::defaultConnectCallback).
onDirect(v -> {
BluetoothGatt gatt = (BluetoothGatt) v;
return gatt.discoverServices() ? waitForNextEvent() : stop();
@@ -162,15 +158,14 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
return stop();
}).
onFinally(() -> {
- btDevice.disconnect();
+// btDevice.disconnect();
if (smDevice.getIsUseful() == null) {
smDevice.setIsUseful(false);
}
-
});
- btDevice.connect(executor);
+ btDevice.withConnection(executor);
}
}
};
@@ -208,29 +203,6 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
});
}
- public static BtPromise.PromiseResult defaultConnectCallback(BluetoothGatt gatt, int status, Integer 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 continueDirectly(gatt);
- } else {
- Log.i(TAG, "Disconnected from " + address + ", trying again");
-
- return detour(new BtPromise().onConnectionStateChange((gatt2, status2, newState2) -> {
- if (newState2 == BluetoothGatt.STATE_CONNECTED) {
- Log.i(TAG, "Connected to " + address);
- return continueDirectly(gatt);
- }
-
- Log.i(TAG, "Could still not connect to " + address + ", failing.");
-
- return stop();
- }));
- }
- }
-
// -----------------------------------------------------------------------
// SmDevicesManager Implementation
// -----------------------------------------------------------------------
@@ -300,7 +272,6 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
void readCurrentValue(SmSensor sensor) {
BtPromise promise = new BtPromise().
- onConnectionStateChange(DefaultSoilMoistureService::defaultConnectCallback).
onDirect(v -> {
BluetoothGatt gatt = (BluetoothGatt) v;
return gatt.discoverServices() ? waitForNextEvent() : stop();
@@ -327,14 +298,14 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
handleNewSensorValueReady(sensor, getSensorCountRes.value);
- gatt.disconnect();
+// gatt.disconnect();
return stop();
}).
onFinally(() -> {
});
- sensor.getDevice().getBtDevice().connect(promise);
+ sensor.getDevice().getBtDevice().withConnection(promise);
}
// -----------------------------------------------------------------------