From 0cfc11f78d0fab91d6b47cd9dc159070e7a7b562 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Fri, 11 Jun 2021 11:44:26 -0400 Subject: [PATCH] Fix media transitions when inactive When there is no active media, the carousel should remain at the bottom of QS. Also ensure that the carousel transitions properly when the media changes state from active to inactive or vice versa Fixes: 184535146 Test: visual Change-Id: I9bcdb76b54c6303785a5783d84e876c162301b14 --- .../systemui/media/MediaHierarchyManager.kt | 24 +++++++++++++++---- .../com/android/systemui/qs/QSFragment.java | 5 ++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt index 075bc700cfa00..edbf18789e285 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt @@ -186,6 +186,12 @@ class MediaHierarchyManager @Inject constructor( @MediaLocation private var currentAttachmentLocation = -1 + /** + * Is there any active media in the carousel? + */ + private var hasActiveMedia: Boolean = false + get() = mediaHosts.get(LOCATION_QQS)?.visible == true + /** * Are we currently waiting on an animation to start? */ @@ -476,8 +482,12 @@ class MediaHierarchyManager @Inject constructor( val viewHost = createUniqueObjectHost() mediaObject.hostView = viewHost mediaObject.addVisibilityChangeListener { + // If QQS changes visibility, we need to force an update to ensure the transition + // goes into the correct state + val stateUpdate = mediaObject.location == LOCATION_QQS + // Never animate because of a visibility change, only state changes should do that - updateDesiredLocation(forceNoAnimation = true) + updateDesiredLocation(forceNoAnimation = true, forceStateUpdate = stateUpdate) } mediaHosts[mediaObject.location] = mediaObject if (mediaObject.location == desiredLocation) { @@ -521,10 +531,15 @@ class MediaHierarchyManager @Inject constructor( * going from the old desired location to the new one. * * @param forceNoAnimation optional parameter telling the system not to animate + * @param forceStateUpdate optional parameter telling the system to update transition state + * even if location did not change */ - private fun updateDesiredLocation(forceNoAnimation: Boolean = false) { + private fun updateDesiredLocation( + forceNoAnimation: Boolean = false, + forceStateUpdate: Boolean = false + ) { val desiredLocation = calculateLocation() - if (desiredLocation != this.desiredLocation) { + if (desiredLocation != this.desiredLocation || forceStateUpdate) { if (this.desiredLocation >= 0) { previousLocation = this.desiredLocation } @@ -784,7 +799,7 @@ class MediaHierarchyManager @Inject constructor( private fun getQSTransformationProgress(): Float { val currentHost = getHost(desiredLocation) val previousHost = getHost(previousLocation) - if (currentHost?.location == LOCATION_QS) { + if (hasActiveMedia && currentHost?.location == LOCATION_QS) { if (previousHost?.location == LOCATION_QQS) { if (previousHost.visible || statusbarState != StatusBarState.KEYGUARD) { return qsExpansion @@ -917,6 +932,7 @@ class MediaHierarchyManager @Inject constructor( val location = when { qsExpansion > 0.0f && !onLockscreen -> LOCATION_QS qsExpansion > 0.4f && onLockscreen -> LOCATION_QS + !hasActiveMedia -> LOCATION_QS onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS onLockscreen && allowedOnLockscreen -> LOCATION_LOCKSCREEN else -> LOCATION_QQS diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index e1a66b2c07ee5..7b8a6a0a8d0e8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -539,8 +539,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca private void pinToBottom(float absoluteBottomPosition, MediaHost mediaHost, boolean expanded) { View hostView = mediaHost.getHostView(); - // on keyguard we cross-fade to expanded, so no need to pin it. - if (mLastQSExpansion > 0 && !isKeyguardState()) { + // On keyguard we cross-fade to expanded, so no need to pin it. + // If the collapsed qs isn't visible, we also just keep it at the laid out position. + if (mLastQSExpansion > 0 && !isKeyguardState() && mQqsMediaHost.getVisible()) { float targetPosition = absoluteBottomPosition - getTotalBottomMargin(hostView) - hostView.getHeight(); float currentPosition = mediaHost.getCurrentBounds().top