mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-28 22:34:25 +02:00
Merge pull request 'BtLEAction: code review' (#6287)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6287
This commit is contained in:
+15
-8
@@ -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.
|
||||
* <p/>
|
||||
* <p>
|
||||
* These actions are then executed one after another, ensuring that every action's result
|
||||
* has been posted before invoking the next action.
|
||||
* </p>
|
||||
*/
|
||||
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.
|
||||
* <p/>
|
||||
* <p>
|
||||
* This is needed because the current Bluedroid stack can only deal
|
||||
* with one single bluetooth operation at a time.
|
||||
* </p>
|
||||
*/
|
||||
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 <code>null</code>
|
||||
* @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();
|
||||
|
||||
+5
-2
@@ -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();
|
||||
|
||||
+3
-2
@@ -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);
|
||||
|
||||
+6
-3
@@ -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 <https://www.gnu.org/licenses/>. */
|
||||
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;
|
||||
}
|
||||
|
||||
+12
-7
@@ -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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
+11
-5
@@ -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();
|
||||
|
||||
+4
-1
@@ -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 <https://www.gnu.org/licenses/>. */
|
||||
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();
|
||||
|
||||
+6
-3
@@ -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();
|
||||
|
||||
+4
-2
@@ -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();
|
||||
|
||||
+5
-2
@@ -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() + " " +
|
||||
|
||||
+8
-4
@@ -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;
|
||||
|
||||
+3
-2
@@ -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() + " "
|
||||
|
||||
+4
-3
@@ -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;
|
||||
}
|
||||
|
||||
+5
-3
@@ -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
|
||||
|
||||
+6
-4
@@ -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 + "%";
|
||||
|
||||
+9
-5
@@ -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";
|
||||
|
||||
+8
-5
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user