Milan Jurkulak 3 mēneši atpakaļ
vecāks
revīzija
abdefff7f2

+ 74 - 0
.run/android.run.xml

@@ -0,0 +1,74 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="android" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
+    <module name="mjdev-desktop.composeApp" />
+    <option name="ANDROID_RUN_CONFIGURATION_SCHEMA_VERSION" value="1" />
+    <option name="DEPLOY" value="true" />
+    <option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
+    <option name="DEPLOY_AS_INSTANT" value="false" />
+    <option name="ARTIFACT_NAME" value="" />
+    <option name="PM_INSTALL_OPTIONS" value="" />
+    <option name="ALL_USERS" value="false" />
+    <option name="ALWAYS_INSTALL_WITH_PM" value="false" />
+    <option name="ALLOW_ASSUME_VERIFIED" value="false" />
+    <option name="CLEAR_APP_STORAGE" value="false" />
+    <option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
+    <option name="ACTIVITY_EXTRA_FLAGS" value="" />
+    <option name="MODE" value="default_activity" />
+    <option name="RESTORE_ENABLED" value="false" />
+    <option name="RESTORE_FILE" value="" />
+    <option name="RESTORE_FRESH_INSTALL_ONLY" value="false" />
+    <option name="CLEAR_LOGCAT" value="false" />
+    <option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
+    <option name="TARGET_SELECTION_MODE" value="DEVICE_AND_SNAPSHOT_COMBO_BOX" />
+    <option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
+    <option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
+    <option name="DEBUGGER_TYPE" value="Auto" />
+    <Auto>
+      <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+      <option name="SHOW_STATIC_VARS" value="true" />
+      <option name="WORKING_DIR" value="" />
+      <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      <option name="SHOW_OPTIMIZED_WARNING" value="true" />
+      <option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
+      <option name="DEBUG_SANDBOX_SDK" value="false" />
+    </Auto>
+    <Hybrid>
+      <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+      <option name="SHOW_STATIC_VARS" value="true" />
+      <option name="WORKING_DIR" value="" />
+      <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      <option name="SHOW_OPTIMIZED_WARNING" value="true" />
+      <option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
+      <option name="DEBUG_SANDBOX_SDK" value="false" />
+    </Hybrid>
+    <Java>
+      <option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
+      <option name="DEBUG_SANDBOX_SDK" value="false" />
+    </Java>
+    <Native>
+      <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+      <option name="SHOW_STATIC_VARS" value="true" />
+      <option name="WORKING_DIR" value="" />
+      <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      <option name="SHOW_OPTIMIZED_WARNING" value="true" />
+      <option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
+      <option name="DEBUG_SANDBOX_SDK" value="false" />
+    </Native>
+    <Profilers>
+      <option name="ADVANCED_PROFILING_ENABLED" value="false" />
+      <option name="STARTUP_PROFILING_ENABLED" value="false" />
+      <option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
+      <option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Java/Kotlin Method Sample (legacy)" />
+      <option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
+      <option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
+    </Profilers>
+    <option name="DEEP_LINK" value="" />
+    <option name="ACTIVITY" value="" />
+    <option name="ACTIVITY_CLASS" value="" />
+    <option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
+    <option name="SKIP_ACTIVITY_VALIDATION" value="false" />
+    <method v="2">
+      <option name="Android.Gradle.BeforeRunTask" enabled="true" />
+    </method>
+  </configuration>
+</component>

+ 31 - 0
.run/desktop.run.xml

@@ -0,0 +1,31 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="desktop" type="GradleRunConfiguration" factoryName="Gradle">
+    <ExternalSystemSettings>
+      <option name="executionName" />
+      <option name="externalProjectPath" value="$PROJECT_DIR$/composeApp" />
+      <option name="externalSystemIdString" value="GRADLE" />
+      <option name="scriptParameters" value="-DmainClass=org.mjdev.desktop.main.MainKt --quiet" />
+      <option name="taskDescriptions">
+        <list />
+      </option>
+      <option name="taskNames">
+        <list>
+          <option value="desktopRun" />
+        </list>
+      </option>
+      <option name="vmOptions" />
+    </ExternalSystemSettings>
+    <ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
+    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
+    <ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
+    <EXTENSION ID="com.android.tools.idea.testartifacts.testsuite.GradleRunConfigurationExtension">
+      <com.android.tools.idea.testartifacts.testsuite.SHOW_TEST_RESULT_IN_ANDROID_TEST_SUITE_VIEW>false</com.android.tools.idea.testartifacts.testsuite.SHOW_TEST_RESULT_IN_ANDROID_TEST_SUITE_VIEW>
+      <android.execution.deploysToLocalDevice>false</android.execution.deploysToLocalDevice>
+    </EXTENSION>
+    <DebugAllEnabled>false</DebugAllEnabled>
+    <RunAsTest>false</RunAsTest>
+    <GradleProfilingDisabled>false</GradleProfilingDisabled>
+    <GradleCoverageDisabled>false</GradleCoverageDisabled>
+    <method v="2" />
+  </configuration>
+</component>

