Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt +33 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -82,7 +84,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { underTest = InstalledTilesComponentRepositoryImpl( context, kosmos.testDispatcher, testScope.backgroundScope, kosmos.packageChangeRepository ) } Loading @@ -103,6 +105,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) } Loading @@ -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( Loading @@ -126,6 +131,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { ) .thenReturn(listOf(resolveInfo)) kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) } Loading @@ -146,6 +152,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() } Loading @@ -165,6 +173,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() } Loading Loading @@ -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 = Loading packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt +33 −25 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 { Loading @@ -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) { Loading @@ -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 Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt +33 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -82,7 +84,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { underTest = InstalledTilesComponentRepositoryImpl( context, kosmos.testDispatcher, testScope.backgroundScope, kosmos.packageChangeRepository ) } Loading @@ -103,6 +105,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) } Loading @@ -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( Loading @@ -126,6 +131,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { ) .thenReturn(listOf(resolveInfo)) kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) } Loading @@ -146,6 +152,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() } Loading @@ -165,6 +173,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() } Loading Loading @@ -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 = Loading
packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt +33 −25 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 { Loading @@ -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) { Loading @@ -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 Loading