diff options
author | 2024-12-10 15:23:33 +0000 | |
---|---|---|
committer | 2024-12-10 15:23:33 +0000 | |
commit | f0b78a46c293dac5f3e04e16ef46004ca0346e1c (patch) | |
tree | e048d6766984b0663aaa73e5f6661e1a91088d2d | |
parent | 5ddbc132fe22fa4dd3c88f16c3fd020561defe2f (diff) | |
parent | 0825ca60f8117a8ac8bdcab51c5b79b5eb736c59 (diff) |
Merge "Move shade to the default display when the keyguard is visible" into main
3 files changed, 97 insertions, 8 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt index ef1ae093bcc9..fd9f5f02ee62 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt @@ -25,6 +25,7 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.display.data.repository.display import com.android.systemui.display.data.repository.displayRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.testKosmos @@ -38,17 +39,31 @@ import org.junit.runner.RunWith class StatusBarTouchShadeDisplayPolicyTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope + private val keyguardRepository = kosmos.fakeKeyguardRepository private val displayRepository = kosmos.displayRepository - val underTest = StatusBarTouchShadeDisplayPolicy(displayRepository, testScope.backgroundScope) + + private fun createUnderTest( + shadeOnDefaultDisplayWhenLocked: Boolean = false + ): StatusBarTouchShadeDisplayPolicy { + return StatusBarTouchShadeDisplayPolicy( + displayRepository, + keyguardRepository, + testScope.backgroundScope, + shadeOnDefaultDisplayWhenLocked = shadeOnDefaultDisplayWhenLocked, + ) + } @Test fun displayId_defaultToDefaultDisplay() { + val underTest = createUnderTest() + assertThat(underTest.displayId.value).isEqualTo(Display.DEFAULT_DISPLAY) } @Test fun onStatusBarTouched_called_updatesDisplayId() = testScope.runTest { + val underTest = createUnderTest() val displayId by collectLastValue(underTest.displayId) displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL)) @@ -60,6 +75,7 @@ class StatusBarTouchShadeDisplayPolicyTest : SysuiTestCase() { @Test fun onStatusBarTouched_notExistentDisplay_displayIdNotUpdated() = testScope.runTest { + val underTest = createUnderTest() val displayIds by collectValues(underTest.displayId) assertThat(displayIds).isEqualTo(listOf(Display.DEFAULT_DISPLAY)) @@ -72,6 +88,7 @@ class StatusBarTouchShadeDisplayPolicyTest : SysuiTestCase() { @Test fun onStatusBarTouched_afterDisplayRemoved_goesBackToDefaultDisplay() = testScope.runTest { + val underTest = createUnderTest() val displayId by collectLastValue(underTest.displayId) displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL)) @@ -83,4 +100,40 @@ class StatusBarTouchShadeDisplayPolicyTest : SysuiTestCase() { assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) } + + @Test + fun onStatusBarTouched_afterKeyguardVisible_goesBackToDefaultDisplay() = + testScope.runTest { + val underTest = createUnderTest(shadeOnDefaultDisplayWhenLocked = true) + val displayId by collectLastValue(underTest.displayId) + + displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL)) + underTest.onStatusBarTouched(2) + + assertThat(displayId).isEqualTo(2) + + keyguardRepository.setKeyguardShowing(true) + + assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) + } + + @Test + fun onStatusBarTouched_afterKeyguardHides_goesBackToPreviousDisplay() = + testScope.runTest { + val underTest = createUnderTest(shadeOnDefaultDisplayWhenLocked = true) + val displayId by collectLastValue(underTest.displayId) + + displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL)) + underTest.onStatusBarTouched(2) + + assertThat(displayId).isEqualTo(2) + + keyguardRepository.setKeyguardShowing(true) + + assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) + + keyguardRepository.setKeyguardShowing(false) + + assertThat(displayId).isEqualTo(2) + } } diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt index a002aa53736a..0954e5e35770 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt @@ -49,6 +49,7 @@ import dagger.Provides import dagger.multibindings.ClassKey import dagger.multibindings.IntoMap import javax.inject.Provider +import javax.inject.Qualifier /** * Module responsible for managing display-specific components and resources for the notification @@ -237,9 +238,23 @@ object ShadeDisplayAwareModule { CoreStartable.NOP } } + + @Provides + @ShadeOnDefaultDisplayWhenLocked + fun provideShadeOnDefaultDisplayWhenLocked(): Boolean = true } @Module internal interface OptionalShadeDisplayAwareBindings { @BindsOptionalOf fun bindOptionalOfWindowRootView(): WindowRootView } + +/** + * Annotates the boolean value that defines whether the shade window should go back to the default + * display when the keyguard is visible. + * + * As of today (Dec 2024), This is a configuration parameter provided in the dagger graph as the + * final policy around keyguard display is still under discussion, and will be evaluated based on + * how well this solution behaves from the performance point of view. + */ +@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class ShadeOnDefaultDisplayWhenLocked diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt index 22e9487af84c..30b086f03d66 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt @@ -22,34 +22,55 @@ import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.display.data.repository.DisplayRepository +import com.android.systemui.keyguard.data.repository.KeyguardRepository +import com.android.systemui.shade.ShadeOnDefaultDisplayWhenLocked import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn /** * Moves the shade on the last display that received a status bar touch. * - * If the display is removed, falls back to the default one. + * If the display is removed, falls back to the default one. When [shadeOnDefaultDisplayWhenLocked] + * is true, the shade falls back to the default display when the keyguard is visible. */ @SysUISingleton class StatusBarTouchShadeDisplayPolicy @Inject -constructor(displayRepository: DisplayRepository, @Background val backgroundScope: CoroutineScope) : - ShadeDisplayPolicy { - override val name: String - get() = "status_bar_latest_touch" +constructor( + displayRepository: DisplayRepository, + keyguardRepository: KeyguardRepository, + @Background val backgroundScope: CoroutineScope, + @ShadeOnDefaultDisplayWhenLocked val shadeOnDefaultDisplayWhenLocked: Boolean, +) : ShadeDisplayPolicy { + override val name: String = "status_bar_latest_touch" private val currentDisplayId = MutableStateFlow(Display.DEFAULT_DISPLAY) private val availableDisplayIds: StateFlow<Set<Int>> = displayRepository.displayIds - override val displayId: StateFlow<Int> - get() = currentDisplayId + override val displayId: StateFlow<Int> = + if (shadeOnDefaultDisplayWhenLocked) { + keyguardRepository.isKeyguardShowing + .combine(currentDisplayId) { isKeyguardShowing, currentDisplayId -> + if (isKeyguardShowing) { + Display.DEFAULT_DISPLAY + } else { + currentDisplayId + } + } + .stateIn(backgroundScope, SharingStarted.WhileSubscribed(), currentDisplayId.value) + } else { + currentDisplayId + } private var removalListener: Job? = null |