customized asset file handling

This commit is contained in:
Daniel Dakhno 2020-01-13 00:40:06 +01:00
parent 4a9bd67101
commit a4d4d6ed91
7 changed files with 94 additions and 42 deletions

View File

@ -241,6 +241,7 @@ public class QHybridSupport extends QHybridBaseSupport {
globalCommandReceiver = new BroadcastReceiver() { globalCommandReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if(watchAdapter == null) return;
//noinspection SwitchStatementWithTooFewBranches //noinspection SwitchStatementWithTooFewBranches
switch (intent.getAction()) { switch (intent.getAction()) {
case QHYBRID_ACTION_SET_ACTIVITY_HAND: { case QHYBRID_ACTION_SET_ACTIVITY_HAND: {

View File

@ -18,6 +18,7 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.BufferOverflowException; import java.nio.BufferOverflowException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Random; import java.util.Random;
@ -82,6 +83,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
int imageNameIndex = 0; int imageNameIndex = 0;
private byte jsonIndex = 0; private byte jsonIndex = 0;
private AssetImage backGroundImage = null;
public FossilHRWatchAdapter(QHybridSupport deviceSupport) { public FossilHRWatchAdapter(QHybridSupport deviceSupport) {
super(deviceSupport); super(deviceSupport);
} }
@ -103,18 +106,17 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
loadNotificationConfigurations(); loadNotificationConfigurations();
// queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations,this)); // queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations,this));
String[] appNames = {"instagram", "snapchat", "line", "whatsapp"}; /*try {
String[] paths = { final String[] appNames = {"instagram", "snapchat", "line", "whatsapp"};
final String[] paths = {
"/storage/emulated/0/Q/images/icInstagram.icon", "/storage/emulated/0/Q/images/icInstagram.icon",
"/storage/emulated/0/Q/images/icSnapchat.icon", "/storage/emulated/0/Q/images/icSnapchat.icon",
"/storage/emulated/0/Q/images/icLine.icon", "/storage/emulated/0/Q/images/icLine.icon",
"/storage/emulated/0/Q/images/icWhatsapp.icon" "/storage/emulated/0/Q/images/icWhatsapp.icon"
}; };
/*NotificationHRConfiguration[] configs = new NotificationHRConfiguration[4];
NotificationHRConfiguration[] configs = new NotificationHRConfiguration[4];
NotificationImage[] images = new NotificationImage[4]; NotificationImage[] images = new NotificationImage[4];
try {
for(int i = 0; i < 4; i++){ for(int i = 0; i < 4; i++){
FileInputStream fis = new FileInputStream(paths[i]); FileInputStream fis = new FileInputStream(paths[i]);
byte[] imageData = new byte[fis.available()]; byte[] imageData = new byte[fis.available()];
@ -125,9 +127,6 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
} }
queueWrite(new NotificationImagePutRequest(images, this)); queueWrite(new NotificationImagePutRequest(images, this));
queueWrite(new NotificationFilterPutHRRequest(configs, this)); queueWrite(new NotificationFilterPutHRRequest(configs, this));
} catch (Exception e) {
e.printStackTrace();
}
for(String appName : appNames){ for(String appName : appNames){
queueWrite(new PlayNotificationHRRequest( queueWrite(new PlayNotificationHRRequest(
@ -136,11 +135,12 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
"this is some strange message", "this is some strange message",
this this
)); ));
}
} catch (Exception e) {
e.printStackTrace();
}*/ }*/
// no effect setVibrationStrength((short) 75);
// negotiateSymmetricKey();
// queueWrite(new ConfigurationPutRequest(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.HeartRateMeasurementModeItem((byte) 2), this));
syncSettings(); syncSettings();
@ -155,12 +155,27 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED)); queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
} }
@Override
public void setVibrationStrength(short strength) {
negotiateSymmetricKey();
queueWrite(new ConfigurationPutRequest(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength), this));
}
private void loadNotificationConfigurations(){ private void loadNotificationConfigurations(){
this.notificationConfigurations = new NotificationHRConfiguration[]{ this.notificationConfigurations = new NotificationHRConfiguration[]{
new NotificationHRConfiguration("generic", 0), new NotificationHRConfiguration("generic", 0),
}; };
} }
private void loadBackground(){
Bitmap backgroundBitmap = BitmapFactory.decodeFile("");
try {
this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0, 0, 0);
} catch (IOException e) {
GB.log("Backgroundimage error", GB.ERROR, e);
}
}
private void loadWidgets() { private void loadWidgets() {
CustomWidget ethWidget = new CustomWidget(90, 63); CustomWidget ethWidget = new CustomWidget(90, 63);
// ethWidget.addElement(new CustomWidgetElement(CustomWidgetElement.WidgetElementType.TYPE_TEXT, "date", "-", CustomWidgetElement.X_CENTER, CustomWidgetElement.Y_UPPER_HALF)); // ethWidget.addElement(new CustomWidgetElement(CustomWidgetElement.WidgetElementType.TYPE_TEXT, "date", "-", CustomWidgetElement.X_CENTER, CustomWidgetElement.Y_UPPER_HALF));
@ -190,7 +205,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
private void renderWidgets() { private void renderWidgets() {
try { try {
AssetImage[] widgetImages = new AssetImage[this.widgets.length]; ArrayList<AssetImage> widgetImages = new ArrayList<>();
if(this.backGroundImage != null){
widgetImages.add(this.backGroundImage);
}
for (int i = 0; i < this.widgets.length; i++) { for (int i = 0; i < this.widgets.length; i++) {
CustomWidget widget = widgets[i]; CustomWidget widget = widgets[i];
@ -239,32 +258,27 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
paint); paint);
} }
} }
widgetImages[i] = AssetImageFactory.createAssetImage( widgetImages.add(AssetImageFactory.createAssetImage(
StringUtils.bytesToHex(
ByteBuffer.allocate(8)
.putLong(System.currentTimeMillis() + imageNameIndex++)
.array()
)
,
widgetBitmap, widgetBitmap,
true, true,
widget.getAngle(), widget.getAngle(),
widget.getDistance(), widget.getDistance(),
1 1
); ));
} }
AssetImage[] images = widgetImages.toArray(new AssetImage[0]);
// queueWrite(new FileDeleteRequest((short) 0x0700)); // queueWrite(new FileDeleteRequest((short) 0x0700));
queueWrite(new AssetFilePutRequest( queueWrite(new AssetFilePutRequest(
widgetImages, images,
(byte) 0x00, (byte) 0x00,
this this
)); ));
// queueWrite(new FileDeleteRequest((short) 0x0503)); // queueWrite(new FileDeleteRequest((short) 0x0503));
queueWrite(new ImagesSetRequest( queueWrite(new ImagesSetRequest(
widgetImages, images,
this this
)); ));
} catch (IOException e) { } catch (IOException e) {

View File

@ -1,14 +1,32 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file;
import java.nio.ByteBuffer;
import java.util.zip.CRC32;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.utils.StringUtils;
public class AssetFile { public class AssetFile {
private String fileName; private String fileName;
private byte[] fileData; private byte[] fileData;
public AssetFile(String fileName, byte[] fileData) { protected AssetFile(String fileName, byte[] fileData) {
this.fileName = fileName; this.fileName = fileName;
this.fileData = fileData; this.fileData = fileData;
} }
public AssetFile(byte[] fileData) {
CRC32 crc = new CRC32();
crc.update(fileData);
this.fileName = StringUtils.bytesToHex(
ByteBuffer.allocate(4)
.putInt((int) crc.getValue())
.array()
);
this.fileData = fileData;
}
public String getFileName() { public String getFileName() {
return fileName; return fileName;
} }

View File

@ -10,8 +10,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
public class AssetImage extends AssetFile { public class AssetImage extends AssetFile {
private int angle, distance, indexZ; private int angle, distance, indexZ;
protected AssetImage(String fileName, byte[] fileData, int angle, int distance, int indexZ) { protected AssetImage(byte[] fileData, int angle, int distance, int indexZ) {
super(fileName, fileData); super(fileData);
this.angle = angle; this.angle = angle;
this.distance = distance; this.distance = distance;
this.indexZ = indexZ; this.indexZ = indexZ;

View File

@ -9,11 +9,11 @@ import androidx.annotation.ColorInt;
import java.io.IOException; import java.io.IOException;
public class AssetImageFactory { public class AssetImageFactory {
public static AssetImage createAssetImage(String fileName, byte[] fileData, int angle, int distance, int indexZ){ public static AssetImage createAssetImage(byte[] fileData, int angle, int distance, int indexZ){
return new AssetImage(fileName, fileData, angle, distance, indexZ); return new AssetImage(fileData, angle, distance, indexZ);
} }
public static AssetImage createAssetImage(String fileName, Bitmap fileData, boolean RLEencode, int angle, int distance, int indexZ) throws IOException { public static AssetImage createAssetImage(Bitmap fileData, boolean RLEencode, int angle, int distance, int indexZ) throws IOException {
int height = fileData.getHeight(); int height = fileData.getHeight();
int width = fileData.getWidth(); int width = fileData.getWidth();
@ -33,7 +33,9 @@ public class AssetImageFactory {
} }
if(RLEencode){ if(RLEencode){
return new AssetImage(fileName, ImageConverter.encodeToRLEImage(pixelBytes, height, width), angle, distance, indexZ); return new AssetImage(ImageConverter.encodeToRLEImage(pixelBytes, height, width), angle, distance, indexZ);
}else{
} }
return null; return null;

View File

@ -1,5 +1,7 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image;
import android.graphics.Bitmap;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -23,4 +25,19 @@ public class ImageConverter {
return bos.toByteArray(); return bos.toByteArray();
} }
public static byte[] encodeToRawImage(byte[] monochromeImage, int height, int width){
int pixelCount = height * width;
byte[] result = new byte[pixelCount / 4]; // 4 pixels per byte e.g. 2 bits per pixel
for(int i = 0; i < pixelCount; i++){
int resultPixelIndex = i / 4;
int shiftIndex = i % 4 * 2;
result[resultPixelIndex] = (byte) ((monochromeImage[i] >> 6) << shiftIndex);
}
return result;
}
} }

View File

@ -8,7 +8,7 @@ public class NotificationImage extends AssetFile {
public NotificationImage(String packageName, byte[] imageData) { public NotificationImage(String packageName, byte[] imageData) {
//TODO this is defo not functional //TODO this is defo not functional
super("whatever", imageData); super(packageName, imageData);
this.packageName = packageName; this.packageName = packageName;
this.imageData = imageData; this.imageData = imageData;
} }