diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt index cccbfc6..e605cd9 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt @@ -2,7 +2,6 @@ package io.github.miuzarte.scrcpyforandroid.pages import android.app.Activity import android.content.Intent -import android.content.pm.ActivityInfo import android.net.Uri import android.os.SystemClock import android.provider.OpenableColumns @@ -51,9 +50,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberDecoratedNavEntries @@ -299,7 +295,6 @@ fun MainScreen() { } } - val currentSession by scrcpy.currentSessionState.collectAsState() val deviceConnectionServices = remember(scrcpy) { val adbCoordinator = DeviceAdbConnectionCoordinator() val connectionStateStore = ConnectionStateStore() @@ -678,45 +673,11 @@ fun MainScreen() { } entry(RootScreen.FullscreenControl) { - val lifecycleOwner = LocalLifecycleOwner.current - LaunchedEffect(currentSession) { - if (currentSession == null) rootNavigator.pop() - } - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_STOP) { - rootNavigator.pop() - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - } - } - DisposableEffect(activity) { - onDispose { - activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - } - } - FullscreenControlScreen( + FullscreenControlRoute( scrcpy = scrcpy, onBack = rootNavigator.pop, isInPip = false, - onVideoSizeChanged = { width, height -> - activity?.requestedOrientation = - if (width >= height) { - if (asBundle.fullscreenControlIgnoreSystemRotationLock) - ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE - else - ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE - } else { - if (asBundle.fullscreenControlIgnoreSystemRotationLock) - ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT - else - ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT - } - }, - onVideoBoundsInWindowChanged = {}, + autoExitOnStop = true, ) } diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt index 57ac175..bca6d28 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt @@ -3,6 +3,7 @@ package io.github.miuzarte.scrcpyforandroid.pages import android.content.pm.ActivityInfo import android.graphics.Rect import android.util.Rational +import androidx.activity.compose.LocalActivity import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect @@ -13,7 +14,11 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LocalLifecycleOwner import io.github.miuzarte.scrcpyforandroid.StreamActivity +import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy import io.github.miuzarte.scrcpyforandroid.services.AppRuntime import io.github.miuzarte.scrcpyforandroid.services.LocalSnackbarController import io.github.miuzarte.scrcpyforandroid.services.SnackbarController @@ -31,29 +36,17 @@ fun StreamScreen(activity: StreamActivity) { val isInPip by activity.pipModeState.collectAsState() - val currentSession by scrcpy.currentSessionState.collectAsState() - var pipSourceRectHint by remember { mutableStateOf(null) } var lastPipAspectRatio by remember { mutableStateOf(null) } var lastPipOrientationLandscape by remember { mutableStateOf(null) } - LaunchedEffect(currentSession) { - if (currentSession == null) { - activity.finish() - } - } - DisposableEffect(isInPip) { onDispose { VideoOutputTargetState.set(VideoOutputTarget.PREVIEW) } } - DisposableEffect(activity) { - onDispose { - activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - } - } + val currentSession by scrcpy.currentSessionState.collectAsState() LaunchedEffect( activity, isInPip, @@ -109,26 +102,10 @@ fun StreamScreen(activity: StreamActivity) { CompositionLocalProvider( LocalSnackbarController provides snackbarController, ) { - FullscreenControlScreen( + FullscreenControlRoute( scrcpy = scrcpy, onBack = activity::finish, isInPip = isInPip, - onVideoSizeChanged = { width, height -> - if (!isInPip) { - activity.requestedOrientation = - if (width >= height) { - if (asBundle.fullscreenControlIgnoreSystemRotationLock) - ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE - else - ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE - } else { - if (asBundle.fullscreenControlIgnoreSystemRotationLock) - ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT - else - ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT - } - } - }, onVideoBoundsInWindowChanged = { // 记录下一次进入 PiP 时可用的 sourceRectHint pipSourceRectHint = it @@ -137,3 +114,78 @@ fun StreamScreen(activity: StreamActivity) { } } } + +@Composable +fun FullscreenControlRoute( + scrcpy: Scrcpy, + onBack: () -> Unit, + isInPip: Boolean = false, + autoExitOnStop: Boolean = false, + onVideoBoundsInWindowChanged: (Rect?) -> Unit = {}, +) { + val activity = LocalActivity.current + val lifecycleOwner = LocalLifecycleOwner.current + val asBundle by Storage.appSettings.bundleState.collectAsState() + val currentSession by scrcpy.currentSessionState.collectAsState() + + LaunchedEffect(currentSession) { + if (currentSession == null) { + onBack() + } + } + + DisposableEffect(activity) { + onDispose { + activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + } + } + + DisposableEffect(lifecycleOwner, autoExitOnStop) { + if (!autoExitOnStop) { + onDispose {} + } else { + val observer = LifecycleEventObserver { _, event -> + if (event == Lifecycle.Event.ON_STOP) { + onBack() + } + } + lifecycleOwner.lifecycle.addObserver(observer) + onDispose { + lifecycleOwner.lifecycle.removeObserver(observer) + } + } + } + + FullscreenControlScreen( + scrcpy = scrcpy, + onBack = onBack, + isInPip = isInPip, + onVideoSizeChanged = { width, height -> + if (!isInPip) { + activity?.requestedOrientation = + fullscreenRequestedOrientation( + width = width, + height = height, + ignoreSystemRotationLock = asBundle.fullscreenControlIgnoreSystemRotationLock, + ) + } + }, + onVideoBoundsInWindowChanged = onVideoBoundsInWindowChanged, + ) +} + +private fun fullscreenRequestedOrientation( + width: Int, + height: Int, + ignoreSystemRotationLock: Boolean, +) = if (width >= height) { + if (ignoreSystemRotationLock) + ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE + else + ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE +} else { + if (ignoreSystemRotationLock) + ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT + else + ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT +}