diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java index 757dc2ec807d5..b83ea4acd26f8 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java @@ -55,13 +55,14 @@ public interface QS extends FragmentBase { /** * Asks QS to update its presentation, according to {@code NotificationPanelViewController}. - * * @param qsExpansionFraction How much each UI element in QS should be expanded (QQS to QS.) * @param panelExpansionFraction Whats the expansion of the whole shade. * @param headerTranslation How much we should vertically translate QS. + * @param squishinessFraction Fraction that affects tile height. 0 when collapsed, + * 1 when expanded. */ void setQsExpansion(float qsExpansionFraction, float panelExpansionFraction, - float headerTranslation); + float headerTranslation, float squishinessFraction); void setHeaderListening(boolean listening); void notifyCustomizeChanged(); void setContainerController(QSContainerController controller); diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml index d816b3a461cd9..17765b51c3258 100644 --- a/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml +++ b/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml @@ -23,6 +23,6 @@ 88dp 0dp - 0dp + @dimen/qqs_layout_margin_top \ No newline at end of file diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml index 6b14c96b58e27..10a2f4c625c6e 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml @@ -63,7 +63,7 @@ android:id="@+id/qqs_footer_actions" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="16dp" + android:layout_marginTop="@dimen/qqs_layout_margin_top" android:layout_marginStart="@dimen/qs_footer_margin" android:layout_marginEnd="@dimen/qs_footer_margin" /> diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 1a7a306c978cb..7e5ff8a955623 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -166,6 +166,11 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { updateListening(); } + @Override + public void setSquishinessFraction(float squishinessFraction) { + // No-op, paged layouts are not squishy. + } + private void updateListening() { for (TileLayout tilePage : mPages) { tilePage.setListening(tilePage.getParent() != null && mListening); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index 90d3448ac1eff..44d5e21e6354b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -316,8 +316,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha if (mQQSTileHeightAnimator == null) { mQQSTileHeightAnimator = new HeightExpansionAnimator(this, - quickTileView.getHeight(), tileView.getHeight()); - qqsTileHeight = quickTileView.getHeight(); + quickTileView.getMeasuredHeight(), tileView.getMeasuredHeight()); + qqsTileHeight = quickTileView.getMeasuredHeight(); } mQQSTileHeightAnimator.addView(quickTileView); @@ -380,7 +380,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha if (mOtherTilesExpandAnimator == null) { mOtherTilesExpandAnimator = new HeightExpansionAnimator( - this, qqsTileHeight, tileView.getHeight()); + this, qqsTileHeight, tileView.getMeasuredHeight()); } mOtherTilesExpandAnimator.addView(tileView); tileView.setClipChildren(true); @@ -658,7 +658,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mTranslateWhileExpanding = shouldTranslate; } - static class HeightExpansionAnimator { + private static class HeightExpansionAnimator { private final List mViews = new ArrayList<>(); private final ValueAnimator mAnimator; private final TouchAnimator.Listener mListener; @@ -673,9 +673,10 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha int height = (Integer) valueAnimator.getAnimatedValue(); for (int i = 0; i < viewCount; i++) { View v = mViews.get(i); - v.setBottom(v.getTop() + height); if (v instanceof HeightOverrideable) { ((HeightOverrideable) v).setHeightOverride(height); + } else { + v.setBottom(v.getTop() + height); } } if (t == 0f) { @@ -713,9 +714,10 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha final int viewsCount = mViews.size(); for (int i = 0; i < viewsCount; i++) { View v = mViews.get(i); - v.setBottom(v.getTop() + v.getMeasuredHeight()); if (v instanceof HeightOverrideable) { ((HeightOverrideable) v).resetOverride(); + } else { + v.setBottom(v.getTop() + v.getMeasuredHeight()); } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 8df13614e0d3e..0ce77352fc61b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -82,6 +82,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca private QSAnimator mQSAnimator; private HeightListener mPanelView; + private QSSquishinessController mQSSquishinessController; protected QuickStatusBarHeader mHeader; protected NonInterceptingScrollView mQSPanelScrollView; private QSDetail mQSDetail; @@ -91,6 +92,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca private QSFooter mFooter; private float mLastQSExpansion = -1; private float mLastPanelFraction; + private float mSquishinessFraction = 1; private boolean mQsDisabled; private ImageView mQsDragHandler; @@ -211,6 +213,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter, mFalsingManager); mQSAnimator = qsFragmentComponent.getQSAnimator(); + mQSSquishinessController = qsFragmentComponent.getQSSquishinessController(); mQSCustomizerController = qsFragmentComponent.getQSCustomizerController(); mQSCustomizerController.init(); @@ -232,7 +235,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca boolean sizeChanged = (oldTop - oldBottom) != (top - bottom); if (sizeChanged) { setQsExpansion(mLastQSExpansion, mLastPanelFraction, - mLastHeaderTranslation); + mLastHeaderTranslation, mSquishinessFraction); } }); mQSPanelController.setUsingHorizontalLayoutChangeListener( @@ -414,7 +417,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mQSAnimator.setShowCollapsedOnKeyguard(showCollapsed); } if (!showCollapsed && isKeyguardState()) { - setQsExpansion(mLastQSExpansion, mLastPanelFraction, 0); + setQsExpansion(mLastQSExpansion, mLastPanelFraction, 0, + mSquishinessFraction); } } } @@ -495,12 +499,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca updateShowCollapsedOnKeyguard(); } mFullShadeProgress = progress; - setQsExpansion(mLastQSExpansion, mLastPanelFraction, mLastHeaderTranslation); + setQsExpansion(mLastQSExpansion, mLastPanelFraction, mLastHeaderTranslation, + isTransitioningToFullShade ? progress : mSquishinessFraction); } @Override public void setQsExpansion(float expansion, float panelExpansionFraction, - float proposedTranslation) { + float proposedTranslation, float squishinessFraction) { float headerTranslation = mTransitioningToFullShade ? 0 : proposedTranslation; float progress = mTransitioningToFullShade ? mFullShadeProgress : panelExpansionFraction; setAlphaAnimationProgress(mInSplitShade ? progress : 1); @@ -518,11 +523,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca if (expansion == mLastQSExpansion && mLastKeyguardAndExpanded == onKeyguardAndExpanded && mLastViewHeight == currentHeight - && mLastHeaderTranslation == headerTranslation) { + && mLastHeaderTranslation == headerTranslation + && mSquishinessFraction == squishinessFraction) { return; } mLastHeaderTranslation = headerTranslation; mLastPanelFraction = panelExpansionFraction; + mSquishinessFraction = squishinessFraction; mLastQSExpansion = expansion; mLastKeyguardAndExpanded = onKeyguardAndExpanded; mLastViewHeight = currentHeight; @@ -558,6 +565,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca } updateQsBounds(); + if (mQSSquishinessController != null) { + mQSSquishinessController.setSquishiness(mSquishinessFraction); + } if (mQSAnimator != null) { mQSAnimator.setPosition(expansion); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 28aa884d6f9e1..2665f3ad98b3c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -735,6 +735,11 @@ public class QSPanel extends LinearLayout implements Tunable { /** */ void setListening(boolean listening, UiEventLogger uiEventLogger); + /** + * Sets a size modifier for the tile. Where 0 means collapsed, and 1 expanded. + */ + void setSquishinessFraction(float squishinessFraction); + /** * Sets the minimum number of rows to show * diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt b/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt new file mode 100644 index 0000000000000..6de837008d916 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt @@ -0,0 +1,64 @@ +package com.android.systemui.qs + +import android.view.ViewGroup +import com.android.systemui.qs.dagger.QSFragmentModule.QQS_FOOTER +import com.android.systemui.qs.dagger.QSScope +import com.android.systemui.qs.tileimpl.HeightOverrideable +import javax.inject.Inject +import javax.inject.Named + +@QSScope +class QSSquishinessController @Inject constructor( + private val qsTileHost: QSTileHost, + @Named(QQS_FOOTER) private val qqsFooterActionsView: FooterActionsView, + private val qsAnimator: QSAnimator, + private val quickQSPanelController: QuickQSPanelController +) { + + /** + * Fraction from 0 to 1, where 0 is collapsed and 1 expanded. + */ + var squishiness: Float = 1f + set(value) { + if (field == value) { + return + } + if ((field != 1f && value == 1f) || (field != 0f && value == 0f)) { + qsAnimator.requestAnimatorUpdate() + } + field = value + updateSquishiness() + } + + /** + * Change the height of all tiles and repositions their siblings. + */ + private fun updateSquishiness() { + // Start by updating the height of all tiles + for (tile in qsTileHost.tiles) { + val tileView = quickQSPanelController.getTileView(tile) + (tileView as? HeightOverrideable)?.let { + it.squishinessFraction = squishiness + } + } + + // Update tile positions in the layout + val tileLayout = quickQSPanelController.tileLayout as TileLayout + tileLayout.setSquishinessFraction(squishiness) + + // Calculate how much we should move the footer + val tileHeightOffset = tileLayout.height - tileLayout.tilesHeight + val footerTopMargin = (qqsFooterActionsView.layoutParams as ViewGroup.MarginLayoutParams) + .topMargin + val nextTop = tileLayout.bottom - tileHeightOffset + footerTopMargin + val amountMoved = nextTop - qqsFooterActionsView.top + + // Move the footer and other siblings (MediaPlayer) + (qqsFooterActionsView.parent as ViewGroup?)?.let { parent -> + val index = parent.indexOfChild(qqsFooterActionsView) + for (i in index until parent.childCount) { + parent.getChildAt(i).top += amountMoved + } + } + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java index 1a890a7ad07bb..ee5d5ffb961cf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -41,6 +41,8 @@ public class TileLayout extends ViewGroup implements QSTileLayout { private int mMinRows = 1; private int mMaxColumns = NO_MAX_COLUMNS; protected int mResourceColumns; + private float mSquishinessFraction = 1f; + private int mLastTileBottom; public TileLayout(Context context) { this(context, null); @@ -210,10 +212,11 @@ public class TileLayout extends ViewGroup implements QSTileLayout { return mMaxCellHeight; } - protected void layoutTileRecords(int numRecords) { + private void layoutTileRecords(int numRecords) { final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; int row = 0; int column = 0; + mLastTileBottom = 0; // Layout each QS tile. final int tilesToLayout = Math.min(numRecords, mRows * mColumns); @@ -228,7 +231,9 @@ public class TileLayout extends ViewGroup implements QSTileLayout { final int top = getRowTop(row); final int left = getColumnStart(isRtl ? mColumns - column - 1 : column); final int right = left + mCellWidth; - record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight()); + final int bottom = top + record.tileView.getMeasuredHeight(); + record.tileView.layout(left, top, right, bottom); + mLastTileBottom = bottom; } } @@ -238,7 +243,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } protected int getRowTop(int row) { - return row * (mCellHeight + mCellMarginVertical); + return (int) (row * (mCellHeight * mSquishinessFraction + mCellMarginVertical)); } protected int getColumnStart(int column) { @@ -264,4 +269,17 @@ public class TileLayout extends ViewGroup implements QSTileLayout { // up. return Math.max(mColumns * mRows, 1); } + + public int getTilesHeight() { + return mLastTileBottom + getPaddingBottom(); + } + + @Override + public void setSquishinessFraction(float squishinessFraction) { + if (Float.compare(mSquishinessFraction, squishinessFraction) == 0) { + return; + } + mSquishinessFraction = squishinessFraction; + layoutTileRecords(mRecords.size()); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java index 8cc05026e1f17..63cbc21ddf74f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java @@ -21,6 +21,7 @@ import com.android.systemui.qs.QSContainerImplController; import com.android.systemui.qs.QSFooter; import com.android.systemui.qs.QSFragment; import com.android.systemui.qs.QSPanelController; +import com.android.systemui.qs.QSSquishinessController; import com.android.systemui.qs.QuickQSPanelController; import com.android.systemui.qs.customize.QSCustomizerController; @@ -57,4 +58,7 @@ public interface QSFragmentComponent { /** Construct a {@link QSCustomizerController}. */ QSCustomizerController getQSCustomizerController(); + + /** Construct a {@link QSSquishinessController}. */ + QSSquishinessController getQSSquishinessController(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt index 866fa097d6fdf..61d68eceb961c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt @@ -21,9 +21,8 @@ interface HeightOverrideable { const val NO_OVERRIDE = -1 } - var heightOverride: Int + abstract var heightOverride: Int + abstract fun resetOverride() - fun resetOverride() { - heightOverride = NO_OVERRIDE - } + abstract var squishinessFraction: Float } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt index 222539d495268..36101c9e25874 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt @@ -68,6 +68,18 @@ open class QSTileViewImpl @JvmOverloads constructor( } override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE + set(value) { + if (field == value) return + field = value + updateHeight() + } + + override var squishinessFraction: Float = 1f + set(value) { + if (field == value) return + field = value + updateHeight() + } private val colorActive = Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorAccentPrimary) @@ -148,6 +160,11 @@ open class QSTileViewImpl @JvmOverloads constructor( updateResources() } + override fun resetOverride() { + heightOverride = HeightOverrideable.NO_OVERRIDE + updateHeight() + } + fun updateResources() { FontSizeUtils.updateFontSize(label, R.dimen.qs_tile_text_size) FontSizeUtils.updateFontSize(secondaryLabel, R.dimen.qs_tile_text_size) @@ -218,9 +235,17 @@ open class QSTileViewImpl @JvmOverloads constructor( override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { super.onLayout(changed, l, t, r, b) - if (heightOverride != HeightOverrideable.NO_OVERRIDE) { - bottom = top + heightOverride - } + updateHeight() + } + + private fun updateHeight() { + val actualHeight = (if (heightOverride != HeightOverrideable.NO_OVERRIDE) { + heightOverride + } else { + measuredHeight + } * squishinessFraction).toInt() + bottom = top + actualHeight + scrollY = (actualHeight - height) / 2 } override fun updateAccessibilityOrder(previousView: View?): View { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 7213b2fb46f93..58e44792571c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -664,6 +664,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable return 0f; } + public float getNotificationSquishinessFraction() { + return mStackScrollAlgorithm.getNotificationSquishinessFraction(mAmbientState); + } + void reinflateViews() { inflateFooterView(); inflateEmptyShadeView(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index b226aec88cd82..9923faeb8b5c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -1077,6 +1077,10 @@ public class NotificationStackScrollLayoutController { mView.setOnStackYChanged(onStackYChanged); } + public float getNotificationSquishinessFraction() { + return mView.getNotificationSquishinessFraction(); + } + public float calculateAppearFractionBypass() { return mView.calculateAppearFractionBypass(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index afe0bbafbd314..015edb8e55412 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -110,6 +110,15 @@ public class StackScrollAlgorithm { getNotificationChildrenStates(algorithmState, ambientState); } + /** + * How expanded or collapsed notifications are when pulling down the shade. + * @param ambientState Current ambient state. + * @return 0 when fully collapsed, 1 when expanded. + */ + public float getNotificationSquishinessFraction(AmbientState ambientState) { + return getExpansionFractionWithoutShelf(mTempAlgorithmState, ambientState); + } + private void resetChildViewStates() { int numChildren = mHostView.getChildCount(); for (int i = 0; i < numChildren; i++) { @@ -364,7 +373,6 @@ public class StackScrollAlgorithm { final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding; final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding; - return stackHeight / stackEndHeight; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 233acfe601a72..ffa8b119ef3b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -438,7 +438,6 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mPulsing; private boolean mUserSetupComplete; - private int mQsNotificationTopPadding; private boolean mHideIconsDuringLaunchAnimation = true; private int mStackScrollerMeasuringPass; private ArrayList> @@ -2218,7 +2217,8 @@ public class NotificationPanelViewController extends PanelViewController { private void updateQsExpansion() { if (mQs == null) return; float qsExpansionFraction = computeQsExpansionFraction(); - mQs.setQsExpansion(qsExpansionFraction, getExpandedFraction(), getHeaderTranslation()); + mQs.setQsExpansion(qsExpansionFraction, getExpandedFraction(), getHeaderTranslation(), + mNotificationStackScrollLayoutController.getNotificationSquishinessFraction()); mMediaHierarchyManager.setQsExpansion(qsExpansionFraction); int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction); mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt new file mode 100644 index 0000000000000..3059aa1ae6585 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt @@ -0,0 +1,62 @@ +package com.android.systemui.qs + +import android.testing.AndroidTestingRunner +import android.view.ViewGroup +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.qs.tileimpl.QSTileViewImpl +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.junit.MockitoJUnit + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class QSSquishinessControllerTest : SysuiTestCase() { + + @Mock private lateinit var qsTileHost: QSTileHost + @Mock private lateinit var qqsFooterActionsView: FooterActionsView + @Mock private lateinit var qqsFooterActionsViewLP: ViewGroup.MarginLayoutParams + @Mock private lateinit var qsAnimator: QSAnimator + @Mock private lateinit var quickQsPanelController: QuickQSPanelController + @Mock private lateinit var qstileView: QSTileViewImpl + @Mock private lateinit var qstile: QSTile + @Mock private lateinit var tileLayout: TileLayout + + @JvmField @Rule val mockitoRule = MockitoJUnit.rule() + + private lateinit var qsSquishinessController: QSSquishinessController + + @Before + fun setup() { + qsSquishinessController = QSSquishinessController(qsTileHost, qqsFooterActionsView, + qsAnimator, quickQsPanelController) + `when`(qsTileHost.tiles).thenReturn(mutableListOf(qstile)) + `when`(quickQsPanelController.getTileView(any())).thenReturn(qstileView) + `when`(quickQsPanelController.tileLayout).thenReturn(tileLayout) + `when`(qqsFooterActionsView.layoutParams).thenReturn(qqsFooterActionsViewLP) + } + + @Test + fun setSquishiness_requestsAnimatorUpdate() { + qsSquishinessController.squishiness = 0.5f + verify(qsAnimator, never()).requestAnimatorUpdate() + + qsSquishinessController.squishiness = 0f + verify(qsAnimator).requestAnimatorUpdate() + } + + @Test + fun setSquishiness_updatesTiles() { + qsSquishinessController.squishiness = 0.5f + verify(qstileView).squishinessFraction = 0.5f + verify(tileLayout).setSquishinessFraction(0.5f) + } +} \ No newline at end of file