Merge "Fix incorrect QS paddings after relayout" into sc-v2-dev
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 71eb4a2..d69deef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -26,6 +26,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Gravity;
@@ -103,6 +104,8 @@
     protected LinearLayout mHorizontalContentContainer;
 
     protected QSTileLayout mTileLayout;
+    private float mSquishinessFraction = 1f;
+    private final ArrayMap<View, Integer> mChildrenLayoutTop = new ArrayMap<>();
 
     public QSPanel(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -179,10 +182,26 @@
         if (mTileLayout == null) {
             mTileLayout = (QSTileLayout) LayoutInflater.from(mContext)
                     .inflate(R.layout.qs_paged_tile_layout, this, false);
+            mTileLayout.setSquishinessFraction(mSquishinessFraction);
         }
         return mTileLayout;
     }
 
+    public void setSquishinessFraction(float squishinessFraction) {
+        if (Float.compare(squishinessFraction, mSquishinessFraction) == 0) {
+            return;
+        }
+        mSquishinessFraction = squishinessFraction;
+        if (mTileLayout == null) {
+            return;
+        }
+        mTileLayout.setSquishinessFraction(squishinessFraction);
+        if (getMeasuredWidth() == 0) {
+            return;
+        }
+        updateViewPositions();
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (mTileLayout instanceof PagedTileLayout) {
@@ -228,6 +247,39 @@
         setMeasuredDimension(getMeasuredWidth(), height);
     }
 
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            mChildrenLayoutTop.put(child, child.getTop());
+        }
+        updateViewPositions();
+    }
+
+    private void updateViewPositions() {
+        if (!(mTileLayout instanceof TileLayout)) {
+            return;
+        }
+        TileLayout layout = (TileLayout) mTileLayout;
+
+        // Adjust view positions based on tile squishing
+        int tileHeightOffset = layout.getTilesHeight() - layout.getHeight();
+
+        boolean move = false;
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (move) {
+                int top = mChildrenLayoutTop.get(child);
+                child.setLeftTopRightBottom(child.getLeft(), top + tileHeightOffset,
+                        child.getRight(), top + tileHeightOffset + child.getHeight());
+            }
+            if (child == mTileLayout) {
+                move = true;
+            }
+        }
+    }
+
     protected String getDumpableTag() {
         return TAG;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index f7d1b1e..eddc206 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -147,6 +147,10 @@
         return mMediaHost;
     }
 
+    public void setSquishinessFraction(float squishinessFraction) {
+        mView.setSquishinessFraction(squishinessFraction);
+    }
+
     @Override
     protected void onViewAttached() {
         mQsTileRevealController = createTileRevealController();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt b/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt
index c1c146d..c680cb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt
@@ -1,14 +1,10 @@
 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 javax.inject.Inject
-import javax.inject.Named
 
 @QSScope
 class QSSquishinessController @Inject constructor(
-    @Named(QQS_FOOTER) private val qqsFooterActionsView: FooterActionsView,
     private val qsAnimator: QSAnimator,
     private val qsPanelController: QSPanelController,
     private val quickQSPanelController: QuickQSPanelController
@@ -33,23 +29,7 @@
      * Change the height of all tiles and repositions their siblings.
      */
     private fun updateSquishiness() {
-        (qsPanelController.tileLayout as QSPanel.QSTileLayout).setSquishinessFraction(squishiness)
-        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
-            }
-        }
+        qsPanelController.setSquishinessFraction(squishiness)
+        quickQSPanelController.setSquishinessFraction(squishiness)
     }
 }
\ 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 2bd5c8f..9d60e63 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -247,7 +247,10 @@
         } else {
             measuredHeight
         }
-        bottom = top + (actualHeight * squishinessFraction).toInt()
+        // Limit how much we affect the height, so we don't have rounding artifacts when the tile
+        // is too short.
+        val constrainedSquishiness = 0.1f + squishinessFraction * 0.9f
+        bottom = top + (actualHeight * constrainedSquishiness).toInt()
         scrollY = (actualHeight - height) / 2
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt
index f41d7b1..e2a0626 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt
@@ -1,7 +1,6 @@
 package com.android.systemui.qs
 
 import android.testing.AndroidTestingRunner
-import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Before
@@ -9,7 +8,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
@@ -18,13 +16,9 @@
 @SmallTest
 class QSSquishinessControllerTest : SysuiTestCase() {
 
-    @Mock private lateinit var qqsFooterActionsView: FooterActionsView
-    @Mock private lateinit var qqsFooterActionsViewLP: ViewGroup.MarginLayoutParams
     @Mock private lateinit var qsAnimator: QSAnimator
     @Mock private lateinit var qsPanelController: QSPanelController
     @Mock private lateinit var quickQsPanelController: QuickQSPanelController
-    @Mock private lateinit var tileLayout: TileLayout
-    @Mock private lateinit var pagedTileLayout: PagedTileLayout
 
     @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
 
@@ -32,11 +26,8 @@
 
     @Before
     fun setup() {
-        qsSquishinessController = QSSquishinessController(qqsFooterActionsView, qsAnimator,
+        qsSquishinessController = QSSquishinessController(qsAnimator,
                 qsPanelController, quickQsPanelController)
-        `when`(quickQsPanelController.tileLayout).thenReturn(tileLayout)
-        `when`(qsPanelController.tileLayout).thenReturn(pagedTileLayout)
-        `when`(qqsFooterActionsView.layoutParams).thenReturn(qqsFooterActionsViewLP)
     }
 
     @Test
@@ -51,7 +42,7 @@
     @Test
     fun setSquishiness_updatesTiles() {
         qsSquishinessController.squishiness = 0.5f
-        verify(tileLayout).setSquishinessFraction(0.5f)
-        verify(pagedTileLayout).setSquishinessFraction(0.5f)
+        verify(qsPanelController).setSquishinessFraction(0.5f)
+        verify(quickQsPanelController).setSquishinessFraction(0.5f)
     }
 }
\ No newline at end of file