huawei: packets and requests to for watchlist

* added packets requests and parsing for getting list of
installed watchfaces and its names
This commit is contained in:
Vitaliy Tomin 2024-04-07 00:58:30 +08:00
parent ad4e373131
commit ef3654b7e3
6 changed files with 249 additions and 1 deletions

View File

@ -555,6 +555,10 @@ public class HuaweiPacket {
switch (this.commandId) {
case Watchface.WatchfaceParams.id:
return new Watchface.WatchfaceParams.Response(paramsProvider).fromPacket(this);
case Watchface.DeviceWatchInfo.id:
return new Watchface.DeviceWatchInfo.Response(paramsProvider).fromPacket(this);
case Watchface.WatchfaceNameInfo.id:
return new Watchface.WatchfaceNameInfo.Response(paramsProvider).fromPacket(this);
default:
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
return this;

View File

@ -1,5 +1,9 @@
package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
@ -15,6 +19,37 @@ public class Watchface {
public String otherWatchfaceVersions = "";
}
public static class InstalledWatchfaceInfo {
public String fileName = "";
public String version = "";
public byte type = 0;
// bit 0 - is current
// bit 1 - is factory preset
// bit 2 - ???
// bit 3 - editable
// bit 4 - video
// bit 5 - photo
// bit 6 - tryout (trial version)
// bit 7 - kaleidoskop
public byte expandedtype = 0;
public InstalledWatchfaceInfo(HuaweiTLV tlv) {
try {
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.expandedtype = tlv.getByte(0x07);
} catch (HuaweiPacket.MissingTagException e) {
throw new RuntimeException(e);
}
}
}
public static class WatchfaceParams {
public static final byte id = 0x01;
public static class Request extends HuaweiPacket {
@ -70,6 +105,49 @@ public class Watchface {
}
public static class DeviceWatchInfo {
public static final byte id = 0x02;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider) {
super(paramsProvider);
this.serviceId = Watchface.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01)
.put(0x06, (byte) 0x03); //3 -overseas non-test, 2 - test, 1 -null?
}
}
public static class Response extends HuaweiPacket {
public List<InstalledWatchfaceInfo> watchfaceInfoList;
public Response (ParamsProvider paramsProvider) {
super(paramsProvider);
}
@Override
public void parseTlv() throws HuaweiPacket.ParseException {
watchfaceInfoList = new ArrayList<>();
try {
if(this.tlv.contains(0x81)) {
for (HuaweiTLV subTlv : this.tlv.getObject(0x81).getObjects(0x82)) {
watchfaceInfoList.add(new Watchface.InstalledWatchfaceInfo(subTlv));
}
}
} catch (HuaweiPacket.MissingTagException e) {
throw new RuntimeException(e);
}
}
}
}
public static class WatchfaceOperation {
public static final byte id = 0x03;
@ -105,12 +183,13 @@ public class Watchface {
String fileName) {
super(paramsProvider);
this.serviceId = Watchface.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, fileName.split("_")[0])
.put(0x02, fileName.split("_")[1])
.put(0x7f, 0x000186A0);
this.commandId = id;
}
}
@ -124,4 +203,58 @@ public class Watchface {
}
public static class WatchfaceNameInfo {
public static final byte id = 0x06;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider,
List<InstalledWatchfaceInfo> watchfaceList) {
super(paramsProvider);
this.serviceId = Watchface.id;
this.commandId = id;
HuaweiTLV tlvList = new HuaweiTLV();
for (InstalledWatchfaceInfo watchface : watchfaceList) {
//TODO: ask name only for custom watchfaces
HuaweiTLV wfTlv = new HuaweiTLV().put(0x04, watchface.fileName);
tlvList.put(0x83, wfTlv);
}
this.tlv = new HuaweiTLV()
.put(0x01, (byte) 0x01)
.put(0x82, tlvList);
}
}
public static class Response extends HuaweiPacket {
public HashMap<String, String> watchFaceNames = new HashMap<String, String>();
public Response (ParamsProvider paramsProvider) {
super(paramsProvider);
}
@Override
public void parseTlv() throws HuaweiPacket.ParseException {
try {
if(this.tlv.contains(0x82)) {
for (HuaweiTLV subTlv : this.tlv.getObject(0x82).getObjects(0x83)) {
watchFaceNames.put(subTlv.getString(0x04), subTlv.getString(0x05));
}
}
} catch (HuaweiPacket.MissingTagException e) {
throw new RuntimeException(e);
}
}
}
}
}

