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

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

Merge "Guard access to SparseArray" into main

parents c2acd70c deda74a9
Loading
Loading
Loading
Loading
+39 −17
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.qs.pipeline.data.repository
import android.annotation.UserIdInt
import android.content.res.Resources
import android.util.SparseArray
import androidx.annotation.GuardedBy
import com.android.app.tracing.coroutines.launchTraced
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -36,6 +37,8 @@ import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

/** Repository that tracks the current tiles. */
interface TileSpecRepository {
@@ -116,19 +119,13 @@ constructor(
    private val _tilesUpgradePath = Channel<Pair<TilesUpgradePath, Int>>(capacity = 5)
    override val tilesUpgradePath = _tilesUpgradePath

    private val sparseArrayMutex = Mutex()

    @GuardedBy("sparseArrayMutex")
    private val userTileRepositories = SparseArray<UserTileSpecRepository>()

    override suspend fun tilesSpecs(userId: Int): Flow<List<TileSpec>> {
        if (userId !in userTileRepositories) {
            val userTileRepository = userTileSpecRepositoryFactory.create(userId)
            userTileRepositories.put(userId, userTileRepository)
            applicationScope.launchTraced("TileSpecRepository.aggregateTilesPerUser") {
                for (tileUpgrade in userTileRepository.tilesUpgradePath) {
                    _tilesUpgradePath.send(tileUpgrade to userId)
                }
            }
        }
        val realTiles = userTileRepositories.get(userId).tiles()
        val realTiles = getTileRepositoryForUser(userId).tiles()

        return retailModeRepository.retailMode.flatMapLatest { inRetailMode ->
            if (inRetailMode) {
@@ -147,29 +144,28 @@ constructor(
        if (tile is TileSpec.Invalid) {
            return
        }
        userTileRepositories.get(userId)?.addTile(tile, position)
        maybeGetTileRepositoryForUser(userId)?.addTile(tile, position)
    }

    override suspend fun removeTiles(userId: Int, tiles: Collection<TileSpec>) {
        if (retailModeRepository.inRetailMode) {
            return
        }
        userTileRepositories.get(userId)?.removeTiles(tiles)
        maybeGetTileRepositoryForUser(userId)?.removeTiles(tiles)
    }

    override suspend fun setTiles(userId: Int, tiles: List<TileSpec>) {
        if (retailModeRepository.inRetailMode) {
            return
        }
        userTileRepositories.get(userId)?.setTiles(tiles)
        maybeGetTileRepositoryForUser(userId)?.setTiles(tiles)
    }

    override suspend fun reconcileRestore(
        restoreData: RestoreData,
        currentAutoAdded: Set<TileSpec>,
    ) {
        userTileRepositories
            .get(restoreData.userId)
        maybeGetTileRepositoryForUser(restoreData.userId)
            ?.reconcileRestore(restoreData, currentAutoAdded)
    }

@@ -177,11 +173,37 @@ constructor(
        if (retailModeRepository.inRetailMode) {
            return
        }
        userTileRepositories.get(userId)?.prependDefault()
        maybeGetTileRepositoryForUser(userId)?.prependDefault()
    }

    override suspend fun resetToDefault(userId: Int) {
        userTileRepositories.get(userId)?.resetToDefault()
        maybeGetTileRepositoryForUser(userId)?.resetToDefault()
    }

    private suspend fun getTileRepositoryForUser(userId: Int): UserTileSpecRepository {
        return if (userId !in userTileRepositories) {
            sparseArrayMutex.withLock {
                if (userId !in userTileRepositories) {
                    val userTileRepository = userTileSpecRepositoryFactory.create(userId)
                    userTileRepositories.put(userId, userTileRepository)
                    logger.logTileSpecRespoitoryCreatedForUser(userId)
                    applicationScope.launchTraced("TileSpecRepository.aggregateTilesPerUser") {
                        for (tileUpgrade in userTileRepository.tilesUpgradePath) {
                            _tilesUpgradePath.send(tileUpgrade to userId)
                        }
                    }
                    userTileRepository
                } else {
                    userTileRepositories.get(userId)
                }
            }
        } else {
            sparseArrayMutex.withLock { userTileRepositories.get(userId) }
        }
    }

    private suspend fun maybeGetTileRepositoryForUser(userId: Int): UserTileSpecRepository? {
        return sparseArrayMutex.withLock { userTileRepositories.get(userId) }
    }

    companion object {
+10 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ constructor(
        const val TILE_LIST_TAG = "QSTileListLog"
        const val AUTO_ADD_TAG = "QSAutoAddableLog"
        const val RESTORE_TAG = "QSRestoreLog"
        const val REPOSITORY_TAG = "TileSpecRepositoryLog"
    }

    /**
@@ -271,6 +272,15 @@ constructor(
        )
    }

    fun logTileSpecRespoitoryCreatedForUser(userId: Int) {
        tileListLogBuffer.log(
            REPOSITORY_TAG,
            LogLevel.DEBUG,
            { int1 = userId },
            { "UserTileSpecRepository created for user $int1" },
        )
    }

    /** Reasons for destroying an existing tile. */
    enum class TileDestroyedReason(val readable: String) {
        TILE_REMOVED("Tile removed from  current set"),