1
0
mirror of https://github.com/oliexdev/openScale.git synced 2025-08-24 09:13:04 +02:00

Try to run all ble commands on the main thread

This commit is contained in:
Erik Johansson
2018-10-07 22:26:40 +02:00
parent c381f48aa9
commit 8d47f9b968

View File

@@ -80,7 +80,6 @@ public abstract class BluetoothCommunication {
private Queue<GattObjectValue<BluetoothGattDescriptor>> descriptorRequestQueue;
private Queue<GattObjectValue<BluetoothGattCharacteristic>> characteristicRequestQueue;
private boolean openRequest;
private final Object lock = new Object();
public BluetoothCommunication(Context context)
{
@@ -240,11 +239,9 @@ public abstract class BluetoothCommunication {
* @param btMachineState the machine state that should be set.
*/
protected void setBtMachineState(BT_MACHINE_STATE btMachineState) {
synchronized (lock) {
this.btMachineState = btMachineState;
handleRequests();
}
}
/**
* Write a byte array to a Bluetooth device.
@@ -254,14 +251,12 @@ public abstract class BluetoothCommunication {
* @param bytes the bytes that should be write
*/
protected void writeBytes(UUID service, UUID characteristic, byte[] bytes) {
synchronized (lock) {
characteristicRequestQueue.add(
new GattObjectValue<>(
bluetoothGatt.getService(service).getCharacteristic(characteristic),
bytes));
handleRequests();
}
}
/**
* Read bytes from a Bluetooth device.
@@ -301,14 +296,12 @@ public abstract class BluetoothCommunication {
bluetoothGatt.getService(service).getCharacteristic(characteristic);
bluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
synchronized (lock) {
descriptorRequestQueue.add(
new GattObjectValue<>(
gattCharacteristic.getDescriptor(descriptor),
BluetoothGattDescriptor.ENABLE_INDICATION_VALUE));
handleRequests();
}
}
catch (Exception e) {
Timber.e(e);
}
@@ -328,14 +321,12 @@ public abstract class BluetoothCommunication {
bluetoothGatt.getService(service).getCharacteristic(characteristic);
bluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
synchronized (lock) {
descriptorRequestQueue.add(
new GattObjectValue<>(
gattCharacteristic.getDescriptor(descriptor),
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
handleRequests();
}
}
catch (Exception e) {
Timber.e(e);
}
@@ -354,14 +345,12 @@ public abstract class BluetoothCommunication {
bluetoothGatt.getService(service).getCharacteristic(characteristic);
bluetoothGatt.setCharacteristicNotification(gattCharacteristic, false);
synchronized (lock) {
descriptorRequestQueue.add(
new GattObjectValue<>(
gattCharacteristic.getDescriptor(descriptor),
BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
handleRequests();
}
}
/**
* Convert a byte array to hex for debugging purpose
@@ -415,6 +404,8 @@ public abstract class BluetoothCommunication {
* @param hwAddress the Bluetooth address to connect to
*/
public void connect(String hwAddress) {
disconnect(false);
logBluetoothStatus();
// Some good tips to improve BLE connections:
@@ -481,6 +472,7 @@ public abstract class BluetoothCommunication {
if (!device.getAddress().equals(hwAddress)) {
return;
}
// Stop scan and connect to the device on the main thread
handler.post(new Runnable() {
@Override
public void run() {
@@ -496,15 +488,14 @@ public abstract class BluetoothCommunication {
Timber.d("Starting LE scan for device [%s]", hwAddress);
btAdapter.startLeScan(leScanCallback);
// Stop scan and try to connect to the device directly if the device isn't found in time
handler.postAtTime(new Runnable() {
@Override
public void run() {
Timber.d("Device not found in LE scan, connecting directly");
synchronized (lock) {
stopLeScan();
connectGatt(hwAddress);
}
}
}, leScanCallback, SystemClock.uptimeMillis() + LE_SCAN_TIMEOUT_MS);
}
@@ -521,7 +512,6 @@ public abstract class BluetoothCommunication {
* Disconnect from a Bluetooth device
*/
public void disconnect(boolean doCleanup) {
synchronized (lock) {
stopLeScan();
if (bluetoothGatt == null) {
@@ -530,9 +520,6 @@ public abstract class BluetoothCommunication {
Timber.i("Disconnecting%s", doCleanup ? " (with cleanup)" : "");
handler.removeCallbacksAndMessages(null);
callbackBtHandler = null;
if (doCleanup) {
if (btMachineState != BT_MACHINE_STATE.BT_CLEANUP_STATE) {
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
@@ -541,13 +528,12 @@ public abstract class BluetoothCommunication {
handler.post(new Runnable() {
@Override
public void run() {
synchronized (lock) {
if (openRequest) {
handler.postDelayed(this, 10);
} else {
bluetoothGatt.close();
bluetoothGatt = null;
}
handler.removeCallbacksAndMessages(null);
}
}
});
@@ -556,7 +542,9 @@ public abstract class BluetoothCommunication {
bluetoothGatt.close();
bluetoothGatt = null;
}
}
handler.removeCallbacksAndMessages(null);
callbackBtHandler = null;
}
/**
@@ -586,7 +574,6 @@ public abstract class BluetoothCommunication {
}
private void handleRequests() {
synchronized (lock) {
// check for pending request
if (openRequest) {
Timber.d("Request pending (queue %d %d)",
@@ -615,8 +602,9 @@ public abstract class BluetoothCommunication {
if (characteristic != null) {
characteristic.gattObject.setValue(characteristic.value);
Timber.d("Write characteristic %s: %s (queue: %d %d)",
Timber.d("Write characteristic %s: %s (type: %d; queue: %d %d)",
characteristic.gattObject.getUuid(), byteInHex(characteristic.gattObject.getValue()),
characteristic.gattObject.getWriteType(),
descriptorRequestQueue.size(), characteristicRequestQueue.size());
if (!bluetoothGatt.writeCharacteristic(characteristic.gattObject)) {
Timber.e("Failed to initiate write of characteristic %s",
@@ -629,7 +617,6 @@ public abstract class BluetoothCommunication {
// After every command was executed, continue with the next step
nextMachineStateStep();
}
}
/**
* Custom Gatt callback class to set up a Bluetooth state machine.
@@ -640,9 +627,10 @@ public abstract class BluetoothCommunication {
Timber.d("onConnectionStateChange: status=%d, newState=%d", status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
synchronized (lock) {
handler.post(new Runnable() {
@Override
public void run() {
stopLeScan();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
gatt.readPhy();
@@ -650,25 +638,32 @@ public abstract class BluetoothCommunication {
connectionEstablished = true;
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_ESTABLISHED);
}
});
try {
Thread.sleep(1000);
}
catch (Exception e) {
// Empty
}
// Wait a short while after connecting before scanning for services
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (!gatt.discoverServices()) {
Timber.e("Could not start service discovery");
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
disconnect(false);
}
}
}, 1000);
}
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
handler.post(new Runnable() {
@Override
public void run() {
setBtStatus(connectionEstablished
? BT_STATUS_CODE.BT_CONNECTION_LOST
: BT_STATUS_CODE.BT_NO_DEVICE_FOUND);
disconnect(false);
}
});
}
}
@Override
@@ -677,12 +672,22 @@ public abstract class BluetoothCommunication {
status, gatt.getServices().size());
if (gatt.getServices().isEmpty()) {
handler.post(new Runnable() {
@Override
public void run() {
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "No services found");
disconnect(false);
}
});
return;
}
synchronized (lock) {
// Sleeping a while after discovering services fixes connection problems.
// See https://github.com/NordicSemiconductor/Android-DFU-Library/issues/10
// for some technical background.
handler.postDelayed(new Runnable() {
@Override
public void run() {
cmdStepNr = 0;
initStepNr = 0;
cleanupStepNr = 0;
@@ -691,21 +696,12 @@ public abstract class BluetoothCommunication {
characteristicRequestQueue = new LinkedList<>();
descriptorRequestQueue = new LinkedList<>();
openRequest = false;
}
try {
// Sleeping a while after discovering services fixes connection problems.
// See https://github.com/NordicSemiconductor/Android-DFU-Library/issues/10
// for some technical background.
Thread.sleep(1000);
}
catch (Exception e) {
// Empty
}
// Start the state machine
setBtMachineState(BT_MACHINE_STATE.BT_INIT_STATE);
}
}, 1000);
}
@Override
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
@@ -723,11 +719,9 @@ public abstract class BluetoothCommunication {
handler.postDelayed(new Runnable() {
@Override
public void run() {
synchronized (lock) {
openRequest = false;
handleRequests();
}
}
}, 60);
}
@@ -746,27 +740,33 @@ public abstract class BluetoothCommunication {
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
public void onCharacteristicRead(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic,
final int status) {
Timber.d("onCharacteristicRead %s (status=%d): %s",
characteristic.getUuid(), status, byteInHex(characteristic.getValue()));
synchronized (lock) {
handler.post(new Runnable() {
@Override
public void run() {
onBluetoothDataRead(gatt, characteristic, status);
postDelayedHandleRequests();
}
});
postDelayedHandleRequests();
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
public void onCharacteristicChanged(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic) {
Timber.d("onCharacteristicChanged %s: %s",
characteristic.getUuid(), byteInHex(characteristic.getValue()));
synchronized (lock) {
handler.post(new Runnable() {
@Override
public void run() {
onBluetoothDataChange(gatt, characteristic);
}
});
}
@Override