diff options
| author | 2024-06-27 16:53:27 +0000 | |
|---|---|---|
| committer | 2024-06-27 16:53:27 +0000 | |
| commit | 244eacae86ca69f60a3d7064f25901de312942a5 (patch) | |
| tree | 233eb15a2aba652a5e90a54c4eddd3a1ad95c93b | |
| parent | f122915f3a02277aa695a4a73452d8d33ed51042 (diff) | |
| parent | 828dd91d49bf390026f5a4f12806f221f7da83af (diff) | |
Merge "[Flexiglass] Fix brightness mirror" into main
7 files changed, 103 insertions, 47 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt index 73a624a030fe..aca473d8eabc 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt @@ -18,8 +18,9 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -39,6 +40,7 @@ fun BrightnessMirror( viewModel: BrightnessMirrorViewModel, qsSceneAdapter: QSSceneAdapter, modifier: Modifier = Modifier, + measureFromContainer: Boolean = false, ) { val isShowing by viewModel.isShowing.collectAsStateWithLifecycle() val mirrorAlpha by @@ -47,9 +49,22 @@ fun BrightnessMirror( label = "alphaAnimationBrightnessMirrorShowing", ) val mirrorOffsetAndSize by viewModel.locationAndSize.collectAsStateWithLifecycle() - val offset = IntOffset(0, mirrorOffsetAndSize.yOffset) + val yOffset = + if (measureFromContainer) { + mirrorOffsetAndSize.yOffsetFromContainer + } else { + mirrorOffsetAndSize.yOffsetFromWindow + } + val offset = IntOffset(0, yOffset) - Box(modifier = modifier.fillMaxSize().graphicsLayer { alpha = mirrorAlpha }) { + // Use unbounded=true as the full mirror (with paddings and background offset) may be larger + // than the space we have (but it will fit, because the brightness slider fits). + Box( + modifier = + modifier.fillMaxHeight().wrapContentWidth(unbounded = true).graphicsLayer { + alpha = mirrorAlpha + } + ) { QuickSettingsTheme { // The assumption for using this AndroidView is that there will be only one in view at // a given time (which is a reasonable assumption). Because `QSSceneAdapter` (actually diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt index 0b57151e971d..2d5d25913074 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt @@ -185,7 +185,11 @@ private fun SceneScope.QuickSettingsScene( BrightnessMirror( viewModel = viewModel.brightnessMirrorViewModel, - qsSceneAdapter = viewModel.qsSceneAdapter + qsSceneAdapter = viewModel.qsSceneAdapter, + modifier = + Modifier.thenIf(cutoutLocation != CutoutLocation.CENTER) { + Modifier.displayCutoutPadding() + } ) val shouldPunchHoleBehindScrim = diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt index edef5fb2760a..3d6362eb1b62 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt @@ -36,7 +36,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -474,9 +473,9 @@ private fun SceneScope.SplitShade( BrightnessMirror( viewModel = viewModel.brightnessMirrorViewModel, qsSceneAdapter = viewModel.qsSceneAdapter, - // Need to remove the offset of the header height, as the mirror uses - // the position of the Brightness slider in the window - modifier = Modifier.offset(y = -ShadeHeader.Dimensions.CollapsedHeight) + // Need to use the offset measured from the container as the header + // has to be accounted for + measureFromContainer = true ) Column( verticalArrangement = Arrangement.Top, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt index 6de7f403a745..13b61bcae6ce 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt @@ -68,4 +68,27 @@ class BrightnessMirrorInflaterTest : SysuiTestCase() { Assert.setTestThread(null) } + + @Test + fun inflate_frameHasPadding() { + Assert.setTestThread(Thread.currentThread()) + + val (frame, _) = + BrightnessMirrorInflater.inflate( + themedContext, + kosmos.brightnessSliderControllerFactory, + ) + + assertThat(frame.visibility).isEqualTo(View.VISIBLE) + + val padding = + context.resources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding) + + assertThat(frame.paddingLeft).isEqualTo(padding) + assertThat(frame.paddingTop).isEqualTo(padding) + assertThat(frame.paddingRight).isEqualTo(padding) + assertThat(frame.paddingBottom).isEqualTo(padding) + + Assert.setTestThread(null) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt index 09fc6f9ad96d..90c11d466f80 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt @@ -16,10 +16,9 @@ package com.android.systemui.settings.brightness.ui.viewmodel -import android.content.applicationContext import android.content.res.mainResources -import android.view.ContextThemeWrapper import android.view.View +import android.widget.FrameLayout import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -27,12 +26,10 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor -import com.android.systemui.settings.brightness.ui.binder.BrightnessMirrorInflater import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize import com.android.systemui.settings.brightnessSliderControllerFactory import com.android.systemui.testKosmos -import com.android.systemui.util.Assert import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -47,9 +44,6 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() - private val themedContext = - ContextThemeWrapper(kosmos.applicationContext, R.style.Theme_SystemUI_QuickSettings) - private val underTest = with(kosmos) { BrightnessMirrorViewModel( @@ -76,7 +70,7 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { } @Test - fun setLocationInWindow_correctLocationAndSize() = + fun locationInWindowAndContainer_correctLocationAndSize() = with(kosmos) { testScope.runTest { val locationAndSize by collectLastValue(underTest.locationAndSize) @@ -101,6 +95,7 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { whenever(measuredHeight).thenReturn(height) whenever(measuredWidth).thenReturn(width) } + val yOffsetFromContainer = setContainerViewHierarchy(mockView) underTest.setLocationAndSize(mockView) @@ -108,7 +103,8 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { .isEqualTo( // Adjust for padding around the view LocationAndSize( - yOffset = y - padding, + yOffsetFromWindow = y - padding, + yOffsetFromContainer = yOffsetFromContainer - padding, width = width + 2 * padding, height = height + 2 * padding, ) @@ -116,31 +112,20 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { } } - @Test - fun setLocationInWindow_paddingSetToRootView() = - with(kosmos) { - Assert.setTestThread(Thread.currentThread()) - val padding = - mainResources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding) - - val view = mock<View>() - - val (_, sliderController) = - BrightnessMirrorInflater.inflate( - themedContext, - brightnessSliderControllerFactory, - ) - underTest.setToggleSlider(sliderController) - - underTest.setLocationAndSize(view) - - with(sliderController.rootView) { - assertThat(paddingBottom).isEqualTo(padding) - assertThat(paddingTop).isEqualTo(padding) - assertThat(paddingLeft).isEqualTo(padding) - assertThat(paddingRight).isEqualTo(padding) - } + private fun setContainerViewHierarchy(mockView: View): Int { + val rootView = FrameLayout(context) + val containerView = FrameLayout(context).apply { id = R.id.quick_settings_container } + val otherView = FrameLayout(context) - Assert.setTestThread(null) - } + rootView.addView(containerView) + containerView.addView(otherView) + otherView.addView(mockView) + + containerView.setLeftTopRightBottom(1, /* top= */ 1, 1, 1) + otherView.setLeftTopRightBottom(0, /* top= */ 2, 0, 0) + whenever(mockView.parent).thenReturn(otherView) + whenever(mockView.top).thenReturn(3) + + return 2 + 3 + } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt index 468a87325507..cebc59bdd94b 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt @@ -21,6 +21,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.core.view.setPadding import com.android.systemui.res.R import com.android.systemui.settings.brightness.BrightnessSliderController @@ -33,7 +34,15 @@ object BrightnessMirrorInflater { val frame = (LayoutInflater.from(context).inflate(R.layout.brightness_mirror_container, null) as ViewGroup) - .apply { isVisible = true } + .apply { + isVisible = true + // Match BrightnessMirrorController padding + setPadding( + context.resources.getDimensionPixelSize( + R.dimen.rounded_slider_background_padding + ) + ) + } val sliderController = sliderControllerFactory.create(context, frame) sliderController.init() frame.addView( diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt index 2651a994bb55..79e8b879288e 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt @@ -17,6 +17,7 @@ package com.android.systemui.settings.brightness.ui.viewModel import android.content.res.Resources +import android.util.Log import android.view.View import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main @@ -67,25 +68,45 @@ constructor( override fun setLocationAndSize(view: View) { view.getLocationInWindow(tempPosition) val padding = resources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding) - _toggleSlider?.rootView?.setPadding(padding, padding, padding, padding) // Account for desired padding _locationAndSize.value = LocationAndSize( - yOffset = tempPosition[1] - padding, + yOffsetFromContainer = view.findTopFromContainer() - padding, + yOffsetFromWindow = tempPosition[1] - padding, width = view.measuredWidth + 2 * padding, height = view.measuredHeight + 2 * padding, ) } + private fun View.findTopFromContainer(): Int { + var out = 0 + var view = this + while (view.id != R.id.quick_settings_container) { + out += view.top + val parent = view.parent as? View + if (parent == null) { + Log.wtf(TAG, "Couldn't find container in parents of $this") + break + } + view = parent + } + return out + } + // Callbacks are used for indicating reinflation when the config changes in some ways (like // density). However, we don't need that as we recompose the view anyway override fun addCallback(listener: MirrorController.BrightnessMirrorListener) {} override fun removeCallback(listener: MirrorController.BrightnessMirrorListener) {} + + companion object { + private const val TAG = "BrightnessMirrorViewModel" + } } data class LocationAndSize( - val yOffset: Int = 0, + val yOffsetFromContainer: Int = 0, + val yOffsetFromWindow: Int = 0, val width: Int = 0, val height: Int = 0, ) |