Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f117d04 authored by Olivier St-Onge's avatar Olivier St-Onge
Browse files

Reapply "Use the number of columns for extra large tiles, or half if past the threshold"

This reverts commit 86bb30d0.
This time fixing the unit tests changing the font scale

Flag: com.android.systemui.qs_ui_refactor_compose_fragment
Bug: 416742299
Test: LargeTileSpanRepositoryTest.kt
Test: LargeTileSpanInteractorTest.kt
Change-Id: Ibd7e996939189edb9ba42158d9639a47f698a022
parent 21c5f04f
Loading
Loading
Loading
Loading
+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 android.content.res.Configuration
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)

            val configuration = Configuration().apply { this.fontScale = 1f }
            context.orCreateTestableResources.overrideConfiguration(configuration)
            fakeConfigurationRepository.onConfigurationChange()
            assertThat(latest).isFalse()

            configuration.fontScale = 1.3f
            fakeConfigurationRepository.onConfigurationChange()
            assertThat(latest).isFalse()

            configuration.fontScale = 1.5f
            fakeConfigurationRepository.onConfigurationChange()
            assertThat(latest).isFalse()

            configuration.fontScale = 1.8f
            fakeConfigurationRepository.onConfigurationChange()
            assertThat(latest).isTrue()

            configuration.fontScale = 2f
            fakeConfigurationRepository.onConfigurationChange()
            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 setColumnsInConfig(columns: Int) =
        with(kosmos) {
            testCase.context.orCreateTestableResources.addOverride(
                R.integer.quick_settings_infinite_grid_tile_max_width,
                columns,
            )
            fakeConfigurationRepository.onConfigurationChange()
        }
}
+146 −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 android.content.res.Configuration
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)

            // Set extra large tiles to false
            val configuration = Configuration().apply { this.fontScale = 1f }
            context.orCreateTestableResources.overrideConfiguration(configuration)
            fakeConfigurationRepository.onConfigurationChange()

            // 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)

            // Set extra large tiles to true
            val configuration = Configuration().apply { this.fontScale = 2f }
            context.orCreateTestableResources.overrideConfiguration(configuration)
            fakeConfigurationRepository.onConfigurationChange()

            // 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)

            // Set extra large tiles to true
            val configuration = Configuration().apply { this.fontScale = 2f }
            context.orCreateTestableResources.overrideConfiguration(configuration)
            fakeConfigurationRepository.onConfigurationChange()

            // 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)

            // Set extra large tiles to false
            val configuration = Configuration().apply { this.fontScale = 1f }
            context.orCreateTestableResources.overrideConfiguration(configuration)
            fakeConfigurationRepository.onConfigurationChange()

            assertThat(latest).isEqualTo(2)

            // Set extra large tiles to true
            configuration.fontScale = 2f
            fakeConfigurationRepository.onConfigurationChange()
            assertThat(latest).isEqualTo(4)
        }

    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()
        }
}
+0 −3
Original line number Diff line number Diff line
@@ -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>

+21 −16
Original line number Diff line number Diff line
@@ -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
    }
}
+6 −3
Original line number Diff line number Diff line
@@ -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
@@ -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