diff options
| author | 2023-05-03 10:58:37 +0000 | |
|---|---|---|
| committer | 2023-05-03 10:58:37 +0000 | |
| commit | 372ed2a84fcefaa53da4792625145f02030e69f7 (patch) | |
| tree | cc42ee400b10e7b5c9999b9f76d237fefd8fcb15 | |
| parent | 674e0b8a427d975772efcd6cd1086d086c77491e (diff) | |
| parent | 5d891f5f63b6a45e3deacd40fd57b929ece8e0e9 (diff) | |
Merge "Fix split_shade_status_bar height to avoid layout on each animation frame" into udc-dev am: 7db06f8503 am: 5d891f5f63
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22645423
Change-Id: Iaf1532c145b44acbd30e292c52e64f51f86840a8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
5 files changed, 132 insertions, 7 deletions
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml index 441f963a855a..386c9d66a0c1 100644 --- a/packages/SystemUI/res/layout/combined_qs_header.xml +++ b/packages/SystemUI/res/layout/combined_qs_header.xml @@ -14,12 +14,17 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + +<!-- +keep split_shade_status_bar height constant to avoid requestLayout calls on each +frame when animating QS <-> QQS transition +--> <com.android.systemui.util.NoRemeasureMotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/split_shade_status_bar" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/qs_header_height" android:minHeight="@dimen/large_screen_shade_header_min_height" android:clickable="false" android:focusable="true" @@ -30,6 +35,14 @@ app:layoutDescription="@xml/combined_qs_header_scene"> <androidx.constraintlayout.widget.Guideline + android:id="@+id/qqs_header_bottom_guideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_begin="@dimen/large_screen_shade_header_min_height" + /> + + <androidx.constraintlayout.widget.Guideline android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/begin_guide" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 0aa880fe6d88..aff0e8052739 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -615,6 +615,7 @@ <dimen name="qs_header_carrier_separator_width">6dp</dimen> <dimen name="qs_carrier_margin_width">4dp</dimen> <dimen name="qs_footer_icon_size">20dp</dimen> + <dimen name="qs_header_height">120dp</dimen> <dimen name="qs_header_row_min_height">48dp</dimen> <dimen name="qs_header_non_clickable_element_height">24dp</dimen> diff --git a/packages/SystemUI/res/xml/qqs_header.xml b/packages/SystemUI/res/xml/qqs_header.xml index 00a0444a1c9d..1950965fc298 100644 --- a/packages/SystemUI/res/xml/qqs_header.xml +++ b/packages/SystemUI/res/xml/qqs_header.xml @@ -28,7 +28,7 @@ android:layout_height="@dimen/large_screen_shade_header_min_height" app:layout_constraintStart_toStartOf="@id/begin_guide" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toBottomOf="@id/qqs_header_bottom_guideline" app:layout_constraintEnd_toStartOf="@id/date" app:layout_constraintHorizontal_bias="0" app:layout_constraintHorizontal_chainStyle="packed" @@ -62,7 +62,7 @@ app:layout_constraintStart_toEndOf="@id/date" app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toBottomOf="@id/qqs_header_bottom_guideline" app:layout_constraintHorizontal_bias="1" app:layout_constraintHorizontal_chainStyle="packed" /> @@ -77,7 +77,7 @@ app:layout_constraintStart_toEndOf="@id/statusIcons" app:layout_constraintEnd_toEndOf="@id/end_guide" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toBottomOf="@id/qqs_header_bottom_guideline" app:layout_constraintHorizontal_bias="1" app:layout_constraintHorizontal_chainStyle="packed" /> @@ -105,7 +105,7 @@ app:layout_constraintStart_toEndOf="@id/date" app:layout_constraintEnd_toEndOf="@id/end_guide" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toBottomOf="@id/qqs_header_bottom_guideline" app:layout_constraintHorizontal_bias="1" /> </Constraint> diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt index fb7c5c2e31fa..31b361f83758 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt @@ -18,7 +18,6 @@ package com.android.systemui.shade import android.view.View import android.view.ViewGroup -import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.WindowInsets import androidx.annotation.VisibleForTesting import androidx.constraintlayout.widget.ConstraintSet @@ -62,6 +61,7 @@ class NotificationsQSContainerController @Inject constructor( private var isQSCustomizing = false private var isQSCustomizerAnimating = false + private var shadeHeaderHeight = 0 private var largeScreenShadeHeaderHeight = 0 private var largeScreenShadeHeaderActive = false private var notificationsBottomMargin = 0 @@ -146,6 +146,8 @@ class NotificationsQSContainerController @Inject constructor( R.dimen.notification_panel_margin_bottom) largeScreenShadeHeaderHeight = resources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height) + shadeHeaderHeight = + resources.getDimensionPixelSize(R.dimen.qs_header_height) panelMarginHorizontal = resources.getDimensionPixelSize( R.dimen.notification_panel_margin_horizontal) topMargin = if (largeScreenShadeHeaderActive) { @@ -245,7 +247,7 @@ class NotificationsQSContainerController @Inject constructor( if (largeScreenShadeHeaderActive) { constraintSet.constrainHeight(R.id.split_shade_status_bar, largeScreenShadeHeaderHeight) } else { - constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT) + constraintSet.constrainHeight(R.id.split_shade_status_bar, shadeHeaderHeight) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt new file mode 100644 index 000000000000..d4751c86a87f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.testing.TestableResources +import androidx.constraintlayout.widget.ConstraintSet +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.fragments.FragmentService +import com.android.systemui.navigationbar.NavigationModeController +import com.android.systemui.recents.OverviewProxyService +import com.android.systemui.util.concurrency.DelayableExecutor +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +@SmallTest +class NotificationsQSContainerControllerTest : SysuiTestCase() { + + @Mock lateinit var view: NotificationsQuickSettingsContainer + @Mock lateinit var navigationModeController: NavigationModeController + @Mock lateinit var overviewProxyService: OverviewProxyService + @Mock lateinit var shadeHeaderController: ShadeHeaderController + @Mock lateinit var shadeExpansionStateManager: ShadeExpansionStateManager + @Mock lateinit var fragmentService: FragmentService + + lateinit var underTest: NotificationsQSContainerController + + private lateinit var fakeResources: TestableResources + + private val delayableExecutor: DelayableExecutor = FakeExecutor(FakeSystemClock()) + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + fakeResources = TestableResources(context.resources) + + whenever(view.resources).thenReturn(fakeResources.resources) + + underTest = + NotificationsQSContainerController( + view, + navigationModeController, + overviewProxyService, + shadeHeaderController, + shadeExpansionStateManager, + fragmentService, + delayableExecutor, + ) + } + + @Test + fun testSmallScreen_updateResources_splitShadeHeightIsSet() { + with(fakeResources) { + addOverride(R.bool.config_use_large_screen_shade_header, false) + addOverride(R.dimen.qs_header_height, 1) + addOverride(R.dimen.large_screen_shade_header_height, 2) + } + + underTest.updateResources() + + val captor = ArgumentCaptor.forClass(ConstraintSet::class.java) + verify(view).applyConstraints(capture(captor)) + assertThat(captor.value.getHeight(R.id.split_shade_status_bar)).isEqualTo(1) + } + + @Test + fun testLargeScreen_updateResources_splitShadeHeightIsSet() { + with(fakeResources) { + addOverride(R.bool.config_use_large_screen_shade_header, true) + addOverride(R.dimen.qs_header_height, 1) + addOverride(R.dimen.large_screen_shade_header_height, 2) + } + + underTest.updateResources() + + val captor = ArgumentCaptor.forClass(ConstraintSet::class.java) + verify(view).applyConstraints(capture(captor)) + assertThat(captor.value.getHeight(R.id.split_shade_status_bar)).isEqualTo(2) + } +} |