Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c30013da authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Fall back shade window to default display when mirroring is enabled

When content mirroring is active, the shade should consistently appear on the default display, irrespective of any active ShadeDisplayPolicy.

This fixes the issue of shade being moved while mirroring, because we were using the display Id from the MotionEvent to decide where it was. On external displays with touchscreen, expanding the shade on the external display was causing the shade window to be reparented there

Bug: 441689533
Test: ShadeDisplaysRepositoryTest
Flag: com.android.systemui.shade_window_goes_around
Change-Id: Ic0cafa532220c95c2fc3e010238efd91ed472520
parent 2b1decbe
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.shade.data.repository

import android.provider.Settings.Global.DEVELOPMENT_SHADE_DISPLAY_AWARENESS
import android.provider.Settings.Secure.MIRROR_BUILT_IN_DISPLAY
import android.view.Display
import android.view.Display.TYPE_EXTERNAL
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -36,6 +37,7 @@ import com.android.systemui.shade.display.FocusShadeDisplayPolicy
import com.android.systemui.shade.display.StatusBarTouchShadeDisplayPolicy
import com.android.systemui.testKosmos
import com.android.systemui.util.settings.fakeGlobalSettings
import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -47,6 +49,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val testScope = kosmos.testScope
    private val globalSettings = kosmos.fakeGlobalSettings
    private val secureSettings = kosmos.fakeSettings
    private val displayRepository = kosmos.displayRepository
    private val defaultPolicy = DefaultDisplayShadePolicy()
    private val policies = kosmos.shadeDisplayPolicies
@@ -55,6 +58,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
    private fun createUnderTest(shadeOnDefaultDisplayWhenLocked: Boolean = false) =
        ShadeDisplaysRepositoryImpl(
            globalSettings,
            secureSettings,
            defaultPolicy,
            testScope.backgroundScope,
            policies,
@@ -189,4 +193,30 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {

            assertThat(displayId).isEqualTo(1)
        }

    @Test
    fun displayId_whileMirroringEnabled_ignoresThePolicyId() =
        testScope.runTest {
            val underTest = createUnderTest()
            globalSettings.putString(
                DEVELOPMENT_SHADE_DISPLAY_AWARENESS,
                FakeShadeDisplayPolicy.name,
            )
            secureSettings.putInt(MIRROR_BUILT_IN_DISPLAY, 0)

            val displayId by collectLastValue(underTest.pendingDisplayId)

            displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL))
            FakeShadeDisplayPolicy.setDisplayId(2)

            assertThat(displayId).isEqualTo(2)

            secureSettings.putInt(MIRROR_BUILT_IN_DISPLAY, 1)

            assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)

            secureSettings.putInt(MIRROR_BUILT_IN_DISPLAY, 0)

            assertThat(displayId).isEqualTo(2)
        }
}
+22 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.shade.data.repository

import android.provider.Settings.Global.DEVELOPMENT_SHADE_DISPLAY_AWARENESS
import android.provider.Settings.Secure.MIRROR_BUILT_IN_DISPLAY
import android.view.Display
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -25,6 +26,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.shade.ShadeOnDefaultDisplayWhenLocked
import com.android.systemui.shade.display.ShadeDisplayPolicy
import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -75,7 +77,8 @@ interface MutableShadeDisplaysRepository : ShadeDisplaysRepository {
class ShadeDisplaysRepositoryImpl
@Inject
constructor(
    globalSettings: GlobalSettings,
    private val globalSettings: GlobalSettings,
    private val secureSettings: SecureSettings,
    defaultPolicy: ShadeDisplayPolicy,
    @Background bgScope: CoroutineScope,
    policies: Set<@JvmSuppressWildcards ShadeDisplayPolicy>,
@@ -99,11 +102,25 @@ constructor(
            .distinctUntilChanged()
            .stateIn(bgScope, SharingStarted.Eagerly, defaultPolicy)

    private val mirroringEnabled: StateFlow<Boolean> =
        secureSettings
            .observerFlow(MIRROR_BUILT_IN_DISPLAY)
            .map { isMirroring() }
            .stateIn(bgScope, SharingStarted.Eagerly, isMirroring())

    private fun isMirroring() = secureSettings.getInt(MIRROR_BUILT_IN_DISPLAY, default = 0) == 1

    private val displayIdFromPolicy: Flow<Int> =
        policy
            .flatMapLatest { it.displayId }
            .combine(displayRepository.displayIds) { policyDisplayId, availableIds ->
                if (policyDisplayId !in availableIds) Display.DEFAULT_DISPLAY else policyDisplayId
        combine(
            policy.flatMapLatest { it.displayId },
            displayRepository.displayIds,
            mirroringEnabled,
        ) { policyDisplayId, availableIds, isMirroring ->
            when {
                isMirroring -> Display.DEFAULT_DISPLAY
                policyDisplayId !in availableIds -> Display.DEFAULT_DISPLAY
                else -> policyDisplayId
            }
        }

    private val keyguardAwareDisplayPolicy: Flow<Int> =
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.shade.display.StatusBarTouchShadeDisplayPolicy
import com.android.systemui.shade.domain.interactor.notificationElement
import com.android.systemui.shade.domain.interactor.qsElement
import com.android.systemui.util.settings.fakeGlobalSettings
import com.android.systemui.util.settings.fakeSettings

val Kosmos.defaultShadeDisplayPolicy: DefaultDisplayShadePolicy by
    Kosmos.Fixture { DefaultDisplayShadePolicy() }
@@ -60,6 +61,7 @@ val Kosmos.shadeDisplaysRepository: ShadeDisplaysRepository by
        ShadeDisplaysRepositoryImpl(
            bgScope = testScope.backgroundScope,
            globalSettings = fakeGlobalSettings,
            secureSettings = fakeSettings,
            policies = shadeDisplayPolicies,
            defaultPolicy = defaultShadeDisplayPolicy,
            shadeOnDefaultDisplayWhenLocked = true,