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

Commit bf020d37 authored by Behnam Heydarshahi's avatar Behnam Heydarshahi
Browse files

Cache installed tile component flow per user

Flag: NA
Fixes: 319909665
Test: atest InstalledTilesComponentRepositoryImplTests
Test: atest SystemUiRoboTests
Change-Id: I7a62493d9f09b26781136f384082ed2d598f8718
parent 5eba0763
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import com.android.systemui.common.data.repository.fakePackageChangeRepository
import com.android.systemui.common.data.repository.packageChangeRepository
import com.android.systemui.common.data.shared.model.PackageChangeModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
@@ -44,6 +43,8 @@ import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
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
@@ -52,6 +53,7 @@ import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@@ -82,7 +84,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
        underTest =
            InstalledTilesComponentRepositoryImpl(
                context,
                kosmos.testDispatcher,
                testScope.backgroundScope,
                kosmos.packageChangeRepository
            )
    }
@@ -103,6 +105,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
                .thenReturn(listOf(resolveInfo))

            val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId))
            runCurrent()

            assertThat(componentNames).containsExactly(TEST_COMPONENT)
        }
@@ -115,6 +118,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
                ResolveInfo(TEST_COMPONENT, hasPermission = true, defaultEnabled = true)

            val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId))
            runCurrent()

            assertThat(componentNames).isEmpty()

            whenever(
@@ -126,6 +131,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
                )
                .thenReturn(listOf(resolveInfo))
            kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty)
            runCurrent()

            assertThat(componentNames).containsExactly(TEST_COMPONENT)
        }
@@ -146,6 +152,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
                .thenReturn(listOf(resolveInfo))

            val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId))
            runCurrent()

            assertThat(componentNames).isEmpty()
        }

@@ -165,6 +173,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
                .thenReturn(listOf(resolveInfo))

            val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId))
            runCurrent()

            assertThat(componentNames).isEmpty()
        }

@@ -210,10 +220,31 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() {
                .thenReturn(listOf(resolveInfo))

            val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId))
            runCurrent()

            assertThat(componentNames).containsExactly(TEST_COMPONENT)
        }

    @Test
    fun loadComponentsForSameUserTwice_returnsSameFlow() =
        testScope.runTest {
            val flowForUser1 = underTest.getInstalledTilesComponents(1)
            val flowForUser1TheSecondTime = underTest.getInstalledTilesComponents(1)
            runCurrent()

            assertThat(flowForUser1TheSecondTime).isEqualTo(flowForUser1)
        }

    @Test
    fun loadComponentsForDifferentUsers_returnsDifferentFlow() =
        testScope.runTest {
            val flowForUser1 = underTest.getInstalledTilesComponents(1)
            val flowForUser2 = underTest.getInstalledTilesComponents(2)
            runCurrent()

            assertThat(flowForUser2).isNotEqualTo(flowForUser1)
        }

    companion object {
        private val INTENT = Intent(TileService.ACTION_QS_TILE)
        private val FLAGS =
+33 −25
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.pm.PackageManager
import android.content.pm.PackageManager.ResolveInfoFlags
import android.os.UserHandle
import android.service.quicksettings.TileService
import androidx.annotation.GuardedBy
import com.android.systemui.common.data.repository.PackageChangeRepository
import com.android.systemui.common.data.shared.model.PackageChangeModel
import com.android.systemui.dagger.SysUISingleton
@@ -32,12 +33,13 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.util.kotlin.isComponentActuallyEnabled
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn

interface InstalledTilesComponentRepository {

@@ -49,14 +51,19 @@ class InstalledTilesComponentRepositoryImpl
@Inject
constructor(
    @Application private val applicationContext: Context,
    @Background private val backgroundDispatcher: CoroutineDispatcher,
    @Background private val backgroundScope: CoroutineScope,
    private val packageChangeRepository: PackageChangeRepository
) : InstalledTilesComponentRepository {

    override fun getInstalledTilesComponents(userId: Int): Flow<Set<ComponentName>> {
    @GuardedBy("userMap") private val userMap = mutableMapOf<Int, Flow<Set<ComponentName>>>()

    override fun getInstalledTilesComponents(userId: Int): Flow<Set<ComponentName>> =
        synchronized(userMap) {
            userMap.getOrPut(userId) {
                /*
         * In order to query [PackageManager] for different users, this implementation will call
         * [Context.createContextAsUser] and retrieve the [PackageManager] from that context.
                 * In order to query [PackageManager] for different users, this implementation will
                 * call [Context.createContextAsUser] and retrieve the [PackageManager] from that
                 * context.
                 */
                val packageManager =
                    if (applicationContext.userId == userId) {
@@ -69,12 +76,13 @@ constructor(
                            )
                            .packageManager
                    }
        return packageChangeRepository
                packageChangeRepository
                    .packageChanged(UserHandle.of(userId))
                    .onStart { emit(PackageChangeModel.Empty) }
                    .map { reloadComponents(userId, packageManager) }
                    .distinctUntilChanged()
            .flowOn(backgroundDispatcher)
                    .shareIn(backgroundScope, SharingStarted.WhileSubscribed(), replay = 1)
            }
        }

    @WorkerThread