summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt27
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt153
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt6
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt87
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt15
7 files changed, 254 insertions, 61 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
index f4d9e820ad8f..3d8ca1e96a09 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
@@ -22,7 +22,9 @@ import android.widget.FrameLayout
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
+import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.approachLayout
import androidx.compose.ui.layout.layout
@@ -31,8 +33,12 @@ import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.MovableElementKey
import com.android.compose.animation.scene.SceneScope
+import com.android.compose.windowsizeclass.LocalWindowSizeClass
+import com.android.internal.R.attr.layout
+import com.android.systemui.media.controls.ui.composable.MediaCarouselStateLoader.stateForMediaCarouselContent
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.res.R
import com.android.systemui.util.animation.MeasurementInput
@@ -53,12 +59,20 @@ fun SceneScope.MediaCarousel(
modifier: Modifier = Modifier,
carouselController: MediaCarouselController,
offsetProvider: (() -> IntOffset)? = null,
+ usingCollapsedLandscapeMedia: Boolean = false,
) {
if (!isVisible || carouselController.isLockedAndHidden()) {
return
}
- val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)
+ val carouselState = remember { { stateForMediaCarouselContent() } }
+ val isCollapsed = usingCollapsedLandscapeMedia && isLandscape()
+ val mediaHeight =
+ if (isCollapsed && mediaHost.expansion == MediaHostState.COLLAPSED) {
+ dimensionResource(R.dimen.qs_media_session_height_collapsed)
+ } else {
+ dimensionResource(R.dimen.qs_media_session_height_expanded)
+ }
MovableElement(
key = MediaCarousel.Elements.Content,
@@ -95,6 +109,7 @@ fun SceneScope.MediaCarousel(
}
},
factory = { context ->
+ MediaCarouselStateLoader.loadCarouselState(carouselController, carouselState())
FrameLayout(context).apply {
layoutParams =
FrameLayout.LayoutParams(
@@ -103,7 +118,10 @@ fun SceneScope.MediaCarousel(
)
}
},
- update = { it.setView(carouselController.mediaFrame) },
+ update = {
+ MediaCarouselStateLoader.loadCarouselState(carouselController, carouselState())
+ it.setView(carouselController.mediaFrame)
+ },
onRelease = { it.removeAllViews() },
)
}
@@ -117,3 +135,8 @@ private fun ViewGroup.setView(view: View) {
(view.parent as? ViewGroup)?.removeView(view)
addView(view)
}
+
+@Composable
+fun SceneScope.isLandscape(): Boolean {
+ return LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Compact
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt
new file mode 100644
index 000000000000..b43a5b80b1b6
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2024 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.systemui.media.controls.ui.composable
+
+import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneScope
+import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.systemui.media.controls.ui.controller.MediaCarouselController
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
+import com.android.systemui.media.controls.ui.controller.MediaLocation
+import com.android.systemui.scene.shared.model.Overlays
+import com.android.systemui.scene.shared.model.Scenes
+import kotlin.math.min
+
+object MediaCarouselStateLoader {
+
+ /** Sets current state for media carousel. */
+ fun loadCarouselState(carouselController: MediaCarouselController, state: State) {
+ if (state is State.Gone) return
+
+ carouselController.setCurrentState(
+ state.startLocation,
+ state.endLocation,
+ state.transitionProgress,
+ immediately = true,
+ )
+ }
+
+ /** Returns the corresponding media location for the given [scene] */
+ @MediaLocation
+ private fun getMediaLocation(scene: SceneKey): Int {
+ return when (scene) {
+ Scenes.QuickSettings -> MediaHierarchyManager.LOCATION_QS
+ Scenes.Shade -> MediaHierarchyManager.LOCATION_QQS
+ Scenes.Lockscreen -> MediaHierarchyManager.LOCATION_LOCKSCREEN
+ Scenes.Communal -> MediaHierarchyManager.LOCATION_COMMUNAL_HUB
+ else -> -1
+ }
+ }
+
+ /** Returns the corresponding media location for the given [content] */
+ @MediaLocation
+ private fun getMediaLocation(content: ContentKey): Int {
+ return when (content) {
+ Overlays.QuickSettingsShade -> MediaHierarchyManager.LOCATION_QS
+ Overlays.NotificationsShade -> MediaHierarchyManager.LOCATION_QQS
+ else -> -1
+ }
+ }
+
+ /** State for media carousel. */
+ sealed interface State {
+ val transitionProgress: Float
+ // TODO b/368368388: implement media squishiness
+ val squishFraction: () -> Float
+ @MediaLocation val startLocation: Int
+ @MediaLocation val endLocation: Int
+
+ /** State when media carousel is not visible on screen. */
+ data object Gone : State {
+ override val transitionProgress: Float = 1.0F
+ override val squishFraction: () -> Float = { 1.0F }
+ override val endLocation: Int = -1
+ override val startLocation: Int = -1
+ }
+
+ /** State when media carousel is moving from one media location to another */
+ data class InProgress(
+ override val transitionProgress: Float,
+ override val startLocation: Int,
+ override val endLocation: Int,
+ ) : State {
+ override val squishFraction = { 1.0F }
+ }
+
+ /** State when media carousel reached the end location. */
+ data class Idle(override val endLocation: Int) : State {
+ override val transitionProgress = 1.0F
+ override val startLocation = -1
+ override val squishFraction = { 1.0F }
+ }
+ }
+
+ /** Returns the state of media carousel */
+ fun SceneScope.stateForMediaCarouselContent(): State {
+ return when (val transitionState = layoutState.transitionState) {
+ is TransitionState.Idle -> {
+ if (MediaContentPicker.contents.contains(transitionState.currentScene)) {
+ State.Idle(getMediaLocation(transitionState.currentScene))
+ } else {
+ State.Gone
+ }
+ }
+ is TransitionState.Transition.ChangeScene ->
+ with(transitionState) {
+ if (
+ MediaContentPicker.contents.contains(toScene) &&
+ MediaContentPicker.contents.contains(fromScene)
+ ) {
+ State.InProgress(
+ min(progress, 1.0F),
+ getMediaLocation(fromScene),
+ getMediaLocation(toScene),
+ )
+ } else if (MediaContentPicker.contents.contains(toScene)) {
+ State.InProgress(
+ transitionProgress = 1.0F,
+ startLocation = -1,
+ getMediaLocation(toScene),
+ )
+ } else {
+ State.Gone
+ }
+ }
+ is TransitionState.Transition.OverlayTransition ->
+ with(transitionState) {
+ if (
+ MediaContentPicker.contents.contains(toContent) &&
+ MediaContentPicker.contents.contains(fromContent)
+ ) {
+ State.InProgress(
+ min(progress, 1.0F),
+ getMediaLocation(fromContent),
+ getMediaLocation(toContent),
+ )
+ } else if (MediaContentPicker.contents.contains(toContent)) {
+ State.InProgress(
+ transitionProgress = 1.0F,
+ startLocation = -1,
+ getMediaLocation(toContent),
+ )
+ } else {
+ State.Gone
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index d91958adaa1b..5d2474c18fd3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -48,7 +48,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -85,6 +84,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
+import com.android.systemui.media.controls.ui.composable.isLandscape
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
@@ -288,9 +288,7 @@ private fun SceneScope.QuickSettingsScene(
// ############# Media ###############
val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle()
- val mediaInRow =
- isMediaVisible &&
- LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Compact
+ val mediaInRow = isMediaVisible && isLandscape()
val mediaOffset by
animateSceneDpAsState(value = InQS, key = MediaLandscapeTopOffset, canOverflow = false)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 8a59e204eb23..7f2ee2a8351a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -43,7 +43,6 @@ import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -78,7 +77,6 @@ import com.android.compose.animation.scene.animateSceneFloatAsState
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.modifiers.padding
import com.android.compose.modifiers.thenIf
-import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation
import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout
@@ -89,6 +87,7 @@ import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.composable.MediaContentPicker
+import com.android.systemui.media.controls.ui.composable.isLandscape
import com.android.systemui.media.controls.ui.composable.shouldElevateMedia
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
@@ -197,6 +196,8 @@ constructor(
qsMediaHost = qsMediaHost,
modifier = modifier,
shadeSession = shadeSession,
+ usingCollapsedLandscapeMedia =
+ Utils.useCollapsedMediaInLandscape(LocalContext.current.resources),
)
init {
@@ -223,6 +224,7 @@ private fun SceneScope.ShadeScene(
qsMediaHost: MediaHost,
modifier: Modifier = Modifier,
shadeSession: SaveableSession,
+ usingCollapsedLandscapeMedia: Boolean,
) {
val view = LocalView.current
LaunchedEffect(Unit) {
@@ -245,6 +247,7 @@ private fun SceneScope.ShadeScene(
mediaHost = qqsMediaHost,
modifier = modifier,
shadeSession = shadeSession,
+ usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
)
is ShadeMode.Split ->
SplitShade(
@@ -275,14 +278,11 @@ private fun SceneScope.SingleShade(
mediaHost: MediaHost,
modifier: Modifier = Modifier,
shadeSession: SaveableSession,
+ usingCollapsedLandscapeMedia: Boolean,
) {
val cutoutLocation = LocalDisplayCutout.current.location
val cutoutInsets = WindowInsets.Companion.displayCutout
- val isLandscape = LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Compact
- val usingCollapsedLandscapeMedia =
- Utils.useCollapsedMediaInLandscape(LocalContext.current.resources)
- val isExpanded = !usingCollapsedLandscapeMedia || !isLandscape
- mediaHost.expansion = if (isExpanded) EXPANDED else COLLAPSED
+ mediaHost.expansion = if (usingCollapsedLandscapeMedia && isLandscape()) COLLAPSED else EXPANDED
var maxNotifScrimTop by remember { mutableIntStateOf(0) }
val tileSquishiness by
@@ -298,7 +298,7 @@ private fun SceneScope.SingleShade(
layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade) ||
layoutState.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade)
// Media is visible and we are in landscape on a small height screen
- val mediaInRow = isMediaVisible && isLandscape
+ val mediaInRow = isMediaVisible && isLandscape()
val mediaOffset by
animateSceneDpAsState(value = InQQS, key = MediaLandscapeTopOffset, canOverflow = false)
@@ -380,6 +380,7 @@ private fun SceneScope.SingleShade(
mediaOffsetProvider = mediaOffsetProvider,
carouselController = mediaCarouselController,
modifier = Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Media),
+ usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
)
NotificationScrollingStack(
@@ -636,6 +637,7 @@ private fun SceneScope.ShadeMediaCarousel(
carouselController: MediaCarouselController,
mediaOffsetProvider: ShadeMediaOffsetProvider,
modifier: Modifier = Modifier,
+ usingCollapsedLandscapeMedia: Boolean = false,
) {
MediaCarousel(
modifier = modifier.fillMaxWidth(),
@@ -648,5 +650,6 @@ private fun SceneScope.ShadeMediaCarousel(
} else {
{ mediaOffsetProvider.offset }
},
+ usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index bb9517a14142..c1e28b356ce0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -110,6 +110,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -726,6 +727,13 @@ constructor(
)
DiffUtil.calculateDiff(diffUtilCallback).dispatchUpdatesTo(listUpdateCallback)
setNewViewModelsList(it)
+
+ // Update host visibility when media changes.
+ merge(
+ mediaCarouselViewModel.hasAnyMediaOrRecommendations,
+ mediaCarouselViewModel.hasActiveMediaOrRecommendations,
+ )
+ .collect { updateHostVisibility() }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
index e57de09f1063..4d4a5a9780b7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
@@ -91,7 +91,7 @@ constructor(
*/
enum class TYPE {
PLAYER,
- RECOMMENDATION
+ RECOMMENDATION,
}
companion object {
@@ -294,14 +294,14 @@ constructor(
object : MediaHostStatesManager.Callback {
override fun onHostStateChanged(
@MediaLocation location: Int,
- mediaHostState: MediaHostState
+ mediaHostState: MediaHostState,
) {
if (location == currentEndLocation || location == currentStartLocation) {
setCurrentState(
currentStartLocation,
currentEndLocation,
currentTransitionProgress,
- applyImmediately = false
+ applyImmediately = false,
)
}
}
@@ -442,7 +442,7 @@ constructor(
/** Apply squishFraction to a copy of viewState such that the cached version is untouched. */
internal fun squishViewState(
viewState: TransitionViewState,
- squishFraction: Float
+ squishFraction: Float,
): TransitionViewState {
val squishedViewState = viewState.copy()
val squishedHeight = (squishedViewState.measureHeight * squishFraction).toInt()
@@ -458,13 +458,13 @@ constructor(
MediaViewHolder.expandedBottomActionIds,
squishedViewState.measureHeight.toFloat(),
squishedViewState,
- squishFraction
+ squishFraction,
)
calculateWidgetGroupAlphaForSquishiness(
MediaViewHolder.detailIds,
squishedViewState.measureHeight.toFloat(),
squishedViewState,
- squishFraction
+ squishFraction,
)
// recommendation card
val titlesTop =
@@ -472,13 +472,13 @@ constructor(
RecommendationViewHolder.mediaTitlesAndSubtitlesIds,
squishedViewState.measureHeight.toFloat(),
squishedViewState,
- squishFraction
+ squishFraction,
)
calculateWidgetGroupAlphaForSquishiness(
RecommendationViewHolder.mediaContainersIds,
titlesTop,
squishedViewState,
- squishFraction
+ squishFraction,
)
return squishedViewState
}
@@ -517,7 +517,7 @@ constructor(
widgetGroupIds: Set<Int>,
groupEndPosition: Float,
squishedViewState: TransitionViewState,
- squishFraction: Float
+ squishFraction: Float,
): Float {
val nonsquishedHeight = squishedViewState.measureHeight
var groupTop = squishedViewState.measureHeight.toFloat()
@@ -547,7 +547,7 @@ constructor(
calculateAlpha(
squishFraction,
startPosition / nonsquishedHeight,
- endPosition / nonsquishedHeight
+ endPosition / nonsquishedHeight,
)
}
}
@@ -562,10 +562,10 @@ constructor(
@VisibleForTesting
fun obtainViewState(
state: MediaHostState?,
- isGutsAnimation: Boolean = false
+ isGutsAnimation: Boolean = false,
): TransitionViewState? {
if (SceneContainerFlag.isEnabled) {
- return obtainSceneContainerViewState()
+ return obtainSceneContainerViewState(state)
}
if (state == null || state.measurementInput == null) {
@@ -606,7 +606,7 @@ constructor(
transitionLayout!!.calculateViewState(
state.measurementInput!!,
constraintSetForExpansion(state.expansion),
- TransitionViewState()
+ TransitionViewState(),
)
setGutsViewState(result)
@@ -661,7 +661,7 @@ constructor(
startLocation = currentStartLocation,
endLocation = currentEndLocation,
transitionProgress = currentTransitionProgress,
- applyImmediately = true
+ applyImmediately = true,
)
}
@@ -695,7 +695,7 @@ constructor(
Interpolators.EMPHASIZED_DECELERATE,
titleText,
artistText,
- explicitIndicator
+ explicitIndicator,
)
val exit =
loadAnimator(
@@ -704,7 +704,7 @@ constructor(
Interpolators.EMPHASIZED_ACCELERATE,
titleText,
artistText,
- explicitIndicator
+ explicitIndicator,
)
metadataAnimationHandler = MetadataAnimationHandler(exit, enter)
@@ -713,7 +713,7 @@ constructor(
mediaCard.context,
mediaViewHolder,
multiRippleController,
- turbulenceNoiseController
+ turbulenceNoiseController,
)
// For Turbulence noise.
@@ -728,7 +728,7 @@ constructor(
object : LoadingEffect.AnimationStateChangedCallback {
override fun onStateChanged(
oldState: LoadingEffect.AnimationState,
- newState: LoadingEffect.AnimationState
+ newState: LoadingEffect.AnimationState,
) {
if (newState === LoadingEffect.AnimationState.NOT_PLAYING) {
loadingEffectView.visibility = View.INVISIBLE
@@ -755,12 +755,12 @@ constructor(
MediaControlViewBinder.setVisibleAndAlpha(
expandedLayout,
it.scrubbingTotalTimeView.id,
- isTimeVisible
+ isTimeVisible,
)
MediaControlViewBinder.setVisibleAndAlpha(
expandedLayout,
it.scrubbingElapsedTimeView.id,
- isTimeVisible
+ isTimeVisible,
)
}
@@ -788,7 +788,7 @@ constructor(
collapsedLayout,
isButtonVisible,
notVisibleValue,
- showInCollapsed = true
+ showInCollapsed = true,
)
}
}
@@ -822,7 +822,7 @@ constructor(
createTurbulenceNoiseConfig(
it.loadingEffectView,
it.turbulenceNoiseView,
- colorSchemeTransition
+ colorSchemeTransition,
)
}
if (Flags.shaderlibLoadingEffectRefactor()) {
@@ -832,23 +832,23 @@ constructor(
TurbulenceNoiseShader.Companion.Type.SIMPLEX_NOISE,
turbulenceNoiseAnimationConfig,
noiseDrawCallback,
- stateChangedCallback
+ stateChangedCallback,
)
}
colorSchemeTransition.loadingEffect = loadingEffect
loadingEffect.play()
mainExecutor.executeDelayed(
loadingEffect::finish,
- MediaControlViewModel.TURBULENCE_NOISE_PLAY_MS_DURATION
+ MediaControlViewModel.TURBULENCE_NOISE_PLAY_MS_DURATION,
)
} else {
turbulenceNoiseController.play(
TurbulenceNoiseShader.Companion.Type.SIMPLEX_NOISE,
- turbulenceNoiseAnimationConfig
+ turbulenceNoiseAnimationConfig,
)
mainExecutor.executeDelayed(
turbulenceNoiseController::finish,
- MediaControlViewModel.TURBULENCE_NOISE_PLAY_MS_DURATION
+ MediaControlViewModel.TURBULENCE_NOISE_PLAY_MS_DURATION,
)
}
}
@@ -920,7 +920,7 @@ constructor(
startViewState,
startHostState.disappearParameters,
transitionProgress,
- tmpState
+ tmpState,
)
}
} else if (startHostState != null && !startHostState.visible) {
@@ -931,7 +931,7 @@ constructor(
endViewState,
endHostState.disappearParameters,
1.0f - transitionProgress,
- tmpState
+ tmpState,
)
} else if (transitionProgress == 1.0f || startViewState == null) {
// We're at the end. Let's use that state
@@ -945,13 +945,13 @@ constructor(
startViewState,
endViewState,
transitionProgress,
- tmpState
+ tmpState,
)
}
logger.logMediaSize(
"setCurrentState (progress $transitionProgress)",
result.width,
- result.height
+ result.height,
)
layoutController.setState(
result,
@@ -966,7 +966,7 @@ constructor(
private fun updateViewStateSize(
viewState: TransitionViewState?,
location: Int,
- outState: TransitionViewState
+ outState: TransitionViewState,
): TransitionViewState? {
var result = viewState?.copy(outState) ?: return null
val state = mediaHostStatesManager.mediaHostStates[location]
@@ -1020,15 +1020,19 @@ constructor(
}
/** Get a view state based on the width and height set by the scene */
- private fun obtainSceneContainerViewState(): TransitionViewState? {
+ private fun obtainSceneContainerViewState(state: MediaHostState?): TransitionViewState? {
logger.logMediaSize("scene container", widthInSceneContainerPx, heightInSceneContainerPx)
+ if (state?.measurementInput == null) {
+ return null
+ }
+
// Similar to obtainViewState: Let's create a new measurement
val result =
transitionLayout?.calculateViewState(
MeasurementInput(widthInSceneContainerPx, heightInSceneContainerPx),
- expandedLayout,
- TransitionViewState()
+ if (state.expansion > 0) expandedLayout else collapsedLayout,
+ TransitionViewState(),
)
result?.let {
// And then ensure the guts visibility is set correctly
@@ -1049,7 +1053,7 @@ constructor(
private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? {
val mediaHostState = mediaHostStatesManager.mediaHostStates[location] ?: return null
if (SceneContainerFlag.isEnabled) {
- return obtainSceneContainerViewState()
+ return obtainSceneContainerViewState(mediaHostState)
}
val viewState = obtainViewState(mediaHostState)
@@ -1080,9 +1084,10 @@ constructor(
fun refreshState() =
traceSection("MediaViewController#refreshState") {
if (SceneContainerFlag.isEnabled) {
+ val hostState = mediaHostStatesManager.mediaHostStates[currentEndLocation]
// We don't need to recreate measurements for scene container, since it's a known
// size. Just get the view state and update the layout controller
- obtainSceneContainerViewState()?.let {
+ obtainSceneContainerViewState(hostState)?.let {
// Get scene container state, then setCurrentState
layoutController.setState(
state = it,
@@ -1106,7 +1111,7 @@ constructor(
currentStartLocation,
currentEndLocation,
currentTransitionProgress,
- applyImmediately = true
+ applyImmediately = true,
)
}
@@ -1115,7 +1120,7 @@ constructor(
context: Context,
animId: Int,
motionInterpolator: Interpolator?,
- vararg targets: View?
+ vararg targets: View?,
): AnimatorSet {
val animators = ArrayList<Animator>()
for (target in targets) {
@@ -1132,7 +1137,7 @@ constructor(
private fun createTurbulenceNoiseConfig(
loadingEffectView: LoadingEffectView,
turbulenceNoiseView: TurbulenceNoiseView,
- colorSchemeTransition: ColorSchemeTransition
+ colorSchemeTransition: ColorSchemeTransition,
): TurbulenceNoiseAnimationConfig {
val targetView: View =
if (Flags.shaderlibLoadingEffectRefactor()) {
@@ -1163,7 +1168,7 @@ constructor(
targetView.context.resources.displayMetrics.density,
lumaMatteBlendFactor = 0.26f,
lumaMatteOverallBrightness = 0.09f,
- shouldInverseNoiseLuminosity = false
+ shouldInverseNoiseLuminosity = false,
)
}
@@ -1185,5 +1190,5 @@ private data class CacheKey(
var widthMeasureSpec: Int = -1,
var heightMeasureSpec: Int = -1,
var expansion: Float = 0.0f,
- var gutsVisible: Boolean = false
+ var gutsVisible: Boolean = false,
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
index e7f7171d5be3..b2137afa05e6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
@@ -56,6 +56,9 @@ constructor(
private val mediaLogger: MediaLogger,
) {
+ val hasAnyMediaOrRecommendations: StateFlow<Boolean> = interactor.hasAnyMediaOrRecommendation
+ val hasActiveMediaOrRecommendations: StateFlow<Boolean> =
+ interactor.hasActiveMediaOrRecommendation
val mediaItems: StateFlow<List<MediaCommonViewModel>> =
interactor.currentMedia
.map { sortedItems ->
@@ -114,7 +117,7 @@ constructor(
qsExpanded: Boolean,
visibleIndex: Int,
location: Int,
- isUpdate: Boolean = false
+ isUpdate: Boolean = false,
) {
// Skip logging if on LS or QQS, and there is no active media card
if (!qsExpanded && !interactor.hasActiveMediaOrRecommendation()) return
@@ -127,7 +130,7 @@ constructor(
val instanceId = commonModel.mediaLoadedModel.instanceId
return mediaControlByInstanceId[instanceId]?.copy(
immediatelyUpdateUi = commonModel.mediaLoadedModel.immediatelyUpdateUi,
- updateTime = commonModel.updateTime
+ updateTime = commonModel.updateTime,
)
?: MediaCommonViewModel.MediaControl(
instanceId = instanceId,
@@ -144,7 +147,7 @@ constructor(
},
onUpdated = { onMediaControlAddedOrUpdated(it, commonModel) },
isMediaFromRec = commonModel.isMediaFromRec,
- updateTime = commonModel.updateTime
+ updateTime = commonModel.updateTime,
)
.also { mediaControlByInstanceId[instanceId] = it }
}
@@ -165,7 +168,7 @@ constructor(
return mediaRecs?.copy(
key = commonModel.recsLoadingModel.key,
loadingEnabled =
- interactor.isRecommendationActive() || mediaFlags.isPersistentSsCardEnabled()
+ interactor.isRecommendationActive() || mediaFlags.isPersistentSsCardEnabled(),
)
?: MediaCommonViewModel.MediaRecommendations(
key = commonModel.recsLoadingModel.key,
@@ -195,7 +198,7 @@ constructor(
private fun onMediaControlAddedOrUpdated(
commonViewModel: MediaCommonViewModel,
- commonModel: MediaCommonModel.MediaControl
+ commonModel: MediaCommonModel.MediaControl,
) {
if (commonModel.canBeRemoved && !Utils.useMediaResumption(applicationContext)) {
// This media control is due for removal as it is now paused + timed out, and resumption
@@ -222,7 +225,7 @@ constructor(
private fun onMediaRecommendationRemoved(
commonModel: MediaCommonModel.MediaRecommendations,
- immediatelyRemove: Boolean
+ immediatelyRemove: Boolean,
) {
mediaLogger.logMediaRecommendationCardRemoved(commonModel.recsLoadingModel.key)
if (immediatelyRemove || isReorderingAllowed()) {