ble+btbr: add TransactionBuilder.setProgress (#5098)

This commit is contained in:
Thomas Kuehne
2025-07-14 19:04:38 +02:00
parent 7dac462f7d
commit 8daa0178ce
20 changed files with 62 additions and 64 deletions
@@ -30,6 +30,7 @@ import java.util.function.Predicate;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.FunctionAction;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.WaitAction;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.WriteAction;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.SetDeviceStateAction;
@@ -99,6 +100,14 @@ public class TransactionBuilder {
return add(action);
}
/// updates the progress bar
/// @see SetProgressAction#SetProgressAction
@NonNull
public TransactionBuilder setProgress(@StringRes int textRes, boolean ongoing, int percentage, @NonNull Context context) {
BtBRAction action = new SetProgressAction(textRes, ongoing, percentage, context);
return add(action);
}
/// Set the device as busy or not ({@code taskName = 0}).
/// @see SetDeviceBusyAction#SetDeviceBusyAction
@NonNull
@@ -1,5 +1,5 @@
/* Copyright (C) 2015-2023 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Yoran Vulker
/* Copyright (C) 2015-2025 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Yoran Vulker, Thomas Kuehne
This file is part of Gadgetbridge.
@@ -17,12 +17,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.btbr.actions;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -42,13 +42,13 @@ public class SetProgressAction extends PlainAction {
/**
* When run, will update the progress notification.
*
* @param text Text shown in the notification
* @param textRes Text shown in the notification
* @param ongoing State of action, true when the action is still being performed
* @param percentage Current percentage indicating how far along the action has progressed
* @param context Context in which to create the notification
*/
public SetProgressAction(String text, boolean ongoing, int percentage, Context context) {
this.text = text;
public SetProgressAction(@StringRes int textRes, boolean ongoing, int percentage, Context context) {
this.text = context.getString(textRes);
this.ongoing = ongoing;
this.percentage = percentage;
this.context = context;
@@ -45,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.RequestMtuActio
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetPreferredPhyAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction;
@@ -195,6 +196,14 @@ public class TransactionBuilder {
return add(action);
}
/// updates the progress bar
/// @see SetProgressAction#SetProgressAction
@NonNull
public TransactionBuilder setProgress(@StringRes int textRes, boolean ongoing, int percentage, @NonNull Context context) {
BtLEAction action = new SetProgressAction(textRes, ongoing, percentage, context);
return add(action);
}
/**
* Read the current transmitter PHY and receiver PHY of the connection.
* @see ReadPhyAction
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo
/* Copyright (C) 2015-2025 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, Thomas Kuehne
This file is part of Gadgetbridge.
@@ -20,15 +20,12 @@ import android.bluetooth.BluetoothGatt;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.StringRes;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class SetProgressAction extends PlainAction {
private static final Logger LOG = LoggerFactory.getLogger(SetProgressAction.class);
private final String text;
private final boolean ongoing;
@@ -38,14 +35,13 @@ public class SetProgressAction extends PlainAction {
/**
* When run, will update the progress notification.
*
* @param text
* @param ongoing
* @param percentage
* @param context
* @param textRes Text shown in the notification
* @param ongoing State of action, true when the action is still being performed
* @param percentage Current percentage indicating how far along the action has progressed
* @param context Context in which to create the notification
*/
public SetProgressAction(String text, boolean ongoing, int percentage, Context context) {
this.text = text;
public SetProgressAction(@StringRes int textRes, boolean ongoing, int percentage, Context context) {
this.text = context.getString(textRes);;
this.ongoing = ongoing;
this.percentage = percentage;
this.context = context;
@@ -53,7 +49,6 @@ public class SetProgressAction extends PlainAction {
@Override
public boolean run(BluetoothGatt gatt) {
LOG.info(toString());
GB.updateInstallNotification(this.text, this.ongoing, this.percentage, this.context);
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(context);
@@ -50,7 +50,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLESingleDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.util.CheckSums;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@@ -188,7 +187,7 @@ public class ATCBLEOEPLDeviceSupport extends AbstractBTLESingleDeviceSupport {
GB.toast(getContext().getString(R.string.same_image_already_on_device), Toast.LENGTH_LONG, GB.WARN);
}
final TransactionBuilder builder = createTransactionBuilder("finish upload");
builder.add(new SetProgressAction(getContext().getString(R.string.sending_image), false, 100, getContext()));
builder.setProgress(R.string.sending_image, false, 100, getContext());
if (!is_firmware) {
builder.write(getCharacteristic(UUID_CHARACTERISTIC_MAIN), new byte[]{0x00, 0x03});
}
@@ -212,7 +211,7 @@ public class ATCBLEOEPLDeviceSupport extends AbstractBTLESingleDeviceSupport {
block_data = encodeBlock(image_payload, current_block);
builder.write(getCharacteristic(UUID_CHARACTERISTIC_MAIN), encodeImageChunk(block_data, current_block, current_chunk));
int progressPercent = (int) ((((float) current_block) / blocks_total) * 100);
builder.add(new SetProgressAction(getContext().getString(R.string.sending_image), true, progressPercent, getContext()));
builder.setProgress(R.string.sending_image, true, progressPercent, getContext());
builder.queue(getQueue());
}
@@ -29,7 +29,6 @@ import java.util.Random;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
public class CmfDataUploader implements CmfCharacteristic.Handler {
private static final Logger LOG = LoggerFactory.getLogger(CmfDataUploader.class);
@@ -226,12 +225,12 @@ public class CmfDataUploader implements CmfCharacteristic.Handler {
uploadMessage = R.string.updating_firmware;
}
builder.add(new SetProgressAction(
mSupport.getContext().getString(uploadMessage),
builder.setProgress(
uploadMessage,
ongoing,
progressPercent,
mSupport.getContext()
));
);
}
private void setDeviceBusy() {
@@ -36,7 +36,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiFirmwareInfo;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
@@ -255,7 +254,7 @@ public class UpdateFirmwareOperation extends AbstractMiBandOperation<HuamiSuppor
int progressPercent = (int) ((((float) firmwareProgress) / len) * 100);
if ((i > 0) && (i % 100 == 0)) {
builder.write(fwCControlChar, new byte[]{HuamiService.COMMAND_FIRMWARE_UPDATE_SYNC});
builder.add(new SetProgressAction(getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, getContext()));
builder.setProgress(R.string.updatefirmwareoperation_update_in_progress, true, progressPercent, getContext());
}
}
@@ -29,7 +29,6 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiFirmwareInfo;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
@@ -264,7 +263,7 @@ public class UpdateFirmwareOperation2020 extends UpdateFirmwareOperation {
int progressPercent = (int) ((((float) (offset + chunkLength)) / len) * 100);
builder.add(new SetProgressAction(getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, getContext()));
builder.setProgress(R.string.updatefirmwareoperation_update_in_progress, true, progressPercent, getContext());
builder.queue(getQueue());
@@ -24,7 +24,6 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.SetProgressAction;
public class ZeppOsBtbrTransactionBuilder implements ZeppOsTransactionBuilder {
private final ZeppOsBtbrSupport mSupport;
@@ -41,8 +40,8 @@ public class ZeppOsBtbrTransactionBuilder implements ZeppOsTransactionBuilder {
}
@Override
public void setProgress(final String text, final boolean ongoing, final int percentage, final Context context) {
mBuilder.add(new SetProgressAction(text, ongoing, percentage, context));
public void setProgress(@StringRes final int textRes, final boolean ongoing, final int percentage, final Context context) {
mBuilder.setProgress(textRes, ongoing, percentage, context);
}
@Override
@@ -24,7 +24,6 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
public class ZeppOsBtleTransactionBuilder implements ZeppOsTransactionBuilder {
private final ZeppOsBtleSupport mSupport;
@@ -41,8 +40,8 @@ public class ZeppOsBtleTransactionBuilder implements ZeppOsTransactionBuilder {
}
@Override
public void setProgress(final String text, final boolean ongoing, final int percentage, final Context context) {
mBuilder.add(new SetProgressAction(text, ongoing, percentage, context));
public void setProgress(@StringRes final int textRes, final boolean ongoing, final int percentage, final Context context) {
mBuilder.setProgress(textRes, ongoing, percentage, context);
}
@Override
@@ -25,7 +25,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public interface ZeppOsTransactionBuilder {
void setProgress(final String text, final boolean ongoing, final int percentage, final Context context);
void setProgress(@StringRes final int textRes, final boolean ongoing, final int percentage, final Context context);
void setDeviceState(final GBDevice device, final GBDevice.State deviceState, final Context context);
@@ -132,7 +132,7 @@ public class ZeppOsAgpsUpdateOperation extends AbstractZeppOsOperation<ZeppOsSup
private void updateProgress(final int progressPercent) {
try {
final ZeppOsTransactionBuilder builder = getSupport().createZeppOsTransactionBuilder("send agps update progress");
builder.setProgress(getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, getContext());
builder.setProgress(R.string.updatefirmwareoperation_update_in_progress, true, progressPercent, getContext());
builder.queue(getSupport());
} catch (final Exception e) {
LOG.error("Failed to update progress notification", e);
@@ -301,7 +301,7 @@ public class ZeppOsFirmwareUpdateOperation extends AbstractZeppOsOperation<ZeppO
int progressPercent = (int) ((((float) (offset + chunkLength)) / len) * 100);
builder.setProgress(getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, getContext());
builder.setProgress(R.string.updatefirmwareoperation_update_in_progress, true, progressPercent, getContext());
builder.queue(getSupport());
@@ -90,7 +90,7 @@ public class ZeppOsGpxRouteUploadOperation extends AbstractZeppOsOperation<ZeppO
private void updateProgress(final int progressPercent) {
try {
final ZeppOsTransactionBuilder builder = getSupport().createZeppOsTransactionBuilder("send gpx route upload progress");
builder.setProgress(getContext().getString(R.string.gpx_route_upload_in_progress), true, progressPercent, getContext());
builder.setProgress(R.string.gpx_route_upload_in_progress, true, progressPercent, getContext());
builder.queue(getSupport());
} catch (final Exception e) {
LOG.error("Failed to update progress notification", e);
@@ -98,7 +98,7 @@ public class ZeppOsMusicUploadOperation extends AbstractZeppOsOperation<ZeppOsSu
private void updateProgress(final int progressPercent) {
try {
final ZeppOsTransactionBuilder builder = getSupport().createZeppOsTransactionBuilder("send music upload progress");
builder.setProgress(getContext().getString(R.string.music_upload_in_progress), true, progressPercent, getContext());
builder.setProgress(R.string.music_upload_in_progress, true, progressPercent, getContext());
builder.queue(getSupport());
} catch (final Exception e) {
LOG.error("Failed to update progress notification", e);
@@ -2608,20 +2608,20 @@ public class HuaweiSupportProvider {
try {
if (isBLE()) {
nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder leBuilder = createLeTransactionBuilder("FetchRecordedData");
leBuilder.add(new nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction(
context.getString(textRsrc),
leBuilder.setProgress(
textRsrc,
ongoing,
progressPercent,
context
));
);
leBuilder.queue(leSupport.getQueue());
} else {
nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder brBuilder = createBrTransactionBuilder("FetchRecordedData");
brBuilder.add(new nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.SetProgressAction(
context.getString(textRsrc),
brBuilder.setProgress(
textRsrc,
ongoing,
progressPercent,
context));
context);
brBuilder.queue(brSupport.getQueue());
}
@@ -37,7 +37,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.PlainAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.AbstractMiFirmwareInfo;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
@@ -321,7 +320,7 @@ public class UpdateFirmwareOperation extends AbstractMiBand1Operation {
int progressPercent = (int) ((((float) firmwareProgress) / len) * 100);
if ((i > 0) && (i % 50 == 0)) {
builder.write(characteristicControlPoint, new byte[]{MiBandService.COMMAND_SYNC});
builder.add(new SetProgressAction(getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, getContext()));
builder.setProgress(R.string.updatefirmwareoperation_update_in_progress, true, progressPercent, getContext());
}
}
@@ -21,10 +21,7 @@ import android.content.Context;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRawRequest;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class FirmwareFilePutRequest extends FilePutRawRequest {
@@ -35,7 +32,7 @@ public class FirmwareFilePutRequest extends FilePutRawRequest {
@Override
public void onPacketWritten(TransactionBuilder transactionBuilder, int packetNr, int packetCount) {
int progressPercent = (int) ((((float) packetNr) / packetCount) * 100);
transactionBuilder.add(new SetProgressAction(GBApplication.getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, GBApplication.getContext()));
transactionBuilder.setProgress(R.string.updatefirmwareoperation_update_in_progress, true, progressPercent, GBApplication.getContext());
}
@Override
@@ -36,8 +36,6 @@ import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLESingleDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.PlainAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class XiaomiBleSupport extends XiaomiConnectionSupport {
@@ -291,12 +289,12 @@ public class XiaomiBleSupport extends XiaomiConnectionSupport {
public void onUploadProgress(int textRsrc, int progressPercent, boolean ongoing) {
try {
final TransactionBuilder builder = commsSupport.createTransactionBuilder("send data upload progress");
builder.add(new SetProgressAction(
commsSupport.getContext().getString(textRsrc),
builder.setProgress(
textRsrc,
ongoing,
progressPercent,
commsSupport.getContext()
));
);
builder.queue(commsSupport.getQueue());
} catch (final Exception e) {
LOG.error("Failed to update progress notification", e);
@@ -20,7 +20,6 @@ import static nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.Xiaomi
import static nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSppPacketV1.OPCODE_READ;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
@@ -41,8 +40,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.AbstractBTBRDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.PlainAction;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.actions.SetProgressAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiChannelHandler.Channel;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@@ -135,12 +132,12 @@ public class XiaomiSppSupport extends XiaomiConnectionSupport {
public void onUploadProgress(final int textRsrc, final int progressPercent, final boolean ongoing) {
try {
final TransactionBuilder builder = commsSupport.createTransactionBuilder("send data upload progress");
builder.add(new SetProgressAction(
commsSupport.getContext().getString(textRsrc),
builder.setProgress(
textRsrc,
ongoing,
progressPercent,
commsSupport.getContext()
));
);
builder.queue(commsSupport.getQueue());
} catch (final Exception e) {
LOG.error("Failed to update progress notification", e);