Loading packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageChangeRepositoryTest.kt +4 −2 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.applicationCoroutineScope Loading @@ -32,6 +32,7 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.testKosmos import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before Loading Loading @@ -67,7 +68,8 @@ class PackageChangeRepositoryTest : SysuiTestCase() { scope = applicationCoroutineScope, context = context, bgHandler = handler, logger = PackageUpdateLogger(logcatLogBuffer()) logger = PackageUpdateLogger(logcatLogBuffer()), systemClock = fakeSystemClock, ) updateMonitor } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageUpdateMonitorTest.kt +30 −7 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.applicationCoroutineScope Loading @@ -32,6 +32,7 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.testKosmos import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow Loading Loading @@ -71,8 +72,11 @@ class PackageUpdateMonitorTest : SysuiTestCase() { bgHandler = handler, context = context, scope = applicationCoroutineScope, logger = PackageUpdateLogger(logcatLogBuffer()) logger = PackageUpdateLogger(logcatLogBuffer()), systemClock = fakeSystemClock, ) fakeSystemClock.setCurrentTimeMillis(0) } @Test Loading @@ -96,11 +100,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageAdded(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.Installed(packageName = TEST_PACKAGE, packageUid = 123) PackageChangeModel.Installed( packageName = TEST_PACKAGE, packageUid = 123, timeMillis = 100, ) ) } } Loading @@ -112,11 +121,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(200) monitor.onPackageRemoved(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.Uninstalled(packageName = TEST_PACKAGE, packageUid = 123) PackageChangeModel.Uninstalled( packageName = TEST_PACKAGE, packageUid = 123, timeMillis = 200, ) ) } } Loading @@ -128,11 +142,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageChanged(TEST_PACKAGE, 123, emptyArray()) assertThat(packageChange) .isEqualTo( PackageChangeModel.Changed(packageName = TEST_PACKAGE, packageUid = 123) PackageChangeModel.Changed( packageName = TEST_PACKAGE, packageUid = 123, timeMillis = 100, ) ) } } Loading @@ -144,13 +163,15 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageUpdateStarted(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.UpdateStarted( packageName = TEST_PACKAGE, packageUid = 123 packageUid = 123, timeMillis = 100, ) ) } Loading @@ -163,13 +184,15 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageUpdateFinished(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.UpdateFinished( packageName = TEST_PACKAGE, packageUid = 123 packageUid = 123, timeMillis = 100, ) ) } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/PackageChangeInteractorTest.kt 0 → 100644 +175 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.common.domain.interactor import android.content.pm.UserInfo import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.repository.fakePackageChangeRepository import com.android.systemui.common.data.repository.packageChangeRepository import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.user.domain.interactor.selectedUserInteractor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class PackageChangeInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private lateinit var underTest: PackageChangeInteractor @Before fun setUp() = with(kosmos) { underTest = PackageChangeInteractor( packageChangeRepository = packageChangeRepository, userInteractor = selectedUserInteractor, ) fakeUserRepository.setUserInfos(listOf(MAIN_USER, SECONDARY_USER)) } @Test fun packageChanges() = with(kosmos) { testScope.runTest { val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE)) assertThat(packageChange).isNull() // Even if secondary user is active, we should still receive changes for the // primary user. setUser(SECONDARY_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "pkg", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java) assertThat(packageChange?.packageName).isEqualTo("pkg") } } @Test fun packageChanges_ignoresUpdatesFromOtherUsers() = with(kosmos) { testScope.runTest { val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE)) assertThat(packageChange).isNull() setUser(SECONDARY_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "pkg", packageUid = UserHandle.getUid(SECONDARY_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isNull() } } @Test fun packageChanges_forCurrentUser() = with(kosmos) { testScope.runTest { val packageChanges by collectValues(underTest.packageChanged(UserHandle.CURRENT)) assertThat(packageChanges).isEmpty() setUser(SECONDARY_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "first", packageUid = UserHandle.getUid(SECONDARY_USER.id, /* appId = */ 10), ) ) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "second", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) setUser(MAIN_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "third", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChanges.map { it.packageName }) .containsExactly("first", "third") .inOrder() } } @Test fun packageChanges_forSpecificPackageName() = with(kosmos) { testScope.runTest { val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE, "mypkg")) assertThat(packageChange).isNull() fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "other", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isNull() fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "mypkg", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java) assertThat(packageChange?.packageName).isEqualTo("mypkg") } } private suspend fun TestScope.setUser(user: UserInfo) { kosmos.fakeUserRepository.setSelectedUserInfo(user) runCurrent() } private companion object { val MAIN_USER_HANDLE = UserHandle.of(1) val MAIN_USER = UserInfo(MAIN_USER_HANDLE.identifier, "main", UserInfo.FLAG_MAIN) val SECONDARY_USER_HANDLE = UserHandle.of(2) val SECONDARY_USER = UserInfo(SECONDARY_USER_HANDLE.identifier, "secondary", 0) } } packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorKosmos.kt +7 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.systemui.dreams.homecontrols import android.service.dream.dreamManager import com.android.systemui.common.domain.interactor.packageChangeInteractor import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.panels.authorizedPanelsRepository Loading @@ -24,15 +26,19 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.mock import com.android.systemui.util.time.fakeSystemClock val Kosmos.homeControlsComponentInteractor by Kosmos.Fixture { HomeControlsComponentInteractor( selectedComponentRepository = selectedComponentRepository, controlsComponent, controlsComponent = controlsComponent, authorizedPanelsRepository = authorizedPanelsRepository, userRepository = fakeUserRepository, bgScope = applicationCoroutineScope, systemClock = fakeSystemClock, dreamManager = dreamManager, packageChangeInteractor = packageChangeInteractor, ) } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt +109 −37 Original line number Diff line number Diff line Loading @@ -20,37 +20,38 @@ import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.ServiceInfo import android.content.pm.UserInfo import android.os.UserHandle import android.service.dream.dreamManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.repository.fakePackageChangeRepository import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.panels.AuthorizedPanelsRepository import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.panels.authorizedPanelsRepository import com.android.systemui.controls.panels.selectedComponentRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.dreams.homecontrols.domain.interactor.HomeControlsComponentInteractor import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.dreams.homecontrols.domain.interactor.HomeControlsComponentInteractor.Companion.MAX_UPDATE_CORRELATION_DELAY import com.android.systemui.kosmos.testScope import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import java.util.Optional import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest Loading @@ -59,36 +60,17 @@ class HomeControlsComponentInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private lateinit var controlsComponent: ControlsComponent private lateinit var controlsListingController: ControlsListingController private lateinit var authorizedPanelsRepository: AuthorizedPanelsRepository private lateinit var underTest: HomeControlsComponentInteractor private lateinit var userRepository: FakeUserRepository private lateinit var selectedComponentRepository: SelectedComponentRepository @Before fun setUp() { MockitoAnnotations.initMocks(this) controlsComponent = kosmos.controlsComponent authorizedPanelsRepository = kosmos.authorizedPanelsRepository controlsListingController = kosmos.controlsListingController selectedComponentRepository = kosmos.selectedComponentRepository userRepository = kosmos.fakeUserRepository userRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER)) fun setUp() = with(kosmos) { fakeSystemClock.setCurrentTimeMillis(0) fakeUserRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER)) whenever(controlsComponent.getControlsListingController()) .thenReturn(Optional.of(controlsListingController)) underTest = HomeControlsComponentInteractor( selectedComponentRepository, controlsComponent, authorizedPanelsRepository, userRepository, kosmos.applicationCoroutineScope, ) underTest = homeControlsComponentInteractor } @Test Loading Loading @@ -181,22 +163,112 @@ class HomeControlsComponentInteractorTest : SysuiTestCase() { authorizedPanelsRepository.addAuthorizedPanels(setOf(TEST_PACKAGE)) whenever(controlsComponent.getControlsListingController()) .thenReturn(Optional.empty()) userRepository.setSelectedUserInfo(PRIMARY_USER) fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) selectedComponentRepository.setSelectedComponent(TEST_SELECTED_COMPONENT_PANEL) val actualValue by collectLastValue(underTest.panelComponent) assertThat(actualValue).isNull() } } @Test fun testMonitoringUpdatesAndRestart() = with(kosmos) { testScope.runTest { setActiveUser(PRIMARY_USER) authorizedPanelsRepository.addAuthorizedPanels(setOf(TEST_PACKAGE)) selectedComponentRepository.setSelectedComponent(TEST_SELECTED_COMPONENT_PANEL) whenever(controlsListingController.getCurrentServices()) .thenReturn( listOf(ControlsServiceInfo(TEST_COMPONENT, "panel", hasPanel = true)) ) val job = launch { underTest.monitorUpdatesAndRestart() } val panelComponent by collectLastValue(underTest.panelComponent) assertThat(panelComponent).isEqualTo(TEST_COMPONENT) verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(100) // The package update is started. fakePackageChangeRepository.notifyUpdateStarted( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) fakeSystemClock.advanceTime(MAX_UPDATE_CORRELATION_DELAY.inWholeMilliseconds) // Task fragment becomes empty as a result of the update. underTest.onTaskFragmentEmpty() runCurrent() verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(500) // The package update is finished. fakePackageChangeRepository.notifyUpdateFinished( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) runCurrent() verify(dreamManager).startDream() job.cancel() } } @Test fun testMonitoringUpdatesAndRestart_dreamEndsAfterDelay() = with(kosmos) { testScope.runTest { setActiveUser(PRIMARY_USER) authorizedPanelsRepository.addAuthorizedPanels(setOf(TEST_PACKAGE)) selectedComponentRepository.setSelectedComponent(TEST_SELECTED_COMPONENT_PANEL) whenever(controlsListingController.getCurrentServices()) .thenReturn( listOf(ControlsServiceInfo(TEST_COMPONENT, "panel", hasPanel = true)) ) val job = launch { underTest.monitorUpdatesAndRestart() } val panelComponent by collectLastValue(underTest.panelComponent) assertThat(panelComponent).isEqualTo(TEST_COMPONENT) verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(100) // The package update is started. fakePackageChangeRepository.notifyUpdateStarted( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) fakeSystemClock.advanceTime(MAX_UPDATE_CORRELATION_DELAY.inWholeMilliseconds + 100) // Task fragment becomes empty as a result of the update. underTest.onTaskFragmentEmpty() runCurrent() verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(500) // The package update is finished. fakePackageChangeRepository.notifyUpdateFinished( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) runCurrent() verify(dreamManager, never()).startDream() job.cancel() } } private fun runServicesUpdate(hasPanelBoolean: Boolean = true) { val listings = listOf(ControlsServiceInfo(TEST_COMPONENT, "panel", hasPanel = hasPanelBoolean)) val callback = withArgCaptor { verify(controlsListingController).addCallback(capture()) } val callback = withArgCaptor { verify(kosmos.controlsListingController).addCallback(capture()) } callback.onServicesUpdated(listings) } private suspend fun TestScope.setActiveUser(user: UserInfo) { userRepository.setSelectedUserInfo(user) kosmos.fakeUserRepository.setSelectedUserInfo(user) kosmos.fakeUserTracker.set(listOf(user), 0) runCurrent() } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageChangeRepositoryTest.kt +4 −2 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.applicationCoroutineScope Loading @@ -32,6 +32,7 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.testKosmos import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before Loading Loading @@ -67,7 +68,8 @@ class PackageChangeRepositoryTest : SysuiTestCase() { scope = applicationCoroutineScope, context = context, bgHandler = handler, logger = PackageUpdateLogger(logcatLogBuffer()) logger = PackageUpdateLogger(logcatLogBuffer()), systemClock = fakeSystemClock, ) updateMonitor } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageUpdateMonitorTest.kt +30 −7 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.shared.model.PackageChangeModel import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.applicationCoroutineScope Loading @@ -32,6 +32,7 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.testKosmos import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow Loading Loading @@ -71,8 +72,11 @@ class PackageUpdateMonitorTest : SysuiTestCase() { bgHandler = handler, context = context, scope = applicationCoroutineScope, logger = PackageUpdateLogger(logcatLogBuffer()) logger = PackageUpdateLogger(logcatLogBuffer()), systemClock = fakeSystemClock, ) fakeSystemClock.setCurrentTimeMillis(0) } @Test Loading @@ -96,11 +100,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageAdded(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.Installed(packageName = TEST_PACKAGE, packageUid = 123) PackageChangeModel.Installed( packageName = TEST_PACKAGE, packageUid = 123, timeMillis = 100, ) ) } } Loading @@ -112,11 +121,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(200) monitor.onPackageRemoved(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.Uninstalled(packageName = TEST_PACKAGE, packageUid = 123) PackageChangeModel.Uninstalled( packageName = TEST_PACKAGE, packageUid = 123, timeMillis = 200, ) ) } } Loading @@ -128,11 +142,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageChanged(TEST_PACKAGE, 123, emptyArray()) assertThat(packageChange) .isEqualTo( PackageChangeModel.Changed(packageName = TEST_PACKAGE, packageUid = 123) PackageChangeModel.Changed( packageName = TEST_PACKAGE, packageUid = 123, timeMillis = 100, ) ) } } Loading @@ -144,13 +163,15 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageUpdateStarted(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.UpdateStarted( packageName = TEST_PACKAGE, packageUid = 123 packageUid = 123, timeMillis = 100, ) ) } Loading @@ -163,13 +184,15 @@ class PackageUpdateMonitorTest : SysuiTestCase() { val packageChange by collectLastValue(monitor.packageChanged) assertThat(packageChange).isNull() fakeSystemClock.setCurrentTimeMillis(100) monitor.onPackageUpdateFinished(TEST_PACKAGE, 123) assertThat(packageChange) .isEqualTo( PackageChangeModel.UpdateFinished( packageName = TEST_PACKAGE, packageUid = 123 packageUid = 123, timeMillis = 100, ) ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/PackageChangeInteractorTest.kt 0 → 100644 +175 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.common.domain.interactor import android.content.pm.UserInfo import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.repository.fakePackageChangeRepository import com.android.systemui.common.data.repository.packageChangeRepository import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.user.domain.interactor.selectedUserInteractor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class PackageChangeInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private lateinit var underTest: PackageChangeInteractor @Before fun setUp() = with(kosmos) { underTest = PackageChangeInteractor( packageChangeRepository = packageChangeRepository, userInteractor = selectedUserInteractor, ) fakeUserRepository.setUserInfos(listOf(MAIN_USER, SECONDARY_USER)) } @Test fun packageChanges() = with(kosmos) { testScope.runTest { val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE)) assertThat(packageChange).isNull() // Even if secondary user is active, we should still receive changes for the // primary user. setUser(SECONDARY_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "pkg", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java) assertThat(packageChange?.packageName).isEqualTo("pkg") } } @Test fun packageChanges_ignoresUpdatesFromOtherUsers() = with(kosmos) { testScope.runTest { val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE)) assertThat(packageChange).isNull() setUser(SECONDARY_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "pkg", packageUid = UserHandle.getUid(SECONDARY_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isNull() } } @Test fun packageChanges_forCurrentUser() = with(kosmos) { testScope.runTest { val packageChanges by collectValues(underTest.packageChanged(UserHandle.CURRENT)) assertThat(packageChanges).isEmpty() setUser(SECONDARY_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "first", packageUid = UserHandle.getUid(SECONDARY_USER.id, /* appId = */ 10), ) ) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "second", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) setUser(MAIN_USER) fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "third", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChanges.map { it.packageName }) .containsExactly("first", "third") .inOrder() } } @Test fun packageChanges_forSpecificPackageName() = with(kosmos) { testScope.runTest { val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE, "mypkg")) assertThat(packageChange).isNull() fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "other", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isNull() fakePackageChangeRepository.notifyChange( PackageChangeModel.Installed( packageName = "mypkg", packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10), ) ) assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java) assertThat(packageChange?.packageName).isEqualTo("mypkg") } } private suspend fun TestScope.setUser(user: UserInfo) { kosmos.fakeUserRepository.setSelectedUserInfo(user) runCurrent() } private companion object { val MAIN_USER_HANDLE = UserHandle.of(1) val MAIN_USER = UserInfo(MAIN_USER_HANDLE.identifier, "main", UserInfo.FLAG_MAIN) val SECONDARY_USER_HANDLE = UserHandle.of(2) val SECONDARY_USER = UserInfo(SECONDARY_USER_HANDLE.identifier, "secondary", 0) } }
packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorKosmos.kt +7 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.systemui.dreams.homecontrols import android.service.dream.dreamManager import com.android.systemui.common.domain.interactor.packageChangeInteractor import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.panels.authorizedPanelsRepository Loading @@ -24,15 +26,19 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.mock import com.android.systemui.util.time.fakeSystemClock val Kosmos.homeControlsComponentInteractor by Kosmos.Fixture { HomeControlsComponentInteractor( selectedComponentRepository = selectedComponentRepository, controlsComponent, controlsComponent = controlsComponent, authorizedPanelsRepository = authorizedPanelsRepository, userRepository = fakeUserRepository, bgScope = applicationCoroutineScope, systemClock = fakeSystemClock, dreamManager = dreamManager, packageChangeInteractor = packageChangeInteractor, ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt +109 −37 Original line number Diff line number Diff line Loading @@ -20,37 +20,38 @@ import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.ServiceInfo import android.content.pm.UserInfo import android.os.UserHandle import android.service.dream.dreamManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.repository.fakePackageChangeRepository import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.panels.AuthorizedPanelsRepository import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.panels.authorizedPanelsRepository import com.android.systemui.controls.panels.selectedComponentRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.dreams.homecontrols.domain.interactor.HomeControlsComponentInteractor import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.dreams.homecontrols.domain.interactor.HomeControlsComponentInteractor.Companion.MAX_UPDATE_CORRELATION_DELAY import com.android.systemui.kosmos.testScope import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import java.util.Optional import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest Loading @@ -59,36 +60,17 @@ class HomeControlsComponentInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private lateinit var controlsComponent: ControlsComponent private lateinit var controlsListingController: ControlsListingController private lateinit var authorizedPanelsRepository: AuthorizedPanelsRepository private lateinit var underTest: HomeControlsComponentInteractor private lateinit var userRepository: FakeUserRepository private lateinit var selectedComponentRepository: SelectedComponentRepository @Before fun setUp() { MockitoAnnotations.initMocks(this) controlsComponent = kosmos.controlsComponent authorizedPanelsRepository = kosmos.authorizedPanelsRepository controlsListingController = kosmos.controlsListingController selectedComponentRepository = kosmos.selectedComponentRepository userRepository = kosmos.fakeUserRepository userRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER)) fun setUp() = with(kosmos) { fakeSystemClock.setCurrentTimeMillis(0) fakeUserRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER)) whenever(controlsComponent.getControlsListingController()) .thenReturn(Optional.of(controlsListingController)) underTest = HomeControlsComponentInteractor( selectedComponentRepository, controlsComponent, authorizedPanelsRepository, userRepository, kosmos.applicationCoroutineScope, ) underTest = homeControlsComponentInteractor } @Test Loading Loading @@ -181,22 +163,112 @@ class HomeControlsComponentInteractorTest : SysuiTestCase() { authorizedPanelsRepository.addAuthorizedPanels(setOf(TEST_PACKAGE)) whenever(controlsComponent.getControlsListingController()) .thenReturn(Optional.empty()) userRepository.setSelectedUserInfo(PRIMARY_USER) fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) selectedComponentRepository.setSelectedComponent(TEST_SELECTED_COMPONENT_PANEL) val actualValue by collectLastValue(underTest.panelComponent) assertThat(actualValue).isNull() } } @Test fun testMonitoringUpdatesAndRestart() = with(kosmos) { testScope.runTest { setActiveUser(PRIMARY_USER) authorizedPanelsRepository.addAuthorizedPanels(setOf(TEST_PACKAGE)) selectedComponentRepository.setSelectedComponent(TEST_SELECTED_COMPONENT_PANEL) whenever(controlsListingController.getCurrentServices()) .thenReturn( listOf(ControlsServiceInfo(TEST_COMPONENT, "panel", hasPanel = true)) ) val job = launch { underTest.monitorUpdatesAndRestart() } val panelComponent by collectLastValue(underTest.panelComponent) assertThat(panelComponent).isEqualTo(TEST_COMPONENT) verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(100) // The package update is started. fakePackageChangeRepository.notifyUpdateStarted( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) fakeSystemClock.advanceTime(MAX_UPDATE_CORRELATION_DELAY.inWholeMilliseconds) // Task fragment becomes empty as a result of the update. underTest.onTaskFragmentEmpty() runCurrent() verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(500) // The package update is finished. fakePackageChangeRepository.notifyUpdateFinished( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) runCurrent() verify(dreamManager).startDream() job.cancel() } } @Test fun testMonitoringUpdatesAndRestart_dreamEndsAfterDelay() = with(kosmos) { testScope.runTest { setActiveUser(PRIMARY_USER) authorizedPanelsRepository.addAuthorizedPanels(setOf(TEST_PACKAGE)) selectedComponentRepository.setSelectedComponent(TEST_SELECTED_COMPONENT_PANEL) whenever(controlsListingController.getCurrentServices()) .thenReturn( listOf(ControlsServiceInfo(TEST_COMPONENT, "panel", hasPanel = true)) ) val job = launch { underTest.monitorUpdatesAndRestart() } val panelComponent by collectLastValue(underTest.panelComponent) assertThat(panelComponent).isEqualTo(TEST_COMPONENT) verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(100) // The package update is started. fakePackageChangeRepository.notifyUpdateStarted( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) fakeSystemClock.advanceTime(MAX_UPDATE_CORRELATION_DELAY.inWholeMilliseconds + 100) // Task fragment becomes empty as a result of the update. underTest.onTaskFragmentEmpty() runCurrent() verify(dreamManager, never()).startDream() fakeSystemClock.advanceTime(500) // The package update is finished. fakePackageChangeRepository.notifyUpdateFinished( TEST_PACKAGE, UserHandle.of(PRIMARY_USER_ID), ) runCurrent() verify(dreamManager, never()).startDream() job.cancel() } } private fun runServicesUpdate(hasPanelBoolean: Boolean = true) { val listings = listOf(ControlsServiceInfo(TEST_COMPONENT, "panel", hasPanel = hasPanelBoolean)) val callback = withArgCaptor { verify(controlsListingController).addCallback(capture()) } val callback = withArgCaptor { verify(kosmos.controlsListingController).addCallback(capture()) } callback.onServicesUpdated(listings) } private suspend fun TestScope.setActiveUser(user: UserInfo) { userRepository.setSelectedUserInfo(user) kosmos.fakeUserRepository.setSelectedUserInfo(user) kosmos.fakeUserTracker.set(listOf(user), 0) runCurrent() } Loading