From 4298d293b7cc57170fdf77f6541317c97dd92f70 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Thu, 25 Apr 2024 13:19:25 +0800 Subject: [PATCH] huawei: Many fixes after pull review * added missing license headers * added fileType fields and args, removed hardcoded values * changed some names from watchface to more general fileupload * moved app management methods implementation from LE and BR coordinator to HuaweiCoordinator * extra empty lines removed * removed unnecessary tlv tag checks --- .../devices/huawei/HuaweiBRCoordinator.java | 13 ++- .../devices/huawei/HuaweiCoordinator.java | 30 +++++++ .../devices/huawei/HuaweiInstallHandler.java | 17 ++++ .../devices/huawei/HuaweiLECoordinator.java | 14 ++-- .../devices/huawei/packets/FileUpload.java | 77 +++++++++--------- .../devices/huawei/packets/Watchface.java | 80 +++++++------------ .../devices/huawei/AsynchronousResponse.java | 9 ++- .../devices/huawei/HuaweiFwHelper.java | 30 +++++++ .../devices/huawei/HuaweiSupportProvider.java | 11 ++- .../devices/huawei/HuaweiUploadManager.java | 21 +++++ .../huawei/HuaweiWatchfaceManager.java | 30 ++++--- .../huawei/requests/GetWatchfaceParams.java | 17 ++++ .../huawei/requests/GetWatchfacesList.java | 17 ++++ .../huawei/requests/GetWatchfacesNames.java | 17 ++++ .../huawei/requests/SendFileUploadAck.java | 23 +++++- .../huawei/requests/SendFileUploadChunk.java | 20 ++++- .../requests/SendFileUploadComplete.java | 24 +++++- .../huawei/requests/SendFileUploadHash.java | 20 ++++- .../huawei/requests/SendFileUploadInfo.java | 19 ++++- .../huawei/requests/SendWatchfaceConfirm.java | 18 ++++- .../requests/SendWatchfaceOperation.java | 17 ++++ 21 files changed, 386 insertions(+), 138 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java index a7574d9c2..4eaae5beb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java @@ -165,16 +165,16 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin @Override public Class getAppsManagementActivity() { - return AppManagerActivity.class; + return huaweiCoordinator.getAppManagerActivity(); } @Override public boolean supportsAppListFetching() { - return true; + return huaweiCoordinator.getSupportsAppListFetching(); } @Override public boolean supportsAppsManagement(GBDevice device) { - return true; + return huaweiCoordinator.getSupportsAppsManagement(device); } @Override @@ -184,12 +184,12 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin @Override public boolean supportsInstalledAppManagement(GBDevice device) { - return false; + return huaweiCoordinator.getSupportsInstalledAppManagement(device); } @Override public boolean supportsCachedAppManagement(GBDevice device) { - return false; + return huaweiCoordinator.getSupportsCachedAppManagement(device); } @Override @@ -225,8 +225,7 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin @Override public InstallHandler findInstallHandler(Uri uri, Context context) { - HuaweiInstallHandler handler = new HuaweiInstallHandler(uri, context); - return handler.isValid() ? handler : null; + return huaweiCoordinator.getInstallHandler(uri, context); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java index 91a635a80..92a6fe7db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java @@ -16,8 +16,10 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.huawei; +import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; +import android.net.Uri; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -30,8 +32,10 @@ import org.slf4j.Logger; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AppManagerActivity; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsScreen; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications.NotificationConstraintsType; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface; @@ -562,4 +566,30 @@ public class HuaweiCoordinator { public void setWatchfaceDeviceParams(Watchface.WatchfaceDeviceParams watchfaceDeviceParams) { this.watchfaceDeviceParams = watchfaceDeviceParams; } + + public Class getAppManagerActivity() { + return AppManagerActivity.class; + } + + public boolean getSupportsAppListFetching() { + return true; + } + + public boolean getSupportsAppsManagement(GBDevice device) { + return true; + } + + public boolean getSupportsInstalledAppManagement(GBDevice device) { + return false; + } + + public boolean getSupportsCachedAppManagement(GBDevice device) { + return false; + } + + public InstallHandler getInstallHandler(Uri uri, Context context) { + HuaweiInstallHandler handler = new HuaweiInstallHandler(uri, context); + return handler.isValid() ? handler : null; + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiInstallHandler.java index fd3d9b862..78dc64898 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiInstallHandler.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.devices.huawei; import android.content.Context; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java index 3ed3cb655..8b3e007fd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java @@ -14,6 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.devices.huawei; import android.app.Activity; @@ -166,16 +167,16 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i @Override public Class getAppsManagementActivity() { - return AppManagerActivity.class; + return huaweiCoordinator.getAppManagerActivity(); } @Override public boolean supportsAppListFetching() { - return true; + return huaweiCoordinator.getSupportsAppListFetching(); } @Override public boolean supportsAppsManagement(GBDevice device) { - return true; + return huaweiCoordinator.getSupportsAppsManagement(device); } @Override @@ -185,12 +186,12 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i @Override public boolean supportsInstalledAppManagement(GBDevice device) { - return false; + return huaweiCoordinator.getSupportsInstalledAppManagement(device); } @Override public boolean supportsCachedAppManagement(GBDevice device) { - return false; + return huaweiCoordinator.getSupportsCachedAppManagement(device); } @Override @@ -225,8 +226,7 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i @Override public InstallHandler findInstallHandler(Uri uri, Context context) { - HuaweiInstallHandler handler = new HuaweiInstallHandler(uri, context); - return handler.isValid() ? handler : null; + return huaweiCoordinator.getInstallHandler(uri, context); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FileUpload.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FileUpload.java index 15a22d538..e540b2af3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FileUpload.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FileUpload.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; @@ -10,16 +27,22 @@ public class FileUpload { public byte file_id = 0; public String protocolVersion = ""; public short app_wait_time = 0; - public byte bitmap_enable = 0; public short unit_size = 0; public int max_apply_data_size = 0; public short interval =0; public int received_file_size =0; - public byte no_encrypt = 0; } + public static class Filetype { + public static final byte watchface = 1; + public static final byte music = 2; + public static final byte backgroundImage = 3; + public static final byte app = 7; + } + + public static class FileInfoSend { public static final byte id = 0x02; public static class Request extends HuaweiPacket { @@ -39,12 +62,11 @@ public class FileUpload { .put(0x02, fileSize) .put(0x03, (byte) fileType); - if (fileType == 1) + if (fileType == Filetype.watchface) this.tlv.put(0x05, watchfaceName) .put(0x06, watchfaceVersion); this.complete = true; - } } @@ -53,8 +75,6 @@ public class FileUpload { super(paramsProvider); } } - - } public static class FileHashSend { @@ -63,19 +83,17 @@ public class FileUpload { public static class Request extends HuaweiPacket { public Request(ParamsProvider paramsProvider, - byte[] hash) { + byte[] hash, + byte fileType) { super(paramsProvider); this.serviceId = FileUpload.id; this.commandId = id; this.tlv = new HuaweiTLV() - .put(0x01, (byte) 1) // filetype 1 - watchface, 2 - music + .put(0x01, fileType) .put(0x03, hash); - this.complete = true; - } - } public static class Response extends HuaweiPacket { @@ -83,19 +101,18 @@ public class FileUpload { super(paramsProvider); } } - } public static class FileUploadConsultAck { public static final byte id = 0x04; public static class Request extends HuaweiPacket { - public Request(ParamsProvider paramsProvider, byte noEncryption) { + public Request(ParamsProvider paramsProvider, byte noEncryption, byte fileType) { super(paramsProvider); this.serviceId = FileUpload.id; this.commandId = id; this.tlv = new HuaweiTLV() .put(0x7f, 0x000186A0) //ok - .put(0x01, (byte) 0x01); // filetype 1 - watchface, 2 -music, 3 - png image for watchface background, 7 - app + .put(0x01, fileType); if (noEncryption == 1) this.tlv.put(0x09, (byte)0x01); // need on devices which generally encrypted, but files this.complete = true; @@ -111,25 +128,16 @@ public class FileUpload { @Override public void parseTlv() throws HuaweiPacket.ParseException { - if (this.tlv.contains(0x01) && this.tlv.getBytes(0x01).length == 1) this.fileUploadParams.file_id = this.tlv.getByte(0x01); - if (this.tlv.contains(0x02)) this.fileUploadParams.protocolVersion = this.tlv.getString(0x02); - if (this.tlv.contains(0x03) && this.tlv.getBytes(0x03).length == 2) this.fileUploadParams.app_wait_time = this.tlv.getShort(0x03); - if (this.tlv.contains(0x04)) this.fileUploadParams.bitmap_enable = this.tlv.getByte(0x04); - if (this.tlv.contains(0x05) && this.tlv.getBytes(0x05).length == 2) this.fileUploadParams.unit_size = this.tlv.getShort(0x05); - if (this.tlv.contains(0x06) && this.tlv.getBytes(0x06).length == 4) this.fileUploadParams.max_apply_data_size = this.tlv.getInteger(0x06); - if (this.tlv.contains(0x07) && this.tlv.getBytes(0x07).length == 2) this.fileUploadParams.interval = this.tlv.getShort(0x07); - if (this.tlv.contains(0x08) && this.tlv.getBytes(0x08).length == 4) this.fileUploadParams.received_file_size = this.tlv.getInteger(0x08); - if (this.tlv.contains(0x09)) - this.fileUploadParams.no_encrypt = this.tlv.getByte(0x09); - + if (this.tlv.contains(0x09)) // optional for older devices + this.fileUploadParams.no_encrypt = this.tlv.getByte(0x09); } } } @@ -147,12 +155,9 @@ public class FileUpload { } @Override public void parseTlv() throws HuaweiPacket.ParseException { - if (this.tlv.contains(0x02) && this.tlv.getBytes(0x02).length == 4) - this.bytesUploaded = this.tlv.getInteger(0x02); - if (this.tlv.contains(0x03) && this.tlv.getBytes(0x03).length == 4) - this.nextchunkSize = this.tlv.getInteger(0x03); + this.bytesUploaded = this.tlv.getInteger(0x02); + this.nextchunkSize = this.tlv.getInteger(0x03); } - } public static class FileNextChunkSend extends HuaweiPacket { @@ -170,20 +175,19 @@ public class FileUpload { public static final byte id = 0x07; public static class Request extends HuaweiPacket { - public Request(ParamsProvider paramsProvider) { + public Request(ParamsProvider paramsProvider, byte fileType) { super(paramsProvider); this.serviceId = FileUpload.id; this.commandId = id; this.tlv = new HuaweiTLV() .put(0x7f, 0x000186A0) //ok - .put(0x01, (byte) 0x01); // filetype 1 - watchface, 2 -music + .put(0x01, fileType); this.complete = true; } } public static class Response extends HuaweiPacket { - byte status = 0; public Response (ParamsProvider paramsProvider) { super(paramsProvider); @@ -191,13 +195,8 @@ public class FileUpload { @Override public void parseTlv() throws HuaweiPacket.ParseException { - if (this.tlv.contains(0x02) && this.tlv.getBytes(0x02).length == 1) - this.status = this.tlv.getByte(0x02); + this.status = this.tlv.getByte(0x02); } - } - } - - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Watchface.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Watchface.java index 422b8154f..39b0aaf8b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Watchface.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Watchface.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets; import java.util.ArrayList; @@ -34,47 +51,36 @@ public class Watchface { public byte expandedtype = 0; public InstalledWatchfaceInfo(HuaweiTLV tlv) throws HuaweiPacket.MissingTagException { - if(tlv.contains(0x03)) - this.fileName = tlv.getString(0x03); - if(tlv.contains(0x04)) - this.version = tlv.getString(0x04); - if(tlv.contains(0x05)) - this.type = tlv.getByte(0x05); - if(tlv.contains(0x07)) + this.fileName = tlv.getString(0x03); + this.version = tlv.getString(0x04); + this.type = tlv.getByte(0x05); + if (tlv.contains(0x07)) // optional this.expandedtype = tlv.getByte(0x07); } public boolean isCurrent() { return (this.type & 1) == 1; } - public boolean isFactory() { return ((this.type >> 1 )& 1) == 1; } - public boolean isEditable() { return ((this.type >> 3 )& 1) == 1; } - public boolean isVideo() { return ((this.type >> 4 )& 1) == 1; } - public boolean isPhoto() { return ((this.type >> 5 )& 1) == 1; } - public boolean isTryout() { return ((this.type >> 6 )& 1) == 1; } - public boolean isKaleidoskop() { return ((this.type >> 7 )& 1) == 1; } - } - public static class WatchfaceParams { public static final byte id = 0x01; public static class Request extends HuaweiPacket { @@ -84,7 +90,6 @@ public class Watchface { this.serviceId = Watchface.id; this.commandId = id; - this.tlv = new HuaweiTLV() .put(0x01) .put(0x02) @@ -95,12 +100,9 @@ public class Watchface { .put(0x0f); this.complete = true; - } - } - public static class Response extends HuaweiPacket { public WatchfaceDeviceParams params = new WatchfaceDeviceParams(); public Response (ParamsProvider paramsProvider) { @@ -109,21 +111,14 @@ public class Watchface { @Override public void parseTlv() throws ParseException { - if(this.tlv.contains(0x01)) - this.params.maxVersion = this.tlv.getString(0x01); - if(this.tlv.contains(0x02)) - this.params.width = this.tlv.getShort(0x02); - if(this.tlv.contains(0x03)) - this.params.height = this.tlv.getShort(0x03); - if(this.tlv.contains(0x04)) - this.params.supportFileType = this.tlv.getByte(0x04); - if(this.tlv.contains(0x05)) - this.params.sort = this.tlv.getByte(0x05); - if(this.tlv.contains(0x06)) - this.params.otherWatchfaceVersions = this.tlv.getString(0x06); + this.params.maxVersion = this.tlv.getString(0x01); + this.params.width = this.tlv.getShort(0x02); + this.params.height = this.tlv.getShort(0x03); + this.params.supportFileType = this.tlv.getByte(0x04); + this.params.sort = this.tlv.getByte(0x05); + this.params.otherWatchfaceVersions = this.tlv.getString(0x06); } } - } public static class DeviceWatchInfo { @@ -138,7 +133,6 @@ public class Watchface { .put(0x01) .put(0x06, (byte) 0x03); //3 -overseas non-test, 2 - test, 1 -null? } - } public static class Response extends HuaweiPacket { @@ -157,13 +151,9 @@ public class Watchface { } } } - } - } - - public static class WatchfaceOperation { public static final byte id = 0x03; @@ -182,8 +172,6 @@ public class Watchface { this.commandId = id; } - - } public static class Response extends HuaweiPacket { @@ -191,7 +179,6 @@ public class Watchface { super(paramsProvider); } } - } public static class WatchfaceConfirm { @@ -207,10 +194,7 @@ public class Watchface { .put(0x01, fileName.split("_")[0]) .put(0x02, fileName.split("_")[1]) .put(0x7f, 0x000186A0); - - } - } public static class Response extends HuaweiPacket { @@ -218,10 +202,8 @@ public class Watchface { super(paramsProvider); } } - } - public static class WatchfaceNameInfo { public static final byte id = 0x06; @@ -244,11 +226,9 @@ public class Watchface { .put(0x82, tlvList); } - } public static class Response extends HuaweiPacket { - public HashMap watchFaceNames = new HashMap(); public Response (ParamsProvider paramsProvider) { super(paramsProvider); @@ -262,12 +242,6 @@ public class Watchface { } } } - } - - - } - - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/AsynchronousResponse.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/AsynchronousResponse.java index 85b2dfdf6..5271f1ece 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/AsynchronousResponse.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/AsynchronousResponse.java @@ -400,7 +400,7 @@ public class AsynchronousResponse { if (response.serviceId == FileUpload.id) { if (response.commandId == FileUpload.FileHashSend.id) { try { - SendFileUploadHash sendFileUploadHash = new SendFileUploadHash(this.support, this.support.huaweiUploadManager); + SendFileUploadHash sendFileUploadHash = new SendFileUploadHash(support, support.huaweiUploadManager); sendFileUploadHash.doPerform(); } catch (IOException e) { LOG.error("Could not send fileupload hash request", e); @@ -414,7 +414,8 @@ public class AsynchronousResponse { try { support.huaweiUploadManager.setDeviceBusy(); - SendFileUploadAck sendFileUploadAck = new SendFileUploadAck(this.support, resp.fileUploadParams.no_encrypt); + SendFileUploadAck sendFileUploadAck = new SendFileUploadAck(support, + resp.fileUploadParams.no_encrypt, support.huaweiUploadManager.getFileType()); sendFileUploadAck.doPerform(); } catch (IOException e) { LOG.error("Could not send fileupload ack request", e); @@ -429,7 +430,7 @@ public class AsynchronousResponse { support.onUploadProgress(R.string.updatefirmwareoperation_update_in_progress, progress, true); try { - SendFileUploadChunk sendFileUploadChunk = new SendFileUploadChunk(this.support, this.support.huaweiUploadManager); + SendFileUploadChunk sendFileUploadChunk = new SendFileUploadChunk(support, support.huaweiUploadManager); sendFileUploadChunk.doPerform(); } catch (IOException e) { LOG.error("Could not send fileupload next chunk request", e); @@ -438,7 +439,7 @@ public class AsynchronousResponse { try { support.huaweiUploadManager.unsetDeviceBusy(); support.onUploadProgress(R.string.updatefirmwareoperation_update_complete, 100, false); - SendFileUploadComplete sendFileUploadComplete = new SendFileUploadComplete(this.support); + SendFileUploadComplete sendFileUploadComplete = new SendFileUploadComplete(this.support, this.support.huaweiUploadManager.getFileType()); SendWatchfaceOperation sendWatchfaceOperation = new SendWatchfaceOperation(this.support, this.support.huaweiUploadManager.getFileName(), Watchface.WatchfaceOperation.operationActive); sendFileUploadComplete.doPerform(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiFwHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiFwHelper.java index 3b77878c2..7a9fcfb59 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiFwHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiFwHelper.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei; import android.content.Context; @@ -11,6 +28,7 @@ import org.slf4j.LoggerFactory; import java.io.FileNotFoundException; import java.io.IOException; +import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FileUpload; import nodomain.freeyourgadget.gadgetbridge.util.GBZipFile; import nodomain.freeyourgadget.gadgetbridge.util.UriHelper; import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException; @@ -24,6 +42,9 @@ public class HuaweiFwHelper { private int fileSize = 0; private boolean typeWatchface; + private byte fileType = 0; + String fileName = ""; + Bitmap watchfacePreviewBitmap; HuaweiWatchfaceManager.WatchfaceDescription watchfaceDescription; Context mContext; @@ -48,6 +69,7 @@ public class HuaweiFwHelper { assert watchfaceDescription.screen != null; assert watchfaceDescription.title != null; typeWatchface = true; + fileType = FileUpload.Filetype.watchface; } } @@ -105,5 +127,13 @@ public class HuaweiFwHelper { return watchfaceDescription; } + public byte getFileType() { + return fileType; + } + + public String getFileName() { + return fileName; + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java index d4710d340..7221c349e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java @@ -1843,16 +1843,21 @@ public class HuaweiSupportProvider { public void onInstallApp(Uri uri) { LOG.info("enter onAppInstall uri: "+uri); - huaweiUploadManager.setFileName(huaweiWatchfaceManager.getRandomName()); HuaweiFwHelper huaweiFwHelper = new HuaweiFwHelper(uri, getContext()); huaweiUploadManager.setBytes(huaweiFwHelper.getBytes()); + huaweiUploadManager.setFileType(huaweiFwHelper.getFileType()); + if (huaweiFwHelper.isWatchface()) { + huaweiUploadManager.setFileName(huaweiWatchfaceManager.getRandomName()); + } else { + huaweiUploadManager.setFileName(huaweiFwHelper.getFileName()); + } try { SendFileUploadInfo sendFileUploadInfo = new SendFileUploadInfo(this, huaweiUploadManager); sendFileUploadInfo.doPerform(); } catch (IOException e) { - GB.toast(context, "Failed to send watchface info", Toast.LENGTH_SHORT, GB.ERROR, e); - LOG.error("Failed to send watchface info", e); + GB.toast(context, "Failed to send file upload info", Toast.LENGTH_SHORT, GB.ERROR, e); + LOG.error("Failed to send file upload info", e); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiUploadManager.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiUploadManager.java index 9f05986a2..4aa12abdc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiUploadManager.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiUploadManager.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei; import org.slf4j.Logger; @@ -76,6 +93,10 @@ public class HuaweiUploadManager { return this.fileType; } + public void setFileType(byte fileType) { + this.fileType = fileType; + } + public byte[] getFileSHA256() { return fileSHA256; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWatchfaceManager.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWatchfaceManager.java index 1bf1eda22..13453b6b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWatchfaceManager.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWatchfaceManager.java @@ -1,5 +1,21 @@ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei; +/* Copyright (C) 2024 Vitalii Tomin + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + +package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +50,6 @@ public class HuaweiWatchfaceManager { Logger LOG = LoggerFactory.getLogger(HuaweiCoordinator.class); - public static class Resolution { Map map = new HashMap<>(); @@ -101,8 +116,6 @@ public class HuaweiWatchfaceManager } } - - private List installedWatchfaceInfoList; private HashMap watchfacesNames; @@ -121,13 +134,11 @@ public class HuaweiWatchfaceManager return installedWatchfaceInfoList; } - public void setWatchfacesNames(HashMap map) { this.watchfacesNames = map; } - public String getRandomName() { Random random = new Random(); @@ -251,8 +262,6 @@ public class HuaweiWatchfaceManager } catch (IOException e) { LOG.error("Could not set watchface ", getFullFileName(uuid), e ); } - - } public void deleteWatchface(UUID uuid) { @@ -288,12 +297,7 @@ public class HuaweiWatchfaceManager break; } } - String filename = name + "_" + version; return filename; - } - - - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfaceParams.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfaceParams.java index 4de518a0b..e29476dd1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfaceParams.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfaceParams.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import org.slf4j.Logger; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesList.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesList.java index 19f8df78f..644508d92 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesList.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesList.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import org.slf4j.Logger; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesNames.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesNames.java index bb8c2b8d6..dd9cc0e67 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesNames.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/GetWatchfacesNames.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import org.slf4j.Logger; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadAck.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadAck.java index f899b241e..bb48ebdf8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadAck.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadAck.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import java.util.List; @@ -8,18 +25,20 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupport public class SendFileUploadAck extends Request { byte noEncryption = 0; - public SendFileUploadAck(HuaweiSupportProvider support, byte noEncryption) { + byte fileType = 1; + public SendFileUploadAck(HuaweiSupportProvider support, byte noEncryption, byte fileType) { super(support); this.serviceId = FileUpload.id; this.commandId = FileUpload.FileUploadConsultAck.id; this.noEncryption = noEncryption; + this.fileType = fileType; this.addToResponse = false; } @Override protected List createRequest() throws RequestCreationException { try { - return new FileUpload.FileUploadConsultAck.Request(this.paramsProvider, this.noEncryption ).serialize(); + return new FileUpload.FileUploadConsultAck.Request(this.paramsProvider, this.noEncryption, this.fileType).serialize(); } catch (HuaweiPacket.CryptoException e) { throw new RequestCreationException(e); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadChunk.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadChunk.java index 43935bbd5..d61cfd3d9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadChunk.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadChunk.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import java.util.List; @@ -19,13 +36,10 @@ public class SendFileUploadChunk extends Request { @Override protected List createRequest() throws RequestCreationException { - //FIXME need new package type with raw data chunks ? return new FileUpload.FileNextChunkSend(this.paramsProvider).serializeFileChunk( huaweiUploadManager.getCurrentChunk(), huaweiUploadManager.getCurrentUploadPosition(), huaweiUploadManager.getUnitSize() ); - } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadComplete.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadComplete.java index 1c39adc01..80a4770d6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadComplete.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadComplete.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import java.util.List; @@ -8,11 +25,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupport public class SendFileUploadComplete extends Request { - public SendFileUploadComplete(HuaweiSupportProvider support) { + byte fileType = 0; + public SendFileUploadComplete(HuaweiSupportProvider support, byte fileType) { super(support); this.serviceId = FileUpload.id; this.commandId = FileUpload.FileUploadResult.id; + this.fileType = fileType; this.addToResponse = false; } @@ -20,10 +39,9 @@ public class SendFileUploadComplete extends Request { @Override protected List createRequest() throws RequestCreationException { try { - return new FileUpload.FileUploadResult.Request(this.paramsProvider).serialize(); + return new FileUpload.FileUploadResult.Request(this.paramsProvider, this.fileType).serialize(); } catch (HuaweiPacket.CryptoException e) { throw new RequestCreationException(e); } } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadHash.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadHash.java index 77bf101f4..c86de3f33 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadHash.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadHash.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import java.util.List; @@ -23,7 +40,8 @@ public class SendFileUploadHash extends Request{ protected List createRequest() throws RequestCreationException { try { return new FileUpload.FileHashSend.Request(this.paramsProvider, - huaweiUploadManager.getFileSHA256() + huaweiUploadManager.getFileSHA256(), + huaweiUploadManager.getFileType() ).serialize(); } catch (HuaweiPacket.CryptoException e) { throw new RequestCreationException(e); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadInfo.java index 569c20395..c8c38ecff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendFileUploadInfo.java @@ -1,7 +1,22 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; - - import java.util.List; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceConfirm.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceConfirm.java index 9fab3fa08..8d8b08f72 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceConfirm.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceConfirm.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import java.util.List; @@ -26,5 +43,4 @@ public class SendWatchfaceConfirm extends Request { throw new RequestCreationException(e); } } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceOperation.java index d0c943362..7fd9ff595 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendWatchfaceOperation.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2024 Vitalii Tomin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import java.util.List;