feat: power manager wake locks

This commit is contained in:
Miuzarte
2026-04-11 20:19:47 +08:00
parent 69e1976e5b
commit 2639da4b2c
5 changed files with 52 additions and 26 deletions

View File

@@ -34,6 +34,9 @@
},
{
"path": "../socialite"
},
{
"path": "../termux-app"
}
],
}

View File

@@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<application

View File

@@ -8,6 +8,7 @@ import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresApi
import io.github.miuzarte.scrcpyforandroid.pages.MainScreen
import io.github.miuzarte.scrcpyforandroid.services.AppRuntime
import io.github.miuzarte.scrcpyforandroid.services.AppWakeLocks
import io.github.miuzarte.scrcpyforandroid.storage.PreferenceMigration
import io.github.miuzarte.scrcpyforandroid.storage.Storage
import kotlinx.coroutines.runBlocking
@@ -17,9 +18,9 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// initialize settings singleton
Storage.init(applicationContext)
AppRuntime.init(applicationContext)
AppWakeLocks.init(applicationContext)
val migration = PreferenceMigration(applicationContext)
runBlocking {

View File

@@ -1,9 +1,7 @@
package io.github.miuzarte.scrcpyforandroid.pages
import android.annotation.SuppressLint
import android.app.Activity
import android.util.Log
import android.view.WindowManager
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
@@ -38,6 +36,7 @@ import io.github.miuzarte.scrcpyforandroid.models.DeviceShortcuts
import io.github.miuzarte.scrcpyforandroid.nativecore.NativeAdbService
import io.github.miuzarte.scrcpyforandroid.scaffolds.LazyColumn
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
import io.github.miuzarte.scrcpyforandroid.services.AppWakeLocks
import io.github.miuzarte.scrcpyforandroid.services.EventLogger
import io.github.miuzarte.scrcpyforandroid.services.EventLogger.logEvent
import io.github.miuzarte.scrcpyforandroid.services.LocalSnackbarController
@@ -150,9 +149,9 @@ fun DeviceTabPage(
scrcpy: Scrcpy,
) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val taskScope = remember { CoroutineScope(Dispatchers.IO + SupervisorJob()) }
val activity = remember(context) { context as? Activity }
val haptics = LocalAppHaptics.current
val navigator = LocalRootNavigator.current
@@ -207,20 +206,9 @@ fun DeviceTabPage(
// read only
val soBundleShared by scrcpyOptions.bundleState.collectAsState()
fun setKeepScreenOn(enabled: Boolean) {
val window = activity?.window ?: return
window.decorView.post {
if (enabled) {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
}
DisposableEffect(activity) {
DisposableEffect(Unit) {
onDispose {
setKeepScreenOn(false)
AppWakeLocks.release()
}
}
@@ -306,8 +294,8 @@ fun DeviceTabPage(
) {
// Also stops scrcpy.
runCatching { scrcpy.stop() }
setKeepScreenOn(false)
runCatching { NativeAdbService.disconnect() }
AppWakeLocks.release()
adbConnected = false
currentTargetHost = ""
currentTargetPort = Defaults.ADB_PORT
@@ -533,14 +521,12 @@ fun DeviceTabPage(
val options = scrcpyOptions.toClientOptions(soBundleShared).fix()
val session = scrcpy.start(options)
pendingScrollToPreview = true
if (openFullscreen) {
withContext(Dispatchers.Main) {
context.startActivity(StreamActivity.createIntent(context))
}
}
if (options.disableScreensaver) {
setKeepScreenOn(true)
if (openFullscreen) withContext(Dispatchers.Main) {
context.startActivity(StreamActivity.createIntent(context))
}
if (options.disableScreensaver)
AppWakeLocks.acquire()
statusLine = "scrcpy 运行中"
@SuppressLint("DefaultLocale")
val videoDetail =
@@ -934,7 +920,7 @@ fun DeviceTabPage(
onStop = {
runBusy("停止 scrcpy") {
scrcpy.stop()
setKeepScreenOn(false)
AppWakeLocks.release()
statusLine = "${currentTarget!!.host}:${currentTarget.port}"
logEvent("scrcpy 已停止")
snackbar.show("scrcpy 已停止")

View File

@@ -0,0 +1,35 @@
package io.github.miuzarte.scrcpyforandroid.services
import android.annotation.SuppressLint
import android.content.Context
import android.os.PowerManager
object AppWakeLocks {
private lateinit var appContext: Context
private lateinit var powerManager: PowerManager
fun init(context: Context) {
appContext = context.applicationContext
powerManager = appContext.getSystemService(Context.POWER_SERVICE) as PowerManager
}
private var wakeLock: PowerManager.WakeLock? = null
@SuppressLint("WakelockTimeout")
fun acquire() {
if (wakeLock != null) return
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"${appContext.packageName}:scrcpy-wakelock",
).apply {
setReferenceCounted(false)
acquire()
}
}
fun release() {
wakeLock?.runCatching { release() }
wakeLock = null
}
}