Merge pull request 'GBDevice: code review' (#6219)

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6219
This commit is contained in:
José Rebelo
2026-05-31 18:47:07 +02:00
15 changed files with 109 additions and 109 deletions
@@ -160,10 +160,10 @@ public class Widget extends AppWidgetProvider {
views.setViewVisibility(R.id.todaywidget_battery_icon, View.GONE);
String status = String.format("%1s", deviceForWidget.getStateString(context));
if (deviceForWidget.isConnected()) {
if (deviceForWidget.getBatteryLevel() > 1) {
if (deviceForWidget.getBatteryLevel(0) > 1) {
views.setViewVisibility(R.id.todaywidget_battery_icon, View.VISIBLE);
status = String.format("%1s%%", deviceForWidget.getBatteryLevel());
status = String.format("%1s%%", deviceForWidget.getBatteryLevel(0));
}
}
@@ -178,7 +178,7 @@ public class ControlActivity extends AbstractGBActivity implements JoystickView.
}
private void setBatteryLabel() {
String level = device.getBatteryLevel() > 0 ? String.format("%1s%%", device.getBatteryLevel()) : device.getName();
String level = device.getBatteryLevel(0) > 0 ? String.format("%1s%%", device.getBatteryLevel(0)) : device.getName();
batteryPercentage.setText(level);
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2025 Andreas Shimokawa, Arjan Schrijver, Carsten
/* Copyright (C) 2015-2026 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniel Dakhno, Daniele Gobbetti, José Rebelo, Petr Vaněk, Taavi
Eomäe, Uwe Hermann, Thomas Kuehne
@@ -25,6 +25,8 @@ import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
@@ -49,12 +51,14 @@ import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
public class GBDevice implements Parcelable {
public static final String ACTION_DEVICE_CHANGED
= "nodomain.freeyourgadget.gadgetbridge.gbdevice.action.device_changed";
public static final Creator<GBDevice> CREATOR = new Creator<GBDevice>() {
public static final Creator<GBDevice> CREATOR = new Creator<>() {
@NonNull
@Override
public GBDevice createFromParcel(Parcel source) {
return new GBDevice(source);
}
@NonNull
@Override
public GBDevice[] newArray(int size) {
return new GBDevice[size];
@@ -122,7 +126,7 @@ public class GBDevice implements Parcelable {
validate();
}
private GBDevice(Parcel in) {
private GBDevice(@NonNull Parcel in) {
mName = in.readString();
mAlias = in.readString();
parentFolder = in.readString();
@@ -149,8 +153,8 @@ public class GBDevice implements Parcelable {
validate();
}
public void copyFromDevice(GBDevice device){
if(!device.mAddress.equals(mAddress)){
public void copyFromDevice(@NonNull GBDevice device) {
if (!device.mAddress.equals(mAddress)) {
throw new RuntimeException("Cannot copy from device with other address");
}
@@ -177,7 +181,7 @@ public class GBDevice implements Parcelable {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
public void writeToParcel(@NonNull final Parcel dest, final int flags) {
dest.writeString(mName);
dest.writeString(mAlias);
dest.writeString(parentFolder);
@@ -208,7 +212,8 @@ public class GBDevice implements Parcelable {
}
}
private int[] enumsToOrdinals(BatteryState[] arrayEnum) {
@NonNull
private static int[] enumsToOrdinals(@NonNull BatteryState[] arrayEnum) {
int[] ordinals = new int[arrayEnum.length];
for (int i = 0; i < arrayEnum.length; i++) {
ordinals[i] = arrayEnum[i].ordinal();
@@ -216,10 +221,11 @@ public class GBDevice implements Parcelable {
return ordinals;
}
private BatteryState[] ordinalsToEnums(int[] arrayInt){
@NonNull
private static BatteryState[] ordinalsToEnums(@NonNull int[] arrayInt) {
BatteryState[] enums = new BatteryState[arrayInt.length];
for(int i = 0; i<arrayInt.length; i++){
enums[i]=BatteryState.values()[arrayInt[i]];
for (int i = 0; i < arrayInt.length; i++) {
enums[i] = BatteryState.values()[arrayInt[i]];
}
return enums;
}
@@ -249,7 +255,7 @@ public class GBDevice implements Parcelable {
public void setName(String name) {
if (name == null) {
LOG.warn("Ignoring setting of GBDevice name to null for " + this);
LOG.warn("Ignoring setting of GBDevice name to null for {}", this);
return;
}
mName = name;
@@ -324,6 +330,7 @@ public class GBDevice implements Parcelable {
return mBusyTask != null;
}
@Nullable
public String getBusyTask() {
return mBusyTask;
}
@@ -341,7 +348,7 @@ public class GBDevice implements Parcelable {
}
public void setNotificationIconDisconnected(int notificationIconDisconnected) {
this.mNotificationIconDisconnected = notificationIconDisconnected;
mNotificationIconDisconnected = notificationIconDisconnected;
}
public int getNotificationIconLowBattery() {
@@ -395,7 +402,7 @@ public class GBDevice implements Parcelable {
}
/// device specific code must use {@link #setUpdateState} instead
public void setState(State state) {
public void setState(@NonNull State state) {
mState = state;
if (state.ordinal() <= State.CONNECTED.ordinal()) {
unsetDynamicState();
@@ -404,7 +411,7 @@ public class GBDevice implements Parcelable {
/// shared helper to set device state and broadcast a {@link #ACTION_DEVICE_CHANGED}
/// intent with subject {@link DeviceUpdateSubject#DEVICE_STATE}
public void setUpdateState(State deviceState, Context context){
public void setUpdateState(@NonNull State deviceState, @NonNull Context context) {
setState(deviceState);
sendDeviceUpdateIntent(context, GBDevice.DeviceUpdateSubject.DEVICE_STATE);
}
@@ -423,7 +430,8 @@ public class GBDevice implements Parcelable {
}
}
public String getStateString(final Context context) {
@NonNull
public String getStateString(@NonNull final Context context) {
return getStateString(context, true);
}
@@ -432,10 +440,11 @@ public class GBDevice implements Parcelable {
* instead of connecting->connected->initializing->initialized
* Set simple to true to get this behavior.
*/
private String getStateString(Context context, boolean simple) {
try{
// TODO: not sure if this is really neccessary...
if(simple){
@NonNull
private String getStateString(@NonNull Context context, boolean simple) {
try {
// TODO: not sure if this is really necessary...
if (simple) {
return context.getString(mState.getSimpleStringId());
}
return context.getString(mState.getStringId());
@@ -446,7 +455,7 @@ public class GBDevice implements Parcelable {
/**
* Returns the general type of this device. For more detailed information,
* soo #getModel()
* see {@link #getModel()}
* @return the general type of this device
*/
@NonNull
@@ -455,13 +464,13 @@ public class GBDevice implements Parcelable {
}
@NonNull
public DeviceCoordinator getDeviceCoordinator(){
public DeviceCoordinator getDeviceCoordinator() {
return mDeviceType.getDeviceCoordinator();
}
public void setRssi(short rssi) {
if (rssi < 0) {
LOG.warn("Illegal RSSI value " + rssi + ", setting to RSSI_UNKNOWN");
LOG.warn("Illegal RSSI value {}, setting to RSSI_UNKNOWN", rssi);
mRssi = RSSI_UNKNOWN;
} else {
mRssi = rssi;
@@ -469,19 +478,19 @@ public class GBDevice implements Parcelable {
}
/**
* Returns the device specific signal strength value, or #RSSI_UNKNOWN
* Returns the device specific signal strength value, or {@link #RSSI_UNKNOWN}
*/
public short getRssi() {
return mRssi;
}
// TODO: this doesn't really belong here
public void sendDeviceUpdateIntent(Context context) {
public void sendDeviceUpdateIntent(@NonNull Context context) {
sendDeviceUpdateIntent(context, DeviceUpdateSubject.UNKNOWN);
}
// TODO: this doesn't really belong here
public void sendDeviceUpdateIntent(Context context, DeviceUpdateSubject subject) {
public void sendDeviceUpdateIntent(@NonNull final Context context, DeviceUpdateSubject subject) {
Intent deviceUpdateIntent = new Intent(ACTION_DEVICE_CHANGED);
deviceUpdateIntent.setPackage(BuildConfig.APPLICATION_ID);
deviceUpdateIntent.putExtra(EXTRA_DEVICE, this);
@@ -495,17 +504,17 @@ public class GBDevice implements Parcelable {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof GBDevice)) {
return false;
if (obj instanceof GBDevice gbDevice) {
return gbDevice.getAddress().equals(mAddress);
}
return ((GBDevice) obj).getAddress().equals(this.mAddress);
return false;
}
@Override
@@ -520,7 +529,7 @@ public class GBDevice implements Parcelable {
* @return the extra info value if set, null otherwise
*/
@Nullable
public Object getExtraInfo(String key) {
public Object getExtraInfo(@NonNull String key) {
if (mExtraInfos == null) {
return null;
}
@@ -530,10 +539,10 @@ public class GBDevice implements Parcelable {
/**
* Sets an extra info value, overwriting the current one, if any
* @param key the extra info key
* @param key the extra info key
* @param info the extra info value
*/
public void setExtraInfo(String key, Object info) {
public void setExtraInfo(@NonNull String key, @Nullable Object info) {
if (mExtraInfos == null) {
mExtraInfos = new HashMap<>();
}
@@ -548,88 +557,87 @@ public class GBDevice implements Parcelable {
mExtraInfos = null;
}
/**
* Ranges from 0-100 (percent), or -1 if unknown
*
* @return the battery level in range 0-100, or -1 if unknown
*/
/// @deprecated use {@link #getBatteryLevel(int)} instead
@Deprecated
public int getBatteryLevel() {
return getBatteryLevel(0);
}
public int getBatteryLevel(int index) {
return mBatteryLevel[index];
/// @return the battery level in range {@code 0} to {@code 100}, or {@link #BATTERY_UNKNOWN} if unknown
/// @see #setBatteryLevel(int, int)
public int getBatteryLevel(@IntRange(from = 0, to = 2) int batteryIndex) {
return mBatteryLevel[batteryIndex];
}
/// @deprecated use {@link #setBatteryLevel(int, int)} instead
@Deprecated
public void setBatteryLevel(int batteryLevel) {
setBatteryLevel(batteryLevel, 0);
}
public void setBatteryLevel(int batteryLevel, int index) {
/// Set the battery level in range {@code 0} to {@code 100}, or {@link #BATTERY_UNKNOWN} if unknown
/// @see #getBatteryLevel(int)
public void setBatteryLevel(@IntRange(from = BATTERY_UNKNOWN, to = 100) int batteryLevel,
@IntRange(from = 0, to = 2) int batteryIndex) {
if ((batteryLevel >= 0 && batteryLevel <= 100) || batteryLevel == BATTERY_UNKNOWN) {
mBatteryLevel[index] = batteryLevel;
mBatteryLevel[batteryIndex] = batteryLevel;
} else {
LOG.error("Battery level must be within range 0-100: {}", batteryLevel);
}
}
/// @deprecated use {@link #setBatteryVoltage(float, int)} instead
@Deprecated
public void setBatteryVoltage(float batteryVoltage) {
setBatteryVoltage(batteryVoltage, 0);
}
public void setBatteryVoltage(float batteryVoltage, int index) {
/// @param batteryVoltage Voltage greater than zero (unit: Volt), or {@link #BATTERY_UNKNOWN} if unknown
public void setBatteryVoltage(float batteryVoltage,
@IntRange(from = 0, to = 2) int batteryIndex) {
if (batteryVoltage >= 0 || batteryVoltage == BATTERY_UNKNOWN) {
mBatteryVoltage[index] = batteryVoltage;
mBatteryVoltage[batteryIndex] = batteryVoltage;
} else {
LOG.error("Battery voltage must be > 0: {}", batteryVoltage);
}
}
/**
* Voltage greater than zero (unit: Volt), or -1 if unknown
*
* @return the battery voltage, or -1 if unknown
*/
/// @deprecated use {@link #getBatteryVoltage(int)} instead
@Deprecated
public float getBatteryVoltage() {
return getBatteryVoltage(0);
}
public float getBatteryVoltage(int index) {
return mBatteryVoltage[index];
/// @return the battery voltage, or {@link #BATTERY_UNKNOWN} if unknown
/// @see #setBatteryVoltage(float, int)
public float getBatteryVoltage(int batteryIndex) {
return mBatteryVoltage[batteryIndex];
}
public BatteryState getBatteryState() {
return getBatteryState(0);
public BatteryState getBatteryState(int batteryIndex) {
return mBatteryState[batteryIndex];
}
public BatteryState getBatteryState(int index) {
return mBatteryState[index];
public void setBatteryState(BatteryState mBatteryState, int batteryIndex) {
this.mBatteryState[batteryIndex] = mBatteryState;
}
public void setBatteryState(BatteryState mBatteryState) {
setBatteryState(mBatteryState, 0);
@DrawableRes
public int getBatteryIcon(int batteryIndex) {
return mBatteryIcons[batteryIndex];
}
public void setBatteryState(BatteryState mBatteryState, int index) {
this.mBatteryState[index] = mBatteryState;
public void setBatteryIcon(@DrawableRes int icon, int batteryIndex) {
mBatteryIcons[batteryIndex] = icon;
}
public int getBatteryIcon(int index) {
return this.mBatteryIcons[index];
@StringRes
public int getBatteryLabel(int batteryIndex) {
return mBatteryLabels[batteryIndex];
}
public void setBatteryIcon(int icon, int index) {
this.mBatteryIcons[index] = icon;
}
public int getBatteryLabel(int index) {
return this.mBatteryLabels[index];
}
public void setBatteryLabel(int label, int index) {
this.mBatteryLabels[index] = label;
public void setBatteryLabel(@StringRes int label, int batteryIndex) {
mBatteryLabels[batteryIndex] = label;
}
@NonNull
@@ -659,7 +667,7 @@ public class GBDevice implements Parcelable {
}
@Nullable
public ItemWithDetails getDeviceInfo(String name) {
public ItemWithDetails getDeviceInfo(@NonNull final String name) {
for (ItemWithDetails item : getDeviceInfos()) {
if (name.equals(item.getName())) {
return item;
@@ -668,8 +676,9 @@ public class GBDevice implements Parcelable {
return null;
}
@NonNull
public List<ItemWithDetails> getDeviceInfos() {
List<ItemWithDetails> result = new ArrayList<>();
List<ItemWithDetails> result = new ArrayList<>(6);
if (mDeviceInfos != null) {
result.addAll(mDeviceInfos);
}
@@ -692,10 +701,6 @@ public class GBDevice implements Parcelable {
return result;
}
public void setDeviceInfos(List<ItemWithDetails> deviceInfos) {
this.mDeviceInfos = deviceInfos;
}
public void addDeviceInfo(ItemWithDetails info) {
if (mDeviceInfos == null) {
mDeviceInfos = new ArrayList<>();
@@ -709,13 +714,6 @@ public class GBDevice implements Parcelable {
mDeviceInfos.add(info);
}
public boolean removeDeviceInfo(ItemWithDetails info) {
if (mDeviceInfos == null) {
return false;
}
return mDeviceInfos.remove(info);
}
public enum State {
NOT_CONNECTED(R.string.not_connected),
WAITING_FOR_RECONNECT(R.string.waiting_for_reconnect),
@@ -735,27 +733,31 @@ public class GBDevice implements Parcelable {
INITIALIZED(R.string.initialized, R.string.connected);
@StringRes
private final int stringId;
@StringRes
private final int simpleStringId;
State(int stringId, int simpleStringId) {
State(@StringRes int stringId, @StringRes int simpleStringId) {
this.stringId = stringId;
this.simpleStringId = simpleStringId;
}
State(int stringId) {
State(@StringRes int stringId) {
this(stringId, stringId);
}
@StringRes
public int getStringId() {
return stringId;
}
@StringRes
public int getSimpleStringId() {
return simpleStringId;
}
public boolean equalsOrHigherThan(State otherState){
public boolean equalsOrHigherThan(State otherState) {
return compareTo(otherState) >= 0;
}
}
@@ -16,9 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.impl;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public class GBDeviceFolder extends GBDevice{
public class GBDeviceFolder extends GBDevice {
public GBDeviceFolder(String name) {
super("", name, null, null, null);
}
@@ -427,7 +427,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
prevRealTimeRecord = record;
getDevice().setBatteryLevel(record.battery);
getDevice().setBatteryLevel(record.battery, 0);
try (DBHandler dbHandler = GBApplication.acquireDB()) {
HPlusHealthSampleProvider provider = new HPlusHealthSampleProvider(getDevice(), dbHandler.getDaoSession());
@@ -719,7 +719,7 @@ public class AsynchronousResponse {
if (resp.multi_level == null) {
byte batteryLevel = resp.level;
this.support.getDevice().setBatteryLevel(batteryLevel);
this.support.getDevice().setBatteryLevel(batteryLevel, 0);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.state = BatteryState.BATTERY_NORMAL;
@@ -67,7 +67,7 @@ public class GetBatteryLevelRequest extends Request {
if (response.multi_level == null) {
byte batteryLevel = response.level;
getDevice().setBatteryLevel(batteryLevel);
getDevice().setBatteryLevel(batteryLevel, 0);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.state = BatteryState.BATTERY_NORMAL;
@@ -454,7 +454,7 @@ public class IGPSportDeviceSupport extends AbstractBTLESingleDeviceSupport {
public void handleFactoryData(byte[] data) throws InvalidProtocolBufferException {
Factory.factory_msg factoryMsg = Factory.factory_msg.parseFrom(data);
if (factoryMsg.hasBattaryMsg()) {
gbDevice.setBatteryLevel(factoryMsg.getBattaryMsg().getPowerPercent());
gbDevice.setBatteryLevel(factoryMsg.getBattaryMsg().getPowerPercent(), 0);
}
if (factoryMsg.getFactorySnMsgList().size() > 0) {
// save serial to volatile address now, need to find way to use it as identifier in database
@@ -240,7 +240,7 @@ public class MarstekB2500DeviceSupport extends AbstractBTLESingleDeviceSupport {
devicePrefsEdit.apply();
devicePrefsEdit.commit();
getDevice().setBatteryLevel(battery_pct);
getDevice().setBatteryLevel(battery_pct, 0);
getDevice().sendDeviceUpdateIntent(getContext());
Intent intent = new Intent(SolarEquipmentStatusActivity.ACTION_SEND_SOLAR_EQUIPMENT_STATUS)
@@ -781,10 +781,10 @@ public class QHybridSupport extends QHybridBaseSupport {
}
case "00002a19-0000-1000-8000-00805f9b34fb": {
short level = value[0];
gbDevice.setBatteryLevel(level);
gbDevice.setBatteryLevel(level, 0);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.level = gbDevice.getBatteryLevel();
batteryInfo.level = gbDevice.getBatteryLevel(0);
batteryInfo.state = BatteryState.BATTERY_NORMAL;
handleGBDeviceEvent(batteryInfo);
break;
@@ -164,10 +164,10 @@ public class MisfitWatchAdapter extends WatchAdapter {
}
case "00002a19-0000-1000-8000-00805f9b34fb": {
short level = value[0];
gbDevice.setBatteryLevel(level);
gbDevice.setBatteryLevel(level, 0);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.level = gbDevice.getBatteryLevel();
batteryInfo.level = gbDevice.getBatteryLevel(0);
batteryInfo.state = BatteryState.BATTERY_NORMAL;
getDeviceSupport().handleGBDeviceEvent(batteryInfo);
break;
@@ -57,8 +57,8 @@ public class ConfigurationGetRequest extends FileEncryptedLookupAndGetRequest im
}else if(item instanceof ConfigurationPutRequest.TimezoneOffsetConfigItem) {
device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_TIMEZONE_OFFSET, String.valueOf(((ConfigurationPutRequest.TimezoneOffsetConfigItem) item).getValue())));
}else if(item instanceof ConfigurationPutRequest.BatteryConfigItem){
device.setBatteryLevel((short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage());
device.setBatteryVoltage(((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryVoltage() / 1000f);
device.setBatteryLevel((short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage(), 0);
device.setBatteryVoltage(((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryVoltage() / 1000f, 0);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.level = (short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage();
@@ -58,7 +58,7 @@ public class RoidmiSupport extends AbstractHeadphoneSerialDeviceSupportV2<Roidmi
}
if (mDeviceProtocol.supportsBatteryVoltage()) {
if (getDevice().getBatteryVoltage() == -1) {
if (getDevice().getBatteryVoltage(0) == -1) {
infoMissing = true;
builder.write(mDeviceProtocol.encodeGetVoltage());
@@ -194,8 +194,8 @@ public class VescDeviceSupport extends VescBaseDeviceSupport {
fullnessPercent = Math.max(fullnessPercent, 0);
fullnessPercent = Math.min(fullnessPercent, 100);
getDevice().setBatteryLevel(fullnessPercent);
getDevice().setBatteryVoltage(voltage);
getDevice().setBatteryLevel(fullnessPercent, 0);
getDevice().setBatteryVoltage(voltage, 0);
getDevice().sendDeviceUpdateIntent(getContext());
}
@@ -275,7 +275,7 @@ public class SolarFlowDeviceSupport extends AbstractBTLESingleDeviceSupport {
int electricLevel = properties.getInt("electricLevel");
if (electricLevel != this.electricLevel) {
this.electricLevel = electricLevel;
getDevice().setBatteryLevel(electricLevel); // update event will be sent when firmware gets read
getDevice().setBatteryLevel(electricLevel, 0); // update event will be sent when firmware gets read
}
}
if (properties.has("MASTER")) {