Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt +33 −2 Original line number Original line 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.repository.packageChangeRepository import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any 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.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Before import org.junit.Test import org.junit.Test Loading @@ -52,6 +53,7 @@ import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mock import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @SmallTest @RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper @TestableLooper.RunWithLooper Loading Loading @@ -82,7 +84,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { underTest = underTest = InstalledTilesComponentRepositoryImpl( InstalledTilesComponentRepositoryImpl( context, context, kosmos.testDispatcher, testScope.backgroundScope, kosmos.packageChangeRepository kosmos.packageChangeRepository ) ) } } Loading @@ -103,6 +105,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) assertThat(componentNames).containsExactly(TEST_COMPONENT) } } Loading @@ -115,6 +118,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { ResolveInfo(TEST_COMPONENT, hasPermission = true, defaultEnabled = true) ResolveInfo(TEST_COMPONENT, hasPermission = true, defaultEnabled = true) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() assertThat(componentNames).isEmpty() whenever( whenever( Loading @@ -126,6 +131,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { ) ) .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty) kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) assertThat(componentNames).containsExactly(TEST_COMPONENT) } } Loading @@ -146,6 +152,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() assertThat(componentNames).isEmpty() } } Loading @@ -165,6 +173,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() assertThat(componentNames).isEmpty() } } Loading Loading @@ -210,10 +220,31 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) 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 { companion object { private val INTENT = Intent(TileService.ACTION_QS_TILE) private val INTENT = Intent(TileService.ACTION_QS_TILE) private val FLAGS = private val FLAGS = Loading packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt +33 −25 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.pm.PackageManager import android.content.pm.PackageManager.ResolveInfoFlags import android.content.pm.PackageManager.ResolveInfoFlags import android.os.UserHandle import android.os.UserHandle import android.service.quicksettings.TileService import android.service.quicksettings.TileService import androidx.annotation.GuardedBy import com.android.systemui.common.data.repository.PackageChangeRepository import com.android.systemui.common.data.repository.PackageChangeRepository import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.dagger.SysUISingleton 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.dagger.qualifiers.Background import com.android.systemui.util.kotlin.isComponentActuallyEnabled import com.android.systemui.util.kotlin.isComponentActuallyEnabled import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn interface InstalledTilesComponentRepository { interface InstalledTilesComponentRepository { Loading @@ -49,14 +51,19 @@ class InstalledTilesComponentRepositoryImpl @Inject @Inject constructor( constructor( @Application private val applicationContext: Context, @Application private val applicationContext: Context, @Background private val backgroundDispatcher: CoroutineDispatcher, @Background private val backgroundScope: CoroutineScope, private val packageChangeRepository: PackageChangeRepository private val packageChangeRepository: PackageChangeRepository ) : InstalledTilesComponentRepository { ) : 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 * In order to query [PackageManager] for different users, this implementation will * [Context.createContextAsUser] and retrieve the [PackageManager] from that context. * call [Context.createContextAsUser] and retrieve the [PackageManager] from that * context. */ */ val packageManager = val packageManager = if (applicationContext.userId == userId) { if (applicationContext.userId == userId) { Loading @@ -69,12 +76,13 @@ constructor( ) ) .packageManager .packageManager } } return packageChangeRepository packageChangeRepository .packageChanged(UserHandle.of(userId)) .packageChanged(UserHandle.of(userId)) .onStart { emit(PackageChangeModel.Empty) } .onStart { emit(PackageChangeModel.Empty) } .map { reloadComponents(userId, packageManager) } .map { reloadComponents(userId, packageManager) } .distinctUntilChanged() .distinctUntilChanged() .flowOn(backgroundDispatcher) .shareIn(backgroundScope, SharingStarted.WhileSubscribed(), replay = 1) } } } @WorkerThread @WorkerThread Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt +33 −2 Original line number Original line 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.repository.packageChangeRepository import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any 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.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Before import org.junit.Test import org.junit.Test Loading @@ -52,6 +53,7 @@ import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mock import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @SmallTest @RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper @TestableLooper.RunWithLooper Loading Loading @@ -82,7 +84,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { underTest = underTest = InstalledTilesComponentRepositoryImpl( InstalledTilesComponentRepositoryImpl( context, context, kosmos.testDispatcher, testScope.backgroundScope, kosmos.packageChangeRepository kosmos.packageChangeRepository ) ) } } Loading @@ -103,6 +105,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) assertThat(componentNames).containsExactly(TEST_COMPONENT) } } Loading @@ -115,6 +118,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { ResolveInfo(TEST_COMPONENT, hasPermission = true, defaultEnabled = true) ResolveInfo(TEST_COMPONENT, hasPermission = true, defaultEnabled = true) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() assertThat(componentNames).isEmpty() whenever( whenever( Loading @@ -126,6 +131,7 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { ) ) .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty) kosmos.fakePackageChangeRepository.notifyChange(PackageChangeModel.Empty) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) assertThat(componentNames).containsExactly(TEST_COMPONENT) } } Loading @@ -146,6 +152,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() assertThat(componentNames).isEmpty() } } Loading @@ -165,6 +173,8 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).isEmpty() assertThat(componentNames).isEmpty() } } Loading Loading @@ -210,10 +220,31 @@ class InstalledTilesComponentRepositoryImplTest : SysuiTestCase() { .thenReturn(listOf(resolveInfo)) .thenReturn(listOf(resolveInfo)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) val componentNames by collectLastValue(underTest.getInstalledTilesComponents(userId)) runCurrent() assertThat(componentNames).containsExactly(TEST_COMPONENT) 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 { companion object { private val INTENT = Intent(TileService.ACTION_QS_TILE) private val INTENT = Intent(TileService.ACTION_QS_TILE) private val FLAGS = private val FLAGS = Loading
packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt +33 −25 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.pm.PackageManager import android.content.pm.PackageManager.ResolveInfoFlags import android.content.pm.PackageManager.ResolveInfoFlags import android.os.UserHandle import android.os.UserHandle import android.service.quicksettings.TileService import android.service.quicksettings.TileService import androidx.annotation.GuardedBy import com.android.systemui.common.data.repository.PackageChangeRepository import com.android.systemui.common.data.repository.PackageChangeRepository import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.dagger.SysUISingleton 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.dagger.qualifiers.Background import com.android.systemui.util.kotlin.isComponentActuallyEnabled import com.android.systemui.util.kotlin.isComponentActuallyEnabled import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn interface InstalledTilesComponentRepository { interface InstalledTilesComponentRepository { Loading @@ -49,14 +51,19 @@ class InstalledTilesComponentRepositoryImpl @Inject @Inject constructor( constructor( @Application private val applicationContext: Context, @Application private val applicationContext: Context, @Background private val backgroundDispatcher: CoroutineDispatcher, @Background private val backgroundScope: CoroutineScope, private val packageChangeRepository: PackageChangeRepository private val packageChangeRepository: PackageChangeRepository ) : InstalledTilesComponentRepository { ) : 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 * In order to query [PackageManager] for different users, this implementation will * [Context.createContextAsUser] and retrieve the [PackageManager] from that context. * call [Context.createContextAsUser] and retrieve the [PackageManager] from that * context. */ */ val packageManager = val packageManager = if (applicationContext.userId == userId) { if (applicationContext.userId == userId) { Loading @@ -69,12 +76,13 @@ constructor( ) ) .packageManager .packageManager } } return packageChangeRepository packageChangeRepository .packageChanged(UserHandle.of(userId)) .packageChanged(UserHandle.of(userId)) .onStart { emit(PackageChangeModel.Empty) } .onStart { emit(PackageChangeModel.Empty) } .map { reloadComponents(userId, packageManager) } .map { reloadComponents(userId, packageManager) } .distinctUntilChanged() .distinctUntilChanged() .flowOn(backgroundDispatcher) .shareIn(backgroundScope, SharingStarted.WhileSubscribed(), replay = 1) } } } @WorkerThread @WorkerThread Loading