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

Commit c12aae9d authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge "Prevent no tiles in QS" into main

parents 36e285f5 db72b29d
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.pipeline.data.repository

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class MinimumTilesResourceRepositoryTest : SysuiTestCase() {

    val testableResources = context.orCreateTestableResources

    @Test
    fun minimumQSTiles_followsConfig() {
        val minTwo = 2
        testableResources.addOverride(R.integer.quick_settings_min_num_tiles, minTwo)
        val underTest = MinimumTilesResourceRepository(context.resources)
        assertThat(underTest.minNumberOfTiles).isEqualTo(minTwo)

        val minSix = 6
        testableResources.addOverride(R.integer.quick_settings_min_num_tiles, minSix)
        val otherUnderTest = MinimumTilesResourceRepository(context.resources)
        assertThat(otherUnderTest.minNumberOfTiles).isEqualTo(minSix)
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -20,11 +20,11 @@ import android.platform.test.annotations.EnabledOnRavenwood
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
import com.android.systemui.res.R
import com.android.systemui.retail.data.repository.FakeRetailModeRepository
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
@@ -187,6 +187,22 @@ class TileSpecSettingsRepositoryTest : SysuiTestCase() {
            assertThat(loadTilesForUser(0)).isEqualTo(DEFAULT_TILES)
        }

    @Test
    fun prependDefault() =
        testScope.runTest {
            val tiles by collectLastValue(underTest.tilesSpecs(0))

            val startingTiles = listOf(TileSpec.create("e"), TileSpec.create("f"))

            underTest.setTiles(0, startingTiles)
            runCurrent()

            underTest.prependDefault(0)

            assertThat(tiles!!)
                .containsExactlyElementsIn(DEFAULT_TILES.toTileSpecs() + startingTiles)
        }

    private fun TestScope.storeTilesForUser(specs: String, forUser: Int) {
        secureSettings.putStringForUser(SETTING, specs, forUser)
        runCurrent()
+3 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.qs.pipeline.data.repository.CustomTileAddedRepositor
import com.android.systemui.qs.pipeline.data.repository.FakeCustomTileAddedRepository
import com.android.systemui.qs.pipeline.data.repository.FakeInstalledTilesComponentRepository
import com.android.systemui.qs.pipeline.data.repository.FakeTileSpecRepository
import com.android.systemui.qs.pipeline.data.repository.MinimumTilesFixedRepository
import com.android.systemui.qs.pipeline.data.repository.TileSpecRepository
import com.android.systemui.qs.pipeline.domain.model.TileModel
import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
@@ -82,6 +83,7 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
        FakeCustomTileAddedRepository()
    private val pipelineFlags = QSPipelineFlagsRepository()
    private val tileLifecycleManagerFactory = TLMFactory()
    private val minimumTilesRepository = MinimumTilesFixedRepository()

    @Mock private lateinit var customTileStatePersister: CustomTileStatePersister

@@ -114,6 +116,7 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
                tileSpecRepository = tileSpecRepository,
                installedTilesComponentRepository = installedTilesPackageRepository,
                userRepository = userRepository,
                minimumTilesRepository = minimumTilesRepository,
                customTileStatePersister = customTileStatePersister,
                tileFactory = tileFactory,
                newQSTileFactory = { newQSTileFactory },
+147 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.pipeline.domain.interactor

import android.content.ComponentName
import android.content.pm.UserInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.FakeQSFactory
import com.android.systemui.qs.pipeline.data.model.RestoreData
import com.android.systemui.qs.pipeline.data.repository.FakeDefaultTilesRepository
import com.android.systemui.qs.pipeline.data.repository.MinimumTilesFixedRepository
import com.android.systemui.qs.pipeline.data.repository.fakeDefaultTilesRepository
import com.android.systemui.qs.pipeline.data.repository.fakeMinimumTilesRepository
import com.android.systemui.qs.pipeline.data.repository.fakeRestoreRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.qsTileFactory
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.settings.userTracker
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

/**
 * This integration test is for testing the solution to b/324575996. In particular, when restoring
 * from a device that uses different specs for tiles, we may end up with empty (or mostly empty) QS.
 * In that case, we want to prepend the default tiles instead.
 */
@OptIn(ExperimentalCoroutinesApi::class)
@MediumTest
@RunWith(AndroidJUnit4::class)
class NoLowNumberOfTilesTest : SysuiTestCase() {

    private val USER_0_INFO =
        UserInfo(
            0,
            "zero",
            "",
            UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
        )

    private val defaultTiles =
        listOf(
            TileSpec.create("internet"),
            TileSpec.create("bt"),
        )

    private val kosmos =
        Kosmos().apply {
            fakeMinimumTilesRepository = MinimumTilesFixedRepository(minNumberOfTiles = 2)
            fakeUserTracker.set(listOf(USER_0_INFO), 0)
            qsTileFactory = FakeQSFactory(::tileCreator)
            fakeDefaultTilesRepository = FakeDefaultTilesRepository(defaultTiles)
        }

    private val currentUser: Int
        get() = kosmos.userTracker.userId

    private val goodTile = TileSpec.create("correct")

    private val restoredTiles =
        listOf(
            TileSpec.create("OEM:internet"),
            TileSpec.create("OEM:bt"),
            TileSpec.create("OEM:dnd"),
            // This is not an installed component so a tile won't be created
            TileSpec.create(ComponentName.unflattenFromString("oem/.tile")!!),
            TileSpec.create("OEM:flashlight"),
            goodTile,
        )

    @Before
    fun setUp() {
        mSetFlagsRule.enableFlags(Flags.FLAG_QS_NEW_PIPELINE)

        with(kosmos) {
            restoreReconciliationInteractor.start()
            autoAddInteractor.init(kosmos.currentTilesInteractor)
        }
    }

    @Test
    fun noLessThanTwoTilesAfterOEMRestore_prependedDefault() =
        with(kosmos) {
            testScope.runTest {
                val tiles by collectLastValue(currentTilesInteractor.currentTiles)
                runCurrent()

                assertThat(tiles!!).isNotEmpty()

                val restoreData = RestoreData(restoredTiles, emptySet(), currentUser)
                fakeRestoreRepository.onDataRestored(restoreData)
                runCurrent()

                assertThat(tiles!!.map { it.spec }).isEqualTo(defaultTiles + listOf(goodTile))
            }
        }

    @Test
    fun noEmptyTilesAfterSettingTilesToUnknownNames() =
        with(kosmos) {
            testScope.runTest {
                val tiles by collectLastValue(currentTilesInteractor.currentTiles)
                runCurrent()

                assertThat(tiles!!).isNotEmpty()

                val badTiles = listOf(TileSpec.create("OEM:unknown_tile"))
                currentTilesInteractor.setTiles(badTiles)
                runCurrent()

                assertThat(tiles!!.map { it.spec }).isEqualTo(defaultTiles)
            }
        }

    private fun tileCreator(spec: String): QSTile? {
        return if (spec.contains("OEM")) {
            null // We don't know how to create OEM spec tiles
        } else {
            FakeQSTile(currentUser)
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import com.android.systemui.qs.pipeline.data.repository.DefaultTilesQSHostReposi
import com.android.systemui.qs.pipeline.data.repository.DefaultTilesRepository
import com.android.systemui.qs.pipeline.data.repository.InstalledTilesComponentRepository
import com.android.systemui.qs.pipeline.data.repository.InstalledTilesComponentRepositoryImpl
import com.android.systemui.qs.pipeline.data.repository.MinimumTilesRepository
import com.android.systemui.qs.pipeline.data.repository.MinimumTilesResourceRepository
import com.android.systemui.qs.pipeline.data.repository.QSSettingsRestoredBroadcastRepository
import com.android.systemui.qs.pipeline.data.repository.QSSettingsRestoredRepository
import com.android.systemui.qs.pipeline.data.repository.TileSpecRepository
@@ -81,6 +83,11 @@ abstract class QSPipelineModule {
        impl: QSSettingsRestoredBroadcastRepository
    ): QSSettingsRestoredRepository

    @Binds
    abstract fun provideMinimumTilesRepository(
        impl: MinimumTilesResourceRepository
    ): MinimumTilesRepository

    companion object {
        /**
         * Provides a logging buffer for all logs related to the new Quick Settings pipeline to log
Loading