Loading packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt +10 −12 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dreams.DreamOverlayStateController import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.media.dream.MediaDreamComplication import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeStateEvents Loading Loading @@ -93,6 +94,7 @@ constructor( private val keyguardStateController: KeyguardStateController, private val bypassController: KeyguardBypassController, private val mediaCarouselController: MediaCarouselController, private val mediaManager: MediaDataManager, private val keyguardViewController: KeyguardViewController, private val dreamOverlayStateController: DreamOverlayStateController, configurationController: ConfigurationController, Loading Loading @@ -224,9 +226,9 @@ constructor( private var inSplitShade = false /** Is there any active media in the carousel? */ private var hasActiveMedia: Boolean = false get() = mediaHosts.get(LOCATION_QQS)?.visible == true /** Is there any active media or recommendation in the carousel? */ private var hasActiveMediaOrRecommendation: Boolean = false get() = mediaManager.hasActiveMediaOrRecommendation() /** Are we currently waiting on an animation to start? */ private var animationPending: Boolean = false Loading Loading @@ -582,12 +584,8 @@ 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, forceStateUpdate = stateUpdate) updateDesiredLocation(forceNoAnimation = true) } mediaHosts[mediaObject.location] = mediaObject if (mediaObject.location == desiredLocation) { Loading Loading @@ -908,7 +906,7 @@ constructor( fun isCurrentlyInGuidedTransformation(): Boolean { return hasValidStartAndEndLocations() && getTransformationProgress() >= 0 && areGuidedTransitionHostsVisible() (areGuidedTransitionHostsVisible() || !hasActiveMediaOrRecommendation) } private fun hasValidStartAndEndLocations(): Boolean { Loading Loading @@ -965,7 +963,7 @@ constructor( private fun getQSTransformationProgress(): Float { val currentHost = getHost(desiredLocation) val previousHost = getHost(previousLocation) if (hasActiveMedia && (currentHost?.location == LOCATION_QS && !inSplitShade)) { if (currentHost?.location == LOCATION_QS && !inSplitShade) { if (previousHost?.location == LOCATION_QQS) { if (previousHost.visible || statusbarState != StatusBarState.KEYGUARD) { return qsExpansion Loading Loading @@ -1028,7 +1026,8 @@ constructor( private fun updateHostAttachment() = traceSection("MediaHierarchyManager#updateHostAttachment") { var newLocation = resolveLocationForFading() var canUseOverlay = !isCurrentlyFading() // Don't use the overlay when fading or when we don't have active media var canUseOverlay = !isCurrentlyFading() && hasActiveMediaOrRecommendation if (isCrossFadeAnimatorRunning) { if ( getHost(newLocation)?.visible == true && Loading Loading @@ -1122,7 +1121,6 @@ constructor( dreamOverlayActive && dreamMediaComplicationActive -> LOCATION_DREAM_OVERLAY (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS qsExpansion > 0.4f && onLockscreen -> LOCATION_QS !hasActiveMedia -> LOCATION_QS onLockscreen && isSplitShadeExpanding() -> LOCATION_QS onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN Loading packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +18 −1 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.util.LifecycleFragment; import com.android.systemui.util.Utils; import java.io.PrintWriter; import java.util.Arrays; Loading Loading @@ -683,7 +684,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca } else { mQsMediaHost.setSquishFraction(mSquishinessFraction); } updateMediaPositions(); } private void setAlphaAnimationProgress(float progress) { Loading Loading @@ -758,6 +759,22 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca - mQSPanelController.getPaddingBottom()); } private void updateMediaPositions() { if (Utils.useQsMediaPlayer(getContext())) { View hostView = mQsMediaHost.getHostView(); // Make sure the media appears a bit from the top to make it look nicer if (mLastQSExpansion > 0 && !isKeyguardState() && !mQqsMediaHost.getVisible() && !mQSPanelController.shouldUseHorizontalLayout() && !mInSplitShade) { float interpolation = 1.0f - mLastQSExpansion; interpolation = Interpolators.ACCELERATE.getInterpolation(interpolation); float translationY = -hostView.getHeight() * 1.3f * interpolation; hostView.setTranslationY(translationY); } else { hostView.setTranslationY(0); } } } private boolean headerWillBeAnimating() { return mStatusBarState == KEYGUARD && mShowCollapsedOnKeyguard && !isKeyguardState(); } Loading packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +5 −5 Original line number Diff line number Diff line Loading @@ -372,18 +372,18 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr if (mUsingHorizontalLayout) { // Only height remaining parameters.getDisappearSize().set(0.0f, 0.4f); // Disappearing on the right side on the bottom parameters.getGonePivot().set(1.0f, 1.0f); // Disappearing on the right side on the top parameters.getGonePivot().set(1.0f, 0.0f); // translating a bit horizontal parameters.getContentTranslationFraction().set(0.25f, 1.0f); parameters.setDisappearEnd(0.6f); } else { // Only width remaining parameters.getDisappearSize().set(1.0f, 0.0f); // Disappearing on the bottom parameters.getGonePivot().set(0.0f, 1.0f); // Disappearing on the top parameters.getGonePivot().set(0.0f, 0.0f); // translating a bit vertical parameters.getContentTranslationFraction().set(0.0f, 1.05f); parameters.getContentTranslationFraction().set(0.0f, 1f); parameters.setDisappearEnd(0.95f); } parameters.setFadeStartPosition(0.95f); Loading packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt +19 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq import com.android.systemui.dreams.DreamOverlayStateController import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.media.dream.MediaDreamComplication import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeExpansionStateManager Loading Loading @@ -76,6 +77,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { @Mock private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle @Mock private lateinit var keyguardViewController: KeyguardViewController @Mock private lateinit var mediaDataManager: MediaDataManager @Mock private lateinit var uniqueObjectHostView: UniqueObjectHostView @Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController @Captor Loading Loading @@ -110,6 +112,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { keyguardStateController, bypassController, mediaCarouselController, mediaDataManager, keyguardViewController, dreamOverlayStateController, configurationController, Loading @@ -125,6 +128,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP) setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP) whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) whenever(mediaDataManager.hasActiveMedia()).thenReturn(true) whenever(mediaCarouselController.mediaCarouselScrollHandler) .thenReturn(mediaCarouselScrollHandler) val observer = wakefullnessObserver.value Loading Loading @@ -357,16 +361,30 @@ class MediaHierarchyManagerTest : SysuiTestCase() { } @Test fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() { fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsFalse_with_active() { goToLockscreen() enterGuidedTransformation() whenever(lockHost.visible).thenReturn(false) whenever(qsHost.visible).thenReturn(true) whenever(qqsHost.visible).thenReturn(true) whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true) assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isFalse() } @Test fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue_without_active() { // To keep the appearing behavior, we need to be in a guided transition goToLockscreen() enterGuidedTransformation() whenever(lockHost.visible).thenReturn(false) whenever(qsHost.visible).thenReturn(true) whenever(qqsHost.visible).thenReturn(true) whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false) assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isTrue() } @Test fun testDream() { goToDream() Loading Loading
packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt +10 −12 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dreams.DreamOverlayStateController import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.media.dream.MediaDreamComplication import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeStateEvents Loading Loading @@ -93,6 +94,7 @@ constructor( private val keyguardStateController: KeyguardStateController, private val bypassController: KeyguardBypassController, private val mediaCarouselController: MediaCarouselController, private val mediaManager: MediaDataManager, private val keyguardViewController: KeyguardViewController, private val dreamOverlayStateController: DreamOverlayStateController, configurationController: ConfigurationController, Loading Loading @@ -224,9 +226,9 @@ constructor( private var inSplitShade = false /** Is there any active media in the carousel? */ private var hasActiveMedia: Boolean = false get() = mediaHosts.get(LOCATION_QQS)?.visible == true /** Is there any active media or recommendation in the carousel? */ private var hasActiveMediaOrRecommendation: Boolean = false get() = mediaManager.hasActiveMediaOrRecommendation() /** Are we currently waiting on an animation to start? */ private var animationPending: Boolean = false Loading Loading @@ -582,12 +584,8 @@ 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, forceStateUpdate = stateUpdate) updateDesiredLocation(forceNoAnimation = true) } mediaHosts[mediaObject.location] = mediaObject if (mediaObject.location == desiredLocation) { Loading Loading @@ -908,7 +906,7 @@ constructor( fun isCurrentlyInGuidedTransformation(): Boolean { return hasValidStartAndEndLocations() && getTransformationProgress() >= 0 && areGuidedTransitionHostsVisible() (areGuidedTransitionHostsVisible() || !hasActiveMediaOrRecommendation) } private fun hasValidStartAndEndLocations(): Boolean { Loading Loading @@ -965,7 +963,7 @@ constructor( private fun getQSTransformationProgress(): Float { val currentHost = getHost(desiredLocation) val previousHost = getHost(previousLocation) if (hasActiveMedia && (currentHost?.location == LOCATION_QS && !inSplitShade)) { if (currentHost?.location == LOCATION_QS && !inSplitShade) { if (previousHost?.location == LOCATION_QQS) { if (previousHost.visible || statusbarState != StatusBarState.KEYGUARD) { return qsExpansion Loading Loading @@ -1028,7 +1026,8 @@ constructor( private fun updateHostAttachment() = traceSection("MediaHierarchyManager#updateHostAttachment") { var newLocation = resolveLocationForFading() var canUseOverlay = !isCurrentlyFading() // Don't use the overlay when fading or when we don't have active media var canUseOverlay = !isCurrentlyFading() && hasActiveMediaOrRecommendation if (isCrossFadeAnimatorRunning) { if ( getHost(newLocation)?.visible == true && Loading Loading @@ -1122,7 +1121,6 @@ constructor( dreamOverlayActive && dreamMediaComplicationActive -> LOCATION_DREAM_OVERLAY (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS qsExpansion > 0.4f && onLockscreen -> LOCATION_QS !hasActiveMedia -> LOCATION_QS onLockscreen && isSplitShadeExpanding() -> LOCATION_QS onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN Loading
packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +18 −1 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.util.LifecycleFragment; import com.android.systemui.util.Utils; import java.io.PrintWriter; import java.util.Arrays; Loading Loading @@ -683,7 +684,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca } else { mQsMediaHost.setSquishFraction(mSquishinessFraction); } updateMediaPositions(); } private void setAlphaAnimationProgress(float progress) { Loading Loading @@ -758,6 +759,22 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca - mQSPanelController.getPaddingBottom()); } private void updateMediaPositions() { if (Utils.useQsMediaPlayer(getContext())) { View hostView = mQsMediaHost.getHostView(); // Make sure the media appears a bit from the top to make it look nicer if (mLastQSExpansion > 0 && !isKeyguardState() && !mQqsMediaHost.getVisible() && !mQSPanelController.shouldUseHorizontalLayout() && !mInSplitShade) { float interpolation = 1.0f - mLastQSExpansion; interpolation = Interpolators.ACCELERATE.getInterpolation(interpolation); float translationY = -hostView.getHeight() * 1.3f * interpolation; hostView.setTranslationY(translationY); } else { hostView.setTranslationY(0); } } } private boolean headerWillBeAnimating() { return mStatusBarState == KEYGUARD && mShowCollapsedOnKeyguard && !isKeyguardState(); } Loading
packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +5 −5 Original line number Diff line number Diff line Loading @@ -372,18 +372,18 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr if (mUsingHorizontalLayout) { // Only height remaining parameters.getDisappearSize().set(0.0f, 0.4f); // Disappearing on the right side on the bottom parameters.getGonePivot().set(1.0f, 1.0f); // Disappearing on the right side on the top parameters.getGonePivot().set(1.0f, 0.0f); // translating a bit horizontal parameters.getContentTranslationFraction().set(0.25f, 1.0f); parameters.setDisappearEnd(0.6f); } else { // Only width remaining parameters.getDisappearSize().set(1.0f, 0.0f); // Disappearing on the bottom parameters.getGonePivot().set(0.0f, 1.0f); // Disappearing on the top parameters.getGonePivot().set(0.0f, 0.0f); // translating a bit vertical parameters.getContentTranslationFraction().set(0.0f, 1.05f); parameters.getContentTranslationFraction().set(0.0f, 1f); parameters.setDisappearEnd(0.95f); } parameters.setFadeStartPosition(0.95f); Loading
packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt +19 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq import com.android.systemui.dreams.DreamOverlayStateController import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.media.dream.MediaDreamComplication import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeExpansionStateManager Loading Loading @@ -76,6 +77,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { @Mock private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle @Mock private lateinit var keyguardViewController: KeyguardViewController @Mock private lateinit var mediaDataManager: MediaDataManager @Mock private lateinit var uniqueObjectHostView: UniqueObjectHostView @Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController @Captor Loading Loading @@ -110,6 +112,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { keyguardStateController, bypassController, mediaCarouselController, mediaDataManager, keyguardViewController, dreamOverlayStateController, configurationController, Loading @@ -125,6 +128,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP) setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP) whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) whenever(mediaDataManager.hasActiveMedia()).thenReturn(true) whenever(mediaCarouselController.mediaCarouselScrollHandler) .thenReturn(mediaCarouselScrollHandler) val observer = wakefullnessObserver.value Loading Loading @@ -357,16 +361,30 @@ class MediaHierarchyManagerTest : SysuiTestCase() { } @Test fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() { fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsFalse_with_active() { goToLockscreen() enterGuidedTransformation() whenever(lockHost.visible).thenReturn(false) whenever(qsHost.visible).thenReturn(true) whenever(qqsHost.visible).thenReturn(true) whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true) assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isFalse() } @Test fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue_without_active() { // To keep the appearing behavior, we need to be in a guided transition goToLockscreen() enterGuidedTransformation() whenever(lockHost.visible).thenReturn(false) whenever(qsHost.visible).thenReturn(true) whenever(qqsHost.visible).thenReturn(true) whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false) assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isTrue() } @Test fun testDream() { goToDream() Loading