diff --git a/app/src/main/assets/devintro.png b/app/src/main/assets/devintro.png new file mode 100644 index 00000000..6fc1a593 Binary files /dev/null and b/app/src/main/assets/devintro.png differ diff --git a/app/src/main/assets/devintro.xmi b/app/src/main/assets/devintro.xmi new file mode 100644 index 00000000..97ec1375 --- /dev/null +++ b/app/src/main/assets/devintro.xmi @@ -0,0 +1,175 @@ + + + + + umbrello uml modeller http://umbrello.kde.org + 1.6.9 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java index 19d07b16..172f5285 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java @@ -31,6 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAppAdapter; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp; +import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; @@ -76,6 +77,7 @@ public class AppManagerActivity extends Activity { List systemApps = new ArrayList<>(); systemApps.add(new GBDeviceApp(UUID.fromString("4dab81a6-d2fc-458a-992c-7a1f3b96a970"), "Sports (System)", "Pebble Inc.", "", GBDeviceApp.Type.APP_SYSTEM)); systemApps.add(new GBDeviceApp(UUID.fromString("cf1e816a-9db0-4511-bbb8-f60c48ca8fac"), "Golf (System)", "Pebble Inc.", "", GBDeviceApp.Type.APP_SYSTEM)); + systemApps.add(new GBDeviceApp(PebbleProtocol.UUID_PEBBLE_HEALTH, "Health (System)", "Pebble Inc.", "", GBDeviceApp.Type.APP_SYSTEM)); return systemApps; } @@ -155,7 +157,7 @@ public class AppManagerActivity extends Activity { AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo; selectedApp = appList.get(acmi.position); - if (!selectedApp.isInCache()) { + if (!selectedApp.isInCache() && !PebbleProtocol.UUID_PEBBLE_HEALTH.equals(selectedApp.getUUID())) { menu.removeItem(R.id.appmanager_app_reinstall); } menu.setHeaderTitle(selectedApp.getName()); @@ -168,6 +170,11 @@ public class AppManagerActivity extends Activity { GBApplication.deviceService().onAppDelete(selectedApp.getUUID()); return true; case R.id.appmanager_app_reinstall: + if (PebbleProtocol.UUID_PEBBLE_HEALTH.equals(selectedApp.getUUID())) { + GBApplication.deviceService().onInstallApp(Uri.parse("fake://health")); + return true; + } + File cachePath; try { cachePath = new File(FileUtils.getExternalFilesDir().getPath() + "/pbw-cache/" + selectedApp.getUUID() + ".pbw"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java index 3d0597e0..49165df4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java @@ -570,6 +570,11 @@ public class PebbleIoThread extends GBDeviceIoThread { return; } + if (uri.equals(Uri.parse("fake://health"))) { + write(mPebbleProtocol.encodeActivateHealth(true)); + return; + } + String hwRev = gbDevice.getHardwareVersion(); String platformName; if (hwRev.startsWith("snowy")) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 05c9b86e..8b27479c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -81,7 +81,7 @@ public class PebbleProtocol extends GBDeviceProtocol { static final byte BLOBDB_APP = 2; static final byte BLOBDB_REMINDER = 3; static final byte BLOBDB_NOTIFICATION = 4; - + static final byte BLOBDB_HEALTH = 7; // might also be some generic registry database static final byte BLOBDB_SUCCESS = 1; static final byte BLOBDB_GENERALFAILURE = 2; static final byte BLOBDB_INVALIDOPERATION = 3; @@ -216,7 +216,6 @@ public class PebbleProtocol extends GBDeviceProtocol { static final short LENGTH_APPFETCH = 2; static final short LENGTH_APPRUNSTATE = 17; - static final short LENGTH_BLOBDB = 21; static final short LENGTH_PING = 5; static final short LENGTH_PHONEVERSION = 17; static final short LENGTH_REMOVEAPP_2X = 17; @@ -344,11 +343,11 @@ public class PebbleProtocol extends GBDeviceProtocol { byte last_id = -1; private final ArrayList tmpUUIDS = new ArrayList<>(); + public static final UUID UUID_PEBBLE_HEALTH = UUID.fromString("36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c"); // FIXME: store somewhere else, this is also accessed by other code private static final UUID UUID_GBPEBBLE = UUID.fromString("61476764-7465-7262-6469-656775527a6c"); private static final UUID UUID_MORPHEUZ = UUID.fromString("5be44f1d-d262-4ea6-aa30-ddbec1e3cab2"); private static final UUID UUID_WHETHERNEAT = UUID.fromString("3684003b-a685-45f9-a713-abc6364ba051"); private static final UUID UUID_MISFIT = UUID.fromString("0b73b76a-cd65-4dc2-9585-aaa213320858"); - private static final UUID UUID_PEBBLE_HEALTH = UUID.fromString("36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c"); private static final UUID UUID_PEBBLE_TIMESTYLE = UUID.fromString("4368ffa4-f0fb-4823-90be-f754b076bdaa"); private static final UUID UUID_PEBSTYLE = UUID.fromString("da05e84d-e2a2-4020-a2dc-9cdcf265fcdd"); private static final UUID UUID_MARIOTIME = UUID.fromString("43caa750-2896-4f46-94dc-1adbd4bc1ff3"); @@ -624,9 +623,25 @@ public class PebbleProtocol extends GBDeviceProtocol { return buf.array(); } - private byte[] encodeBlobdb(UUID uuid, byte command, byte db, byte[] blob) { + private byte[] encodeBlobdb(Object key, byte command, byte db, byte[] blob) { + + int length = 5; + + int key_length; + if (key instanceof UUID) { + key_length = LENGTH_UUID; + } else if (key instanceof String) { + key_length = ((String) key).getBytes().length; + } else { + LOG.warn("unknown key type"); + return null; + } + if (key_length > 255) { + LOG.warn("key is too long"); + return null; + } + length += key_length; - int length = LENGTH_BLOBDB; if (blob != null) { length += blob.length + 2; } @@ -641,11 +656,17 @@ public class PebbleProtocol extends GBDeviceProtocol { buf.put(command); buf.putShort((short) mRandom.nextInt()); // token buf.put(db); - buf.put(LENGTH_UUID); - buf.order(ByteOrder.BIG_ENDIAN); - buf.putLong(uuid.getMostSignificantBits()); - buf.putLong(uuid.getLeastSignificantBits()); - buf.order(ByteOrder.LITTLE_ENDIAN); + + buf.put((byte) key_length); + if (key instanceof UUID) { + UUID uuid = (UUID) key; + buf.order(ByteOrder.BIG_ENDIAN); + buf.putLong(uuid.getMostSignificantBits()); + buf.putLong(uuid.getLeastSignificantBits()); + buf.order(ByteOrder.LITTLE_ENDIAN); + } else { + buf.put(((String) key).getBytes()); + } if (blob != null) { buf.putShort((short) blob.length); @@ -655,6 +676,19 @@ public class PebbleProtocol extends GBDeviceProtocol { return buf.array(); } + public byte[] encodeActivateHealth(boolean activate) { + byte[] blob; + byte command; + if (activate) { + command = BLOBDB_INSERT; + blob = new byte[]{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02}; + } else { + command = BLOBDB_DELETE; + blob = null; + } + return encodeBlobdb("activityPreferences", command, BLOBDB_HEALTH, blob); + } + private byte[] encodeBlobDBClear(byte database) { final short LENGTH_BLOBDB_CLEAR = 4; ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_BLOBDB_CLEAR); @@ -1059,6 +1093,9 @@ public class PebbleProtocol extends GBDeviceProtocol { @Override public byte[] encodeAppDelete(UUID uuid) { if (isFw3x) { + if (UUID_PEBBLE_HEALTH.equals(uuid)) { + return encodeActivateHealth(false); + } return encodeBlobdb(uuid, BLOBDB_DELETE, BLOBDB_APP, null); } else { ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REMOVEAPP_2X);