Merge "fix QS header for new ConstraintLayout version" into tm-qpr-dev am: e291396eca

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20534469

Change-Id: I35a1869bf9a405dac33db770772069f47ae8ab9d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Nicolò Mazzucato
2022-12-05 18:16:31 +00:00
committed by Automerger Merge Worker
6 changed files with 59 additions and 57 deletions

View File

@@ -124,20 +124,9 @@
</KeyFrameSet> </KeyFrameSet>
</Transition> </Transition>
<Transition <Include app:constraintSet="@xml/large_screen_shade_header"/>
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/qs_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"/>
<ConstraintSet android:id="@id/qs_header_constraint"/>
<ConstraintSet android:id="@id/large_screen_header_constraint" />
<Include app:constraintSet="@xml/qqs_header"/>
</MotionScene> </MotionScene>

View File

@@ -59,7 +59,6 @@
<Layout <Layout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height" 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_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintStart_toEndOf="@id/date" app:layout_constraintStart_toEndOf="@id/date"
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon" app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
@@ -75,7 +74,6 @@
<Layout <Layout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height" 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_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintStart_toEndOf="@id/statusIcons" app:layout_constraintStart_toEndOf="@id/statusIcons"
app:layout_constraintEnd_toEndOf="@id/end_guide" app:layout_constraintEnd_toEndOf="@id/end_guide"
@@ -112,5 +110,4 @@
app:layout_constraintHorizontal_bias="1" app:layout_constraintHorizontal_bias="1"
/> />
</Constraint> </Constraint>
</ConstraintSet> </ConstraintSet>

View File

@@ -56,6 +56,7 @@
<Layout <Layout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height" android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/space" app:layout_constraintEnd_toStartOf="@id/space"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
@@ -88,7 +89,6 @@
<Layout <Layout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height" android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="@id/space" app:layout_constraintStart_toEndOf="@id/space"
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon" app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
app:layout_constraintTop_toTopOf="@id/date" app:layout_constraintTop_toTopOf="@id/date"

View File

@@ -46,7 +46,6 @@ import com.android.systemui.qs.carrier.QSCarrierGroup
import com.android.systemui.qs.carrier.QSCarrierGroupController import com.android.systemui.qs.carrier.QSCarrierGroupController
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID 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_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.QQS_HEADER_CONSTRAINT
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
@@ -73,11 +72,9 @@ import javax.inject.Named
* expansion of the headers in small screen portrait. * expansion of the headers in small screen portrait.
* *
* [header] will be a [MotionLayout] if [Flags.COMBINED_QS_HEADERS] is enabled. In this case, the * [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 * * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
* handheld device configuration. * handheld device configuration.
* * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] (to itself) for all
* other configurations
*/ */
@CentralSurfacesScope @CentralSurfacesScope
class LargeScreenShadeHeaderController @Inject constructor( class LargeScreenShadeHeaderController @Inject constructor(
@@ -104,8 +101,6 @@ class LargeScreenShadeHeaderController @Inject constructor(
@VisibleForTesting @VisibleForTesting
internal val HEADER_TRANSITION_ID = R.id.header_transition internal val HEADER_TRANSITION_ID = R.id.header_transition
@VisibleForTesting @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 internal val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
@VisibleForTesting @VisibleForTesting
internal val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint internal val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
@@ -120,10 +115,6 @@ class LargeScreenShadeHeaderController @Inject constructor(
} }
} }
init {
loadConstraints()
}
private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS) private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
private lateinit var iconManager: StatusBarIconController.TintedIconManager private lateinit var iconManager: StatusBarIconController.TintedIconManager
@@ -345,11 +336,11 @@ class LargeScreenShadeHeaderController @Inject constructor(
if (header is MotionLayout) { if (header is MotionLayout) {
// Use resources.getXml instead of passing the resource id due to bug b/205018300 // Use resources.getXml instead of passing the resource id due to bug b/205018300
header.getConstraintSet(QQS_HEADER_CONSTRAINT) 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) 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) 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))
} }
} }
@@ -438,7 +429,6 @@ class LargeScreenShadeHeaderController @Inject constructor(
} }
header as MotionLayout header as MotionLayout
if (largeScreenActive) { if (largeScreenActive) {
header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT).applyTo(header) header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT).applyTo(header)
} else { } else {
header.setTransition(HEADER_TRANSITION_ID) header.setTransition(HEADER_TRANSITION_ID)

View File

@@ -23,9 +23,11 @@ import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.google.common.truth.Expect
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before import org.junit.Before
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -37,6 +39,9 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
private lateinit var qsConstraint: ConstraintSet private lateinit var qsConstraint: ConstraintSet
private lateinit var largeScreenConstraint: ConstraintSet private lateinit var largeScreenConstraint: ConstraintSet
@get:Rule
val expect: Expect = Expect.create()
@Before @Before
fun setUp() { fun setUp() {
qqsConstraint = ConstraintSet().apply { qqsConstraint = ConstraintSet().apply {
@@ -343,6 +348,32 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
} }
} }
@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 @Test
fun testEmptyCutoutDateIconsAreConstrainedWidth() { fun testEmptyCutoutDateIconsAreConstrainedWidth() {
CombinedShadeHeadersConstraintManagerImpl.emptyCutoutConstraints()() CombinedShadeHeadersConstraintManagerImpl.emptyCutoutConstraints()()

View File

@@ -46,7 +46,6 @@ import com.android.systemui.qs.carrier.QSCarrierGroup
import com.android.systemui.qs.carrier.QSCarrierGroupController import com.android.systemui.qs.carrier.QSCarrierGroupController
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID 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_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.QQS_HEADER_CONSTRAINT
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
@@ -77,6 +76,7 @@ import org.mockito.Mockito.anyInt
import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.inOrder import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoJUnit
@@ -211,20 +211,6 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
context.getString(com.android.internal.R.string.status_bar_mobile)) context.getString(com.android.internal.R.string.status_bar_mobile))
} }
@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 @Test
fun testControllersCreatedAndInitialized() { fun testControllersCreatedAndInitialized() {
verify(variableDateViewController).init() verify(variableDateViewController).init()
@@ -286,16 +272,6 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
assertThat(viewVisibility).isEqualTo(View.INVISIBLE) assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
} }
@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 @Test
fun testLargeScreenActive_false() { fun testLargeScreenActive_false() {
controller.largeScreenActive = true // Make sure there's a change controller.largeScreenActive = true // Make sure there's a change
@@ -696,6 +672,25 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
verify(clock).pivotY = height.toFloat() / 2 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( private fun View.executeLayoutChange(
left: Int, left: Int,
top: Int, top: Int,