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

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

Merge "Upgrade path for small/large tiles" into main

parents 644ed4e9 b02dd916
Loading
Loading
Loading
Loading
+109 −9
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.user.data.repository.userRepository
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -104,6 +105,114 @@ class QSPreferencesRepositoryTest : SysuiTestCase() {
            }
        }

    @Test
    fun setInitialTilesFromSettings_noLargeTiles_tilesSet() =
        with(kosmos) {
            testScope.runTest {
                val largeTiles by collectLastValue(underTest.largeTilesSpecs)

                fakeUserRepository.setUserInfos(USERS)
                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
                val tiles = setOf("tileA", "tileB").toTileSpecs()

                assertThat(getSharedPreferences().contains(LARGE_TILES_SPECS_KEY)).isFalse()

                underTest.setInitialLargeTilesSpecs(tiles, PRIMARY_USER_ID)

                assertThat(largeTiles).isEqualTo(tiles)
            }
        }

    @Test
    fun setInitialTilesFromSettings_alreadyLargeTiles_tilesNotSet() =
        with(kosmos) {
            testScope.runTest {
                val largeTiles by collectLastValue(underTest.largeTilesSpecs)

                fakeUserRepository.setUserInfos(USERS)
                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
                setLargeTilesSpecsInSharedPreferences(setOf("tileC"))

                underTest.setInitialLargeTilesSpecs(setOf("tileA").toTileSpecs(), ANOTHER_USER_ID)

                assertThat(largeTiles).isEqualTo(setOf("tileC").toTileSpecs())
            }
        }

    @Test
    fun setInitialTilesFromSettings_emptyLargeTiles_tilesNotSet() =
        with(kosmos) {
            testScope.runTest {
                val largeTiles by collectLastValue(underTest.largeTilesSpecs)

                fakeUserRepository.setUserInfos(USERS)
                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
                setLargeTilesSpecsInSharedPreferences(emptySet())

                underTest.setInitialLargeTilesSpecs(setOf("tileA").toTileSpecs(), ANOTHER_USER_ID)

                assertThat(largeTiles).isEmpty()
            }
        }

    @Test
    fun setInitialTilesFromSettings_nonCurrentUser_tilesSetForCorrectUser() =
        with(kosmos) {
            testScope.runTest {
                val largeTiles by collectLastValue(underTest.largeTilesSpecs)

                fakeUserRepository.setUserInfos(USERS)
                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)

                underTest.setInitialLargeTilesSpecs(setOf("tileA").toTileSpecs(), ANOTHER_USER_ID)

                assertThat(largeTiles).isEqualTo(defaultLargeTilesRepository.defaultLargeTiles)

                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
                assertThat(largeTiles).isEqualTo(setOf("tileA").toTileSpecs())
            }
        }

    @Test
    fun setInitialTiles_afterDefaultRead_noSetOnRepository_initialTilesCorrect() =
        with(kosmos) {
            testScope.runTest {
                val largeTiles by collectLastValue(underTest.largeTilesSpecs)
                fakeUserRepository.setUserInfos(USERS)
                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)

                val currentLargeTiles = underTest.largeTilesSpecs.first()

                assertThat(currentLargeTiles).isNotEmpty()

                val tiles = setOf("tileA", "tileB")
                underTest.setInitialLargeTilesSpecs(tiles.toTileSpecs(), PRIMARY_USER_ID)

                assertThat(largeTiles).isEqualTo(tiles.toTileSpecs())
            }
        }

    @Test
    fun setInitialTiles_afterDefaultRead_largeTilesSetOnRepository_initialTilesCorrect() =
        with(kosmos) {
            testScope.runTest {
                val largeTiles by collectLastValue(underTest.largeTilesSpecs)
                fakeUserRepository.setUserInfos(USERS)
                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)

                val currentLargeTiles = underTest.largeTilesSpecs.first()

                assertThat(currentLargeTiles).isNotEmpty()

                underTest.setLargeTilesSpecs(setOf(TileSpec.create("tileC")))

                val tiles = setOf("tileA", "tileB")
                underTest.setInitialLargeTilesSpecs(tiles.toTileSpecs(), PRIMARY_USER_ID)

                assertThat(largeTiles).isEqualTo(setOf(TileSpec.create("tileC")))
            }
        }

    private fun getSharedPreferences(): SharedPreferences =
        with(kosmos) {
            return userFileManager.getSharedPreferences(
@@ -121,20 +230,11 @@ class QSPreferencesRepositoryTest : SysuiTestCase() {
        return getSharedPreferences().getStringSet(LARGE_TILES_SPECS_KEY, emptySet())!!
    }

    private fun setShowLabelsInSharedPreferences(value: Boolean) {
        getSharedPreferences().edit().putBoolean(ICON_LABELS_KEY, value).apply()
    }

    private fun getShowLabelsFromSharedPreferences(defaultValue: Boolean): Boolean {
        return getSharedPreferences().getBoolean(ICON_LABELS_KEY, defaultValue)
    }

    private fun Set<String>.toTileSpecs(): Set<TileSpec> {
        return map { TileSpec.create(it) }.toSet()
    }

    companion object {
        private const val ICON_LABELS_KEY = "show_icon_labels"
        private const val LARGE_TILES_SPECS_KEY = "large_tiles_specs"
        private const val PRIMARY_USER_ID = 0
        private val PRIMARY_USER = UserInfo(PRIMARY_USER_ID, "user 0", UserInfo.FLAG_MAIN)
+37 −0
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
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
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -90,6 +92,7 @@ class TileSpecSettingsRepositoryTest : SysuiTestCase() {
                logger,
                retailModeRepository,
                userTileSpecRepositoryFactory,
                testScope.backgroundScope,
            )
    }

@@ -231,6 +234,40 @@ class TileSpecSettingsRepositoryTest : SysuiTestCase() {
            assertThat(tiles!!).containsExactlyElementsIn(DEFAULT_TILES.toTileSpecs())
        }

    @Test
    fun readSettingsStored_emittedForUser() =
        testScope.runTest {
            val startingTiles = "a,b"
            val userId = 10
            storeTilesForUser(startingTiles, userId)

            val tiles by collectLastValue(underTest.tilesSpecs(userId))
            val tilesRead by collectLastValue(underTest.tilesReadFromSetting.consumeAsFlow())

            assertThat(tilesRead).isEqualTo(startingTiles.toTileSpecs().toSet() to userId)
        }

    @Test
    fun readSettingsStored_multipleUsers() =
        testScope.runTest {
            val startingTiles10 = "a"
            val startingTiles11 = "b,c"
            storeTilesForUser(startingTiles10, 10)
            storeTilesForUser(startingTiles11, 11)

            val tiles10 by collectLastValue(underTest.tilesSpecs(10))
            val tiles11 by collectLastValue(underTest.tilesSpecs(11))

            val tilesRead by collectValues(underTest.tilesReadFromSetting.consumeAsFlow())

            assertThat(tilesRead).hasSize(2)
            assertThat(tilesRead)
                .containsExactly(
                    startingTiles10.toTileSpecs().toSet() to 10,
                    startingTiles11.toTileSpecs().toSet() to 11,
                )
        }

    private fun TestScope.storeTilesForUser(specs: String, forUser: Int) {
        secureSettings.putStringForUser(SETTING, specs, forUser)
        runCurrent()
+47 −5
Original line number Diff line number Diff line
@@ -7,11 +7,13 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.data.model.RestoreData
import com.android.systemui.qs.pipeline.data.repository.UserTileSpecRepositoryTest.Companion.toTilesSet
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -312,11 +314,7 @@ class UserTileSpecRepositoryTest : SysuiTestCase() {
            runCurrent()

            val restoreData =
                RestoreData(
                    restoredSpecs.toTileSpecs(),
                    restoredAutoAdded.toTilesSet(),
                    USER,
                )
                RestoreData(restoredSpecs.toTileSpecs(), restoredAutoAdded.toTilesSet(), USER)
            underTest.reconcileRestore(restoreData, autoAddedBeforeRestore.toTilesSet())
            runCurrent()

@@ -351,6 +349,49 @@ class UserTileSpecRepositoryTest : SysuiTestCase() {
            assertThat(tiles).isEqualTo(currentTiles)
        }

    @Test
    fun noSettingsStored_noTilesReadFromSettings() =
        testScope.runTest {
            val tilesRead by collectLastValue(underTest.tilesReadFromSettings.consumeAsFlow())
            val tiles by collectLastValue(underTest.tiles())

            assertThat(tiles).isEqualTo(getDefaultTileSpecs())
            assertThat(tilesRead).isEqualTo(null)
        }

    @Test
    fun settingsStored_tilesReadFromSettings() =
        testScope.runTest {
            val storedTiles = "a,b"
            storeTiles(storedTiles)
            val tiles by collectLastValue(underTest.tiles())
            val tilesRead by collectLastValue(underTest.tilesReadFromSettings.consumeAsFlow())

            assertThat(tilesRead).isEqualTo(storedTiles.toTilesSet())
        }

    @Test
    fun noSettingsStored_tilesChanged_tilesReadFromSettingsNotChanged() =
        testScope.runTest {
            val tilesRead by collectLastValue(underTest.tilesReadFromSettings.consumeAsFlow())
            val tiles by collectLastValue(underTest.tiles())

            underTest.addTile(TileSpec.create("a"))
            assertThat(tilesRead).isEqualTo(null)
        }

    @Test
    fun settingsStored_tilesChanged_tilesReadFromSettingsNotChanged() =
        testScope.runTest {
            val storedTiles = "a,b"
            storeTiles(storedTiles)
            val tiles by collectLastValue(underTest.tiles())
            val tilesRead by collectLastValue(underTest.tilesReadFromSettings.consumeAsFlow())

            underTest.addTile(TileSpec.create("c"))
            assertThat(tilesRead).isEqualTo(storedTiles.toTilesSet())
        }

    private fun getDefaultTileSpecs(): List<TileSpec> {
        return defaultTilesRepository.defaultTiles
    }
@@ -370,6 +411,7 @@ class UserTileSpecRepositoryTest : SysuiTestCase() {
        private const val SETTING = Settings.Secure.QS_TILES

        private fun String.toTileSpecs() = TilesSettingConverter.toTilesList(this)

        private fun String.toTilesSet() = TilesSettingConverter.toTilesSet(this)
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.qs.panels.dagger

import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
@@ -23,6 +24,7 @@ import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepositor
import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepositoryImpl
import com.android.systemui.qs.panels.domain.interactor.EditTilesResetInteractor
import com.android.systemui.qs.panels.domain.interactor.SizedTilesResetInteractor
import com.android.systemui.qs.panels.domain.startable.QSPanelsCoreStartable
import com.android.systemui.qs.panels.shared.model.GridLayoutType
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
@@ -36,6 +38,8 @@ import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModelImpl
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import dagger.multibindings.IntoSet
import javax.inject.Named

@@ -57,6 +61,11 @@ interface PanelsModule {

    @Binds @Named("Default") fun bindDefaultGridLayout(impl: PaginatedGridLayout): GridLayout

    @Binds
    @IntoMap
    @ClassKey(QSPanelsCoreStartable::class)
    fun bindQSPanelsCoreStartable(impl: QSPanelsCoreStartable): CoreStartable

    companion object {
        @Provides
        @SysUISingleton
+23 −1
Original line number Diff line number Diff line
@@ -84,11 +84,33 @@ constructor(

    /** Sets for the current user the set of [TileSpec] to display as large tiles. */
    fun setLargeTilesSpecs(specs: Set<TileSpec>) {
        with(getSharedPrefs(userRepository.getSelectedUserInfo().id)) {
        setLargeTilesSpecsForUser(specs, userRepository.getSelectedUserInfo().id)
    }

    private fun setLargeTilesSpecsForUser(specs: Set<TileSpec>, userId: Int) {
        with(getSharedPrefs(userId)) {
            edit().putStringSet(LARGE_TILES_SPECS_KEY, specs.map { it.spec }.toSet()).apply()
        }
    }

    /**
     * Sets the initial tiles as large, if there is no set in SharedPrefs for the [userId]. This is
     * to be used when upgrading to a build that supports large/small tiles.
     *
     * Even if largeTilesSpec is read Eagerly before we know if we are in an initial state, because
     * we are not writing the default values to the SharedPreferences, the file will not contain the
     * key and this call will succeed, as long as there hasn't been any calls to setLargeTilesSpecs
     * for that user before.
     */
    fun setInitialLargeTilesSpecs(specs: Set<TileSpec>, userId: Int) {
        with(getSharedPrefs(userId)) {
            if (!contains(LARGE_TILES_SPECS_KEY)) {
                logger.i("Setting upgraded large tiles for user $userId: $specs")
                setLargeTilesSpecsForUser(specs, userId)
            }
        }
    }

    private fun getSharedPrefs(userId: Int): SharedPreferences {
        return userFileManager.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE, userId)
    }
Loading