+ 6 - 3
.run/mjdev-desktop [desktopRun].run.xml → .run/generateIcons.run.xml

@@ -1,5 +1,5 @@
 <component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="mjdev-desktop [desktopRun]" type="GradleRunConfiguration" factoryName="Gradle">
+  <configuration default="false" name="generateIcons" type="GradleRunConfiguration" factoryName="Gradle">
     <ExternalSystemSettings>
       <option name="executionName" />
       <option name="externalProjectPath" value="$PROJECT_DIR$" />
@@ -10,19 +10,22 @@
       </option>
       <option name="taskNames">
         <list>
-          <option value="desktopRun" />
+          <option value=":generateIcons" />
         </list>
       </option>
       <option name="vmOptions" />
     </ExternalSystemSettings>
-    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
+    <ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
     <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
+    <ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
     <EXTENSION ID="com.android.tools.idea.testartifacts.testsuite.GradleRunConfigurationExtension">
       <com.android.tools.idea.testartifacts.testsuite.SHOW_TEST_RESULT_IN_ANDROID_TEST_SUITE_VIEW>false</com.android.tools.idea.testartifacts.testsuite.SHOW_TEST_RESULT_IN_ANDROID_TEST_SUITE_VIEW>
       <android.execution.deploysToLocalDevice>false</android.execution.deploysToLocalDevice>
     </EXTENSION>
     <DebugAllEnabled>false</DebugAllEnabled>
     <RunAsTest>false</RunAsTest>
+    <GradleProfilingDisabled>false</GradleProfilingDisabled>
+    <GradleCoverageDisabled>false</GradleCoverageDisabled>
     <method v="2" />
   </configuration>
 </component>

+ 0 - 24
.run/mjdev-desktop [generateIcons].run.xml

@@ -1,24 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="mjdev-desktop [generateIcons]" type="GradleRunConfiguration" factoryName="Gradle">
-    <ExternalSystemSettings>
-      <option name="executionName" />
-      <option name="externalProjectPath" value="$PROJECT_DIR$" />
-      <option name="externalSystemIdString" value="GRADLE" />
-      <option name="scriptParameters" value="" />
-      <option name="taskDescriptions">
-        <list />
-      </option>
-      <option name="taskNames">
-        <list>
-          <option value=":generateIcons" />
-        </list>
-      </option>
-      <option name="vmOptions" />
-    </ExternalSystemSettings>
-    <ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
-    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
-    <DebugAllEnabled>false</DebugAllEnabled>
-    <RunAsTest>false</RunAsTest>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 24
.run/mjdev-desktop [jvm run].run.xml

@@ -1,24 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="mjdev-desktop [jvm run]" type="GradleRunConfiguration" factoryName="Gradle">
-    <ExternalSystemSettings>
-      <option name="executionName" />
-      <option name="externalProjectPath" value="$PROJECT_DIR$" />
-      <option name="externalSystemIdString" value="GRADLE" />
-      <option name="scriptParameters" value="" />
-      <option name="taskDescriptions">
-        <list />
-      </option>
-      <option name="taskNames">
-        <list>
-          <option value=":composeApp:run" />
-        </list>
-      </option>
-      <option name="vmOptions" />
-    </ExternalSystemSettings>
-    <ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
-    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
-    <DebugAllEnabled>false</DebugAllEnabled>
-    <RunAsTest>false</RunAsTest>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 24
.run/mjdev-desktop [plugin installPlugin].run.xml