View File

@ -80,12 +80,15 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.AcceptAgreementsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetEventAlarmList;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetGpsParameterRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetNotificationConstraintsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetSmartAlarmList;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetWatchfaceParams;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetWatchfacesList;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetWatchfacesNames;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendExtendedAccountRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsAndTimeToDeviceRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsDataRequest;
@ -733,6 +736,13 @@ public class HuaweiSupportProvider {
if (getHuaweiCoordinator().supportsWatchfaceParams()) {
GetWatchfaceParams getWatchfaceParams = new GetWatchfaceParams(this);
getWatchfaceParams.doPerform();
GetWatchfacesList getWatchfacesList = new GetWatchfacesList(this);
getWatchfacesList.doPerform();
GetWatchfacesNames getWatchfacesNames = new GetWatchfacesNames(this,
getHuaweiCoordinator().getHuaweiWatchfaceManager().getInstalledWatchfaceInfoList());
getWatchfacesNames.doPerform();
}
} catch (IOException e) {
GB.toast(getContext(), "Initialize dynamic services of Huawei device failed", Toast.LENGTH_SHORT, GB.ERROR,

View File

@ -6,12 +6,14 @@ import org.xml.sax.InputSource;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface.WatchfaceDeviceParams;
public class HuaweiWatchfaceManager
@ -85,6 +87,8 @@ public class HuaweiWatchfaceManager
private WatchfaceDeviceParams params;
private List<Watchface.InstalledWatchfaceInfo> installedWatchfaceInfoList;
private HashMap<String, String> watchfacesNames;
public HuaweiWatchfaceManager() {
@ -93,6 +97,20 @@ public class HuaweiWatchfaceManager
this.params = params;
}
public void setInstalledWatchfaceInfoList(List<Watchface.InstalledWatchfaceInfo> list) {
this.installedWatchfaceInfoList = list;
}
public List<Watchface.InstalledWatchfaceInfo> getInstalledWatchfaceInfoList()
{
return installedWatchfaceInfoList;
}
public void setWatchfacesNames(HashMap<String, String> map) {
this.watchfacesNames = map;
}
public short getWidth() {
return params.width;
}

View File

@ -0,0 +1,40 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class GetWatchfacesList extends Request{
private static final Logger LOG = LoggerFactory.getLogger(GetWatchfacesList.class);
public GetWatchfacesList(HuaweiSupportProvider support) {
super(support);
this.serviceId = Watchface.id;
this.commandId = Watchface.DeviceWatchInfo.id;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
try {
return new Watchface.DeviceWatchInfo.Request(paramsProvider).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
@Override
protected void processResponse() throws ResponseParseException {
if (!(receivedPacket instanceof Watchface.DeviceWatchInfo.Response))
throw new ResponseTypeMismatchException(receivedPacket, Watchface.DeviceWatchInfo.Response.class);
Watchface.DeviceWatchInfo.Response resp = (Watchface.DeviceWatchInfo.Response)(receivedPacket);
supportProvider.getHuaweiCoordinator().getHuaweiWatchfaceManager().setInstalledWatchfaceInfoList(resp.watchfaceInfoList);
}
}

View File

@ -0,0 +1,43 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class GetWatchfacesNames extends Request{
private static final Logger LOG = LoggerFactory.getLogger(GetWatchfacesNames.class);
List<Watchface.InstalledWatchfaceInfo> watchfaceInfoList;
public GetWatchfacesNames(HuaweiSupportProvider support, List<Watchface.InstalledWatchfaceInfo> list) {
super(support);
this.serviceId = Watchface.id;
this.commandId = Watchface.WatchfaceNameInfo.id;
this.watchfaceInfoList = list;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
try {
return new Watchface.WatchfaceNameInfo.Request(paramsProvider, this.watchfaceInfoList).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
@Override
protected void processResponse() throws ResponseParseException {
if (!(receivedPacket instanceof Watchface.WatchfaceNameInfo.Response))
throw new ResponseTypeMismatchException(receivedPacket, Watchface.WatchfaceNameInfo.Response.class);
Watchface.WatchfaceNameInfo.Response resp = (Watchface.WatchfaceNameInfo.Response)(receivedPacket);
supportProvider.getHuaweiCoordinator().getHuaweiWatchfaceManager().setWatchfacesNames(resp.watchFaceNames);
}
}