From 9c82180930d550f8fb40cd55acd7d6a18fe8225c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 22 Oct 2022 22:00:01 +0100 Subject: [PATCH] Zepp OS: Do not change GATT Callback unless explicitely set --- .../gadgetbridge/service/AbstractDeviceSupport.java | 5 +++++ .../gadgetbridge/service/DeviceSupport.java | 10 ++++++++++ .../gadgetbridge/service/ServiceDeviceSupport.java | 5 +++++ .../service/btle/AbstractBTLEDeviceSupport.java | 2 +- .../gadgetbridge/service/btle/BtLEQueue.java | 10 +++++++++- .../gadgetbridge/service/btle/Transaction.java | 12 ++++++++++++ .../service/devices/huami/Huami2021Support.java | 9 +++++++++ 7 files changed, 51 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 1119cc181..88d559443 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -141,6 +141,11 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { return autoReconnect; } + @Override + public boolean getImplicitCallbackModify() { + return true; + } + @Override public GBDevice getDevice() { return gbDevice; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java index 71cce5211..dd54530f6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java @@ -114,6 +114,16 @@ public interface DeviceSupport extends EventHandler { */ boolean getAutoReconnect(); + /** + * Returns whether the gatt callback should be implicitly set to the one on the transaction, + * even if it was not set directly on the transaction. If true, the gatt callback will always + * be set to the one in the transaction, even if null and not explicitly set to null. + * See https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2912 for more information. + * This should be false by default, but we are making it configurable to avoid breaking + * older devices that rely on this behavior. + */ + boolean getImplicitCallbackModify(); + /** * Returns the associated device this instance communicates with. */ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index 1630029c1..252bc5de2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -102,6 +102,11 @@ public class ServiceDeviceSupport implements DeviceSupport { return delegate.getAutoReconnect(); } + @Override + public boolean getImplicitCallbackModify() { + return delegate.getImplicitCallbackModify(); + } + @Override public void dispose() { delegate.dispose(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java index 8f718a743..cf3cfc8ff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java @@ -22,7 +22,6 @@ import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; -import android.content.Intent; import android.location.Location; import org.slf4j.Logger; @@ -78,6 +77,7 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im if (mQueue == null) { mQueue = new BtLEQueue(getBluetoothAdapter(), getDevice(), this, this, getContext(), mSupportedServerServices); mQueue.setAutoReconnect(getAutoReconnect()); + mQueue.setImplicitGattCallbackModify(getImplicitCallbackModify()); } return mQueue.connect(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java index 026c34682..9a3b2cf65 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java @@ -79,6 +79,7 @@ public final class BtLEQueue { private final InternalGattCallback internalGattCallback; private final InternalGattServerCallback internalGattServerCallback; private boolean mAutoReconnect; + private boolean mImplicitGattCallbackModify = true; private Thread dispatchThread = new Thread("Gadgetbridge GATT Dispatcher") { @@ -137,7 +138,10 @@ public final class BtLEQueue { if(qTransaction instanceof Transaction) { Transaction transaction = (Transaction)qTransaction; - internalGattCallback.setTransactionGattCallback(transaction.getGattCallback()); + LOG.trace("Changing gatt callback for {}? {}", transaction.getTaskName(), transaction.isModifyGattCallback()); + if (mImplicitGattCallbackModify || transaction.isModifyGattCallback()) { + internalGattCallback.setTransactionGattCallback(transaction.getGattCallback()); + } mAbortTransaction = false; // Run all actions of the transaction until one doesn't succeed for (BtLEAction action : transaction.getActions()) { @@ -202,6 +206,10 @@ public final class BtLEQueue { mAutoReconnect = enable; } + public void setImplicitGattCallbackModify(final boolean enable) { + mImplicitGattCallbackModify = enable; + } + protected boolean isConnected() { return mGbDevice.isConnected(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java index 063eab35f..a64c256e6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java @@ -31,10 +31,13 @@ import androidx.annotation.Nullable; */ public class Transaction extends AbstractTransaction { private final List mActions = new ArrayList<>(4); + private @Nullable GattCallback gattCallback; + private boolean modifyGattCallback; + public Transaction(String taskName) { super(taskName); } @@ -53,6 +56,7 @@ public class Transaction extends AbstractTransaction { public void setGattCallback(@Nullable GattCallback callback) { gattCallback = callback; + modifyGattCallback = true; } /** @@ -64,6 +68,14 @@ public class Transaction extends AbstractTransaction { return gattCallback; } + /** + * Returns whether the gatt callback should be modified for this transaction (either set, or + * unset if {@code getGattCallback} is null. + */ + public boolean isModifyGattCallback() { + return modifyGattCallback; + } + @Override public int getActionCount() { return mActions.size(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java index df5bcd3b7..bc747fe15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java @@ -161,6 +161,15 @@ public abstract class Huami2021Support extends HuamiSupport { return (byte) 0x80; } + /** + * Do not reset the gatt callback implicitly, as that would interrupt operations. + * See https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2912 for more information. + */ + @Override + public boolean getImplicitCallbackModify() { + return false; + } + @Override public void onSendConfiguration(final String config) { final ConfigSetter configSetter = new ConfigSetter();