huawei: Implemented parser for WatchfaceDeviceParams
* watchface resolution validation implemented
This commit is contained in:
parent
3a8fbbe4d3
commit
34e9b5ceb5
|
@ -35,6 +35,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpec
|
|||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications.NotificationConstraintsType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiWatchfaceManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*;
|
||||
|
@ -50,6 +51,8 @@ public class HuaweiCoordinator {
|
|||
ByteBuffer notificationConstraints = null;
|
||||
|
||||
private final HuaweiCoordinatorSupplier parent;
|
||||
|
||||
protected HuaweiWatchfaceManager huaweiWatchfaceManager = new HuaweiWatchfaceManager();
|
||||
private boolean transactionCrypted=true;
|
||||
|
||||
public HuaweiCoordinator(HuaweiCoordinatorSupplier parent) {
|
||||
|
@ -75,6 +78,10 @@ public class HuaweiCoordinator {
|
|||
}
|
||||
}
|
||||
|
||||
public HuaweiWatchfaceManager getHuaweiWatchfaceManager(){
|
||||
return huaweiWatchfaceManager;
|
||||
}
|
||||
|
||||
private SharedPreferences getCapabilitiesSharedPreferences() {
|
||||
return GBApplication.getContext().getSharedPreferences("huawei_coordinator_capatilities" + parent.getDeviceType().name(), Context.MODE_PRIVATE);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@ import java.io.IOException;
|
|||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiWatchfaceManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBZipFile;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException;
|
||||
|
@ -28,8 +30,9 @@ public class HuaweiInstallHandler implements InstallHandler {
|
|||
|
||||
private final Context context;
|
||||
Bitmap previewbMap;
|
||||
byte[] watchfaceBin;
|
||||
byte[] watchfaceSHA256;
|
||||
String watchfaceDescription;
|
||||
boolean valid = false;
|
||||
|
||||
public HuaweiInstallHandler(Uri uri, Context context) {
|
||||
this.context = context;
|
||||
|
||||
|
@ -39,7 +42,7 @@ public class HuaweiInstallHandler implements InstallHandler {
|
|||
uriHelper = UriHelper.get(uri, this.context);
|
||||
|
||||
GBZipFile watchfacePackage = new GBZipFile(uriHelper.openInputStream());
|
||||
String watchfaceDescription = new String(watchfacePackage.getFileFromZip("description.xml"));
|
||||
watchfaceDescription = new String(watchfacePackage.getFileFromZip("description.xml"));
|
||||
final byte[] preview = watchfacePackage.getFileFromZip("preview/cover.jpg");
|
||||
previewbMap = BitmapFactory.decodeByteArray(preview, 0, preview.length);
|
||||
|
||||
|
@ -61,6 +64,23 @@ public class HuaweiInstallHandler implements InstallHandler {
|
|||
|
||||
@Override
|
||||
public void validateInstallation(InstallActivity installActivity, GBDevice device) {
|
||||
|
||||
final DeviceCoordinator coordinator = device.getDeviceCoordinator();
|
||||
if (!(coordinator instanceof HuaweiCoordinatorSupplier)) {
|
||||
LOG.warn("Coordinator is not a HuaweiCoordinatorSupplier: {}", coordinator.getClass());
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final HuaweiCoordinatorSupplier huaweiCoordinatorSupplier = (HuaweiCoordinatorSupplier) coordinator;
|
||||
|
||||
HuaweiWatchfaceManager.WatchfaceDescription description = new HuaweiWatchfaceManager.WatchfaceDescription(watchfaceDescription);
|
||||
|
||||
HuaweiWatchfaceManager.Resolution resolution = new HuaweiWatchfaceManager.Resolution();
|
||||
String deviceScreen = String.format("%d*%d",huaweiCoordinatorSupplier.getHuaweiCoordinator().getHuaweiWatchfaceManager().getHeight(),
|
||||
huaweiCoordinatorSupplier.getHuaweiCoordinator().getHuaweiWatchfaceManager().getWidth());
|
||||
this.valid = resolution.isValid(description.screen, deviceScreen);
|
||||
|
||||
installActivity.setInstallEnabled(true);
|
||||
|
||||
GenericItem installItem = new GenericItem();
|
||||
|
@ -70,6 +90,8 @@ public class HuaweiInstallHandler implements InstallHandler {
|
|||
installItem.setPreview(previewbMap);
|
||||
}
|
||||
|
||||
installItem.setName(description.title);
|
||||
installActivity.setInstallItem(installItem);
|
||||
if (device.isBusy()) {
|
||||
LOG.error("Firmware cannot be installed (device busy)");
|
||||
installActivity.setInfoText("Firmware cannot be installed (device busy)");
|
||||
|
@ -85,18 +107,22 @@ public class HuaweiInstallHandler implements InstallHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!isValid()) {
|
||||
LOG.error("Firmware cannot be installed (not valid)");
|
||||
installActivity.setInfoText("Firmware cannot be installed (not valid)");
|
||||
if (!this.valid) {
|
||||
LOG.error("Watchface cannot be installed");
|
||||
installActivity.setInfoText("Watchface resolution doesnt match device screen. Watchface is "
|
||||
+ resolution.screenByThemeVersion(description.screen) + " device screen is " + deviceScreen);
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
installItem.setName("Huawei watchface preview");
|
||||
|
||||
//installItem.setDetails(getVersion());
|
||||
|
||||
installActivity.setInfoText(context.getString(R.string.firmware_install_warning, "(unknown)"));
|
||||
installActivity.setInstallItem(installItem);
|
||||
installItem.setIcon(R.drawable.ic_watchface);
|
||||
installActivity.setInfoText(context.getString(R.string.watchface_install_info, installItem.getName(), description.version, description.author));
|
||||
|
||||
LOG.debug("Initialized HuaweiInstallHandler");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Alarms;
|
|||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Calls;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.DeviceConfig;
|
||||
|
@ -550,6 +551,14 @@ public class HuaweiPacket {
|
|||
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
|
||||
return this;
|
||||
}
|
||||
case Watchface.id:
|
||||
switch (this.commandId) {
|
||||
case Watchface.WatchfaceParams.id:
|
||||
return new Watchface.WatchfaceParams.Response(paramsProvider).fromPacket(this);
|
||||
default:
|
||||
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
|
||||
return this;
|
||||
}
|
||||
default:
|
||||
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
|
||||
return this;
|
||||
|
|
|
@ -6,6 +6,15 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
|
|||
public class Watchface {
|
||||
public static final byte id = 0x27;
|
||||
|
||||
public static class WatchfaceDeviceParams {
|
||||
public String maxVersion = "";
|
||||
public short width = 0;
|
||||
public short height = 0;
|
||||
public byte supportFileType = 1;
|
||||
public byte sort = 1;
|
||||
public String otherWatchfaceVersions = "";
|
||||
}
|
||||
|
||||
public static class WatchfaceParams {
|
||||
public static final byte id = 0x01;
|
||||
public static class Request extends HuaweiPacket {
|
||||
|
@ -29,14 +38,36 @@ public class Watchface {
|
|||
|
||||
}
|
||||
|
||||
public static class Response extends HuaweiPacket {
|
||||
public Response (ParamsProvider paramsProvider) {
|
||||
super(paramsProvider);
|
||||
}
|
||||
|
||||
|
||||
public static class Response extends HuaweiPacket {
|
||||
public WatchfaceDeviceParams params = new WatchfaceDeviceParams();
|
||||
public Response (ParamsProvider paramsProvider) {
|
||||
super(paramsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseTlv() throws ParseException {
|
||||
try {
|
||||
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);
|
||||
} catch (MissingTagException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
|
||||
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface.WatchfaceDeviceParams;
|
||||
|
||||
public class HuaweiWatchfaceManager
|
||||
{
|
||||
|
||||
public static class Resolution {
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
public Resolution() {
|
||||
map.put("HWHD09", "466*466");
|
||||
map.put("HWHD08", "320*320");
|
||||
map.put("HWHD10", "360*320");
|
||||
map.put("HWHD02", "454*454");
|
||||
map.put("HWHD01", "390*390");
|
||||
map.put("HWHD05", "460*188");
|
||||
map.put("HWHD03", "240*120");
|
||||
map.put("HWHD04", "160*80");
|
||||
map.put("HWHD06", "456*280");
|
||||
map.put("HWHD07", "368*194");
|
||||
}
|
||||
|
||||
public boolean isValid(String themeVersion, String screenResolution) {
|
||||
String screen = map.get(themeVersion).toString();
|
||||
if (screenResolution.equals(screen)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String screenByThemeVersion(String themeVersion) {
|
||||
String screen = map.get(themeVersion).toString();
|
||||
return screen;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class WatchfaceDescription {
|
||||
|
||||
public String title;
|
||||
public String title_cn;
|
||||
public String author;
|
||||
public String designer;
|
||||
public String screen;
|
||||
public String version;
|
||||
public String font;
|
||||
public String font_cn;
|
||||
|
||||
public WatchfaceDescription(String xmlStr) {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder;
|
||||
try {
|
||||
builder = factory.newDocumentBuilder();
|
||||
Document doc = builder.parse(new InputSource(new StringReader(
|
||||
xmlStr)));
|
||||
|
||||
this.title = doc.getElementsByTagName("title").item(0).getTextContent();
|
||||
this.title_cn = doc.getElementsByTagName("title-cn").item(0).getTextContent();
|
||||
this.author = doc.getElementsByTagName("author").item(0).getTextContent();
|
||||
this.designer = doc.getElementsByTagName("designer").item(0).getTextContent();
|
||||
this.screen = doc.getElementsByTagName("screen").item(0).getTextContent();
|
||||
this.version = doc.getElementsByTagName("version").item(0).getTextContent();
|
||||
this.font = doc.getElementsByTagName("font").item(0).getTextContent();
|
||||
this.font_cn = doc.getElementsByTagName("font-cn").item(0).getTextContent();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private WatchfaceDeviceParams params;
|
||||
|
||||
public HuaweiWatchfaceManager() {
|
||||
|
||||
}
|
||||
public void setParams(WatchfaceDeviceParams params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public short getWidth() {
|
||||
return params.width;
|
||||
}
|
||||
|
||||
public short getHeight() {
|
||||
return params.height;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -28,4 +28,13 @@ public class GetWatchfaceParams extends Request{
|
|||
throw new RequestCreationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processResponse() throws ResponseParseException {
|
||||
if (!(receivedPacket instanceof Watchface.WatchfaceParams.Response))
|
||||
throw new ResponseTypeMismatchException(receivedPacket, Watchface.WatchfaceParams.Response.class);
|
||||
|
||||
Watchface.WatchfaceParams.Response resp = (Watchface.WatchfaceParams.Response)(receivedPacket);
|
||||
supportProvider.getHuaweiCoordinator().getHuaweiWatchfaceManager().setParams(resp.params);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue