Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/LargeTileSpanRepositoryTest.kt 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.qs.panels.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.res.R import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class LargeTileSpanRepositoryTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val Kosmos.underTest by Kosmos.Fixture { largeTileSpanRepository } @Test fun useExtraLargeTiles_tracksConfig() = kosmos.runTest { val latest by collectLastValue(underTest.useExtraLargeTiles) setFontScale(1f) assertThat(latest).isFalse() setFontScale(1.3f) assertThat(latest).isFalse() setFontScale(1.5f) assertThat(latest).isFalse() setFontScale(1.8f) assertThat(latest).isTrue() setFontScale(2f) assertThat(latest).isTrue() } @Test fun tileMaxWidth_tracksConfig() = kosmos.runTest { val latest by collectLastValue(underTest.tileMaxWidth) setColumnsInConfig(1) assertThat(latest).isEqualTo(1) setColumnsInConfig(4) assertThat(latest).isEqualTo(4) setColumnsInConfig(8) assertThat(latest).isEqualTo(8) } private fun setFontScale(value: Float) { with(kosmos) { testCase.context.resources.configuration.fontScale = value fakeConfigurationRepository.onConfigurationChange() } } private fun setColumnsInConfig(columns: Int) = with(kosmos) { testCase.context.orCreateTestableResources.addOverride( R.integer.quick_settings_infinite_grid_tile_max_width, columns, ) fakeConfigurationRepository.onConfigurationChange() } } packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/LargeTileSpanInteractorTest.kt 0 → 100644 +135 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.qs.panels.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.res.R import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class LargeTileSpanInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher().apply { testCase.context.orCreateTestableResources.addOverride( R.integer.quick_settings_infinite_grid_num_columns, 4, ) testCase.context.orCreateTestableResources.addOverride( R.integer.quick_settings_infinite_grid_tile_max_width, 4, ) } private val Kosmos.underTest by Kosmos.Fixture { largeTileSpanInteractor } @Test fun span_normalTiles_ignoreColumns() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = false) // Not using extra large tiles means that we stay to the default width of 2, regardless // of columns assertThat(latest).isEqualTo(2) setColumns(10) assertThat(latest).isEqualTo(2) } @Test fun span_extraLargeTiles_tracksColumns() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = true) // Using extra large tiles with a max width of 4 means that we change the width to the // same as the columns if equal or under 4, otherwise we divide it in half assertThat(latest).isEqualTo(4) setColumns(2) assertThat(latest).isEqualTo(2) setColumns(6) assertThat(latest).isEqualTo(3) setColumns(8) assertThat(latest).isEqualTo(4) } @Test fun span_extraLargeTiles_tracksMaxWidth() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = true) // Using extra large tiles with 4 columns means that we change the width to be 4, unless // we're using a max width lower than 4 in which case divide it in half assertThat(latest).isEqualTo(4) setMaxWidth(3) assertThat(latest).isEqualTo(2) setMaxWidth(6) assertThat(latest).isEqualTo(4) setMaxWidth(8) assertThat(latest).isEqualTo(4) } @Test fun span_tracksExtraLargeTiles() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = false) assertThat(latest).isEqualTo(2) setExtraLargeTiles(useExtraLargeTiles = true) assertThat(latest).isEqualTo(4) } private fun setExtraLargeTiles(useExtraLargeTiles: Boolean) { with(kosmos) { val fontScale = if (useExtraLargeTiles) 2f else 1f testCase.context.resources.configuration.fontScale = fontScale fakeConfigurationRepository.onConfigurationChange() } } private fun setColumns(columns: Int) = setValueInConfig(columns, R.integer.quick_settings_infinite_grid_num_columns) private fun setMaxWidth(width: Int) = setValueInConfig(width, R.integer.quick_settings_infinite_grid_tile_max_width) private fun setValueInConfig(value: Int, id: Int) = with(kosmos) { testCase.context.orCreateTestableResources.addOverride(id, value) fakeConfigurationRepository.onConfigurationChange() } } packages/SystemUI/res/values-sw600dp-port/config.xml +0 −3 Original line number Diff line number Diff line Loading @@ -33,9 +33,6 @@ <!-- The number of columns in the infinite grid QuickSettings --> <integer name="quick_settings_infinite_grid_num_columns">6</integer> <!-- The maximum width of large tiles in the infinite grid QuickSettings --> <integer name="quick_settings_infinite_grid_tile_max_width">3</integer> <integer name="power_menu_lite_max_columns">2</integer> <integer name="power_menu_lite_max_rows">3</integer> Loading packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/LargeTileSpanRepository.kt +21 −16 Original line number Diff line number Diff line Loading @@ -19,40 +19,45 @@ package com.android.systemui.qs.panels.data.repository import android.content.res.Resources import com.android.systemui.common.ui.data.repository.ConfigurationRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton class LargeTileSpanRepository @Inject constructor( @Application scope: CoroutineScope, @ShadeDisplayAware private val resources: Resources, @ShadeDisplayAware configurationRepository: ConfigurationRepository, ) { val span: StateFlow<Int> = val useExtraLargeTiles: Flow<Boolean> = configurationRepository.onConfigurationChange .emitOnStart() .mapLatest { if (resources.configuration.fontScale >= FONT_SCALE_THRESHOLD) { resources.getInteger(R.integer.quick_settings_infinite_grid_tile_max_width) } else { 2 } } .mapLatest { currentUseExtraLargeTiles } .distinctUntilChanged() .stateIn(scope, SharingStarted.WhileSubscribed(), 2) val tileMaxWidth: Flow<Int> = configurationRepository.onConfigurationChange .emitOnStart() .mapLatest { currentTileMaxWidth } .distinctUntilChanged() val defaultTileMaxWidth: Int = DEFAULT_LARGE_TILE_WIDTH val currentUseExtraLargeTiles: Boolean get() = resources.configuration.fontScale >= FONT_SCALE_THRESHOLD val currentTileMaxWidth: Int get() = resources.getInteger(R.integer.quick_settings_infinite_grid_tile_max_width) private companion object { const val FONT_SCALE_THRESHOLD = 2f const val FONT_SCALE_THRESHOLD = 1.8f const val DEFAULT_LARGE_TILE_WIDTH = 2 } } packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepository.kt +6 −3 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest @SysUISingleton Loading @@ -35,9 +34,13 @@ constructor( @ShadeDisplayAware configurationRepository: ConfigurationRepository, ) { val splitShadeColumns: Flow<Int> = flowOf(resources.getInteger(R.integer.quick_settings_split_shade_num_columns)) configurationRepository.onConfigurationChange.emitOnStart().mapLatest { resources.getInteger(R.integer.quick_settings_split_shade_num_columns) } val dualShadeColumns: Flow<Int> = flowOf(resources.getInteger(R.integer.quick_settings_dual_shade_num_columns)) configurationRepository.onConfigurationChange.emitOnStart().mapLatest { resources.getInteger(R.integer.quick_settings_dual_shade_num_columns) } val columns: Flow<Int> = configurationRepository.onConfigurationChange.emitOnStart().mapLatest { resources.getInteger(R.integer.quick_settings_infinite_grid_num_columns) Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/LargeTileSpanRepositoryTest.kt 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.qs.panels.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.res.R import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class LargeTileSpanRepositoryTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val Kosmos.underTest by Kosmos.Fixture { largeTileSpanRepository } @Test fun useExtraLargeTiles_tracksConfig() = kosmos.runTest { val latest by collectLastValue(underTest.useExtraLargeTiles) setFontScale(1f) assertThat(latest).isFalse() setFontScale(1.3f) assertThat(latest).isFalse() setFontScale(1.5f) assertThat(latest).isFalse() setFontScale(1.8f) assertThat(latest).isTrue() setFontScale(2f) assertThat(latest).isTrue() } @Test fun tileMaxWidth_tracksConfig() = kosmos.runTest { val latest by collectLastValue(underTest.tileMaxWidth) setColumnsInConfig(1) assertThat(latest).isEqualTo(1) setColumnsInConfig(4) assertThat(latest).isEqualTo(4) setColumnsInConfig(8) assertThat(latest).isEqualTo(8) } private fun setFontScale(value: Float) { with(kosmos) { testCase.context.resources.configuration.fontScale = value fakeConfigurationRepository.onConfigurationChange() } } private fun setColumnsInConfig(columns: Int) = with(kosmos) { testCase.context.orCreateTestableResources.addOverride( R.integer.quick_settings_infinite_grid_tile_max_width, columns, ) fakeConfigurationRepository.onConfigurationChange() } }
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/LargeTileSpanInteractorTest.kt 0 → 100644 +135 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.qs.panels.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.res.R import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class LargeTileSpanInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher().apply { testCase.context.orCreateTestableResources.addOverride( R.integer.quick_settings_infinite_grid_num_columns, 4, ) testCase.context.orCreateTestableResources.addOverride( R.integer.quick_settings_infinite_grid_tile_max_width, 4, ) } private val Kosmos.underTest by Kosmos.Fixture { largeTileSpanInteractor } @Test fun span_normalTiles_ignoreColumns() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = false) // Not using extra large tiles means that we stay to the default width of 2, regardless // of columns assertThat(latest).isEqualTo(2) setColumns(10) assertThat(latest).isEqualTo(2) } @Test fun span_extraLargeTiles_tracksColumns() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = true) // Using extra large tiles with a max width of 4 means that we change the width to the // same as the columns if equal or under 4, otherwise we divide it in half assertThat(latest).isEqualTo(4) setColumns(2) assertThat(latest).isEqualTo(2) setColumns(6) assertThat(latest).isEqualTo(3) setColumns(8) assertThat(latest).isEqualTo(4) } @Test fun span_extraLargeTiles_tracksMaxWidth() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = true) // Using extra large tiles with 4 columns means that we change the width to be 4, unless // we're using a max width lower than 4 in which case divide it in half assertThat(latest).isEqualTo(4) setMaxWidth(3) assertThat(latest).isEqualTo(2) setMaxWidth(6) assertThat(latest).isEqualTo(4) setMaxWidth(8) assertThat(latest).isEqualTo(4) } @Test fun span_tracksExtraLargeTiles() = kosmos.runTest { val latest by collectLastValue(underTest.span) setExtraLargeTiles(useExtraLargeTiles = false) assertThat(latest).isEqualTo(2) setExtraLargeTiles(useExtraLargeTiles = true) assertThat(latest).isEqualTo(4) } private fun setExtraLargeTiles(useExtraLargeTiles: Boolean) { with(kosmos) { val fontScale = if (useExtraLargeTiles) 2f else 1f testCase.context.resources.configuration.fontScale = fontScale fakeConfigurationRepository.onConfigurationChange() } } private fun setColumns(columns: Int) = setValueInConfig(columns, R.integer.quick_settings_infinite_grid_num_columns) private fun setMaxWidth(width: Int) = setValueInConfig(width, R.integer.quick_settings_infinite_grid_tile_max_width) private fun setValueInConfig(value: Int, id: Int) = with(kosmos) { testCase.context.orCreateTestableResources.addOverride(id, value) fakeConfigurationRepository.onConfigurationChange() } }
packages/SystemUI/res/values-sw600dp-port/config.xml +0 −3 Original line number Diff line number Diff line Loading @@ -33,9 +33,6 @@ <!-- The number of columns in the infinite grid QuickSettings --> <integer name="quick_settings_infinite_grid_num_columns">6</integer> <!-- The maximum width of large tiles in the infinite grid QuickSettings --> <integer name="quick_settings_infinite_grid_tile_max_width">3</integer> <integer name="power_menu_lite_max_columns">2</integer> <integer name="power_menu_lite_max_rows">3</integer> Loading
packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/LargeTileSpanRepository.kt +21 −16 Original line number Diff line number Diff line Loading @@ -19,40 +19,45 @@ package com.android.systemui.qs.panels.data.repository import android.content.res.Resources import com.android.systemui.common.ui.data.repository.ConfigurationRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton class LargeTileSpanRepository @Inject constructor( @Application scope: CoroutineScope, @ShadeDisplayAware private val resources: Resources, @ShadeDisplayAware configurationRepository: ConfigurationRepository, ) { val span: StateFlow<Int> = val useExtraLargeTiles: Flow<Boolean> = configurationRepository.onConfigurationChange .emitOnStart() .mapLatest { if (resources.configuration.fontScale >= FONT_SCALE_THRESHOLD) { resources.getInteger(R.integer.quick_settings_infinite_grid_tile_max_width) } else { 2 } } .mapLatest { currentUseExtraLargeTiles } .distinctUntilChanged() .stateIn(scope, SharingStarted.WhileSubscribed(), 2) val tileMaxWidth: Flow<Int> = configurationRepository.onConfigurationChange .emitOnStart() .mapLatest { currentTileMaxWidth } .distinctUntilChanged() val defaultTileMaxWidth: Int = DEFAULT_LARGE_TILE_WIDTH val currentUseExtraLargeTiles: Boolean get() = resources.configuration.fontScale >= FONT_SCALE_THRESHOLD val currentTileMaxWidth: Int get() = resources.getInteger(R.integer.quick_settings_infinite_grid_tile_max_width) private companion object { const val FONT_SCALE_THRESHOLD = 2f const val FONT_SCALE_THRESHOLD = 1.8f const val DEFAULT_LARGE_TILE_WIDTH = 2 } }
packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepository.kt +6 −3 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest @SysUISingleton Loading @@ -35,9 +34,13 @@ constructor( @ShadeDisplayAware configurationRepository: ConfigurationRepository, ) { val splitShadeColumns: Flow<Int> = flowOf(resources.getInteger(R.integer.quick_settings_split_shade_num_columns)) configurationRepository.onConfigurationChange.emitOnStart().mapLatest { resources.getInteger(R.integer.quick_settings_split_shade_num_columns) } val dualShadeColumns: Flow<Int> = flowOf(resources.getInteger(R.integer.quick_settings_dual_shade_num_columns)) configurationRepository.onConfigurationChange.emitOnStart().mapLatest { resources.getInteger(R.integer.quick_settings_dual_shade_num_columns) } val columns: Flow<Int> = configurationRepository.onConfigurationChange.emitOnStart().mapLatest { resources.getInteger(R.integer.quick_settings_infinite_grid_num_columns) Loading