fix QS header for new ConstraintLayout version

With new ConstraintLayout versions layout_constrainedWidth was causing the view to assume match_parent width.

As MotionScene supports importing external layouts, we're not loading them at runtime anymore.

Also, the transition for large_screen_header_constraint is not used anymore, as initial and final constraint were the same.

Bug: 259933125
Test: CombinedShadeHeaderConstraintsTest and manual
Change-Id: I3961d9f4311c96b5d0663e1700fca78be5e6544b
diff --git a/packages/SystemUI/res/xml/combined_qs_header_scene.xml b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
index de855e2..c32de70 100644
--- a/packages/SystemUI/res/xml/combined_qs_header_scene.xml
+++ b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
@@ -124,20 +124,9 @@
         </KeyFrameSet>
     </Transition>
 
-    <Transition
-        android:id="@+id/large_screen_header_transition"
-        app:constraintSetStart="@id/large_screen_header_constraint"
-        app:constraintSetEnd="@id/large_screen_header_constraint"/>
+    <Include app:constraintSet="@xml/large_screen_shade_header"/>
 
-    <!--
-        Placeholder ConstraintSet. They are populated in the controller for this class.
-        This is needed because there's no easy way to just refer to a `ConstraintSet` file. The
-        options are either a layout file or inline the ConstraintSets.
-     -->
-    <ConstraintSet android:id="@id/qqs_header_constraint"/>
+    <Include app:constraintSet="@xml/qs_header"/>
 
-    <ConstraintSet android:id="@id/qs_header_constraint"/>
-
-    <ConstraintSet android:id="@id/large_screen_header_constraint" />
-
+    <Include app:constraintSet="@xml/qqs_header"/>
 </MotionScene>
diff --git a/packages/SystemUI/res/xml/qqs_header.xml b/packages/SystemUI/res/xml/qqs_header.xml
index 5d3650c..e56e5d5 100644
--- a/packages/SystemUI/res/xml/qqs_header.xml
+++ b/packages/SystemUI/res/xml/qqs_header.xml
@@ -59,7 +59,6 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
-            app:layout_constrainedWidth="true"
             app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
             app:layout_constraintStart_toEndOf="@id/date"
             app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
@@ -75,7 +74,6 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
-            app:layout_constrainedWidth="true"
             app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
             app:layout_constraintStart_toEndOf="@id/statusIcons"
             app:layout_constraintEnd_toEndOf="@id/end_guide"
@@ -112,5 +110,4 @@
             app:layout_constraintHorizontal_bias="1"
         />
     </Constraint>
-
 </ConstraintSet>
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/qs_header.xml b/packages/SystemUI/res/xml/qs_header.xml
index 982c422..eca2b2a 100644
--- a/packages/SystemUI/res/xml/qs_header.xml
+++ b/packages/SystemUI/res/xml/qs_header.xml
@@ -56,6 +56,7 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
+            app:layout_constrainedWidth="true"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintEnd_toStartOf="@id/space"
             app:layout_constraintBottom_toBottomOf="parent"
@@ -88,7 +89,6 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
-            app:layout_constrainedWidth="true"
             app:layout_constraintStart_toEndOf="@id/space"
             app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
             app:layout_constraintTop_toTopOf="@id/date"
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
index 31e4464..f24c6a1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -43,7 +43,6 @@
 import com.android.systemui.qs.carrier.QSCarrierGroupController
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
@@ -69,11 +68,9 @@
  * expansion of the headers in small screen portrait.
  *
  * [header] will be a [MotionLayout] if [Flags.COMBINED_QS_HEADERS] is enabled. In this case, the
- * [MotionLayout] has 2 transitions:
+ * [MotionLayout] has one transitions:
  * * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
  *   handheld device configuration.
- * * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] (to itself) for all
- *   other configurations
  */
 @CentralSurfacesScope
 class LargeScreenShadeHeaderController @Inject constructor(
@@ -99,8 +96,6 @@
         @VisibleForTesting
         internal val HEADER_TRANSITION_ID = R.id.header_transition
         @VisibleForTesting
-        internal val LARGE_SCREEN_HEADER_TRANSITION_ID = R.id.large_screen_header_transition
-        @VisibleForTesting
         internal val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
         @VisibleForTesting
         internal val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
@@ -115,10 +110,6 @@
         }
     }
 
-    init {
-        loadConstraints()
-    }
-
     private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
 
     private lateinit var iconManager: StatusBarIconController.TintedIconManager