@@ -1,24 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="mjdev-desktop [plugin installPlugin]" type="GradleRunConfiguration" factoryName="Gradle">
-    <ExternalSystemSettings>
-      <option name="executionName" />
-      <option name="externalProjectPath" value="/mnt/fe2c4809-fb9c-44f1-aa6e-48b0323031f1/backups/IdeaProjects/mjdev-desktop" />
-      <option name="externalSystemIdString" value="GRADLE" />
-      <option name="scriptParameters" value="" />
-      <option name="taskDescriptions">
-        <list />
-      </option>
-      <option name="taskNames">
-        <list>
-          <option value=":buildSrc:installPlugin" />
-        </list>
-      </option>
-      <option name="vmOptions" />
-    </ExternalSystemSettings>
-    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
-    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
-    <DebugAllEnabled>false</DebugAllEnabled>
-    <RunAsTest>false</RunAsTest>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 25
.run/mjdev-desktop [plugin run verifications].run.xml

@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="mjdev-desktop [plugin run verifications]" type="GradleRunConfiguration" factoryName="Gradle">
-    <log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
-    <ExternalSystemSettings>
-      <option name="executionName" />
-      <option name="externalProjectPath" value="$PROJECT_DIR$" />
-      <option name="externalSystemIdString" value="GRADLE" />
-      <option name="scriptParameters" value="" />
-      <option name="taskDescriptions">
-        <list />
-      </option>
-      <option name="taskNames">
-        <list>
-          <option value="verifyPlugin" />
-        </list>
-      </option>
-      <option name="vmOptions" value="" />
-    </ExternalSystemSettings>
-    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
-    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
-    <DebugAllEnabled>false</DebugAllEnabled>
-    <RunAsTest>false</RunAsTest>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 25
.run/mjdev-desktop [plugin run].run.xml

@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="mjdev-desktop [plugin run]" type="GradleRunConfiguration" factoryName="Gradle">
-    <log_file alias="IDE logs" path="$PROJECT_DIR$/build/idea-sandbox/*/log/idea.log" show_all="true" />
-    <ExternalSystemSettings>
-      <option name="executionName" />
-      <option name="externalProjectPath" value="$PROJECT_DIR$" />
-      <option name="externalSystemIdString" value="GRADLE" />
-      <option name="scriptParameters" value="" />
-      <option name="taskDescriptions">
-        <list />
-      </option>
-      <option name="taskNames">
-        <list>
-          <option value="runIde" />
-        </list>
-      </option>
-      <option name="vmOptions" value="" />
-    </ExternalSystemSettings>
-    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
-    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
-    <DebugAllEnabled>false</DebugAllEnabled>
-    <RunAsTest>false</RunAsTest>
-    <method v="2" />
-  </configuration>
-</component>

+ 66 - 66
buildSrc/src/main/kotlin/DeployTask.kt

