Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt +18 −3 Original line number Original line Diff line number Diff line Loading @@ -18,8 +18,9 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box 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.offset import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment Loading @@ -39,6 +40,7 @@ fun BrightnessMirror( viewModel: BrightnessMirrorViewModel, viewModel: BrightnessMirrorViewModel, qsSceneAdapter: QSSceneAdapter, qsSceneAdapter: QSSceneAdapter, modifier: Modifier = Modifier, modifier: Modifier = Modifier, measureFromContainer: Boolean = false, ) { ) { val isShowing by viewModel.isShowing.collectAsStateWithLifecycle() val isShowing by viewModel.isShowing.collectAsStateWithLifecycle() val mirrorAlpha by val mirrorAlpha by Loading @@ -47,9 +49,22 @@ fun BrightnessMirror( label = "alphaAnimationBrightnessMirrorShowing", label = "alphaAnimationBrightnessMirrorShowing", ) ) val mirrorOffsetAndSize by viewModel.locationAndSize.collectAsStateWithLifecycle() 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 { QuickSettingsTheme { // The assumption for using this AndroidView is that there will be only one in view at // 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 // a given time (which is a reasonable assumption). Because `QSSceneAdapter` (actually Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +5 −1 Original line number Original line Diff line number Diff line Loading @@ -185,7 +185,11 @@ private fun SceneScope.QuickSettingsScene( BrightnessMirror( BrightnessMirror( viewModel = viewModel.brightnessMirrorViewModel, viewModel = viewModel.brightnessMirrorViewModel, qsSceneAdapter = viewModel.qsSceneAdapter qsSceneAdapter = viewModel.qsSceneAdapter, modifier = Modifier.thenIf(cutoutLocation != CutoutLocation.CENTER) { Modifier.displayCutoutPadding() } ) ) val shouldPunchHoleBehindScrim = val shouldPunchHoleBehindScrim = Loading packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +3 −4 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape Loading Loading @@ -474,9 +473,9 @@ private fun SceneScope.SplitShade( BrightnessMirror( BrightnessMirror( viewModel = viewModel.brightnessMirrorViewModel, viewModel = viewModel.brightnessMirrorViewModel, qsSceneAdapter = viewModel.qsSceneAdapter, qsSceneAdapter = viewModel.qsSceneAdapter, // Need to remove the offset of the header height, as the mirror uses // Need to use the offset measured from the container as the header // the position of the Brightness slider in the window // has to be accounted for modifier = Modifier.offset(y = -ShadeHeader.Dimensions.CollapsedHeight) measureFromContainer = true ) ) Column( Column( verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top, Loading packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt +23 −0 Original line number Original line Diff line number Diff line Loading @@ -68,4 +68,27 @@ class BrightnessMirrorInflaterTest : SysuiTestCase() { Assert.setTestThread(null) 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) } } } packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt +20 −35 Original line number Original line Diff line number Diff line Loading @@ -16,10 +16,9 @@ package com.android.systemui.settings.brightness.ui.viewmodel package com.android.systemui.settings.brightness.ui.viewmodel import android.content.applicationContext import android.content.res.mainResources import android.content.res.mainResources import android.view.ContextThemeWrapper import android.view.View import android.view.View import android.widget.FrameLayout import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase Loading @@ -27,12 +26,10 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.res.R import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor 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.BrightnessMirrorViewModel import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize import com.android.systemui.settings.brightnessSliderControllerFactory import com.android.systemui.settings.brightnessSliderControllerFactory import com.android.systemui.testKosmos import com.android.systemui.testKosmos import com.android.systemui.util.Assert import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever Loading @@ -47,9 +44,6 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos() private val themedContext = ContextThemeWrapper(kosmos.applicationContext, R.style.Theme_SystemUI_QuickSettings) private val underTest = private val underTest = with(kosmos) { with(kosmos) { BrightnessMirrorViewModel( BrightnessMirrorViewModel( Loading @@ -76,7 +70,7 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { } } @Test @Test fun setLocationInWindow_correctLocationAndSize() = fun locationInWindowAndContainer_correctLocationAndSize() = with(kosmos) { with(kosmos) { testScope.runTest { testScope.runTest { val locationAndSize by collectLastValue(underTest.locationAndSize) val locationAndSize by collectLastValue(underTest.locationAndSize) Loading @@ -101,6 +95,7 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { whenever(measuredHeight).thenReturn(height) whenever(measuredHeight).thenReturn(height) whenever(measuredWidth).thenReturn(width) whenever(measuredWidth).thenReturn(width) } } val yOffsetFromContainer = setContainerViewHierarchy(mockView) underTest.setLocationAndSize(mockView) underTest.setLocationAndSize(mockView) Loading @@ -108,7 +103,8 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { .isEqualTo( .isEqualTo( // Adjust for padding around the view // Adjust for padding around the view LocationAndSize( LocationAndSize( yOffset = y - padding, yOffsetFromWindow = y - padding, yOffsetFromContainer = yOffsetFromContainer - padding, width = width + 2 * padding, width = width + 2 * padding, height = height + 2 * padding, height = height + 2 * padding, ) ) Loading @@ -116,31 +112,20 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { } } } } @Test private fun setContainerViewHierarchy(mockView: View): Int { fun setLocationInWindow_paddingSetToRootView() = val rootView = FrameLayout(context) with(kosmos) { val containerView = FrameLayout(context).apply { id = R.id.quick_settings_container } Assert.setTestThread(Thread.currentThread()) val otherView = FrameLayout(context) val padding = mainResources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding) val view = mock<View>() val (_, sliderController) = rootView.addView(containerView) BrightnessMirrorInflater.inflate( containerView.addView(otherView) themedContext, otherView.addView(mockView) brightnessSliderControllerFactory, ) underTest.setToggleSlider(sliderController) underTest.setLocationAndSize(view) containerView.setLeftTopRightBottom(1, /* top= */ 1, 1, 1) otherView.setLeftTopRightBottom(0, /* top= */ 2, 0, 0) with(sliderController.rootView) { whenever(mockView.parent).thenReturn(otherView) assertThat(paddingBottom).isEqualTo(padding) whenever(mockView.top).thenReturn(3) assertThat(paddingTop).isEqualTo(padding) assertThat(paddingLeft).isEqualTo(padding) assertThat(paddingRight).isEqualTo(padding) } Assert.setTestThread(null) return 2 + 3 } } } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt +18 −3 Original line number Original line Diff line number Diff line Loading @@ -18,8 +18,9 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box 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.offset import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment Loading @@ -39,6 +40,7 @@ fun BrightnessMirror( viewModel: BrightnessMirrorViewModel, viewModel: BrightnessMirrorViewModel, qsSceneAdapter: QSSceneAdapter, qsSceneAdapter: QSSceneAdapter, modifier: Modifier = Modifier, modifier: Modifier = Modifier, measureFromContainer: Boolean = false, ) { ) { val isShowing by viewModel.isShowing.collectAsStateWithLifecycle() val isShowing by viewModel.isShowing.collectAsStateWithLifecycle() val mirrorAlpha by val mirrorAlpha by Loading @@ -47,9 +49,22 @@ fun BrightnessMirror( label = "alphaAnimationBrightnessMirrorShowing", label = "alphaAnimationBrightnessMirrorShowing", ) ) val mirrorOffsetAndSize by viewModel.locationAndSize.collectAsStateWithLifecycle() 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 { QuickSettingsTheme { // The assumption for using this AndroidView is that there will be only one in view at // 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 // a given time (which is a reasonable assumption). Because `QSSceneAdapter` (actually Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +5 −1 Original line number Original line Diff line number Diff line Loading @@ -185,7 +185,11 @@ private fun SceneScope.QuickSettingsScene( BrightnessMirror( BrightnessMirror( viewModel = viewModel.brightnessMirrorViewModel, viewModel = viewModel.brightnessMirrorViewModel, qsSceneAdapter = viewModel.qsSceneAdapter qsSceneAdapter = viewModel.qsSceneAdapter, modifier = Modifier.thenIf(cutoutLocation != CutoutLocation.CENTER) { Modifier.displayCutoutPadding() } ) ) val shouldPunchHoleBehindScrim = val shouldPunchHoleBehindScrim = Loading
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +3 −4 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape Loading Loading @@ -474,9 +473,9 @@ private fun SceneScope.SplitShade( BrightnessMirror( BrightnessMirror( viewModel = viewModel.brightnessMirrorViewModel, viewModel = viewModel.brightnessMirrorViewModel, qsSceneAdapter = viewModel.qsSceneAdapter, qsSceneAdapter = viewModel.qsSceneAdapter, // Need to remove the offset of the header height, as the mirror uses // Need to use the offset measured from the container as the header // the position of the Brightness slider in the window // has to be accounted for modifier = Modifier.offset(y = -ShadeHeader.Dimensions.CollapsedHeight) measureFromContainer = true ) ) Column( Column( verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top, Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt +23 −0 Original line number Original line Diff line number Diff line Loading @@ -68,4 +68,27 @@ class BrightnessMirrorInflaterTest : SysuiTestCase() { Assert.setTestThread(null) 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) } } }
packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt +20 −35 Original line number Original line Diff line number Diff line Loading @@ -16,10 +16,9 @@ package com.android.systemui.settings.brightness.ui.viewmodel package com.android.systemui.settings.brightness.ui.viewmodel import android.content.applicationContext import android.content.res.mainResources import android.content.res.mainResources import android.view.ContextThemeWrapper import android.view.View import android.view.View import android.widget.FrameLayout import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase Loading @@ -27,12 +26,10 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.res.R import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor 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.BrightnessMirrorViewModel import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize import com.android.systemui.settings.brightnessSliderControllerFactory import com.android.systemui.settings.brightnessSliderControllerFactory import com.android.systemui.testKosmos import com.android.systemui.testKosmos import com.android.systemui.util.Assert import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever Loading @@ -47,9 +44,6 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos() private val themedContext = ContextThemeWrapper(kosmos.applicationContext, R.style.Theme_SystemUI_QuickSettings) private val underTest = private val underTest = with(kosmos) { with(kosmos) { BrightnessMirrorViewModel( BrightnessMirrorViewModel( Loading @@ -76,7 +70,7 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { } } @Test @Test fun setLocationInWindow_correctLocationAndSize() = fun locationInWindowAndContainer_correctLocationAndSize() = with(kosmos) { with(kosmos) { testScope.runTest { testScope.runTest { val locationAndSize by collectLastValue(underTest.locationAndSize) val locationAndSize by collectLastValue(underTest.locationAndSize) Loading @@ -101,6 +95,7 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { whenever(measuredHeight).thenReturn(height) whenever(measuredHeight).thenReturn(height) whenever(measuredWidth).thenReturn(width) whenever(measuredWidth).thenReturn(width) } } val yOffsetFromContainer = setContainerViewHierarchy(mockView) underTest.setLocationAndSize(mockView) underTest.setLocationAndSize(mockView) Loading @@ -108,7 +103,8 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { .isEqualTo( .isEqualTo( // Adjust for padding around the view // Adjust for padding around the view LocationAndSize( LocationAndSize( yOffset = y - padding, yOffsetFromWindow = y - padding, yOffsetFromContainer = yOffsetFromContainer - padding, width = width + 2 * padding, width = width + 2 * padding, height = height + 2 * padding, height = height + 2 * padding, ) ) Loading @@ -116,31 +112,20 @@ class BrightnessMirrorViewModelTest : SysuiTestCase() { } } } } @Test private fun setContainerViewHierarchy(mockView: View): Int { fun setLocationInWindow_paddingSetToRootView() = val rootView = FrameLayout(context) with(kosmos) { val containerView = FrameLayout(context).apply { id = R.id.quick_settings_container } Assert.setTestThread(Thread.currentThread()) val otherView = FrameLayout(context) val padding = mainResources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding) val view = mock<View>() val (_, sliderController) = rootView.addView(containerView) BrightnessMirrorInflater.inflate( containerView.addView(otherView) themedContext, otherView.addView(mockView) brightnessSliderControllerFactory, ) underTest.setToggleSlider(sliderController) underTest.setLocationAndSize(view) containerView.setLeftTopRightBottom(1, /* top= */ 1, 1, 1) otherView.setLeftTopRightBottom(0, /* top= */ 2, 0, 0) with(sliderController.rootView) { whenever(mockView.parent).thenReturn(otherView) assertThat(paddingBottom).isEqualTo(padding) whenever(mockView.top).thenReturn(3) assertThat(paddingTop).isEqualTo(padding) assertThat(paddingLeft).isEqualTo(padding) assertThat(paddingRight).isEqualTo(padding) } Assert.setTestThread(null) return 2 + 3 } } } }