From d2ede421c1250917ba68072b6ce6d229c836480b Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Fri, 3 Jan 2020 00:15:48 +0100 Subject: [PATCH] added custom wuidget code (WIP) --- .../fossil_hr/FossilHRWatchAdapter.java | 115 ++++++++---------- .../RLEEncoder.java} | 8 +- .../fossil_hr/image/AssetImageFactory.java | 38 +++++- .../fossil_hr/image/ImageConverter.java | 26 ++++ ...sPutRequest.java => ImagesSetRequest.java} | 4 +- 5 files changed, 122 insertions(+), 69 deletions(-) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/{requests/fossil_hr/image/ImageRLEEncoder.java => encoder/RLEEncoder.java} (92%) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/{ImagesPutRequest.java => ImagesSetRequest.java} (91%) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index abba0add3..73bea520d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -2,17 +2,23 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fos import android.bluetooth.BluetoothGattCharacteristic; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; import android.os.Build; +import android.util.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.ByteArrayOutputStream; import java.io.FileInputStream; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.Date; import java.util.GregorianCalendar; -import java.util.Random; import java.util.TimeZone; import java.util.zip.CRC32; @@ -24,6 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.encoder.RLEEncoder; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.*; @@ -35,8 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImageRLEEncoder; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImagesPutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImagesSetRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.menu.SetCommuteMenuMessage; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicInfoSetRequest; @@ -57,12 +63,6 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { @Override public void initialize() { - byte[] input = new byte[]{ - 0, 0, 0, 1, 0, 1, 2, 0, 4, 4, 0 - }; - - ImageRLEEncoder.RLEEncode(input); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { queueWrite(new RequestMtuRequest(512)); } @@ -84,66 +84,57 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { setTime(); - try { - FileInputStream fis = new FileInputStream("/sdcard/traditional_bg.bin"); - byte[] backgroundData = new byte[fis.available()]; - fis.read(backgroundData); - // new Random().nextBytes(backgroundData); - fis.close(); - - CRC32 crc = new CRC32(); - crc.update(backgroundData); - - String backgroundFileName = StringUtils.bytesToHex( - ByteBuffer - .allocate(4) - .putInt((int) crc.getValue()) - .array() - ); - - AssetImage bg = AssetImageFactory.createAssetImage(backgroundFileName, backgroundData, 0, 0, 0); - - queueWrite(new AssetFilePutRequest( - bg, - this - )); - queueWrite(new ImagesPutRequest( - new AssetImage[]{bg}, - this - )); - } catch (Exception e) { - e.printStackTrace(); - } - overwriteButtons(null); - /*try { - FileInputStream fis = new FileInputStream("/sdcard/traditional_bg.bin"); - byte[] backgroundData = new byte[fis.available()]; - fis.read(backgroundData); - fis.close(); + drawWidgetText("19.00"); + + queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED)); + } + + private void drawWidgetText(String text){ + + try { + Bitmap testBitmap = Bitmap.createBitmap(76, 76, Bitmap.Config.ARGB_8888); + + Canvas testCanvas = new Canvas(testBitmap); + + Paint circlePaint = new Paint(); + circlePaint.setColor(Color.WHITE); + circlePaint.setStyle(Paint.Style.STROKE); + circlePaint.setStrokeWidth(3); + + testCanvas.drawCircle(38, 38, 37, circlePaint); + + circlePaint.setStrokeWidth(4); + circlePaint.setTextSize(17f); + circlePaint.setStyle(Paint.Style.FILL); + + testCanvas.drawText(text, 16, 60, circlePaint); + + AssetImage image = AssetImageFactory.createAssetImage( + StringUtils.bytesToHex( + ByteBuffer.allocate(4) + .putInt((int) System.currentTimeMillis()) + .array() + ) + , testBitmap, true, 0, 60, 1); + + AssetImage[] images = new AssetImage[]{ + image, + }; queueWrite(new AssetFilePutRequest( - new byte[][]{ - new byte[]{(byte) 0x41, (byte) 0x41, (byte) 0x44, (byte) 0x33, (byte) 0x36, (byte) 0x35, (byte) 0x37, (byte) 0x37, (byte) 0x36, (byte) 0x00}, - // new byte[]{(byte) 0x30, (byte) 0x44, (byte) 0x35, (byte) 0x38, (byte) 0x42, (byte) 0x44, (byte) 0x32, (byte) 0x34, (byte) 0x00}, - // new byte[]{(byte) 0x43, (byte) 0x33, (byte) 0x46, (byte) 0x36, (byte) 0x39, (byte) 0x33, (byte) 0x36, (byte) 0x33, (byte) 0x00}, - // new byte[]{(byte) 0x37, (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x43, (byte) 0x38, (byte) 0x32, (byte) 0x42, (byte) 0x00}, - }, - new byte[][]{ - backgroundData - // new byte[]{(byte) 0x18, (byte) 0x18, (byte) 0x1D, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x14, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x0B, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x07, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x08, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0A, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0C, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0D, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x04, (byte) 0x03, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x04, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x07, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x05, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x05, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x1D, (byte) 0x00, (byte) 0xFF, (byte) 0xFF}, - // new byte[]{(byte) 0x18, (byte) 0x18, (byte) 0x1D, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x14, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x12, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x0E, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x0D, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x0D, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x0E, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x0F, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x11, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x04, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x07, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x0B, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x0D, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x05, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x1D, (byte) 0x00, (byte) 0xFF, (byte) 0xFF}, - // new byte[]{(byte) 0x18, (byte) 0x18, (byte) 0x1E, (byte) 0x00, (byte) 0x0C, (byte) 0x01, (byte) 0x09, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x0E, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x0E, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x0B, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x00, (byte) 0x0D, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x09, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x0F, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x11, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x12, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x14, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x16, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0xFF, (byte) 0xFF}, - // new byte[]{(byte) 0x18, (byte) 0x18, (byte) 0x3B, (byte) 0x0C, (byte) 0x02, (byte) 0x0D, (byte) 0x16, (byte) 0x0C, (byte) 0x02, (byte) 0x07, (byte) 0x16, (byte) 0x0C, (byte) 0x02, (byte) 0x03, (byte) 0x15, (byte) 0x0C, (byte) 0x01, (byte) 0x0A, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x0A, (byte) 0x14, (byte) 0x0C, (byte) 0x04, (byte) 0x03, (byte) 0x13, (byte) 0x0C, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x03, (byte) 0x02, (byte) 0x0A, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x09, (byte) 0x0F, (byte) 0x0C, (byte) 0x02, (byte) 0x0D, (byte) 0x01, (byte) 0x09, (byte) 0x02, (byte) 0x03, (byte) 0x02, (byte) 0x0C, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x09, (byte) 0x02, (byte) 0x0D, (byte) 0x08, (byte) 0x0C, (byte) 0x01, (byte) 0x0A, (byte) 0x07, (byte) 0x03, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x06, (byte) 0x07, (byte) 0x03, (byte) 0x01, (byte) 0x0A, (byte) 0x05, (byte) 0x0C, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x09, (byte) 0x01, (byte) 0x0D, (byte) 0x04, (byte) 0x0C, (byte) 0x01, (byte) 0x0D, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x0A, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x06, (byte) 0x07, (byte) 0x0C, (byte) 0x01, (byte) 0x0A, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x0D, (byte) 0x08, (byte) 0x0C, (byte) 0x01, (byte) 0x0D, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x0A, (byte) 0x09, (byte) 0x0C, (byte) 0x01, (byte) 0x09, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x09, (byte) 0x06, (byte) 0x0C, (byte) 0x01, (byte) 0x09, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x09, (byte) 0x0B, (byte) 0x0C, (byte) 0x01, (byte) 0x0D, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x0D, (byte) 0x05, (byte) 0x0C, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x0D, (byte) 0x0D, (byte) 0x0C, (byte) 0x01, (byte) 0x07, (byte) 0x01, (byte) 0x03, (byte) 0x06, (byte) 0x0C, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x0E, (byte) 0x0C, (byte) 0x02, (byte) 0x03, (byte) 0x02, (byte) 0x0C, (byte) 0x02, (byte) 0x09, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x07, (byte) 0x01, (byte) 0x03, (byte) 0x0D, (byte) 0x0C, (byte) 0x01, (byte) 0x0D, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x06, (byte) 0x01, (byte) 0x0D, (byte) 0x01, (byte) 0x07, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x01, (byte) 0x0D, (byte) 0x01, (byte) 0x06, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x0D, (byte) 0x0C, (byte) 0x0C, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x02, (byte) 0x03, (byte) 0x02, (byte) 0x06, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x09, (byte) 0x0C, (byte) 0x0C, (byte) 0x01, (byte) 0x06, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x0D, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x0D, (byte) 0x03, (byte) 0x03, (byte) 0x01, (byte) 0x06, (byte) 0x0C, (byte) 0x0C, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x0A, (byte) 0x06, (byte) 0x0C, (byte) 0x01, (byte) 0x0A, (byte) 0x02, (byte) 0x03, (byte) 0x0C, (byte) 0x0C, (byte) 0x01, (byte) 0x06, (byte) 0x0A, (byte) 0x0C, (byte) 0x01, (byte) 0x06, (byte) 0x4E, (byte) 0x0C, (byte) 0xFF, (byte) 0xFF}, - }, + images, + this + )); + + queueWrite(new ImagesSetRequest( + images, this )); } catch (IOException e) { e.printStackTrace(); - }*/ - - queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED)); + } } private void negotiateSymmetricKey() { @@ -198,7 +189,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } private void setBackgroundImages(AssetImage background, AssetImage[] complications) { - queueWrite(new ImagesPutRequest(new AssetImage[]{background}, this)); + queueWrite(new ImagesSetRequest(new AssetImage[]{background}, this)); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageRLEEncoder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/encoder/RLEEncoder.java similarity index 92% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageRLEEncoder.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/encoder/RLEEncoder.java index e867dde17..96efc49a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageRLEEncoder.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/encoder/RLEEncoder.java @@ -1,8 +1,8 @@ -package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.encoder; import java.io.ByteArrayOutputStream; -public class ImageRLEEncoder { +public class RLEEncoder { public static byte[] RLEEncode(byte[] data) { ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length * 2); @@ -14,8 +14,8 @@ public class ImageRLEEncoder { currentByte = data[i]; if (currentByte != lastByte || count >= 255) { - bos.write(data[i - 1]); bos.write(count); + bos.write(data[i - 1]); count = 1; lastByte = data[i]; @@ -24,8 +24,8 @@ public class ImageRLEEncoder { } } - bos.write(currentByte); bos.write(count); + bos.write(currentByte); byte[] result = bos.toByteArray(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java index d0117363e..acb890f1b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java @@ -1,13 +1,49 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.ColorSpace; + +import androidx.annotation.ColorInt; + +import java.io.IOException; public class AssetImageFactory { public static AssetImage createAssetImage(String fileName, byte[] fileData, int angle, int distance, int indexZ){ return new AssetImage(fileName, fileData, angle, distance, indexZ); } - public static AssetImage createAssetImage(String fileName, Bitmap fileData, boolean RLEencode, int angle, int distance, int indexZ){ + public static AssetImage createAssetImage(String fileName, Bitmap fileData, boolean RLEencode, int angle, int distance, int indexZ) throws IOException { + int height = fileData.getHeight(); + int width = fileData.getWidth(); + + // if(fileData.getConfig() != Bitmap.Config.ALPHA_8) throw new RuntimeException("Bitmap is not ALPHA_8"); + + int[] pixels = new int[height * width]; + + fileData.getPixels(pixels, 0, width, 0, 0, width, height); + + byte[] pixelBytes = new byte[width * height]; + + for(int i = 0; i < pixels.length; i++){ + int monochrome = convertToMonochrome(pixels[i]); + monochrome >>= 6; + + pixelBytes[i] = (byte) monochrome; + } + + if(RLEencode){ + return new AssetImage(fileName, ImageConverter.encodeToRLEImage(pixelBytes, height, width), angle, distance, indexZ); + } + return null; } + + private static @ColorInt int convertToMonochrome(@ColorInt int color){ + int sum = Color.red(color) + Color.green(color) + Color.blue(color); + + sum /= 3; + + return sum; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java new file mode 100644 index 000000000..1699bd45b --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java @@ -0,0 +1,26 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.encoder.RLEEncoder; + +public class ImageConverter { + public static void encodeToTwoBitImage(byte monochromeImage){ + + } + + public static byte[] encodeToRLEImage(byte[] monochromeImage, int height, int width) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(monochromeImage.length * 2); + + bos.write((byte) height); + bos.write((byte) width); + + bos.write(RLEEncoder.RLEEncode(monochromeImage)); + + bos.write((byte) 0x0FF); + bos.write((byte) 0x0FF); + + return bos.toByteArray(); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesSetRequest.java similarity index 91% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesPutRequest.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesSetRequest.java index 4e88db07d..e7abf0050 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesPutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesSetRequest.java @@ -7,8 +7,8 @@ import org.json.JSONObject; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest; -public class ImagesPutRequest extends JsonPutRequest { - public ImagesPutRequest(AssetImage[] images, FossilWatchAdapter adapter) { +public class ImagesSetRequest extends JsonPutRequest { + public ImagesSetRequest(AssetImage[] images, FossilWatchAdapter adapter) { super((short) 0x0503, prepareObject(images), adapter); }