Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,11 @@ actual fun createImageBitmapFromPixelArray(
Logger.w(e) { "Failed to create image bitmap" }
null
}
}

actual fun isScreenshotFinished(
buffer: DataBuffer,
expectedSize: Int
): Boolean {
return buffer.remaining == 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import io.rebble.libpebblecommon.packets.ScreenshotVersion
import io.rebble.libpebblecommon.protocolhelpers.PebblePacket.Companion.deserialize
import io.rebble.libpebblecommon.util.DataBuffer
import io.rebble.libpebblecommon.util.createImageBitmapFromPixelArray
import io.rebble.libpebblecommon.util.isScreenshotFinished
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down Expand Up @@ -46,6 +47,7 @@ class ScreenshotService(
var header: ParsedScreenshotHeader? = null
var data: DataBuffer? = null
var finished = false
var expectedSize = 0

/** Returns true if screenshot is incomplete */
fun handleBytes(bytes: UByteArray): Boolean {
Expand All @@ -54,7 +56,7 @@ class ScreenshotService(
throw IllegalStateException("buffer is null")
}
buffer.putBytes(bytes)
if (buffer.remaining == 0) {
if (isScreenshotFinished(buffer, expectedSize)) {
finished = true
}
return !finished
Expand All @@ -79,6 +81,7 @@ class ScreenshotService(
}
logger.v { "header: $header" }
val bufferSize = (parsedHeader.height * parsedHeader.width) / parsedHeader.version.bitsPerPixel
expectedSize = bufferSize
data = DataBuffer(bufferSize)
handleBytes(headerPacket.data.get())
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ expect fun createImageBitmapFromPixelArray(
pixels: IntArray,
width: Int,
height: Int
): ImageBitmap?
): ImageBitmap?

expect fun isScreenshotFinished(
buffer: DataBuffer,
expectedSize: Int
): Boolean
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
package io.rebble.libpebblecommon.util

import kotlinx.cinterop.addressOf
import kotlinx.cinterop.allocArrayOf
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.usePinned
import org.jetbrains.skia.Bitmap
import org.jetbrains.skia.ColorAlphaType
import org.jetbrains.skia.ImageInfo
import org.jetbrains.skia.ColorType
import androidx.compose.ui.graphics.asComposeImageBitmap
import androidx.compose.ui.graphics.ImageBitmap
import co.touchlab.kermit.Logger

actual fun createImageBitmapFromPixelArray(
pixels: IntArray,
width: Int,
height: Int
): ImageBitmap? {
return null
return try {
val bitmap = Bitmap()
val imageInfo = ImageInfo(width, height, ColorType.BGRA_8888, ColorAlphaType.PREMUL)

val bytes = ByteArray(pixels.size * 4)
for (i in pixels.indices) {
val p = pixels[i]
bytes[i * 4] = (p and 0xFF).toByte()
bytes[i * 4 + 1] = ((p shr 8) and 0xFF).toByte()
bytes[i * 4 + 2] = ((p shr 16) and 0xFF).toByte()
bytes[i * 4 + 3] = ((p shr 24) and 0xFF).toByte()
}

bitmap.installPixels(imageInfo, bytes, width * 4)
bitmap.asComposeImageBitmap()
} catch (e: Exception) {
Logger.w(e) { "Failed to create image bitmap" }
null
}
}

actual fun isScreenshotFinished(
buffer: DataBuffer,
expectedSize: Int
): Boolean {
return buffer.length >= expectedSize
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ import coredevices.pebble.services.displayName
import coredevices.ui.PebbleElevatedButton
import coredevices.util.CoreConfigFlow
import coredevices.util.Platform
import coredevices.util.isIOS
import io.rebble.libpebblecommon.connection.BleDiscoveredPebbleDevice
import io.rebble.libpebblecommon.connection.ConnectedPebble
import io.rebble.libpebblecommon.connection.ConnectedPebbleDevice
Expand Down Expand Up @@ -483,9 +482,6 @@ private fun Screenshot(watch: PebbleDevice, scope: CoroutineScope) {
return
}
val platform = koinInject<Platform>()
if (platform.isIOS) {
return
}
if (watch !is ConnectedPebbleDevice) {
return
}
Expand Down
Loading