Loading packages/SystemUI/multivalentTests/src/com/android/systemui/actioncorner/domain/interactor/ActionCornerInteractorTest.kt +72 −7 Original line number Diff line number Diff line Loading @@ -21,19 +21,28 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.LauncherProxyService import com.android.systemui.SysuiTestCase import com.android.systemui.actioncorner.data.model.ActionCornerRegion import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_LEFT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_RIGHT import com.android.systemui.actioncorner.data.model.ActionCornerState import com.android.systemui.actioncorner.data.model.ActionCornerState.ActiveActionCorner import com.android.systemui.actioncorner.data.repository.FakeActionCornerRepository import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.domain.interactor.shadeModeInteractor import com.android.systemui.shade.shadeTestUtil import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.HOME import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.OVERVIEW import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import org.junit.Before import org.junit.runner.RunWith Loading @@ -41,35 +50,91 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.verify @SmallTest @EnableSceneContainer @RunWith(AndroidJUnit4::class) class ActionCornerInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val Kosmos.actionCornerRepository by Fixture { FakeActionCornerRepository() } private val Kosmos.launcherProxyService by Fixture { mock<LauncherProxyService>() } private val Kosmos.underTest by Fixture { ActionCornerInteractor(kosmos.actionCornerRepository, kosmos.launcherProxyService) ActionCornerInteractor( testScope.coroutineContext, actionCornerRepository, launcherProxyService, shadeModeInteractor, shadeInteractor, ) } @Before fun setUp() { kosmos.enableDualShade() kosmos.underTest.activateIn(kosmos.testScope) } @Test fun bottomLeftCornerActivated_notifyLauncherOfOverviewAction() = kosmos.runTest { actionCornerRepository.addState( ActionCornerState.ActiveActionCorner(BOTTOM_LEFT, DEFAULT_DISPLAY) ) actionCornerRepository.addState(ActiveActionCorner(BOTTOM_LEFT, DEFAULT_DISPLAY)) verify(launcherProxyService).onActionCornerActivated(OVERVIEW, DEFAULT_DISPLAY) } @Test fun bottomRightCornerActivated_notifyLauncherOfHomeAction() = kosmos.runTest { actionCornerRepository.addState(ActiveActionCorner(BOTTOM_RIGHT, DEFAULT_DISPLAY)) verify(launcherProxyService).onActionCornerActivated(HOME, DEFAULT_DISPLAY) } @Test fun shadeCollapsed_topLeftCornerActivated_expandNotificationShade() = kosmos.runTest { shadeTestUtil.setShadeExpansion(0f) actionCornerRepository.addState( ActiveActionCorner(ActionCornerRegion.TOP_LEFT, DEFAULT_DISPLAY) ) assertThat(sceneInteractor.currentOverlays.value) .containsExactly(Overlays.NotificationsShade) } @Test fun shadeExpanded_topLeftCornerActivated_collapseNotificationShade() = kosmos.runTest { shadeTestUtil.setShadeExpansion(1f) actionCornerRepository.addState( ActionCornerState.ActiveActionCorner(BOTTOM_RIGHT, DEFAULT_DISPLAY) ActiveActionCorner(ActionCornerRegion.TOP_LEFT, DEFAULT_DISPLAY) ) verify(launcherProxyService).onActionCornerActivated(HOME, DEFAULT_DISPLAY) assertThat(sceneInteractor.currentOverlays.value) .doesNotContain(Overlays.NotificationsShade) } @Test fun qsCollapsed_topRightCornerActivated_expandQsPanel() = kosmos.runTest { shadeTestUtil.setQsExpansion(0f) actionCornerRepository.addState( ActiveActionCorner(ActionCornerRegion.TOP_RIGHT, DEFAULT_DISPLAY) ) assertThat(sceneInteractor.currentOverlays.value) .containsExactly(Overlays.QuickSettingsShade) } @Test fun qsExpanded_topRightCornerActivated_collapseQsPanel() = kosmos.runTest { shadeTestUtil.setQsExpansion(1f) actionCornerRepository.addState( ActiveActionCorner(ActionCornerRegion.TOP_RIGHT, DEFAULT_DISPLAY) ) assertThat(sceneInteractor.currentOverlays.value) .doesNotContain(Overlays.QuickSettingsShade) } } packages/SystemUI/src/com/android/systemui/actioncorner/domain/interactor/ActionCornerInteractor.kt +42 −2 Original line number Diff line number Diff line Loading @@ -19,22 +19,34 @@ package com.android.systemui.actioncorner.domain.interactor import com.android.systemui.LauncherProxyService import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_LEFT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_RIGHT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.TOP_LEFT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.TOP_RIGHT import com.android.systemui.actioncorner.data.model.ActionCornerState import com.android.systemui.actioncorner.data.repository.ActionCornerRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.shade.shared.model.ShadeMode.Dual import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.HOME import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.OVERVIEW import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.withContext @SysUISingleton class ActionCornerInteractor @Inject constructor( @Main private val mainThreadContext: CoroutineContext, private val repository: ActionCornerRepository, private val launcherProxyService: LauncherProxyService, private val shadeModeInteractor: ShadeModeInteractor, private val shadeInteractor: ShadeInteractor, ) : ExclusiveActivatable() { override suspend fun onActivated(): Nothing { Loading @@ -43,13 +55,41 @@ constructor( .collect { // TODO(b/410791828): Read corresponding action from Action Corner Setting page when (it.region) { TOP_LEFT -> { if (isDualShadeEnabled()) { withContext(mainThreadContext) { if (shadeInteractor.isShadeAnyExpanded.value) { shadeInteractor.collapseNotificationsShade(LOGGING_REASON) } else { shadeInteractor.expandNotificationsShade(LOGGING_REASON) } } } } TOP_RIGHT -> { if (isDualShadeEnabled()) { withContext(mainThreadContext) { if (shadeInteractor.isQsExpanded.value) { shadeInteractor.collapseQuickSettingsShade(LOGGING_REASON) } else { shadeInteractor.expandQuickSettingsShade(LOGGING_REASON) } } } } BOTTOM_LEFT -> launcherProxyService.onActionCornerActivated(OVERVIEW, it.displayId) BOTTOM_RIGHT -> launcherProxyService.onActionCornerActivated(HOME, it.displayId) // TODO(b/411091884): Handle actions for notification shade and QS else -> {} } } awaitCancellation() } private fun isDualShadeEnabled(): Boolean { return SceneContainerFlag.isEnabled && shadeModeInteractor.shadeMode.value == Dual } companion object { private const val LOGGING_REASON = "Active action corner" } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/actioncorner/domain/interactor/ActionCornerInteractorTest.kt +72 −7 Original line number Diff line number Diff line Loading @@ -21,19 +21,28 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.LauncherProxyService import com.android.systemui.SysuiTestCase import com.android.systemui.actioncorner.data.model.ActionCornerRegion import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_LEFT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_RIGHT import com.android.systemui.actioncorner.data.model.ActionCornerState import com.android.systemui.actioncorner.data.model.ActionCornerState.ActiveActionCorner import com.android.systemui.actioncorner.data.repository.FakeActionCornerRepository import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.domain.interactor.shadeModeInteractor import com.android.systemui.shade.shadeTestUtil import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.HOME import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.OVERVIEW import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import org.junit.Before import org.junit.runner.RunWith Loading @@ -41,35 +50,91 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.verify @SmallTest @EnableSceneContainer @RunWith(AndroidJUnit4::class) class ActionCornerInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val Kosmos.actionCornerRepository by Fixture { FakeActionCornerRepository() } private val Kosmos.launcherProxyService by Fixture { mock<LauncherProxyService>() } private val Kosmos.underTest by Fixture { ActionCornerInteractor(kosmos.actionCornerRepository, kosmos.launcherProxyService) ActionCornerInteractor( testScope.coroutineContext, actionCornerRepository, launcherProxyService, shadeModeInteractor, shadeInteractor, ) } @Before fun setUp() { kosmos.enableDualShade() kosmos.underTest.activateIn(kosmos.testScope) } @Test fun bottomLeftCornerActivated_notifyLauncherOfOverviewAction() = kosmos.runTest { actionCornerRepository.addState( ActionCornerState.ActiveActionCorner(BOTTOM_LEFT, DEFAULT_DISPLAY) ) actionCornerRepository.addState(ActiveActionCorner(BOTTOM_LEFT, DEFAULT_DISPLAY)) verify(launcherProxyService).onActionCornerActivated(OVERVIEW, DEFAULT_DISPLAY) } @Test fun bottomRightCornerActivated_notifyLauncherOfHomeAction() = kosmos.runTest { actionCornerRepository.addState(ActiveActionCorner(BOTTOM_RIGHT, DEFAULT_DISPLAY)) verify(launcherProxyService).onActionCornerActivated(HOME, DEFAULT_DISPLAY) } @Test fun shadeCollapsed_topLeftCornerActivated_expandNotificationShade() = kosmos.runTest { shadeTestUtil.setShadeExpansion(0f) actionCornerRepository.addState( ActiveActionCorner(ActionCornerRegion.TOP_LEFT, DEFAULT_DISPLAY) ) assertThat(sceneInteractor.currentOverlays.value) .containsExactly(Overlays.NotificationsShade) } @Test fun shadeExpanded_topLeftCornerActivated_collapseNotificationShade() = kosmos.runTest { shadeTestUtil.setShadeExpansion(1f) actionCornerRepository.addState( ActionCornerState.ActiveActionCorner(BOTTOM_RIGHT, DEFAULT_DISPLAY) ActiveActionCorner(ActionCornerRegion.TOP_LEFT, DEFAULT_DISPLAY) ) verify(launcherProxyService).onActionCornerActivated(HOME, DEFAULT_DISPLAY) assertThat(sceneInteractor.currentOverlays.value) .doesNotContain(Overlays.NotificationsShade) } @Test fun qsCollapsed_topRightCornerActivated_expandQsPanel() = kosmos.runTest { shadeTestUtil.setQsExpansion(0f) actionCornerRepository.addState( ActiveActionCorner(ActionCornerRegion.TOP_RIGHT, DEFAULT_DISPLAY) ) assertThat(sceneInteractor.currentOverlays.value) .containsExactly(Overlays.QuickSettingsShade) } @Test fun qsExpanded_topRightCornerActivated_collapseQsPanel() = kosmos.runTest { shadeTestUtil.setQsExpansion(1f) actionCornerRepository.addState( ActiveActionCorner(ActionCornerRegion.TOP_RIGHT, DEFAULT_DISPLAY) ) assertThat(sceneInteractor.currentOverlays.value) .doesNotContain(Overlays.QuickSettingsShade) } }
packages/SystemUI/src/com/android/systemui/actioncorner/domain/interactor/ActionCornerInteractor.kt +42 −2 Original line number Diff line number Diff line Loading @@ -19,22 +19,34 @@ package com.android.systemui.actioncorner.domain.interactor import com.android.systemui.LauncherProxyService import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_LEFT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.BOTTOM_RIGHT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.TOP_LEFT import com.android.systemui.actioncorner.data.model.ActionCornerRegion.TOP_RIGHT import com.android.systemui.actioncorner.data.model.ActionCornerState import com.android.systemui.actioncorner.data.repository.ActionCornerRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.shade.shared.model.ShadeMode.Dual import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.HOME import com.android.systemui.shared.system.actioncorner.ActionCornerConstants.OVERVIEW import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.withContext @SysUISingleton class ActionCornerInteractor @Inject constructor( @Main private val mainThreadContext: CoroutineContext, private val repository: ActionCornerRepository, private val launcherProxyService: LauncherProxyService, private val shadeModeInteractor: ShadeModeInteractor, private val shadeInteractor: ShadeInteractor, ) : ExclusiveActivatable() { override suspend fun onActivated(): Nothing { Loading @@ -43,13 +55,41 @@ constructor( .collect { // TODO(b/410791828): Read corresponding action from Action Corner Setting page when (it.region) { TOP_LEFT -> { if (isDualShadeEnabled()) { withContext(mainThreadContext) { if (shadeInteractor.isShadeAnyExpanded.value) { shadeInteractor.collapseNotificationsShade(LOGGING_REASON) } else { shadeInteractor.expandNotificationsShade(LOGGING_REASON) } } } } TOP_RIGHT -> { if (isDualShadeEnabled()) { withContext(mainThreadContext) { if (shadeInteractor.isQsExpanded.value) { shadeInteractor.collapseQuickSettingsShade(LOGGING_REASON) } else { shadeInteractor.expandQuickSettingsShade(LOGGING_REASON) } } } } BOTTOM_LEFT -> launcherProxyService.onActionCornerActivated(OVERVIEW, it.displayId) BOTTOM_RIGHT -> launcherProxyService.onActionCornerActivated(HOME, it.displayId) // TODO(b/411091884): Handle actions for notification shade and QS else -> {} } } awaitCancellation() } private fun isDualShadeEnabled(): Boolean { return SceneContainerFlag.isEnabled && shadeModeInteractor.shadeMode.value == Dual } companion object { private const val LOGGING_REASON = "Active action corner" } }