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

Commit c018d4b3 authored by Fabián Kozynski's avatar Fabián Kozynski
Browse files

Do not remove work tile from inside the tile.

AutoAddable will take care of removing it for the correct user, as it
gets its user from CurrentTilesInteractor.

Also, fix user switch in CurrentTilesInteractor. It was triggering more
often than it should.

Test: manual
Fixes: 352008994
Flag: EXEMPT bugfix
Change-Id: If1b66e06649566335ee904e3d40f11cc3c921064
parent 8a225631
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -675,6 +675,24 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
            assertThat(tiles!!.size).isEqualTo(3)
        }

    @Test
    fun changeInPackagesTiles_doesntTriggerUserChange_logged() =
        testScope.runTest(USER_INFO_0) {
            val specs =
                listOf(
                    TileSpec.create("a"),
                )
            tileSpecRepository.setTiles(USER_INFO_0.id, specs)
            runCurrent()
            // Settled on the same list of tiles.
            assertThat(underTest.currentTilesSpecs).isEqualTo(specs)

            installedTilesPackageRepository.setInstalledPackagesForUser(USER_INFO_0.id, emptySet())
            runCurrent()

            verify(logger, never()).logTileUserChanged(TileSpec.create("a"), 0)
        }

    private fun QSTile.State.fillIn(state: Int, label: CharSequence, secondaryLabel: CharSequence) {
        this.state = state
        this.label = label
+100 −104
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ import com.android.systemui.qs.toProto
import com.android.systemui.retail.data.repository.RetailModeRepository
import com.android.systemui.settings.UserTracker
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.pairwiseBy
import dagger.Lazy
import java.io.PrintWriter
import javax.inject.Inject
@@ -63,7 +63,6 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@@ -169,16 +168,18 @@ constructor(
    private val userAndTiles =
        currentUser
            .flatMapLatest { userId ->
                tileSpecRepository.tilesSpecs(userId).map { UserAndTiles(userId, it) }
                val currentTiles = tileSpecRepository.tilesSpecs(userId)
                val installedComponents =
                    installedTilesComponentRepository.getInstalledTilesComponents(userId)
                currentTiles.combine(installedComponents) { tiles, components ->
                    UserTilesAndComponents(userId, tiles, components)
                }
            }
            .distinctUntilChanged()
            .pairwise(UserAndTiles(-1, emptyList()))
            .flowOn(backgroundDispatcher)

    private val installedPackagesWithTiles =
        currentUser.flatMapLatest {
            installedTilesComponentRepository.getInstalledTilesComponents(it)
            .pairwiseBy(UserTilesAndComponents(-1, emptyList(), emptySet())) { prev, new ->
                DataWithUserChange(data = new, userChange = prev.userId != new.userId)
            }
            .flowOn(backgroundDispatcher)

    private val minTiles: Int
        get() =
@@ -194,7 +195,6 @@ constructor(
        }
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    private fun startTileCollection() {
        scope.launch {
            launch {
@@ -205,25 +205,15 @@ constructor(
            }

            launch(backgroundDispatcher) {
                userAndTiles
                    .combine(installedPackagesWithTiles) { usersAndTiles, packages ->
                        Data(
                            usersAndTiles.previousValue,
                            usersAndTiles.newValue,
                            packages,
                        )
                    }
                    .collectLatest {
                        val newTileList = it.newData.tiles
                        val userChanged = it.oldData.userId != it.newData.userId
                        val newUser = it.newData.userId
                userAndTiles.collectLatest {
                    val newUser = it.userId
                    val newTileList = it.tiles
                    val components = it.installedComponents
                    val userChanged = it.userChange

                    // Destroy all tiles that are not in the new set
                    specsToTiles
                            .filter {
                                it.key !in newTileList && it.value is TileOrNotInstalled.Tile
                            }
                        .filter { it.key !in newTileList && it.value is TileOrNotInstalled.Tile }
                        .forEach { entry ->
                            logger.logTileDestroyed(
                                entry.key,
@@ -256,8 +246,7 @@ constructor(
                                            specsToTiles.getValue(tileSpec),
                                            userChanged,
                                            newUser
                                            )
                                                ?: createTile(tileSpec)
                                        ) ?: createTile(tileSpec)
                                    } else {
                                        createTile(tileSpec)
                                    }
@@ -274,9 +263,7 @@ constructor(
                    val newResolvedTiles =
                        newTileMap
                            .filter { it.value is TileOrNotInstalled.Tile }
                                .map {
                                    TileModel(it.key, (it.value as TileOrNotInstalled.Tile).tile)
                                }
                            .map { TileModel(it.key, (it.value as TileOrNotInstalled.Tile).tile) }

                    _currentSpecsAndTiles.value = newResolvedTiles
                    logger.logTilesNotInstalled(
@@ -362,8 +349,7 @@ constructor(
                    newQSTileFactory.get().createTile(spec.spec)
                } else {
                    null
                }
                    ?: tileFactory.createTile(spec.spec)
                } ?: tileFactory.createTile(spec.spec)
            }
        if (tile == null) {
            logger.logTileNotFoundInFactory(spec)
@@ -436,15 +422,25 @@ constructor(

        @JvmInline value class Tile(val tile: QSTile) : TileOrNotInstalled
    }
}

    private data class UserAndTiles(
private data class UserTilesAndComponents(
    val userId: Int,
    val tiles: List<TileSpec>,
    val installedComponents: Set<ComponentName>
)

    private data class Data(
        val oldData: UserAndTiles,
        val newData: UserAndTiles,
private data class DataWithUserChange(
    val userId: Int,
    val tiles: List<TileSpec>,
    val installedComponents: Set<ComponentName>,
    val userChange: Boolean,
)

private fun DataWithUserChange(data: UserTilesAndComponents, userChange: Boolean) =
    DataWithUserChange(
        data.userId,
        data.tiles,
        data.installedComponents,
        userChange,
    )
}
+2 −1
Original line number Diff line number Diff line
@@ -106,7 +106,8 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
    @Override
    @MainThread
    public void onManagedProfileRemoved() {
        mHost.removeTile(getTileSpec());
        // No OP as this may race with the user change in CurrentTilesInteractor.
        // If the tile needs to be removed, AutoAdd (or AutoTileManager) will take care of that.
    }

    @Override
+6 −1
Original line number Diff line number Diff line
@@ -22,12 +22,15 @@ import androidx.annotation.StringRes
import com.android.internal.logging.InstanceId
import com.android.systemui.qs.pipeline.shared.TileSpec

data class QSTileConfig(
data class QSTileConfig
@JvmOverloads
constructor(
    val tileSpec: TileSpec,
    val uiConfig: QSTileUIConfig,
    val instanceId: InstanceId,
    val metricsSpec: String = tileSpec.spec,
    val policy: QSTilePolicy = QSTilePolicy.NoRestrictions,
    val autoRemoveOnUnavailable: Boolean = true,
)

/**
@@ -38,6 +41,7 @@ sealed interface QSTileUIConfig {

    val iconRes: Int
        @DrawableRes get

    val labelRes: Int
        @StringRes get

@@ -48,6 +52,7 @@ sealed interface QSTileUIConfig {
    data object Empty : QSTileUIConfig {
        override val iconRes: Int
            get() = Resources.ID_NULL

        override val labelRes: Int
            get() = Resources.ID_NULL
    }
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ constructor(
            applicationScope.launch {
                launch {
                    qsTileViewModel.isAvailable.collectIndexed { index, isAvailable ->
                        if (!isAvailable) {
                        if (!isAvailable && qsTileViewModel.config.autoRemoveOnUnavailable) {
                            qsHost.removeTile(tileSpec)
                        }
                        // qsTileViewModel.isAvailable flow often starts with isAvailable == true.
Loading