@@ -1,71 +1,71 @@
 import org.gradle.api.DefaultTask
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.TaskAction
+//import org.gradle.api.tasks.Input
+//import org.gradle.api.tasks.TaskAction
 
 @Suppress("DEPRECATION")
 open class DeployTask : DefaultTask() {
-    @Input
-    var versionName: String = ""
-    @Input
-    var appName: String = ""
-    @Input
-    var nexusUrl: String = ""
-    @Input
-    var nexusUsername: String = ""
-    @Input
-    var nexusPassword: String = ""
-    @Input
-    var tagPrefix: String = ""
-        get() = field.lowercase()
-
-    private val buildType: String
-        get() = if (tagPrefix == "development") "debug" else "release"
-
-    @TaskAction
-    fun upload() {
-        val apkPath = project.layout
-            .projectDirectory
-            .file("build/outputs/apk/$buildType/$appName-$versionName-$buildType.apk")
-        val changelogPath = project.layout
-            .projectDirectory
-            .file("build/outputs/apk/$buildType/CHANGELOG-$appName-$versionName-$tagPrefix.md")
-        val apkFile = apkPath.asFile
-        val changelogFile = changelogPath.asFile
-        when {
-            !apkFile.exists() -> {
-                throw RuntimeException("APK file does not exist: ${apkFile.absolutePath}")
-            }
-            !changelogFile.exists() -> {
-                throw RuntimeException("Changelog file does not exist: ${changelogFile.absolutePath}")
-            }
-            nexusUrl.isBlank() || nexusUsername.isBlank() || nexusPassword.isBlank() -> {
-                throw RuntimeException("Nexus credentials are not set")
-            }
-            else -> {
-                val targetUrl = "$nexusUrl/kompakt-$appName/$versionName/$tagPrefix"
-                project.exec {
-                    commandLine(
-                        "curl",
-                        "-v",
-                        "-u",
-                        "$nexusUsername:$nexusPassword",
-                        "--upload-file",
-                        apkFile.absolutePath,
-                        "$targetUrl/${apkFile.name}"
-                    )
-                }
-                project.exec {
-                    commandLine(
-                        "curl",
-                        "-v",
-                        "-u",
-                        "$nexusUsername:$nexusPassword",
-                        "--upload-file",
-                        changelogFile.absolutePath,
-                        "$targetUrl/${changelogFile.name}"
-                    )
-                }
-            }
-        }
-    }
+//    @Input
+//    var versionName: String = ""
+//    @Input
+//    var appName: String = ""
+//    @Input
+//    var nexusUrl: String = ""
+//    @Input
+//    var nexusUsername: String = ""
+//    @Input
+//    var nexusPassword: String = ""
+//    @Input
+//    var tagPrefix: String = ""
+//        get() = field.lowercase()
+//
+//    private val buildType: String
+//        get() = if (tagPrefix == "development") "debug" else "release"
+//
+//    @TaskAction
+//    fun upload() {
+//        val apkPath = project.layout
+//            .projectDirectory
+//            .file("build/outputs/apk/$buildType/$appName-$versionName-$buildType.apk")
+//        val changelogPath = project.layout
+//            .projectDirectory
+//            .file("build/outputs/apk/$buildType/CHANGELOG-$appName-$versionName-$tagPrefix.md")
+//        val apkFile = apkPath.asFile
+//        val changelogFile = changelogPath.asFile
+//        when {
+//            !apkFile.exists() -> {
+//                throw RuntimeException("APK file does not exist: ${apkFile.absolutePath}")
+//            }
+//            !changelogFile.exists() -> {
+//                throw RuntimeException("Changelog file does not exist: ${changelogFile.absolutePath}")
+//            }
+//            nexusUrl.isBlank() || nexusUsername.isBlank() || nexusPassword.isBlank() -> {
+//                throw RuntimeException("Nexus credentials are not set")
+//            }
+//            else -> {
+//                val targetUrl = "$nexusUrl/kompakt-$appName/$versionName/$tagPrefix"
+//                project.exec {
+//                    commandLine(
+//                        "curl",
+//                        "-v",
+//                        "-u",
+//                        "$nexusUsername:$nexusPassword",
+//                        "--upload-file",
+//                        apkFile.absolutePath,
+//                        "$targetUrl/${apkFile.name}"
+//                    )
+//                }
+//                project.exec {
+//                    commandLine(
+//                        "curl",
+//                        "-v",
+//                        "-u",
+//                        "$nexusUsername:$nexusPassword",
+//                        "--upload-file",
+//                        changelogFile.absolutePath,
+//                        "$targetUrl/${changelogFile.name}"
+//                    )
+//                }
+//            }
+//        }
+//    }
 }

+ 3 - 0
composeApp/composeApp.gradle.kts

