Skip to content

Commit

Permalink
add app customization packets
Browse files Browse the repository at this point in the history
  • Loading branch information
matejdro committed Oct 30, 2021
1 parent 432b1f1 commit 98efc1f
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 3 deletions.
27 changes: 27 additions & 0 deletions src/androidMain/kotlin/util/Bitmap.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.rebble.libpebblecommon.util

/**
* Convert android bitmap into common multiplatform bitmap.
*
* Only supported for [android.graphics.Bitmap.Config.ARGB_8888] formats
*/
actual class Bitmap(private val androidBitmap: android.graphics.Bitmap) {
init {
if (androidBitmap.config != android.graphics.Bitmap.Config.ARGB_8888) {
throw IllegalArgumentException("Only ARGB_8888 bitmaps are supported")
}
}

actual val width: Int
get() = androidBitmap.width
actual val height: Int
get() = androidBitmap.height

/**
* Return pixel at the specified position at in AARRGGBB format.
*/
actual fun getPixel(x: Int, y: Int): Int {
return androidBitmap.getPixel(x, y)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package io.rebble.libpebblecommon.packets

import io.rebble.libpebblecommon.protocolhelpers.PebblePacket
import io.rebble.libpebblecommon.protocolhelpers.ProtocolEndpoint
import io.rebble.libpebblecommon.structmapper.SBytes
import io.rebble.libpebblecommon.structmapper.SFixedString
import io.rebble.libpebblecommon.structmapper.SUByte
import io.rebble.libpebblecommon.structmapper.SUShort
import io.rebble.libpebblecommon.util.Bitmap
import io.rebble.libpebblecommon.util.DataBuffer

class AppCustomizationSetStockAppTitleMessage(
appType: AppType,
newName: String
) : PebblePacket(ProtocolEndpoint.APP_CUSTOMIZE) {
val appType = SUByte(m, appType.value)
val name = SFixedString(m, 30, newName)
}

class AppCustomizationSetStockAppIconMessage(
appType: AppType,
icon: Bitmap
) : PebblePacket(ProtocolEndpoint.APP_CUSTOMIZE) {
// First bit being set signifies that this is icon packet instead of name packet
val appType = SUByte(m, appType.value or 0b10000000u)
val bytesPerLine = SUShort(m, endianness = '<')

/**
* No idea what flags are possible. Stock app always sends 4096 here.
*/
val flags = SUShort(m, 4096u, endianness = '<')

/**
* Offset is not supported by app. Always 0.
*/
val originY = SUShort(m, 0u, endianness = '<')
val originX = SUShort(m, 0u, endianness = '<')

val width = SUShort(m, endianness = '<')
val height = SUShort(m, endianness = '<')

val imageData = SBytes(m)

init {
val width = icon.width
val height = icon.height

this.width.set(width.toUShort())
this.height.set(height.toUShort())

val bytesPerLine = ((width + 31) / 32) * 4
val totalBytes = bytesPerLine * height

val dataBuffer = DataBuffer(totalBytes)

for (y in 0 until height) {
for (lineIntIndex in 0 until bytesPerLine / 4) {
var currentInt = 0
val startX = lineIntIndex * 32
val pixelsToTraverse = 32.coerceAtMost(width - startX)

for (innerX in 0 until pixelsToTraverse) {
val x = startX + innerX

val pixelValue = icon.getPixel(x, y)
val valueWithoutAlpha = pixelValue and 0x00FFFFFF

val pixelBit = if (valueWithoutAlpha > 0) {
1
} else {
0
}

currentInt = currentInt or (pixelBit shl innerX)
}

dataBuffer.putInt(currentInt)
}
}

val imageBytes = dataBuffer.array()
imageData.set(imageBytes, imageBytes.size)

this.bytesPerLine.set(bytesPerLine.toUShort())
}
}

enum class AppType(val value: UByte) {
SPORTS(0x00u),
GOLF(0x01u),
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package io.rebble.libpebblecommon.services

import io.rebble.libpebblecommon.PacketPriority
import io.rebble.libpebblecommon.ProtocolHandler
import io.rebble.libpebblecommon.getPlatform
import io.rebble.libpebblecommon.packets.*
import io.rebble.libpebblecommon.packets.PhoneAppVersion
import io.rebble.libpebblecommon.packets.SystemPacket
import io.rebble.libpebblecommon.packets.WatchFactoryData
import io.rebble.libpebblecommon.packets.WatchVersion
import io.rebble.libpebblecommon.protocolhelpers.PebblePacket
import io.rebble.libpebblecommon.protocolhelpers.ProtocolEndpoint
import io.rebble.libpebblecommon.structmapper.SInt
Expand Down Expand Up @@ -83,4 +85,4 @@ class SystemService(private val protocolHandler: ProtocolHandler) : ProtocolServ
}
}

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.rebble.libpebblecommon.services.appmessage

import io.rebble.libpebblecommon.ProtocolHandler
import io.rebble.libpebblecommon.packets.AppCustomizationSetStockAppIconMessage
import io.rebble.libpebblecommon.packets.AppCustomizationSetStockAppTitleMessage
import io.rebble.libpebblecommon.packets.AppMessage
import io.rebble.libpebblecommon.protocolhelpers.PebblePacket
import io.rebble.libpebblecommon.protocolhelpers.ProtocolEndpoint
Expand All @@ -21,6 +23,14 @@ class AppMessageService(private val protocolHandler: ProtocolHandler) : Protocol
protocolHandler.send(packet)
}

suspend fun send(packet: AppCustomizationSetStockAppIconMessage) {
protocolHandler.send(packet)
}

suspend fun send(packet: AppCustomizationSetStockAppTitleMessage) {
protocolHandler.send(packet)
}

fun receive(packet: PebblePacket) {
if (packet !is AppMessage) {
throw IllegalStateException("Received invalid packet type: $packet")
Expand Down
11 changes: 11 additions & 0 deletions src/commonMain/kotlin/io/rebble/libpebblecommon/util/Bitmap.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.rebble.libpebblecommon.util

expect class Bitmap {
val width: Int
val height: Int

/**
* Return pixel at the specified position at in AARRGGBB format.
*/
fun getPixel(x: Int, y: Int): Int
}
15 changes: 15 additions & 0 deletions src/iosMain/kotlin/io/rebble/libpebblecommon/util/Bitmap.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.rebble.libpebblecommon.util

actual class Bitmap {
actual val width: Int
get() = throw UnsupportedOperationException("Not supported on iOS yet")
actual val height: Int
get() = throw UnsupportedOperationException("Not supported on iOS yet")

/**
* Return pixel at the specified position at in AARRGGBB format.
*/
actual fun getPixel(x: Int, y: Int): Int {
throw UnsupportedOperationException("Not supported on iOS yet")
}
}
15 changes: 15 additions & 0 deletions src/jvmMain/kotlin/io/rebble/libpebblecommon/util/Bitmap.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.rebble.libpebblecommon.util

actual class Bitmap {
actual val width: Int
get() = throw UnsupportedOperationException("Not supported on generic JVM")
actual val height: Int
get() = throw UnsupportedOperationException("Not supported on generic JVM")

/**
* Return pixel at the specified position at in AARRGGBB format.
*/
actual fun getPixel(x: Int, y: Int): Int {
throw UnsupportedOperationException("Not supported on generic JVM")
}
}

0 comments on commit 98efc1f

Please sign in to comment.