From 2a7ccef529c5308a90c183b49814861121f72144 Mon Sep 17 00:00:00 2001 From: Thomas Kuehne Date: Sun, 14 Jun 2026 10:43:39 +0000 Subject: [PATCH] BtLEAction: code review --- .../gadgetbridge/service/btle/BtLEAction.java | 23 ++++++++++++------- .../btle/actions/AbortTransactionAction.java | 7 ++++-- .../service/btle/actions/BondAction.java | 5 ++-- .../btle/actions/CheckInitializedAction.java | 9 +++++--- .../btle/actions/ConditionalWriteAction.java | 19 +++++++++------ .../service/btle/actions/FunctionAction.java | 4 ++-- .../service/btle/actions/NotifyAction.java | 16 +++++++++---- .../service/btle/actions/PlainAction.java | 5 +++- .../service/btle/actions/ReadAction.java | 9 +++++--- .../service/btle/actions/ReadPhyAction.java | 6 +++-- .../RequestConnectionPriorityAction.java | 7 ++++-- .../btle/actions/RequestMtuAction.java | 12 ++++++---- .../btle/actions/SetDeviceBusyAction.java | 5 ++-- .../btle/actions/SetDeviceStateAction.java | 7 +++--- .../btle/actions/SetPreferredPhyAction.java | 8 ++++--- .../btle/actions/SetProgressAction.java | 10 ++++---- .../service/btle/actions/SleepAction.java | 14 +++++++---- .../service/btle/actions/WriteAction.java | 13 +++++++---- 18 files changed, 116 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java index 7e630ae4ef..bf7a25eca9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2015-2026 Carsten Pfeiffer, Uwe Hermann, Thomas Kuehne This file is part of Gadgetbridge. @@ -19,15 +19,19 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; /** * The Bluedroid implementation only allows performing one GATT request at a time. * As they are asynchronous anyway, we encapsulate every GATT request (read and write) * inside a runnable action. - *

+ *

* These actions are then executed one after another, ensuring that every action's result * has been posted before invoking the next action. + *

*/ public abstract class BtLEAction { private final BluetoothGattCharacteristic characteristic; @@ -41,33 +45,36 @@ public abstract class BtLEAction { /** * Returns true if this action expects an (async) result which must * be waited for, before continuing with other actions. - *

+ *

* This is needed because the current Bluedroid stack can only deal * with one single bluetooth operation at a time. + *

*/ public abstract boolean expectsResult(); /** - * Executes this action, e.g. reads or write a GATT characteristic. + * Executes this action, e.g. reads or write a {@link GattCharacteristic}. * - * @param gatt the characteristic to manipulate, or null if none. - * @return true if the action was successful, false otherwise + * @return {@code true} if the action was successful, {@code false} otherwise */ - public abstract boolean run(BluetoothGatt gatt); + public abstract boolean run(@NonNull BluetoothGatt gatt); /** * Returns the GATT characteristic being read/written/... * - * @return the GATT characteristic, or null + * @return the GATT characteristic, or {@code null} */ + @Nullable public BluetoothGattCharacteristic getCharacteristic() { return characteristic; } + @NonNull protected String getCreationTime() { return DateTimeUtils.formatLocalTime(creationTimestamp); } + @NonNull public String toString() { BluetoothGattCharacteristic characteristic = getCharacteristic(); String uuid = characteristic == null ? "(null)" : characteristic.getUuid().toString(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java index 12bbe68324..579a6e9b50 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Carsten Pfeiffer +/* Copyright (C) 2015-2026 Carsten Pfeiffer This file is part of Gadgetbridge. @@ -18,6 +18,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; import android.bluetooth.BluetoothGatt; +import androidx.annotation.NonNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +31,7 @@ public abstract class AbortTransactionAction extends PlainAction { private static final Logger LOG = LoggerFactory.getLogger(AbortTransactionAction.class); @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { if (shouldAbort()) { LOG.info("Aborting transaction because abort criteria met."); return false; @@ -39,6 +41,7 @@ public abstract class AbortTransactionAction extends PlainAction { protected abstract boolean shouldAbort(); + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName() + " abort=" + shouldAbort(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java index 9102470835..f6bb1fe037 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2023-2025 Andreas Böhler, Thomas Kuehne +/* Copyright (C) 2023-2026 Andreas Böhler, Thomas Kuehne This file is part of Gadgetbridge. @@ -22,6 +22,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; @@ -70,7 +71,7 @@ public class BondAction extends PlainAction implements BondingInterface { } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { BluetoothDevice device = gatt.getDevice(); mCandidate = new GBDeviceCandidate(device, GBDevice.RSSI_UNKNOWN, null, null); BondingUtil.tryBondThenComplete(this, device); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java index 3dc83b5d01..2d4829d706 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2024 Carsten Pfeiffer +/* Copyright (C) 2016-2026 Carsten Pfeiffer This file is part of Gadgetbridge. @@ -16,6 +16,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; +import androidx.annotation.NonNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,9 +31,10 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; public class CheckInitializedAction extends AbortTransactionAction { private static final Logger LOG = LoggerFactory.getLogger(CheckInitializedAction.class); + @NonNull private final GBDevice device; - public CheckInitializedAction(GBDevice gbDevice) { + public CheckInitializedAction(@NonNull GBDevice gbDevice) { device = gbDevice; } @@ -39,7 +42,7 @@ public class CheckInitializedAction extends AbortTransactionAction { protected boolean shouldAbort() { boolean abort = device.isInitialized(); if (abort) { - LOG.info("Aborting device initialization, because already initialized: " + device); + LOG.info("Aborting device initialization, because already initialized: {}", device); } return abort; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java index 623b6eae82..82d6474d05 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2025 Andreas Shimokawa, Carsten Pfeiffer, Thomas Kuehne +/* Copyright (C) 2016-2026 Andreas Shimokawa, Carsten Pfeiffer, Thomas Kuehne This file is part of Gadgetbridge. @@ -19,16 +19,19 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + public abstract class ConditionalWriteAction extends WriteAction { private boolean actualGenerated; private byte[] actual; - public ConditionalWriteAction(BluetoothGattCharacteristic characteristic) { + public ConditionalWriteAction(@NonNull BluetoothGattCharacteristic characteristic) { super(characteristic, null); } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { byte[] value = getValue(); if (value != null) { return super.run(gatt); @@ -47,12 +50,14 @@ public abstract class ConditionalWriteAction extends WriteAction { /** * Checks the condition whether the write shall happen or not. - * Returns the actual value to be written or null in case nothing shall be written. - *

- * Note that returning null will not cause {@link #run()} to return false, in other words, + * Returns the actual value to be written or {@code null} in case nothing shall be written. + *

+ * Note that returning {@code null} will not cause {@link #run(BluetoothGatt)} to return {@code false}, in other words, * the rest of the queue will still be executed. + *

* - * @return the value to be written or null to not write anything + * @return the value to be written or {@code null} to not write anything */ + @Nullable protected abstract byte[] checkCondition(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/FunctionAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/FunctionAction.java index 4c6c32214b..ca42596e1d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/FunctionAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/FunctionAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2023-2025 Johannes Krude, Thomas Kuehne +/* Copyright (C) 2023-2026 Johannes Krude, Thomas Kuehne This file is part of Gadgetbridge. @@ -50,7 +50,7 @@ public class FunctionAction extends BtLEAction { } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { try { final boolean success; if (mRunnable != null) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java index 55d9de226d..1137e5a695 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Alicia Hormann, Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2026 Alicia Hormann, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. @@ -32,6 +32,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback; import static nodomain.freeyourgadget.gadgetbridge.service.btle.GattDescriptor.UUID_DESCRIPTOR_GATT_CLIENT_CHARACTERISTIC_CONFIGURATION; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.RequiresPermission; /** @@ -43,16 +45,19 @@ public class NotifyAction extends BtLEAction { private static final Logger LOG = LoggerFactory.getLogger(NotifyAction.class); private final boolean enableFlag; - private boolean hasWrittenDescriptor = false; + private boolean hasWrittenDescriptor; - public NotifyAction(BluetoothGattCharacteristic characteristic, boolean enable) { + public NotifyAction(@NonNull BluetoothGattCharacteristic characteristic, boolean enable) { super(characteristic); enableFlag = enable; + hasWrittenDescriptor = false; } /// shared write implementation that can be used without a BtLEAction @SuppressLint("MissingPermission") - public static boolean writeDescriptor(final BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final byte[] value) { + public static boolean writeDescriptor(@Nullable final BluetoothGatt gatt, + @Nullable final BluetoothGattDescriptor descriptor, + @NonNull final byte[] value) { if (gatt == null) { LOG.error("gatt == null"); return false; @@ -96,7 +101,7 @@ public class NotifyAction extends BtLEAction { @Override @RequiresPermission("android.permission.BLUETOOTH_CONNECT") - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { // register gatt's callback to receive notifications boolean result = gatt.setCharacteristicNotification(getCharacteristic(), enableFlag); @@ -137,6 +142,7 @@ public class NotifyAction extends BtLEAction { return hasWrittenDescriptor; } + @NonNull @Override public String toString() { BluetoothGattCharacteristic characteristic = getCharacteristic(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java index 5dc25c2c02..4ad91fd5c3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Carsten Pfeiffer +/* Copyright (C) 2015-2026 Carsten Pfeiffer This file is part of Gadgetbridge. @@ -16,6 +16,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; +import androidx.annotation.NonNull; + import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; @@ -34,6 +36,7 @@ public abstract class PlainAction extends BtLEAction { return false; } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java index 1cfcaf1e47..bfb15e1965 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2026 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. @@ -20,6 +20,8 @@ import android.annotation.SuppressLint; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import androidx.annotation.NonNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,13 +36,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback; public class ReadAction extends BtLEAction { private static final Logger LOG = LoggerFactory.getLogger(ReadAction.class); - public ReadAction(BluetoothGattCharacteristic characteristic) { + public ReadAction(@NonNull BluetoothGattCharacteristic characteristic) { super(characteristic); } @SuppressLint("MissingPermission") @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { int properties = getCharacteristic().getProperties(); if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) > 0) { return gatt.readCharacteristic(getCharacteristic()); @@ -54,6 +56,7 @@ public class ReadAction extends BtLEAction { return true; } + @NonNull @Override public String toString() { BluetoothGattCharacteristic characteristic = getCharacteristic(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadPhyAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadPhyAction.java index 8461fe8e1c..c10d5f78b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadPhyAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadPhyAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Thomas Kuehne +/* Copyright (C) 2025-2026 Thomas Kuehne This file is part of Gadgetbridge. @@ -21,6 +21,7 @@ import android.annotation.SuppressLint; import android.bluetooth.BluetoothGatt; import android.os.Build; +import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import org.slf4j.Logger; @@ -47,7 +48,7 @@ public class ReadPhyAction extends BtLEAction { @SuppressLint("MissingPermission") @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { try { gatt.readPhy(); return true; @@ -57,6 +58,7 @@ public class ReadPhyAction extends BtLEAction { } } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestConnectionPriorityAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestConnectionPriorityAction.java index d9a1a7f37e..229ba372db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestConnectionPriorityAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestConnectionPriorityAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2023-2024 José Rebelo +/* Copyright (C) 2023-2026 José Rebelo This file is part of Gadgetbridge. @@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; import android.annotation.SuppressLint; import android.bluetooth.BluetoothGatt; +import androidx.annotation.NonNull; + import nodomain.freeyourgadget.gadgetbridge.service.btle.BleNamesResolver; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; @@ -38,10 +40,11 @@ public class RequestConnectionPriorityAction extends BtLEAction { @Override @SuppressLint("MissingPermission") - public boolean run(final BluetoothGatt gatt) { + public boolean run(@NonNull final BluetoothGatt gatt) { return gatt.requestConnectionPriority(priority); } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName() + " " + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java index bc30a6576b..ffdbd9d58e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019-2024 Andreas Shimokawa, Daniel Dakhno +/* Copyright (C) 2019-2026 Andreas Shimokawa, Daniel Dakhno This file is part of Gadgetbridge. @@ -19,6 +19,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; import android.annotation.SuppressLint; import android.bluetooth.BluetoothGatt; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; + import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback; @@ -27,7 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback; public class RequestMtuAction extends BtLEAction { private final int mtu; - public RequestMtuAction(int mtu) { + public RequestMtuAction(@IntRange(from = 23L, to = 517L) final int mtu) { super(null); this.mtu = mtu; } @@ -40,10 +43,11 @@ public class RequestMtuAction extends BtLEAction { @SuppressLint("MissingPermission") @Override - public boolean run(BluetoothGatt gatt) { - return gatt.requestMtu(this.mtu); + public boolean run(@NonNull final BluetoothGatt gatt) { + return gatt.requestMtu(mtu); } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName() + " mtu=" + mtu; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java index 1d141df7a3..71345afaf8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2025 Carsten Pfeiffer, Thomas Kuehne +/* Copyright (C) 2015-2026 Carsten Pfeiffer, Thomas Kuehne This file is part of Gadgetbridge. @@ -45,7 +45,7 @@ public class SetDeviceBusyAction extends PlainAction { } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { if (busyTask == 0) { device.unsetBusyTask(); } else { @@ -56,6 +56,7 @@ public class SetDeviceBusyAction extends PlainAction { return true; } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getName() + " " diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java index 17eb53280b..da6e0dcf2b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2025 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Thomas Kuehne +/* Copyright (C) 2015-2026 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Thomas Kuehne This file is part of Gadgetbridge. @@ -28,18 +28,19 @@ public class SetDeviceStateAction extends PlainAction { private final GBDevice.State deviceState; private final Context context; - public SetDeviceStateAction(GBDevice device, GBDevice.State deviceState, Context context) { + public SetDeviceStateAction(@NonNull GBDevice device, @NonNull GBDevice.State deviceState, @NonNull Context context) { this.device = device; this.deviceState = deviceState; this.context = context; } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { device.setUpdateState(deviceState, context); return true; } + @NonNull public Context getContext() { return context; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetPreferredPhyAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetPreferredPhyAction.java index a4e184f54c..cb142e4090 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetPreferredPhyAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetPreferredPhyAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Thomas Kuehne +/* Copyright (C) 2025-2026 Thomas Kuehne This file is part of Gadgetbridge. @@ -21,6 +21,7 @@ import android.annotation.SuppressLint; import android.bluetooth.BluetoothGatt; import android.os.Build; +import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import org.slf4j.Logger; @@ -41,7 +42,7 @@ public class SetPreferredPhyAction extends BtLEAction { private final int mRxPhy; private final int mPhyOptions; - public SetPreferredPhyAction(int txPhy, int rxPhy, int phyOptions) { + public SetPreferredPhyAction(final int txPhy, final int rxPhy, final int phyOptions) { super(null); mTxPhy = txPhy; mRxPhy = rxPhy; @@ -57,7 +58,7 @@ public class SetPreferredPhyAction extends BtLEAction { @SuppressLint("MissingPermission") @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull final BluetoothGatt gatt) { try { gatt.setPreferredPhy(mTxPhy, mRxPhy, mPhyOptions); return true; @@ -68,6 +69,7 @@ public class SetPreferredPhyAction extends BtLEAction { } } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName() + " tx=" + mTxPhy diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java index 0bb75c3d4e..3254e974a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2025 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, Thomas Kuehne +/* Copyright (C) 2015-2026 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, Thomas Kuehne This file is part of Gadgetbridge. @@ -20,6 +20,7 @@ import android.bluetooth.BluetoothGatt; import android.content.Context; import android.content.Intent; +import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.localbroadcastmanager.content.LocalBroadcastManager; @@ -40,15 +41,15 @@ public class SetProgressAction extends PlainAction { * @param percentage Current percentage indicating how far along the action has progressed * @param context Context in which to create the notification */ - public SetProgressAction(@StringRes int textRes, boolean ongoing, int percentage, Context context) { - this.text = context.getString(textRes);; + public SetProgressAction(@StringRes int textRes, boolean ongoing, int percentage, @NonNull Context context) { + this.text = context.getString(textRes); this.ongoing = ongoing; this.percentage = percentage; this.context = context; } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { GB.updateInstallNotification(this.text, this.ongoing, this.percentage, this.context); final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(context); @@ -63,6 +64,7 @@ public class SetProgressAction extends PlainAction { return true; } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName() + ": " + text + "; " + percentage + "%"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SleepAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SleepAction.java index 67afa4d20d..2eac56f6d5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SleepAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SleepAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Carsten Pfeiffer +/* Copyright (C) 2015-2026 Carsten Pfeiffer This file is part of Gadgetbridge. @@ -18,6 +18,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions; import android.bluetooth.BluetoothGatt; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; + /** * An action that will cause the queue to {@link Thread#sleep(long) sleep} for the specified time. * Note that this is usually a bad idea, since it will not be able to process messages @@ -25,22 +28,23 @@ import android.bluetooth.BluetoothGatt; */ public class SleepAction extends PlainAction { - private final int mMillis; + private final long mMillis; - public SleepAction(int millis) { + public SleepAction(@IntRange(from = 0L) final long millis) { mMillis = millis; } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull final BluetoothGatt gatt) { try { Thread.sleep(mMillis); return true; - } catch (InterruptedException e) { + } catch (final InterruptedException e) { return false; } } + @NonNull @Override public String toString() { return getCreationTime() + " " + getClass().getSimpleName() + " " + mMillis + " ms"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java index eb24e9ec70..931a6fc80f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2025 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2026 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Uwe Hermann, Thomas Kuehne This file is part of Gadgetbridge. @@ -22,6 +22,8 @@ import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothStatusCodes; +import androidx.annotation.NonNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,18 +44,18 @@ public class WriteAction extends BtLEAction { private final byte[] value; private final boolean legacyCompat; - public WriteAction(BluetoothGattCharacteristic characteristic, byte[] value) { + public WriteAction(@NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value) { this(characteristic, value, false); } - public WriteAction(BluetoothGattCharacteristic characteristic, byte[] value, boolean legacyCompat) { + public WriteAction(@NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value, boolean legacyCompat) { super(characteristic); this.value = value; this.legacyCompat = legacyCompat; } @Override - public boolean run(BluetoothGatt gatt) { + public boolean run(@NonNull BluetoothGatt gatt) { BluetoothGattCharacteristic characteristic = getCharacteristic(); int properties = characteristic.getProperties(); //TODO: expectsResult should return false if PROPERTY_WRITE_NO_RESPONSE is true, but this leads to timing issues @@ -74,7 +76,7 @@ public class WriteAction extends BtLEAction { } @SuppressLint("MissingPermission") - private static boolean writeCharacteristicImp(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, boolean legacyCompat) { + private static boolean writeCharacteristicImp(@NonNull BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value, boolean legacyCompat) { if (GBApplication.isRunningTiramisuOrLater() && !legacyCompat) { // use API introduced in SDK level 33 to catch exceptions and more specific errors try { @@ -109,6 +111,7 @@ public class WriteAction extends BtLEAction { return true; } + @NonNull @Override public String toString() { BluetoothGattCharacteristic characteristic = getCharacteristic();