Huawei: fileupload: Move watchface parsing to HuaweiFwHelper

* there was duplicated code in HuaweiUploadManager and HuaweiInstallHandler
* now HuaweiUploadManager does not contain watchface specific info, but
  only information related to general file uploading
* verify if file is could be uploaded befor showing InstallHandler
This commit is contained in:
Vitaliy Tomin 2024-04-10 16:48:13 +08:00
parent c64aeacded
commit 378ca31bc0
4 changed files with 127 additions and 75 deletions

View File

@ -1,17 +1,10 @@
package nodomain.freeyourgadget.gadgetbridge.devices.huawei;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
@ -19,49 +12,23 @@ 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.HuaweiFwHelper;
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;
public class HuaweiInstallHandler implements InstallHandler {
private static final Logger LOG = LoggerFactory.getLogger(HuaweiInstallHandler.class);
private final Context context;
Bitmap previewbMap;
String watchfaceDescription;
protected final HuaweiFwHelper helper;
boolean valid = false;
public HuaweiInstallHandler(Uri uri, Context context) {
this.context = context;
UriHelper uriHelper;
try {
uriHelper = UriHelper.get(uri, this.context);
GBZipFile watchfacePackage = new GBZipFile(uriHelper.openInputStream());
watchfaceDescription = new String(watchfacePackage.getFileFromZip("description.xml"));
final byte[] preview = watchfacePackage.getFileFromZip("preview/cover.jpg");
previewbMap = BitmapFactory.decodeByteArray(preview, 0, preview.length);
} catch (ZipFileException e) {
LOG.error("Unable to read watchface file.", e);
return;
} catch (FileNotFoundException e) {
LOG.error("The watchface file was not found.", e);
return;
} catch (IOException e) {
LOG.error("General IO error occurred.", e);
return;
} catch (Exception e) {
LOG.error("Unknown error occurred.", e);
return;
}
this.helper = new HuaweiFwHelper(uri, context);
}
@Override
public void validateInstallation(InstallActivity installActivity, GBDevice device) {
@ -74,7 +41,7 @@ public class HuaweiInstallHandler implements InstallHandler {
final HuaweiCoordinatorSupplier huaweiCoordinatorSupplier = (HuaweiCoordinatorSupplier) coordinator;
HuaweiWatchfaceManager.WatchfaceDescription description = new HuaweiWatchfaceManager.WatchfaceDescription(watchfaceDescription);
HuaweiWatchfaceManager.WatchfaceDescription description = helper.getWatchfaceDescription();
HuaweiWatchfaceManager.Resolution resolution = new HuaweiWatchfaceManager.Resolution();
String deviceScreen = String.format("%d*%d",huaweiCoordinatorSupplier.getHuaweiCoordinator().getHeight(),
@ -86,8 +53,8 @@ public class HuaweiInstallHandler implements InstallHandler {
GenericItem installItem = new GenericItem();
if (previewbMap != null) {
installItem.setPreview(previewbMap);
if (helper.getWatchfacePreviewBitmap() != null) {
installItem.setPreview(helper.getWatchfacePreviewBitmap());
}
installItem.setName(description.title);
@ -100,7 +67,7 @@ public class HuaweiInstallHandler implements InstallHandler {
return;
}
if ( !device.isConnected()) { //FIXME: Add all tested huawei devices?
if ( !device.isConnected()) {
LOG.error("Firmware cannot be installed (not connected or wrong device)");
installActivity.setInfoText("Firmware cannot be installed (not connected or wrong device)");
installActivity.setInstallEnabled(false);
@ -116,7 +83,7 @@ public class HuaweiInstallHandler implements InstallHandler {
}
//installItem.setDetails(getVersion());
//installItem.setDetails(description.version);
installItem.setIcon(R.drawable.ic_watchface);
installActivity.setInfoText(context.getString(R.string.watchface_install_info, installItem.getName(), description.version, description.author));
@ -127,10 +94,11 @@ public class HuaweiInstallHandler implements InstallHandler {
@Override
public boolean isValid() {
return true; //FIXME implement real check
return helper.isValid();
}
@Override
public void onStartInstall(GBDevice device) {
helper.unsetFwBytes();
}
}

View File

@ -0,0 +1,107 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.util.GBZipFile;
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException;
public class HuaweiFwHelper {
private static final Logger LOG = LoggerFactory.getLogger(HuaweiFwHelper.class);
private final Uri uri;
private byte[] fw;
private int fileSize = 0;
private boolean typeWatchface;
Bitmap watchfacePreviewBitmap;
HuaweiWatchfaceManager.WatchfaceDescription watchfaceDescription;
Context mContext;
public HuaweiFwHelper(final Uri uri, final Context context) {
this.uri = uri;
final UriHelper uriHelper;
this.mContext = context;
try {
uriHelper = UriHelper.get(uri, context);
} catch (final IOException e) {
LOG.error("Failed to get uri helper for {}", uri, e);
return;
}
parseFile();
}
private void parseFile() {
if (parseAsWatchFace()) {
assert watchfaceDescription.screen != null;
assert watchfaceDescription.title != null;
typeWatchface = true;
}
}
public byte[] getBytes() {
return fw;
}
public void unsetFwBytes() {
this.fw = null;
}
boolean parseAsWatchFace() {
try {
final UriHelper uriHelper = UriHelper.get(uri, this.mContext);
GBZipFile watchfacePackage = new GBZipFile(uriHelper.openInputStream());
String xmlDescription = new String(watchfacePackage.getFileFromZip("description.xml"));
watchfaceDescription = new HuaweiWatchfaceManager.WatchfaceDescription(xmlDescription);
final byte[] preview = watchfacePackage.getFileFromZip("preview/cover.jpg");
watchfacePreviewBitmap = BitmapFactory.decodeByteArray(preview, 0, preview.length);
fw = watchfacePackage.getFileFromZip("com.huawei.watchface");
fileSize = fw.length;
} catch (ZipFileException e) {
LOG.error("Unable to read watchface file.", e);
return false;
} catch (FileNotFoundException e) {
LOG.error("The watchface file was not found.", e);
return false;
} catch (IOException e) {
LOG.error("General IO error occurred.", e);
return false;
} catch (Exception e) {
LOG.error("Unknown error occurred.", e);
return false;
}
return true;
}
public boolean isWatchface() {
return typeWatchface;
}
public boolean isValid() {
return isWatchface();
}
public Bitmap getWatchfacePreviewBitmap() {
return watchfacePreviewBitmap;
}
public HuaweiWatchfaceManager.WatchfaceDescription getWatchfaceDescription() {
return watchfaceDescription;
}
}

View File

@ -87,8 +87,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetG
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;
@ -1843,7 +1841,8 @@ public class HuaweiSupportProvider {
public void onInstallApp(Uri uri) {
LOG.info("enter onAppInstall uri: "+uri);
huaweiUploadManager.setFileName(huaweiWatchfaceManager.getRandomName());
huaweiUploadManager.setWatchfaceUri(uri);
HuaweiFwHelper huaweiFwHelper = new HuaweiFwHelper(uri, getContext());
huaweiUploadManager.setBytes(huaweiFwHelper.getBytes());
try {
SendFileUploadInfo sendFileUploadInfo = new SendFileUploadInfo(this, huaweiUploadManager);

View File

@ -23,7 +23,7 @@ public class HuaweiUploadManager {
private final HuaweiSupportProvider support;
byte[] fileBin;
byte[] fileSHA256;
byte fileType = 1; // 1 - watchface, 2 - music
byte fileType = 1; // 1 - watchface, 2 - music, 3 - png for background , 7 - app
int fileSize = 0;
int currentUploadPosition = 0;
@ -39,32 +39,10 @@ public class HuaweiUploadManager {
this.support=support;
}
public void setWatchfaceUri(Uri uri) {
UriHelper uriHelper;
try {
uriHelper = UriHelper.get(uri, support.getContext());
GBZipFile watchfacePackage = new GBZipFile(uriHelper.openInputStream());
fileBin = watchfacePackage.getFileFromZip("com.huawei.watchface");
fileSize = fileBin.length;
} catch (ZipFileException e) {
LOG.error("Unable to read watchface file.", e);
return;
} catch (FileNotFoundException e) {
LOG.error("The watchface file was not found.", e);
return;
} catch (IOException e) {
LOG.error("General IO error occurred.", e);
return;
} catch (Exception e) {
LOG.error("Unknown error occurred.", e);
return;
}
public void setBytes(byte[] uploadArray) {
this.fileSize = uploadArray.length;
this.fileBin = uploadArray;
try {
MessageDigest m = MessageDigest.getInstance("SHA256");
@ -77,8 +55,8 @@ public class HuaweiUploadManager {
currentUploadPosition = 0;
uploadChunkSize = 0;
//TODO: generate random watchfaceName and watchfaceVersion
LOG.info("watchface loaded, SHA256: "+ GB.hexdump(fileSHA256) + " fileName: " + fileName);
LOG.info("File ready for upload, SHA256: "+ GB.hexdump(fileSHA256) + " fileName: " + fileName + " filetype: ", fileType);
}