aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/io/trygvis/android
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/io/trygvis/android')
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtDevice.java49
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtPromise.java12
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtScanResult.java9
-rw-r--r--app/src/main/java/io/trygvis/android/bt/BtService.java3
-rw-r--r--app/src/main/java/io/trygvis/android/bt/DefaultBtService.java77
5 files changed, 90 insertions, 60 deletions
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 fd9e2b9..b90ac4f 100644
--- a/app/src/main/java/io/trygvis/android/bt/BtDevice.java
+++ b/app/src/main/java/io/trygvis/android/bt/BtDevice.java
@@ -15,14 +15,13 @@ import static io.trygvis.android.bt.BtPromise.PromiseResult.detour;
import static io.trygvis.android.bt.BtPromise.PromiseResult.fail;
import static io.trygvis.android.bt.BtPromise.PromiseResult.waitForNextEvent;
-public class BtDevice<A> {
+public class BtDevice<A> implements Comparable<BtDevice> {
private final static String TAG = BtDevice.class.getSimpleName();
private final DefaultBtService btService;
private final BluetoothDevice bluetoothDevice;
private BluetoothGatt gatt;
private Integer rssi;
- private BtScanResult scanResult;
private A tag;
private final String address;
@@ -30,6 +29,10 @@ public class BtDevice<A> {
private final boolean seenBefore;
private final Date firstSeen;
private Date lastSeen;
+ /**
+ * If seen in last scan.
+ */
+ private boolean recentlySeen;
private boolean connected;
private final WrappingBluetoothGattCallback wrappingCallback = new WrappingBluetoothGattCallback();
@@ -37,15 +40,15 @@ public class BtDevice<A> {
BtDevice(DefaultBtService btService, BluetoothDevice bluetoothDevice, SQLiteDatabase db,
BtService.BtDbIntegration<A> btDbIntegration, long id, Integer rssi,
- BtScanResult scanResult, boolean seenBefore, Date firstSeen, Date lastSeen) {
+ boolean seenBefore, Date firstSeen, Date lastSeen, boolean recentlySeen) {
this.btService = btService;
this.bluetoothDevice = bluetoothDevice;
this.id = id;
this.rssi = rssi;
- this.scanResult = scanResult;
this.seenBefore = seenBefore;
this.firstSeen = firstSeen;
this.lastSeen = lastSeen;
+ this.recentlySeen = recentlySeen;
this.tag = btDbIntegration.createTag(db, this);
this.address = bluetoothDevice.getAddress();
@@ -60,7 +63,7 @@ public class BtDevice<A> {
}
public String getAddress() {
- return bluetoothDevice.getAddress();
+ return address;
}
public String getName() {
@@ -71,10 +74,6 @@ public class BtDevice<A> {
return rssi;
}
- public BtScanResult getScanResult() {
- return scanResult;
- }
-
public boolean isSeenBefore() {
return seenBefore;
}
@@ -91,6 +90,14 @@ public class BtDevice<A> {
this.lastSeen = lastSeen;
}
+ public boolean isRecentlySeen() {
+ return recentlySeen;
+ }
+
+ public void setRecentlySeen(boolean recentlySeen) {
+ this.recentlySeen = recentlySeen;
+ }
+
/**
* The first handler must handle a onDirect().
* <p>
@@ -101,7 +108,7 @@ public class BtDevice<A> {
throw new RuntimeException("The current callback is not done.");
}
- Log.i(TAG, "withConnection(), address=" + bluetoothDevice.getAddress() + ", connected: " + (gatt != null));
+ Log.i(TAG, "withConnection(), address=" + address + ", connected: " + (gatt != null));
BtPromise newPromise;
if (gatt == null) {
@@ -160,7 +167,7 @@ public class BtDevice<A> {
@Override
public String toString() {
- return "BtDevice{address=" + bluetoothDevice.getAddress() + '}';
+ return "BtDevice{address=" + address + '}';
}
@Override
@@ -174,12 +181,17 @@ public class BtDevice<A> {
BtDevice other = (BtDevice) o;
- return getAddress().equals(other.getAddress());
+ return address.equals(other.getAddress());
}
@Override
public int hashCode() {
- return getAddress().hashCode();
+ return address.hashCode();
+ }
+
+ @Override
+ public int compareTo(BtDevice that) {
+ return address.compareTo(that.address);
}
private class WrappingBluetoothGattCallback extends BluetoothGattCallback {
@@ -196,6 +208,11 @@ public class BtDevice<A> {
BtDevice.this.connected = status == BluetoothGatt.GATT_SUCCESS &&
newState == BluetoothGatt.STATE_CONNECTED;
+ if (oldConnected && BtDevice.this.connected) {
+ Log.i(TAG, "Wrapping: Extra 'onConnectionStateChange' event, ignoring. gatt=" + gatt);
+ return;
+ }
+
try {
if (callback != null) {
callback.onConnectionStateChange(gatt, status, newState);
@@ -203,14 +220,14 @@ public class BtDevice<A> {
} finally {
if (!BtDevice.this.connected) {
if (oldConnected) {
- Log.i(TAG, "Wrapper: Lost connection, removing gatt. gatt=" + gatt);
+ Log.i(TAG, "Wrapping: Lost connection, removing gatt. gatt=" + gatt);
} else {
- Log.i(TAG, "Wrapper: Lost connection, was not connected. gatt=" + gatt);
+ Log.i(TAG, "Wrapping: Lost connection, was not connected. gatt=" + gatt);
}
BtDevice.this.gatt = null;
} else {
- Log.i(TAG, "Wrapper: connected");
+ Log.i(TAG, "Wrapping: 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 50aad13..bffdd19 100644
--- a/app/src/main/java/io/trygvis/android/bt/BtPromise.java
+++ b/app/src/main/java/io/trygvis/android/bt/BtPromise.java
@@ -371,17 +371,11 @@ public class BtPromise {
if (result instanceof Detour) {
BtPromise detour = ((Detour) result).promise;
- Log.i(TAG, "Adding detour with " + detour.actionQ.size() + " actions.");
+// 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);
- }
-
// The new promise should probably be stacked on top, so that all of its
// finally handlers are executed after the added set concludes and then the
// current stack can continue.
@@ -389,10 +383,6 @@ public class BtPromise {
actionQ.addAll(currentAction, detour.actionQ);
// 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();
}
diff --git a/app/src/main/java/io/trygvis/android/bt/BtScanResult.java b/app/src/main/java/io/trygvis/android/bt/BtScanResult.java
deleted file mode 100644
index c443afa..0000000
--- a/app/src/main/java/io/trygvis/android/bt/BtScanResult.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.trygvis.android.bt;
-
-public class BtScanResult {
- private final byte[] scanRecord;
-
- public BtScanResult(byte[] scanRecord) {
- this.scanRecord = scanRecord;
- }
-}
diff --git a/app/src/main/java/io/trygvis/android/bt/BtService.java b/app/src/main/java/io/trygvis/android/bt/BtService.java
index 06857ee..46f1a80 100644
--- a/app/src/main/java/io/trygvis/android/bt/BtService.java
+++ b/app/src/main/java/io/trygvis/android/bt/BtService.java
@@ -61,5 +61,8 @@ public interface BtService<A> {
public void onDeviceConnection(String address) {
}
+
+ public void onDevicePropertyUpdated(String address) {
+ }
}
}
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 e42e685..2487bd8 100644
--- a/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
+++ b/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
@@ -31,6 +31,7 @@ import io.trygvis.android.Function;
import io.trygvis.android.LocalBinder;
import io.trygvis.soilmoisture.R;
+import static android.bluetooth.BluetoothAdapter.LeScanCallback;
import static java.util.Collections.unmodifiableCollection;
public class DefaultBtService<A> extends Service implements BtService<A> {
@@ -54,6 +55,8 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
private boolean scanning = false;
+ private Scanner scanner = new Scanner();
+
// -----------------------------------------------------------------------
// BtService Implementation
// -----------------------------------------------------------------------
@@ -111,7 +114,7 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
for (String address : addresses) {
BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
- register(bluetoothDevice, null, null);
+ register(bluetoothDevice, null, false);
}
return true;
@@ -134,8 +137,9 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
handler.postDelayed(this::stopScanning, timeoutMs);
}
- if (bluetoothAdapter.startLeScan(leScanCallback)) {
+ if (bluetoothAdapter.startLeScan(scanner)) {
scanning = true;
+ scanner.found.clear();
sendBroadcast(createScanStarted());
return true;
}
@@ -148,9 +152,22 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
Log.d(TAG, "stopScanning");
// This doesn't mind being called twice.
- bluetoothAdapter.stopLeScan(leScanCallback);
+ bluetoothAdapter.stopLeScan(scanner);
scanning = false;
+ for (BtDevice<A> device : devices) {
+ boolean recentlySeen = scanner.found.contains(device);
+ Log.i(TAG, "scanner.found.contains(device)=" + recentlySeen + ", " +
+ "address=" + device.getAddress());
+
+ boolean old = device.isRecentlySeen();
+ device.setRecentlySeen(recentlySeen);
+
+ // Only if it not seen and it wasn't previously seen
+ if (!recentlySeen && old) {
+ sendBroadcast(createDevicePropertyUpdated(device.getAddress()));
+ }
+ }
sendBroadcast(createScanStopped());
}
@@ -163,7 +180,7 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
}
BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(mac);
- return register(bluetoothDevice, null, null);
+ return register(bluetoothDevice, null, false);
}
@Override
@@ -205,16 +222,6 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
}
// -----------------------------------------------------------------------
- // Scanning
- // -----------------------------------------------------------------------
-
- private BluetoothAdapter.LeScanCallback leScanCallback = (device, rssi, scanRecord) -> {
- BtScanResult scanResult = new BtScanResult(scanRecord);
-
- register(device, rssi, scanResult);
- };
-
- // -----------------------------------------------------------------------
// Service Implementation
// -----------------------------------------------------------------------
@@ -278,17 +285,19 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
return openOrCreateDatabase("bt-devices", MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
}
- private BtDevice<A> register(BluetoothDevice bluetoothDevice, Integer rssi, BtScanResult scanResult) {
+ private BtDevice<A> register(BluetoothDevice bluetoothDevice, Integer rssi, boolean fromScan) {
String address = bluetoothDevice.getAddress();
- BtDevice<A> btDevice = findDevice(address);
+ BtDevice<A> device = findDevice(address);
- if (btDevice != null) {
- return btDevice;
+ if (device != null) {
+ device.setRecentlySeen(true);
+ sendBroadcast(createDevicePropertyUpdated(device.getAddress()));
+ return device;
}
long now = System.currentTimeMillis();
- btDevice = runTx(db -> {
+ device = runTx(db -> {
Cursor cursor = db.query(Tables.T_BT_DEVICE, new String[]{Tables.C_ID, Tables.C_FIRST_SEEN},
Tables.C_ADDRESS + "=?", new String[]{address}, null, null, null);
@@ -315,15 +324,15 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
Log.i(TAG, "New device: " + address + ", seenBefore=" + seenBefore);
cursor.close();
- return new BtDevice<>(this, bluetoothDevice, db, btDbIntegration, id, rssi, scanResult,
- seenBefore, firstSeen, lastSeen);
+ return new BtDevice<>(this, bluetoothDevice, db, btDbIntegration, id, rssi, seenBefore,
+ firstSeen, lastSeen, fromScan);
});
- devices.add(btDevice);
+ devices.add(device);
- sendBroadcast(createNewDevice(btDevice.getAddress()));
+ sendBroadcast(createNewDevice(device.getAddress()));
- return btDevice;
+ return device;
}
Intent createScanStarted() {
@@ -348,6 +357,12 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
putExtra("address", address);
}
+ Intent createDevicePropertyUpdated(String address) {
+ return new Intent(BtServiceListenerBroadcastReceiver.INTENT_NAME).
+ putExtra("event", "devicePropertyUpdated").
+ putExtra("address", address);
+ }
+
public static void dispatchEvent(Intent intent, BtServiceListenerBroadcastReceiver listener) {
String event = intent.getStringExtra("event");
Log.i(TAG, "Dispatching event " + intent.getAction() + "/" + event);
@@ -361,6 +376,9 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
case "newDevice":
listener.onNewDevice(intent.getStringExtra("address"));
break;
+ case "devicePropertyUpdated":
+ listener.onDevicePropertyUpdated(intent.getStringExtra("address"));
+ break;
case "deviceConnection":
listener.onDeviceConnection(intent.getStringExtra("address"));
break;
@@ -377,4 +395,15 @@ public class DefaultBtService<A> extends Service implements BtService<A> {
}
return null;
}
+
+ private class Scanner implements LeScanCallback {
+
+ private List<BtDevice> found = new ArrayList<>();
+
+ @Override
+ public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
+ BtDevice<A> d = register(device, rssi, true);
+ found.add(d);
+ }
+ }
}