Loading packages/SystemUI/src/com/android/systemui/media/MediaHost.kt +18 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,14 @@ class MediaHost constructor( } } override var squishFraction: Float = 1.0f set(value) { if (!value.equals(field)) { field = value changedListener?.invoke() } } override var showsOnlyActiveMedia: Boolean = false set(value) { if (!value.equals(field)) { Loading Loading @@ -242,6 +250,7 @@ class MediaHost constructor( override fun copy(): MediaHostState { val mediaHostState = MediaHostStateHolder() mediaHostState.expansion = expansion mediaHostState.squishFraction = squishFraction mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia mediaHostState.measurementInput = measurementInput?.copy() mediaHostState.visible = visible Loading @@ -260,6 +269,9 @@ class MediaHost constructor( if (expansion != other.expansion) { return false } if (squishFraction != other.squishFraction) { return false } if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) { return false } Loading @@ -278,6 +290,7 @@ class MediaHost constructor( override fun hashCode(): Int { var result = measurementInput?.hashCode() ?: 0 result = 31 * result + expansion.hashCode() result = 31 * result + squishFraction.hashCode() result = 31 * result + falsingProtectionNeeded.hashCode() result = 31 * result + showsOnlyActiveMedia.hashCode() result = 31 * result + if (visible) 1 else 2 Loading Loading @@ -317,6 +330,11 @@ interface MediaHostState { */ var expansion: Float /** * Fraction of the height animation. */ var squishFraction: Float /** * Is this host only showing active media or is it showing all of them including resumption? */ Loading packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt +52 −35 Original line number Diff line number Diff line Loading @@ -18,13 +18,11 @@ package com.android.systemui.media import android.content.Context import android.content.res.Configuration import androidx.annotation.VisibleForTesting import androidx.constraintlayout.widget.ConstraintSet import com.android.systemui.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.animation.MeasurementOutput import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.animation.TransitionLayoutController import com.android.systemui.util.animation.TransitionViewState import com.android.systemui.util.animation.* import javax.inject.Inject /** Loading Loading @@ -270,7 +268,6 @@ class MediaViewController @Inject constructor( TYPE.PLAYER_SESSION -> PlayerSessionViewHolder.gutsIds TYPE.RECOMMENDATION -> RecommendationViewHolder.gutsIds } controlsIds.forEach { id -> viewState.widgetStates.get(id)?.let { state -> // Make sure to use the unmodified state if guts are not visible. Loading @@ -282,42 +279,61 @@ class MediaViewController @Inject constructor( viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f viewState.widgetStates.get(id)?.gone = !isGutsVisible } if (shouldHideGutsSettings) { viewState.widgetStates.get(R.id.settings)?.gone = true } } /** * Apply squishFraction to a copy of viewState such that the cached version is untouched. */ private fun squishViewState(viewState: TransitionViewState, squishFraction: Float): TransitionViewState { val squishedViewState = viewState.copy() squishedViewState.height = (squishedViewState.height * squishFraction).toInt() val albumArtViewState = viewState.widgetStates.get(R.id.album_art) if (albumArtViewState != null) { albumArtViewState.height = squishedViewState.height } return squishedViewState; } /** * Obtain a new viewState for a given media state. This usually returns a cached state, but if * it's not available, it will recreate one by measuring, which may be expensive. */ private fun obtainViewState(state: MediaHostState?): TransitionViewState? { @VisibleForTesting public fun obtainViewState(state: MediaHostState?): TransitionViewState? { if (state == null || state.measurementInput == null) { return null } // Only a subset of the state is relevant to get a valid viewState. Let's get the cachekey var cacheKey = getKey(state, isGutsVisible, tmpKey) val viewState = viewStates[cacheKey] if (viewState != null) { // we already have cached this measurement, let's continue if (state.squishFraction < 1f) { return squishViewState(viewState, state.squishFraction); } return viewState } // Copy the key since this might call recursively into it and we're using tmpKey cacheKey = cacheKey.copy() val result: TransitionViewState? if (transitionLayout != null) { // Let's create a new measurement if (transitionLayout == null) { return null } // Not cached. Let's create a new measurement if (state.expansion == 0.0f || state.expansion == 1.0f) { result = transitionLayout!!.calculateViewState( state.measurementInput!!, constraintSetForExpansion(state.expansion), TransitionViewState()) setGutsViewState(result) // We don't want to cache interpolated or null states as this could quickly fill up // our cache. We only cache the start and the end states since the interpolation // is cheap setGutsViewState(result) viewStates[cacheKey] = result } else { // This is an interpolated state Loading @@ -327,14 +343,15 @@ class MediaViewController @Inject constructor( // from the start and end state and interpolate them val startViewState = obtainViewState(startState) as TransitionViewState val endState = state.copy().also { it.expansion = 1.0f } val endViewState = obtainViewState(endState) as TransitionViewState result = layoutController.getInterpolatedState( startViewState, endViewState, state.expansion) } } else { result = null if (state.squishFraction < 1f) { return squishViewState(result, state.squishFraction); } return result } Loading packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +1 −0 Original line number Diff line number Diff line Loading @@ -573,6 +573,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca if (mQSAnimator != null) { mQSAnimator.setPosition(expansion); } mQqsMediaHost.setSquishFraction(mSquishinessFraction); updateMediaPositions(); } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +0 −5 Original line number Diff line number Diff line Loading @@ -1332,12 +1332,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ @ShadeViewRefactor(RefactorComponent.COORDINATOR) public void setExpandedHeight(float height) { final float shadeBottom = getHeight() - getEmptyBottomMargin(); final boolean skipHeightUpdate = shouldSkipHeightUpdate(); if (!skipHeightUpdate) { final float expansionFraction = MathUtils.saturate(height / shadeBottom); mAmbientState.setExpansionFraction(expansionFraction); } updateStackPosition(); if (!skipHeightUpdate) { Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +1 −3 Original line number Diff line number Diff line Loading @@ -3009,9 +3009,7 @@ public class NotificationPanelViewController extends PanelViewController { } private int calculatePanelHeightShade() { int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin(); int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin; final int maxHeight = mNotificationStackScrollLayoutController.getHeight(); if (mBarState == KEYGUARD) { int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight() + mNotificationStackScrollLayoutController.getIntrinsicContentHeight(); Loading Loading
packages/SystemUI/src/com/android/systemui/media/MediaHost.kt +18 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,14 @@ class MediaHost constructor( } } override var squishFraction: Float = 1.0f set(value) { if (!value.equals(field)) { field = value changedListener?.invoke() } } override var showsOnlyActiveMedia: Boolean = false set(value) { if (!value.equals(field)) { Loading Loading @@ -242,6 +250,7 @@ class MediaHost constructor( override fun copy(): MediaHostState { val mediaHostState = MediaHostStateHolder() mediaHostState.expansion = expansion mediaHostState.squishFraction = squishFraction mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia mediaHostState.measurementInput = measurementInput?.copy() mediaHostState.visible = visible Loading @@ -260,6 +269,9 @@ class MediaHost constructor( if (expansion != other.expansion) { return false } if (squishFraction != other.squishFraction) { return false } if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) { return false } Loading @@ -278,6 +290,7 @@ class MediaHost constructor( override fun hashCode(): Int { var result = measurementInput?.hashCode() ?: 0 result = 31 * result + expansion.hashCode() result = 31 * result + squishFraction.hashCode() result = 31 * result + falsingProtectionNeeded.hashCode() result = 31 * result + showsOnlyActiveMedia.hashCode() result = 31 * result + if (visible) 1 else 2 Loading Loading @@ -317,6 +330,11 @@ interface MediaHostState { */ var expansion: Float /** * Fraction of the height animation. */ var squishFraction: Float /** * Is this host only showing active media or is it showing all of them including resumption? */ Loading
packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt +52 −35 Original line number Diff line number Diff line Loading @@ -18,13 +18,11 @@ package com.android.systemui.media import android.content.Context import android.content.res.Configuration import androidx.annotation.VisibleForTesting import androidx.constraintlayout.widget.ConstraintSet import com.android.systemui.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.animation.MeasurementOutput import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.animation.TransitionLayoutController import com.android.systemui.util.animation.TransitionViewState import com.android.systemui.util.animation.* import javax.inject.Inject /** Loading Loading @@ -270,7 +268,6 @@ class MediaViewController @Inject constructor( TYPE.PLAYER_SESSION -> PlayerSessionViewHolder.gutsIds TYPE.RECOMMENDATION -> RecommendationViewHolder.gutsIds } controlsIds.forEach { id -> viewState.widgetStates.get(id)?.let { state -> // Make sure to use the unmodified state if guts are not visible. Loading @@ -282,42 +279,61 @@ class MediaViewController @Inject constructor( viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f viewState.widgetStates.get(id)?.gone = !isGutsVisible } if (shouldHideGutsSettings) { viewState.widgetStates.get(R.id.settings)?.gone = true } } /** * Apply squishFraction to a copy of viewState such that the cached version is untouched. */ private fun squishViewState(viewState: TransitionViewState, squishFraction: Float): TransitionViewState { val squishedViewState = viewState.copy() squishedViewState.height = (squishedViewState.height * squishFraction).toInt() val albumArtViewState = viewState.widgetStates.get(R.id.album_art) if (albumArtViewState != null) { albumArtViewState.height = squishedViewState.height } return squishedViewState; } /** * Obtain a new viewState for a given media state. This usually returns a cached state, but if * it's not available, it will recreate one by measuring, which may be expensive. */ private fun obtainViewState(state: MediaHostState?): TransitionViewState? { @VisibleForTesting public fun obtainViewState(state: MediaHostState?): TransitionViewState? { if (state == null || state.measurementInput == null) { return null } // Only a subset of the state is relevant to get a valid viewState. Let's get the cachekey var cacheKey = getKey(state, isGutsVisible, tmpKey) val viewState = viewStates[cacheKey] if (viewState != null) { // we already have cached this measurement, let's continue if (state.squishFraction < 1f) { return squishViewState(viewState, state.squishFraction); } return viewState } // Copy the key since this might call recursively into it and we're using tmpKey cacheKey = cacheKey.copy() val result: TransitionViewState? if (transitionLayout != null) { // Let's create a new measurement if (transitionLayout == null) { return null } // Not cached. Let's create a new measurement if (state.expansion == 0.0f || state.expansion == 1.0f) { result = transitionLayout!!.calculateViewState( state.measurementInput!!, constraintSetForExpansion(state.expansion), TransitionViewState()) setGutsViewState(result) // We don't want to cache interpolated or null states as this could quickly fill up // our cache. We only cache the start and the end states since the interpolation // is cheap setGutsViewState(result) viewStates[cacheKey] = result } else { // This is an interpolated state Loading @@ -327,14 +343,15 @@ class MediaViewController @Inject constructor( // from the start and end state and interpolate them val startViewState = obtainViewState(startState) as TransitionViewState val endState = state.copy().also { it.expansion = 1.0f } val endViewState = obtainViewState(endState) as TransitionViewState result = layoutController.getInterpolatedState( startViewState, endViewState, state.expansion) } } else { result = null if (state.squishFraction < 1f) { return squishViewState(result, state.squishFraction); } return result } Loading
packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +1 −0 Original line number Diff line number Diff line Loading @@ -573,6 +573,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca if (mQSAnimator != null) { mQSAnimator.setPosition(expansion); } mQqsMediaHost.setSquishFraction(mSquishinessFraction); updateMediaPositions(); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +0 −5 Original line number Diff line number Diff line Loading @@ -1332,12 +1332,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ @ShadeViewRefactor(RefactorComponent.COORDINATOR) public void setExpandedHeight(float height) { final float shadeBottom = getHeight() - getEmptyBottomMargin(); final boolean skipHeightUpdate = shouldSkipHeightUpdate(); if (!skipHeightUpdate) { final float expansionFraction = MathUtils.saturate(height / shadeBottom); mAmbientState.setExpansionFraction(expansionFraction); } updateStackPosition(); if (!skipHeightUpdate) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +1 −3 Original line number Diff line number Diff line Loading @@ -3009,9 +3009,7 @@ public class NotificationPanelViewController extends PanelViewController { } private int calculatePanelHeightShade() { int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin(); int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin; final int maxHeight = mNotificationStackScrollLayoutController.getHeight(); if (mBarState == KEYGUARD) { int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight() + mNotificationStackScrollLayoutController.getIntrinsicContentHeight(); Loading