@@ -330,11 +321,11 @@
         if (header is MotionLayout) {
             // Use resources.getXml instead of passing the resource id due to bug b/205018300
             header.getConstraintSet(QQS_HEADER_CONSTRAINT)
-                .load(context, resources.getXml(R.xml.qqs_header))
+                    .load(context, resources.getXml(R.xml.qqs_header))
             header.getConstraintSet(QS_HEADER_CONSTRAINT)
-                .load(context, resources.getXml(R.xml.qs_header))
+                    .load(context, resources.getXml(R.xml.qs_header))
             header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT)
-                .load(context, resources.getXml(R.xml.large_screen_shade_header))
+                    .load(context, resources.getXml(R.xml.large_screen_shade_header))
         }
     }
 
@@ -423,7 +414,6 @@
         }
         header as MotionLayout
         if (largeScreenActive) {
-            header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
             header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT).applyTo(header)
         } else {
             header.setTransition(HEADER_TRANSITION_ID)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 9c36be6..88651c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -23,9 +23,11 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -37,6 +39,9 @@
     private lateinit var qsConstraint: ConstraintSet
     private lateinit var largeScreenConstraint: ConstraintSet
 
+    @get:Rule
+    val expect: Expect = Expect.create()
+
     @Before
     fun setUp() {
         qqsConstraint = ConstraintSet().apply {
@@ -344,6 +349,32 @@
     }
 
     @Test
+    fun testCheckViewsDontChangeSizeBetweenAnimationConstraints() {
+        val views = mapOf(
+                R.id.clock to "clock",
+                R.id.date to "date",
+                R.id.statusIcons to "icons",
+                R.id.privacy_container to "privacy",
+                R.id.carrier_group to "carriers",
+                R.id.batteryRemainingIcon to "battery",
+        )
+        views.forEach { (id, name) ->
+            expect.withMessage("$name changes height")
+                    .that(qqsConstraint.getConstraint(id).layout.mHeight.fromConstraint())
+                    .isEqualTo(qsConstraint.getConstraint(id).layout.mHeight.fromConstraint())
+            expect.withMessage("$name changes width")
+                    .that(qqsConstraint.getConstraint(id).layout.mWidth.fromConstraint())
+                    .isEqualTo(qsConstraint.getConstraint(id).layout.mWidth.fromConstraint())
+        }
+    }
+
+    private fun Int.fromConstraint() = when (this) {
+        -1 -> "MATCH_PARENT"
+        -2 -> "WRAP_CONTENT"
+        else -> toString()
+    }
+
+    @Test
     fun testEmptyCutoutDateIconsAreConstrainedWidth() {
         CombinedShadeHeadersConstraintManagerImpl.emptyCutoutConstraints()()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
index e1007fa..7575e93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.qs.carrier.QSCarrierGroupController
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
 import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
@@ -73,6 +72,7 @@
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
@@ -204,20 +204,6 @@
     }
 
     @Test
-    fun testCorrectConstraints() {
-        val captor = ArgumentCaptor.forClass(XmlResourceParser::class.java)
-
-        verify(qqsConstraints).load(eq(context), capture(captor))
-        assertThat(captor.value.getResId()).isEqualTo(R.xml.qqs_header)
-
-        verify(qsConstraints).load(eq(context), capture(captor))
-        assertThat(captor.value.getResId()).isEqualTo(R.xml.qs_header)
-
-        verify(largeScreenConstraints).load(eq(context), capture(captor))
-        assertThat(captor.value.getResId()).isEqualTo(R.xml.large_screen_shade_header)
-    }
-
-    @Test
     fun testControllersCreatedAndInitialized() {
         verify(variableDateViewController).init()
 
@@ -279,16 +265,6 @@
     }
 
     @Test
-    fun testLargeScreenActive_true() {
-        controller.largeScreenActive = false // Make sure there's a change
-        clearInvocations(view)
-
-        controller.largeScreenActive = true
-
-        verify(view).setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
-    }
-
-    @Test
     fun testLargeScreenActive_false() {
         controller.largeScreenActive = true // Make sure there's a change
         clearInvocations(view)
@@ -673,6 +649,25 @@
         verify(clock).pivotY = height.toFloat() / 2
     }
 
+    @Test
+    fun onDensityOrFontScaleChanged_reloadConstraints() {
+        // After density or font scale change, constraints need to be reloaded to reflect new
+        // dimensions.
+        reset(qqsConstraints)
+        reset(qsConstraints)
+        reset(largeScreenConstraints)
+
+        configurationController.notifyDensityOrFontScaleChanged()
+
+        val captor = ArgumentCaptor.forClass(XmlResourceParser::class.java)
+        verify(qqsConstraints).load(eq(context), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.qqs_header)
+        verify(qsConstraints).load(eq(context), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.qs_header)
+        verify(largeScreenConstraints).load(eq(context), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.large_screen_shade_header)
+    }
+
     private fun View.executeLayoutChange(
             left: Int,
             top: Int,