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

Commit e6b3a7f1 authored by Behnam Heydarshahi's avatar Behnam Heydarshahi Committed by Android (Google) Code Review
Browse files

Merge "Cache installed tile component flow per user" into main

parents 9c539c7b bf020d37
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