Merge "[Media] Demo app changes." into main
diff --git a/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/Dependencies.kt b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/Dependencies.kt
new file mode 100644
index 0000000..bb8f00b
--- /dev/null
+++ b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/Dependencies.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.demo
+
+import androidx.compose.runtime.Composable
+
+data class Dependencies(
+ /** A [Composable] that can render the media player/controls UI element. */
+ val mediaPlayer:
+ (@Composable
+ (
+ presentationStyle: DemoMediaPresentationStyle, onVisibilityChange: (Boolean) -> Unit,
+ ) -> Unit)? =
+ null
+)
diff --git a/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/LocalDependencies.kt b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/LocalDependencies.kt
new file mode 100644
index 0000000..414c739
--- /dev/null
+++ b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/LocalDependencies.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.demo
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.compositionLocalOf
+
+val LocalDependencies = compositionLocalOf { Dependencies() }
+
+@Composable
+fun WithLocalDependencies(dependencies: Dependencies, content: @Composable () -> Unit) {
+ CompositionLocalProvider(LocalDependencies provides dependencies, content)
+}
diff --git a/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/MediaPlayer.kt b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/MediaPlayer.kt
index e2e6595..3f167b3 100644
--- a/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/MediaPlayer.kt
+++ b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/MediaPlayer.kt
@@ -119,46 +119,74 @@
@Composable
fun ContentScope.MediaPlayer(
- isSmall: Boolean,
+ presentationStyle: DemoMediaPresentationStyle,
isPlaying: Boolean,
onIsPlayingChange: (Boolean) -> Unit,
+ onVisibilityChange: (Boolean) -> Unit,
modifier: Modifier = Modifier,
) {
- val key =
- if (isSmall) MediaPlayer.Elements.SmallMediaPlayer else MediaPlayer.Elements.MediaPlayer
- MovableElement(
- key,
- modifier
- .fillMaxWidth()
- .height(
- if (isSmall) MediaPlayer.Dimensions.HeightSmall
- else MediaPlayer.Dimensions.HeightLarge
- ),
- ) {
- content {
- Box(
- Modifier.background(
- MaterialTheme.colorScheme.tertiary,
- MediaPlayer.Shapes.Background,
- )
- .padding(8.dp)
- ) {
- FilledIconButton(
- onClick = { onIsPlayingChange(!isPlaying) },
- Modifier.align(Alignment.CenterEnd),
- colors =
- IconButtonDefaults.filledIconButtonColors(
- MaterialTheme.colorScheme.onTertiary
- ),
+ val injectedContentOrNull = LocalDependencies.current.mediaPlayer
+ if (injectedContentOrNull != null) {
+ Element(
+ key =
+ if (presentationStyle != DemoMediaPresentationStyle.Compact) {
+ MediaPlayer.Elements.MediaPlayer
+ } else {
+ MediaPlayer.Elements.SmallMediaPlayer
+ },
+ modifier = modifier.fillMaxWidth(),
+ ) {
+ injectedContentOrNull(presentationStyle, onVisibilityChange)
+ }
+ } else {
+ val isSmall = presentationStyle == DemoMediaPresentationStyle.Compact
+ val key =
+ if (isSmall) {
+ MediaPlayer.Elements.SmallMediaPlayer
+ } else {
+ MediaPlayer.Elements.MediaPlayer
+ }
+
+ MovableElement(
+ key,
+ modifier
+ .fillMaxWidth()
+ .height(
+ if (isSmall) MediaPlayer.Dimensions.HeightSmall
+ else MediaPlayer.Dimensions.HeightLarge
+ ),
+ ) {
+ content {
+ Box(
+ Modifier.background(
+ MaterialTheme.colorScheme.tertiary,
+ MediaPlayer.Shapes.Background,
+ )
+ .padding(8.dp)
) {
- val color = MaterialTheme.colorScheme.tertiary
- if (isPlaying) {
- Icon(Icons.Default.Pause, null, tint = color)
- } else {
- Icon(Icons.Default.PlayArrow, null, tint = color)
+ FilledIconButton(
+ onClick = { onIsPlayingChange(!isPlaying) },
+ Modifier.align(Alignment.CenterEnd),
+ colors =
+ IconButtonDefaults.filledIconButtonColors(
+ MaterialTheme.colorScheme.onTertiary
+ ),
+ ) {
+ val color = MaterialTheme.colorScheme.tertiary
+ if (isPlaying) {
+ Icon(Icons.Default.Pause, null, tint = color)
+ } else {
+ Icon(Icons.Default.PlayArrow, null, tint = color)
+ }
}
}
}
}
}
}
+
+enum class DemoMediaPresentationStyle {
+ Default,
+ Compressed,
+ Compact,
+}
diff --git a/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/SystemUi.kt b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/SystemUi.kt
index 6cf875c..740a66d 100644
--- a/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/SystemUi.kt
+++ b/samples/SceneTransitionLayoutDemo/src/com/android/compose/animation/scene/demo/SystemUi.kt
@@ -481,22 +481,29 @@
LocalOverscrollFactory provides rememberOffsetOverscrollEffectFactory(),
) {
var isMediaPlayerPlaying by remember { mutableStateOf(false) }
- val mediaPlayer: (@Composable ContentScope.(isSmall: Boolean) -> Unit)? =
+ val mediaPlayer:
+ (@Composable
+ ContentScope.(presentationStyle: DemoMediaPresentationStyle) -> Unit)? =
if (configuration.showMediaPlayer) {
- { isSmall ->
+ { presentationStyle ->
MediaPlayer(
- isSmall = isSmall,
+ presentationStyle = presentationStyle,
isPlaying = isMediaPlayerPlaying,
onIsPlayingChange = { isMediaPlayerPlaying = it },
+ onVisibilityChange = { isVisible ->
+ onConfigurationChange(
+ configuration.copy(showMediaPlayer = isVisible)
+ )
+ },
)
}
} else {
null
}
- val largeMediaPlayer: (@Composable ContentScope.() -> Unit)? =
- mediaPlayer?.let { { it(/* isSmall= */ false) } }
- val smallMediaPlayer: (@Composable ContentScope.() -> Unit)? =
- mediaPlayer?.let { { it(/* isSmall= */ true) } }
+ val defaultMediaPlayer: (@Composable ContentScope.() -> Unit)? =
+ mediaPlayer?.let { { it(DemoMediaPresentationStyle.Default) } }
+ val compactMediaPlayer: (@Composable ContentScope.() -> Unit)? =
+ mediaPlayer?.let { { it(DemoMediaPresentationStyle.Compact) } }
val qsPager: (@Composable ContentScope.() -> Unit) = {
QuickSettingsPager(
@@ -561,7 +568,7 @@
configuration.notificationsInLockscreen
)
},
- mediaPlayer = largeMediaPlayer,
+ mediaPlayer = defaultMediaPlayer,
isDismissable = isLockscreenDismissable,
onToggleDismissable = {
isLockscreenDismissable = !isLockscreenDismissable
@@ -584,7 +591,7 @@
configuration.notificationsInLockscreen
)
},
- mediaPlayer = largeMediaPlayer,
+ mediaPlayer = defaultMediaPlayer,
isDismissable = isLockscreenDismissable,
onToggleDismissable = {
isLockscreenDismissable = !isLockscreenDismissable
@@ -624,7 +631,7 @@
) {
QuickSettings(
qsPager,
- mediaPlayer = largeMediaPlayer,
+ mediaPlayer = defaultMediaPlayer,
::onSettingsButtonClicked,
::onPowerButtonClicked,
)
@@ -640,7 +647,7 @@
overscrollEffect = overscrollEffect,
)
},
- mediaPlayer = largeMediaPlayer,
+ mediaPlayer = defaultMediaPlayer,
quickSettingsTiles,
nQuickSettingsColumns,
)
@@ -655,7 +662,7 @@
maxNotificationCount = configuration.notificationsInShade
)
},
- mediaPlayer = largeMediaPlayer,
+ mediaPlayer = defaultMediaPlayer,
quickSettingsTiles,
nQuickSettingsSplitShadeRows,
nQuickSettingsColumns,
@@ -674,7 +681,7 @@
alignment = Alignment.TopEnd,
effectFactory = overlayEffectFactory,
) {
- QuickSettingsShade(qsPager, smallMediaPlayer)
+ QuickSettingsShade(qsPager, compactMediaPlayer)
}
overlay(
@@ -690,7 +697,7 @@
} else {
{ Clock(MaterialTheme.colorScheme.onSurfaceVariant) }
},
- mediaPlayer = largeMediaPlayer,
+ mediaPlayer = defaultMediaPlayer,
notificationList = {
NotificationList(
maxNotificationCount = configuration.notificationsInShade,