diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 01a07bbc..b9b81ac5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -123,6 +123,7 @@ dependencies { implementation(projects.feature.results) implementation(projects.core.theme) + implementation(projects.core.util) baselineProfile(projects.benchmark) diff --git a/app/src/main/java/com/android/developers/androidify/MainActivity.kt b/app/src/main/java/com/android/developers/androidify/MainActivity.kt index 7b005cf5..ba8b467e 100644 --- a/app/src/main/java/com/android/developers/androidify/MainActivity.kt +++ b/app/src/main/java/com/android/developers/androidify/MainActivity.kt @@ -15,22 +15,31 @@ */ package com.android.developers.androidify +import android.os.Build import android.os.Bundle +import android.util.Log +import android.view.WindowManager +import android.window.TrustedPresentationThresholds import androidx.activity.ComponentActivity import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import com.android.developers.androidify.navigation.MainNavigation import com.android.developers.androidify.theme.AndroidifyTheme +import com.android.developers.androidify.util.LocalOcclusion import dagger.hilt.android.AndroidEntryPoint @ExperimentalMaterial3ExpressiveApi @AndroidEntryPoint class MainActivity : ComponentActivity() { + private val isWindowOccluded = mutableStateOf(false) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -46,8 +55,30 @@ class MainActivity : ComponentActivity() { Color.Transparent.toArgb(), ), ) - MainNavigation() + CompositionLocalProvider(LocalOcclusion provides isWindowOccluded) { + MainNavigation() + } } } } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + val minAlpha = 1f + val minFractionRendered = 0.25f + val stabilityRequirements = 500 + val presentationThreshold = TrustedPresentationThresholds( + minAlpha, minFractionRendered, stabilityRequirements + ) + + val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager + windowManager.registerTrustedPresentationListener( + window.decorView.windowToken, + presentationThreshold, + mainExecutor + ) { isMinFractionRendered -> isWindowOccluded.value = !isMinFractionRendered } + } + } + } diff --git a/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt b/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt index 7327d87d..208a415a 100644 --- a/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt +++ b/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt @@ -26,6 +26,7 @@ import androidx.compose.animation.scaleOut import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -42,7 +43,6 @@ import com.android.developers.androidify.creation.CreationScreen import com.android.developers.androidify.home.AboutScreen import com.android.developers.androidify.home.HomeScreen import com.android.developers.androidify.theme.transitions.ColorSplashTransitionScreen -import com.google.android.gms.oss.licenses.OssLicensesActivity import com.google.android.gms.oss.licenses.OssLicensesMenuActivity @ExperimentalMaterial3ExpressiveApi diff --git a/core/util/src/main/java/com/android/developers/androidify/util/LocalOcclusion.kt b/core/util/src/main/java/com/android/developers/androidify/util/LocalOcclusion.kt new file mode 100644 index 00000000..8b700cea --- /dev/null +++ b/core/util/src/main/java/com/android/developers/androidify/util/LocalOcclusion.kt @@ -0,0 +1,7 @@ +package com.android.developers.androidify.util + +import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.mutableStateOf + +val LocalOcclusion = compositionLocalOf { mutableStateOf(false) } + diff --git a/feature/home/src/androidTest/java/com/android/developers/androidify/home/HomeScreenTest.kt b/feature/home/src/androidTest/java/com/android/developers/androidify/home/HomeScreenTest.kt index 450f2581..43e6c7ba 100644 --- a/feature/home/src/androidTest/java/com/android/developers/androidify/home/HomeScreenTest.kt +++ b/feature/home/src/androidTest/java/com/android/developers/androidify/home/HomeScreenTest.kt @@ -54,7 +54,7 @@ class HomeScreenTest { }, onAboutClicked = {}, // Provide a default or mock value, videoLink = "", - dancingBotLink = "", + dancingBotLink = "" ) } } @@ -78,7 +78,7 @@ class HomeScreenTest { onClickLetsGo = { }, onAboutClicked = {}, videoLink = "", - dancingBotLink = "", + dancingBotLink = "" ) } } diff --git a/feature/home/src/main/java/com/android/developers/androidify/home/HomeScreen.kt b/feature/home/src/main/java/com/android/developers/androidify/home/HomeScreen.kt index 3de5c427..753504d0 100644 --- a/feature/home/src/main/java/com/android/developers/androidify/home/HomeScreen.kt +++ b/feature/home/src/main/java/com/android/developers/androidify/home/HomeScreen.kt @@ -109,6 +109,7 @@ import com.android.developers.androidify.theme.components.AndroidifyTopAppBar import com.android.developers.androidify.theme.components.AndroidifyTranslucentTopAppBar import com.android.developers.androidify.theme.components.SquiggleBackground import com.android.developers.androidify.util.LargeScreensPreview +import com.android.developers.androidify.util.LocalOcclusion import com.android.developers.androidify.util.PhonePreview import com.android.developers.androidify.util.isAtLeastMedium import com.android.developers.androidify.theme.R as ThemeR @@ -123,6 +124,7 @@ fun HomeScreen( onAboutClicked: () -> Unit = {}, ) { val state = homeScreenViewModel.state.collectAsStateWithLifecycle() + if (!state.value.isAppActive) { AppInactiveScreen() } else { @@ -537,6 +539,7 @@ private fun VideoPlayer( } var videoFullyOnScreen by remember { mutableStateOf(false) } + val isWindowOccluded = LocalOcclusion.current Box( Modifier .background(MaterialTheme.colorScheme.surfaceContainerLowest) @@ -547,8 +550,8 @@ private fun VideoPlayer( .then(modifier), ) { player?.let { currentPlayer -> - LaunchedEffect(videoFullyOnScreen) { - if (videoFullyOnScreen) currentPlayer.play() else currentPlayer.pause() + LaunchedEffect(videoFullyOnScreen, LocalOcclusion.current.value) { + if (videoFullyOnScreen && !isWindowOccluded.value) currentPlayer.play() else currentPlayer.pause() } // Render the video diff --git a/feature/home/src/screenshotTest/java/com/android/developers/androidify/home/HomeScreenScreenshotTest.kt b/feature/home/src/screenshotTest/java/com/android/developers/androidify/home/HomeScreenScreenshotTest.kt index 5cdf0e62..e6dfa8f7 100644 --- a/feature/home/src/screenshotTest/java/com/android/developers/androidify/home/HomeScreenScreenshotTest.kt +++ b/feature/home/src/screenshotTest/java/com/android/developers/androidify/home/HomeScreenScreenshotTest.kt @@ -35,7 +35,7 @@ class HomeScreenScreenshotTest { onClickLetsGo = { }, onAboutClicked = {}, videoLink = "", - dancingBotLink = "", + dancingBotLink = "" ) } }