mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-12 21:19:25 +01:00
Initial support for transaction-local GattCallbacks (not used yet)
So that we won't have to mix everything in MiBandSupport
This commit is contained in:
parent
495a8cc650
commit
b7223c7e86
@ -0,0 +1,42 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for GattCallbacks wishing to just implement a few of the methods.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractGattCallback implements GattCallback {
|
||||||
|
@Override
|
||||||
|
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(BluetoothGatt gatt) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import android.bluetooth.BluetoothGattDescriptor;
|
|||||||
import android.bluetooth.BluetoothGattService;
|
import android.bluetooth.BluetoothGattService;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -19,9 +20,9 @@ import java.util.concurrent.BlockingQueue;
|
|||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One queue/thread per connectable device.
|
* One queue/thread per connectable device.
|
||||||
@ -49,7 +50,7 @@ public final class BtLEQueue {
|
|||||||
private CountDownLatch mWaitForActionResultLatch;
|
private CountDownLatch mWaitForActionResultLatch;
|
||||||
private CountDownLatch mConnectionLatch;
|
private CountDownLatch mConnectionLatch;
|
||||||
private BluetoothGattCharacteristic mWaitCharacteristic;
|
private BluetoothGattCharacteristic mWaitCharacteristic;
|
||||||
private GattCallback mExternalGattCallback;
|
private final InternalGattCallback internalGattCallback;
|
||||||
|
|
||||||
private Thread dispatchThread = new Thread("GadgetBridge GATT Dispatcher") {
|
private Thread dispatchThread = new Thread("GadgetBridge GATT Dispatcher") {
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ public final class BtLEQueue {
|
|||||||
while (!mDisposed && !mCrashed) {
|
while (!mDisposed && !mCrashed) {
|
||||||
try {
|
try {
|
||||||
Transaction transaction = mTransactions.take();
|
Transaction transaction = mTransactions.take();
|
||||||
|
internalGattCallback.setTransactionGattCallback(null);
|
||||||
|
|
||||||
if (!isConnected()) {
|
if (!isConnected()) {
|
||||||
// TODO: request connection and initialization from the outside and wait until finished
|
// TODO: request connection and initialization from the outside and wait until finished
|
||||||
|
|
||||||
@ -73,6 +76,7 @@ public final class BtLEQueue {
|
|||||||
mConnectionLatch = null;
|
mConnectionLatch = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internalGattCallback.setTransactionGattCallback(transaction.getGattCallback());
|
||||||
mAbortTransaction = false;
|
mAbortTransaction = false;
|
||||||
// Run all actions of the transaction until one doesn't succeed
|
// Run all actions of the transaction until one doesn't succeed
|
||||||
for (BtLEAction action : transaction.getActions()) {
|
for (BtLEAction action : transaction.getActions()) {
|
||||||
@ -106,6 +110,7 @@ public final class BtLEQueue {
|
|||||||
} finally {
|
} finally {
|
||||||
mWaitForActionResultLatch = null;
|
mWaitForActionResultLatch = null;
|
||||||
mWaitCharacteristic = null;
|
mWaitCharacteristic = null;
|
||||||
|
internalGattCallback.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG.info("Queue Dispatch Thread terminated.");
|
LOG.info("Queue Dispatch Thread terminated.");
|
||||||
@ -115,7 +120,7 @@ public final class BtLEQueue {
|
|||||||
public BtLEQueue(BluetoothAdapter bluetoothAdapter, GBDevice gbDevice, GattCallback externalGattCallback, Context context) {
|
public BtLEQueue(BluetoothAdapter bluetoothAdapter, GBDevice gbDevice, GattCallback externalGattCallback, Context context) {
|
||||||
mBluetoothAdapter = bluetoothAdapter;
|
mBluetoothAdapter = bluetoothAdapter;
|
||||||
mGbDevice = gbDevice;
|
mGbDevice = gbDevice;
|
||||||
mExternalGattCallback = externalGattCallback;
|
internalGattCallback = new InternalGattCallback(externalGattCallback);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
|
||||||
dispatchThread.start();
|
dispatchThread.start();
|
||||||
@ -254,7 +259,25 @@ public final class BtLEQueue {
|
|||||||
|
|
||||||
// Implements callback methods for GATT events that the app cares about. For example,
|
// Implements callback methods for GATT events that the app cares about. For example,
|
||||||
// connection change and services discovered.
|
// connection change and services discovered.
|
||||||
private final BluetoothGattCallback internalGattCallback = new BluetoothGattCallback() {
|
private final class InternalGattCallback extends BluetoothGattCallback {
|
||||||
|
private @Nullable GattCallback mTransactionGattCallback;
|
||||||
|
private GattCallback mExternalGattCallback;
|
||||||
|
|
||||||
|
public InternalGattCallback(GattCallback externalGattCallback) {
|
||||||
|
mExternalGattCallback = externalGattCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionGattCallback(@Nullable GattCallback callback) {
|
||||||
|
mTransactionGattCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GattCallback getCallbackToUse() {
|
||||||
|
if (mTransactionGattCallback != null) {
|
||||||
|
return mTransactionGattCallback;
|
||||||
|
}
|
||||||
|
return mExternalGattCallback;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||||
LOG.debug("connection state change, newState: " + newState + getStatusString(status));
|
LOG.debug("connection state change, newState: " + newState + getStatusString(status));
|
||||||
@ -293,9 +316,9 @@ public final class BtLEQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
// only propagate the successful event
|
// only propagate the successful event
|
||||||
mExternalGattCallback.onServicesDiscovered(gatt);
|
getCallbackToUse().onServicesDiscovered(gatt);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("onServicesDiscovered received: " + status);
|
LOG.warn("onServicesDiscovered received: " + status);
|
||||||
@ -308,8 +331,8 @@ public final class BtLEQueue {
|
|||||||
if (!checkCorrectGattInstance(gatt, "characteristic write")) {
|
if (!checkCorrectGattInstance(gatt, "characteristic write")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
mExternalGattCallback.onCharacteristicWrite(gatt, characteristic, status);
|
getCallbackToUse().onCharacteristicWrite(gatt, characteristic, status);
|
||||||
}
|
}
|
||||||
checkWaitingCharacteristic(characteristic, status);
|
checkWaitingCharacteristic(characteristic, status);
|
||||||
}
|
}
|
||||||
@ -322,8 +345,8 @@ public final class BtLEQueue {
|
|||||||
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
|
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
mExternalGattCallback.onCharacteristicRead(gatt, characteristic, status);
|
getCallbackToUse().onCharacteristicRead(gatt, characteristic, status);
|
||||||
}
|
}
|
||||||
checkWaitingCharacteristic(characteristic, status);
|
checkWaitingCharacteristic(characteristic, status);
|
||||||
}
|
}
|
||||||
@ -334,8 +357,8 @@ public final class BtLEQueue {
|
|||||||
if (!checkCorrectGattInstance(gatt, "descriptor read")) {
|
if (!checkCorrectGattInstance(gatt, "descriptor read")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
mExternalGattCallback.onDescriptorRead(gatt, descriptor, status);
|
getCallbackToUse().onDescriptorRead(gatt, descriptor, status);
|
||||||
}
|
}
|
||||||
checkWaitingCharacteristic(descriptor.getCharacteristic(), status);
|
checkWaitingCharacteristic(descriptor.getCharacteristic(), status);
|
||||||
}
|
}
|
||||||
@ -346,8 +369,8 @@ public final class BtLEQueue {
|
|||||||
if (!checkCorrectGattInstance(gatt, "descriptor write")) {
|
if (!checkCorrectGattInstance(gatt, "descriptor write")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
mExternalGattCallback.onDescriptorWrite(gatt, descriptor, status);
|
getCallbackToUse().onDescriptorWrite(gatt, descriptor, status);
|
||||||
}
|
}
|
||||||
checkWaitingCharacteristic(descriptor.getCharacteristic(), status);
|
checkWaitingCharacteristic(descriptor.getCharacteristic(), status);
|
||||||
}
|
}
|
||||||
@ -363,8 +386,8 @@ public final class BtLEQueue {
|
|||||||
LOG.info("Ignoring characteristic change event from wrong BluetoothGatt instance");
|
LOG.info("Ignoring characteristic change event from wrong BluetoothGatt instance");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
mExternalGattCallback.onCharacteristicChanged(gatt, characteristic);
|
getCallbackToUse().onCharacteristicChanged(gatt, characteristic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,8 +401,8 @@ public final class BtLEQueue {
|
|||||||
LOG.info("Ignoring remote rssi event from wrong BluetoothGatt instance");
|
LOG.info("Ignoring remote rssi event from wrong BluetoothGatt instance");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mExternalGattCallback != null) {
|
if (getCallbackToUse() != null) {
|
||||||
mExternalGattCallback.onReadRemoteRssi(gatt, rssi, status);
|
getCallbackToUse().onReadRemoteRssi(gatt, rssi, status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,9 +421,13 @@ public final class BtLEQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
private String getStatusString(int status) {
|
private String getStatusString(int status) {
|
||||||
return status == BluetoothGatt.GATT_SUCCESS ? " (success)" : " (failed: " + status + ")";
|
return status == BluetoothGatt.GATT_SUCCESS ? " (success)" : " (failed: " + status + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
mTransactionGattCallback = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -17,6 +19,7 @@ public class Transaction {
|
|||||||
private String mName;
|
private String mName;
|
||||||
private List<BtLEAction> mActions = new ArrayList<>(4);
|
private List<BtLEAction> mActions = new ArrayList<>(4);
|
||||||
private long creationTimestamp = System.currentTimeMillis();
|
private long creationTimestamp = System.currentTimeMillis();
|
||||||
|
private @Nullable GattCallback gattCallback;
|
||||||
|
|
||||||
public Transaction(String taskName) {
|
public Transaction(String taskName) {
|
||||||
this.mName = taskName;
|
this.mName = taskName;
|
||||||
@ -46,4 +49,15 @@ public class Transaction {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format(Locale.US, "%s: Transaction task: %s with %d actions", getCreationTime(), getTaskName(), mActions.size());
|
return String.format(Locale.US, "%s: Transaction task: %s with %d actions", getCreationTime(), getTaskName(), mActions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGattCallback(@Nullable GattCallback callback) {
|
||||||
|
gattCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GattCallback for this transaction, or null if none.
|
||||||
|
*/
|
||||||
|
public @Nullable GattCallback getGattCallback() {
|
||||||
|
return gattCallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -60,6 +61,19 @@ public class TransactionBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a GattCallback instance that will be called when the transaction is executed,
|
||||||
|
* resulting in GattCallback events.
|
||||||
|
* @param callback the callback to set, may be null
|
||||||
|
*/
|
||||||
|
public void setGattCallback(@Nullable GattCallback callback) {
|
||||||
|
mTransaction.setGattCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable GattCallback getGattCallback() {
|
||||||
|
return mTransaction.getGattCallback();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To be used as the final step to execute the transaction by the given queue.
|
* To be used as the final step to execute the transaction by the given queue.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user