@@ -335,6 +335,7 @@ android {
     defaultConfig {
         applicationId = "org.mjdev.desktop"
         minSdk = libs.versions.android.min.sdk.get().toInt()
+        targetSdk = libs.versions.android.target.sdk.get().toInt()
         versionCode = libs.versions.app.pkg.version.get().replace(".", "").toInt()
         versionName = libs.versions.app.pkg.version.get()
         resValue("string", "app_name", libs.versions.app.name.get())
@@ -344,6 +345,8 @@ android {
             excludes += "META-INF/{AL2.0,LGPL2.1}"
             excludes += "META-INF/INDEX.LIST"
             excludes += "META-INF/DEPENDENCIES"
+            excludes += "META-INF/io.netty.versions.properties"
+            pickFirsts += "META-INF/native-image/**"
         }
     }
     buildTypes {

+ 18 - 6
composeApp/src/androidMain/kotlin/org/mjdev/desktop/activity/MainActivity.kt

@@ -12,12 +12,15 @@ import androidx.compose.foundation.layout.consumeWindowInsets
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.safeDrawing
+import androidx.compose.foundation.layout.systemBarsPadding
 import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.material3.Scaffold
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Color.Companion.Black
+import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
 import com.google.accompanist.permissions.ExperimentalPermissionsApi
@@ -46,18 +49,26 @@ class MainActivity : ComponentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         installSplashScreen()
         super.onCreate(savedInstanceState)
+        window.statusBarColor = Black.toArgb()
+        window.navigationBarColor = Black.toArgb()
+        window.decorView.setBackgroundColor(Black.toArgb())
         enableEdgeToEdge(
             statusBarStyle = SystemBarStyle.dark(TRANSPARENT),
             navigationBarStyle = SystemBarStyle.dark(TRANSPARENT)
         )
-        setBackgroundColor(Color.Black)
         setContent {
-            OnBackPress()
-            rememberPermissionManager()
             CompositionLocalProvider(
-                LocalDesktopContext provides rememberDesktopContext(this)
+                LocalDesktopContext provides rememberDesktopContext(this@MainActivity)
             ) {
-                ActivityMain()
+                Box(
+                    modifier = Modifier
+                        .fillMaxSize()
+                        .systemBarsPadding()
+                ) {
+                    OnBackPress()
+                    rememberPermissionManager()
+                    ActivityMain()
+                }
             }
         }
     }
@@ -89,7 +100,8 @@ class MainActivity : ComponentActivity() {
 private fun ActivityMain() {
     DesktopTheme {
         Scaffold(
-            modifier = Modifier.fillMaxSize()
+            modifier = Modifier
+                .fillMaxSize()
                 .background(Color.Black)
         ) { paddingValues ->
             Box(

+ 32 - 18
composeApp/src/commonMain/kotlin/org/mjdev/desktop/components/adb/AdbScreenMirror.kt

@@ -13,32 +13,29 @@ import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.input.pointer.pointerInput
 import dadb.Dadb
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.toComposeImageBitmap
+import com.sun.jna.Platform.isAndroid
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
-import org.jetbrains.skia.Image as SkiaImage
 import org.jetbrains.compose.ui.tooling.preview.Preview
+import org.mjdev.desktop.components.adb.DeviceState.Companion.rememberDeviceState
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
+import org.mjdev.desktop.extensions.decodeImage
 
 @Preview
 @Composable
 fun AdbScreenMirror(
     modifier: Modifier = Modifier,
     visibilityState: MutableState<Boolean> = mutableStateOf(false),
-    scope : CoroutineScope = rememberCoroutineScope()
+    scope : CoroutineScope = rememberCoroutineScope(),
+    refreshInterval : Long  = 100L,
+    deviceState : DeviceState = rememberDeviceState(
+        refreshInterval = refreshInterval,
+        scope = scope
+    )
 )  = withDesktopContext {
-    val refreshInterval = 100L
-    val deviceState = remember {
-        DeviceState(scope, visibilityState.value, refreshInterval)
-    }
-    DisposableEffect(visibilityState.value) {
-        deviceState.start()
-        onDispose {
-            deviceState.stop()
-        }
-    }
+    if(isAndroid()) return@withDesktopContext
     Box(
         modifier = modifier,
         contentAlignment = Alignment.Center
@@ -69,11 +66,16 @@ fun AdbScreenMirror(
             else -> Text("Waiting for device...")
         }
     }
+    DisposableEffect(visibilityState.value) {
+        deviceState.start()
+        onDispose {
+            deviceState.stop()
+        }
+    }
 }
 
 class DeviceState(
     private val scope:CoroutineScope,
-    private val visibility: Boolean,
     private val refreshInterval: Long,
 ) {
     var imageBitmap by mutableStateOf<ImageBitmap?>(null)
@@ -101,10 +103,12 @@ class DeviceState(
                         val bytes = stream.source.readByteArray()
                         stream.close()
                         if (bytes.isNotEmpty()) {
-                            val skiaImage = SkiaImage.makeFromEncoded(bytes)
-                            imageBitmap = skiaImage.toComposeImageBitmap()
-                            screenWidth = skiaImage.width
-                            screenHeight = skiaImage.height
+                            val decoded = bytes.decodeImage()
+                            if (decoded != null) {
+                                imageBitmap = decoded.bitmap
+                                screenWidth = decoded.width
+                                screenHeight = decoded.height
+                            }
                         }
                     } catch (e: Exception) {
                         error = e.message
@@ -143,4 +147,14 @@ class DeviceState(
             }
         }
     }
+
+    companion object {
+        @Composable
+        fun rememberDeviceState(
+            refreshInterval : Long  = 100L,
+            scope : CoroutineScope = rememberCoroutineScope()
+        ) = remember {
+            DeviceState(scope,  refreshInterval)
+        }
+    }
 }

+ 1 - 1
composeApp/src/commonMain/kotlin/org/mjdev/desktop/components/desktop/Desktop.kt

@@ -91,7 +91,7 @@ fun Desktop(
 //            )
                 AdbScreenMirror(
                     modifier = Modifier
-                        .align(Alignment.TopCenter)
+                        .align(Alignment.TopEnd)
                         .fillMaxHeight()
                         .wrapContentWidth()
                 )

+ 4 - 0
composeApp/src/commonMain/kotlin/org/mjdev/desktop/extensions/ImageBitmapExt.kt

@@ -5,6 +5,8 @@ import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.graphics.Paint
 import org.mjdev.desktop.context.IDesktopContext
+import org.mjdev.desktop.data.DecodedImage
+import org.mjdev.desktop.helpers.decodeImage
 
 @Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
 expect object ImageBitmapExt {
@@ -13,6 +15,8 @@ expect object ImageBitmapExt {
     ): ImageBitmap?
 }
 
+fun ByteArray.decodeImage(): DecodedImage? = decodeImage(this)
+
 var ImageBitmap.pixels: IntArray
     get() = IntArray(width * height).also { pixels -> readPixels(pixels) }
     set(value) = writePixels(value, 0, 0, width, height)

+ 9 - 2
gradle.properties

@@ -17,8 +17,6 @@ org.gradle.kotlin.dsl.caching.buildcache=true
 #kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
 # android options
 android.nonTransitiveRClass=true
-android.defaults.buildfeatures.aidl=false
-android.defaults.buildfeatures.renderscript=false
 android.defaults.buildfeatures.resvalues=true
 android.defaults.buildfeatures.shaders=false
 android.enableJetifier=false
@@ -42,4 +40,13 @@ platformType = AI
 platformVersion = 2025.1.1.7
 platformPlugins =
 platformBundledPlugins =
+android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
+android.enableAppCompileTimeRClass=false
+android.usesSdkInManifest.disallowed=false
+android.uniquePackageNames=false
+android.dependency.useConstraints=true
+android.r8.strictFullModeForKeepRules=false
+android.r8.optimizedResourceShrinking=false
+android.builtInKotlin=false
+android.newDsl=false
 ####################################################################################################

+ 13 - 0
gradle/gradle-daemon-jvm.properties

@@ -0,0 +1,13 @@
+#This file is generated by updateDaemonJvm
+toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect
+toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect
+toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect
+toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect
+toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7083b89563e7ce20943037b8cd2b8cc2/redirect
+toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/060bbb778a1f55ea705fdebd2ccfeab9/redirect
+toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect
+toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect
+toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/d09679dc60fe5aa05ef7d03efdefac20/redirect
+toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/ed4e3bf2f5e7c5d9aabc4cbd8acd555e/redirect
+toolchainVendor=JETBRAINS
+toolchainVersion=21

+ 3 - 3
gradle/libs.versions.toml

@@ -14,12 +14,12 @@ java-language-version = "17"
 # app specific android
 android-compile-sdk = "36"
 android-min-sdk = "26"
-#android-target-sdk = "36"
+android-target-sdk = "36"
 ### custom versions ################################################################################
 vlc-version = "3.0.21-2"
 vlc-dir = "composeApp/src/commonMain/resources/vlc/"
 ### lib versions ###################################################################################
-gradle = "8.13.0"
+gradle = "9.0.1"
 #gradle-kotlinter = "4.3.0"
 androidx-activity-compose = "1.10.1"
 androidx-lifecycle = "2.9.1"
@@ -35,7 +35,7 @@ human-readable = "1.12.0"
 #i18n4k-core = "0.9.0"
 ini4j = "0.5.4"
 jetlime = "3.0.1"
-kotlin = "2.2.0"
+kotlin = "2.2.10"
 kotlinx-coroutines = "1.10.2"
 kotlinx-date-time = "0.7.1"
 #logback = "1.5.7"

+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,7 +1,7 @@
 #Mon Jun 09 18:31:21 CEST 2025
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME

+ 3 - 0
settings.gradle.kts

@@ -39,6 +39,9 @@ pluginManagement {
         google()
     }
 }
+plugins {
+    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
+}
 //</editor-fold>------------------------------------------------------------------------------------
 
 //<editor-fold desc="dependency management">--------------------------------------------------------