mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
igpsport: Copy FitAsyncProcessor from Garmin
This commit is contained in:
committed by
José Rebelo
parent
4f56b6569b
commit
bab5311d7f
+1
@@ -720,6 +720,7 @@ public class IGPSportDeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
public void setContext(final GBDevice gbDevice, final BluetoothAdapter btAdapter, final Context context) {
|
||||
super.setContext(gbDevice, btAdapter, context);
|
||||
this.mediaManager = new MediaManager(context);
|
||||
this.downloadManager.setContext(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+35
-10
@@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.igpsport;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminTimeUtils.garminTimestampToJavaMillis;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -43,10 +45,11 @@ import nodomain.freeyourgadget.gadgetbridge.proto.igpsport.Common;
|
||||
import nodomain.freeyourgadget.gadgetbridge.proto.igpsport.CyclingData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.proto.igpsport.FileDownload;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.exception.FitParseException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.igpsport.fit.FitAsyncProcessor;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.igpsport.fit.FitImporter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.notifications.GBProgressNotification;
|
||||
|
||||
|
||||
public class IGPSportDownloadManager {
|
||||
@@ -59,15 +62,23 @@ public class IGPSportDownloadManager {
|
||||
private Boolean downloadInProgress = false;
|
||||
private Boolean firstChunk = true;
|
||||
private FitImporter fitImporter;
|
||||
private GBProgressNotification transferNotification;
|
||||
private List<File> filesToProcess = new ArrayList<>();
|
||||
int pbSize=0;
|
||||
|
||||
|
||||
|
||||
public IGPSportDownloadManager(IGPSportDeviceSupport support) {
|
||||
this.support = support;
|
||||
|
||||
recievingDataBuffer = new ByteArrayOutputStream();
|
||||
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.transferNotification = new GBProgressNotification(context, GB.NOTIFICATION_CHANNEL_ID_TRANSFER);
|
||||
}
|
||||
|
||||
public void setFilesAvaliable(byte[] pbData) throws InvalidProtocolBufferException {
|
||||
|
||||
List<CyclingData.cycling_data_file_flag_message> message = CyclingData.cycling_data_msg.parseFrom(pbData).getCyclingDataFileFlagMsgList();
|
||||
@@ -76,6 +87,7 @@ public class IGPSportDownloadManager {
|
||||
}
|
||||
|
||||
LOG.info("Found " + message.size() + " files");
|
||||
filesToProcess.clear();
|
||||
syncNextFile();
|
||||
|
||||
}
|
||||
@@ -83,11 +95,26 @@ public class IGPSportDownloadManager {
|
||||
public void syncNextFile() {
|
||||
if (avaliableActivityFiles.isEmpty()) {
|
||||
LOG.info("No files to sync");
|
||||
if (support.getDevice().isBusy() ) {
|
||||
support.getDevice().unsetBusyTask();
|
||||
GB.signalActivityDataFinish(support.getDevice());
|
||||
support.getDevice().sendDeviceUpdateIntent(getContext());
|
||||
}
|
||||
|
||||
transferNotification.start(R.string.busy_task_processing_files, 0, filesToProcess.size());
|
||||
|
||||
final FitAsyncProcessor fitAsyncProcessor = new FitAsyncProcessor(getContext(), support.getDevice());
|
||||
fitAsyncProcessor.process(filesToProcess, new FitAsyncProcessor.Callback() {
|
||||
@Override
|
||||
public void onProgress(final int i) {
|
||||
transferNotification.setTotalProgress(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
support.getDevice().unsetBusyTask();
|
||||
GB.signalActivityDataFinish(support.getDevice());
|
||||
transferNotification.finish();
|
||||
support.getDevice().sendDeviceUpdateIntent(getContext());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return;
|
||||
} else {
|
||||
if (!support.getDevice().isBusy() ) {
|
||||
@@ -117,7 +144,7 @@ public class IGPSportDownloadManager {
|
||||
recievingDataBuffer.reset();
|
||||
downloadInProgress = true;
|
||||
firstChunk = true;
|
||||
fitImporter = new FitImporter(support.getContext(), support.getDevice());
|
||||
|
||||
}
|
||||
|
||||
public void addData(byte[] data) {
|
||||
@@ -151,11 +178,9 @@ public class IGPSportDownloadManager {
|
||||
FileDownload.file_download pbInfo = FileDownload.file_download.parseFrom(pbData);
|
||||
FileUtils.copyStreamToFile(new ByteArrayInputStream(recievingDataBuffer.toByteArray(), 20+4+pbSize, pbInfo.getFileSize()), outputFile);
|
||||
outputFile.setLastModified(garminTimestampToJavaMillis(downloadingFile.getGarminTimeStamp()));
|
||||
fitImporter.importFile(outputFile);
|
||||
filesToProcess.add(outputFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (FitParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
syncNextFile();
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.igpsport.fit;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.PendingFileProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.igpsport.fit.FitImporter;
|
||||
|
||||
public class FitAsyncProcessor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FitAsyncProcessor.class);
|
||||
private static final AtomicLong THREAD_COUNTER = new AtomicLong(0L);
|
||||
|
||||
private final Context context;
|
||||
private final GBDevice gbDevice;
|
||||
private final Handler handler;
|
||||
|
||||
public FitAsyncProcessor(final Context context, final GBDevice gbDevice) {
|
||||
this.context = context;
|
||||
this.gbDevice = gbDevice;
|
||||
this.handler = new Handler(context.getMainLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a list of files asynchronously. Callback is executed on the UI thread.
|
||||
*/
|
||||
public void process(final List<File> files, final Callback callback) {
|
||||
LOG.debug("Starting processor for {} files", files.size());
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
int i = 0;
|
||||
for (final File file : files) {
|
||||
i++;
|
||||
LOG.debug("Parsing {}", file);
|
||||
|
||||
final int finalI = i;
|
||||
FitAsyncProcessor.this.handler.post(() -> callback.onProgress(finalI));
|
||||
|
||||
try {
|
||||
FitImporter fitImporter = new FitImporter(context, gbDevice);
|
||||
fitImporter.importFile(file);
|
||||
} catch (final Exception ex) {
|
||||
LOG.error("Exception while importing {}", file, ex);
|
||||
continue; // do not remove from pending files
|
||||
}
|
||||
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
|
||||
final PendingFileProvider pendingFileProvider = new PendingFileProvider(gbDevice, session);
|
||||
|
||||
pendingFileProvider.removePendingFile(file.getPath());
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Exception while removing pending file {}", file, e);
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Failed to parse from storage", e);
|
||||
}
|
||||
|
||||
FitAsyncProcessor.this.handler.post(callback::onFinish);
|
||||
}, "FitAsyncProcessor_" + THREAD_COUNTER.getAndIncrement()).start();
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onProgress(final int perc);
|
||||
|
||||
void onFinish();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user