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

Commit 6b256742 authored by Steven Ng's avatar Steven Ng
Browse files

Eagerly initialized per display SystemUIDisplaySubcomponent upon adding a display

Problem:
Previously, the SystemUI display repository created per-display instances on-demand. However, components like the wallpaper presentation require these instances to exist proactively to update the keyguard for secondary display.

Changes:
1. This change introduces a new field to create per-display components eagerly upon display addition, resolving the above problem.
2. Addresses a bug in WallpaperPresentation where we only hide the presentation instead of dismiss it.

Flag: com.android.window.flags.enable_connected_displays_wallpaper_presentations
Bug: 441940469
Test: atest CtsMediaProjectionTestCases:MediaProjectionTest
Test: atest CtsWindowManagerDeviceKeyguard:MultiDisplayKeyguardTests
Test: atest SystemUITests:PerDisplayInstanceRepositoryImplTest
Test: atest SystemUITests:WallpaperPresentationManagerTest
Test: atest SystemUITests:PhoneStatusBarViewControllerTest
Change-Id: I125489126e2fb5c20a8c0649a606129792a0a09b
parent dc5fa92e
Loading
Loading
Loading
Loading
+70 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.display.data.repository
import android.view.Display
import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.app.displaylib.DisplayInstanceLifecycleManager
import com.android.app.displaylib.PerDisplayInstanceProviderWithSetup
import com.android.app.displaylib.PerDisplayInstanceProviderWithSetup
import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
@@ -28,6 +29,8 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Before
@@ -259,6 +262,73 @@ class PerDisplayInstanceRepositoryImplTest : SysuiTestCase() {
            assertThat(perDisplayRepo[NON_DEFAULT_DISPLAY_ID]).isEqualTo(instanceSetUp)
            assertThat(perDisplayRepo[NON_DEFAULT_DISPLAY_ID]).isEqualTo(instanceSetUp)
        }
        }


    private fun createTestPerDisplayInstanceRepositoryImpl(
        createInstanceEagerly: Boolean,
        displayIdsFlow: MutableStateFlow<Set<Int>>,
        displayToInstanceMap: MutableMap<Int, TestPerDisplayInstance?>,
    ): PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> =
        PerDisplayInstanceRepositoryImpl(
            debugName = "fakePerDisplayInstanceRepository",
            instanceProvider =
                object : PerDisplayInstanceProviderWithSetup<TestPerDisplayInstance> {
                    override fun setupInstance(instance: TestPerDisplayInstance) {}

                    override fun createInstance(displayId: Int): TestPerDisplayInstance? {
                        displayToInstanceMap[displayId] = TestPerDisplayInstance(displayId)
                        return displayToInstanceMap[displayId]
                    }
                },
            lifecycleManager =
                object : DisplayInstanceLifecycleManager {
                    override val displayIds: StateFlow<Set<Int>> = displayIdsFlow
                },
            testScope.backgroundScope,
            kosmos.displayRepository,
            kosmos.perDisplayDumpHelper,
            createInstanceEagerly = createInstanceEagerly,
        )

    @Test
    fun setupInstance_doNotCreateEagerly_shouldNotCreateInstanceImmediately() =
        kosmos.runTest {
            val displayIdsFlow = MutableStateFlow<Set<Int>>(emptySet())
            val displayToInstanceMap = mutableMapOf<Int, TestPerDisplayInstance?>()
            createTestPerDisplayInstanceRepositoryImpl(
                createInstanceEagerly = false,
                displayIdsFlow = displayIdsFlow,
                displayToInstanceMap = displayToInstanceMap,
            )

            displayIdsFlow.emit(setOf(DEFAULT_DISPLAY_ID, NON_DEFAULT_DISPLAY_ID))

            assertThat(displayToInstanceMap[DEFAULT_DISPLAY_ID]).isNull()
            assertThat(displayToInstanceMap[NON_DEFAULT_DISPLAY_ID]).isNull()
        }

    @Test
    fun setupInstance_createEagerly_shouldCreateInstanceImmediately() =
        kosmos.runTest {
            val displayIdsFlow = MutableStateFlow<Set<Int>>(emptySet())
            val displayToInstanceMap = mutableMapOf<Int, TestPerDisplayInstance?>()
            createTestPerDisplayInstanceRepositoryImpl(
                createInstanceEagerly = true,
                displayIdsFlow = displayIdsFlow,
                displayToInstanceMap = displayToInstanceMap,
            )
            kosmos.createPerDisplayInstanceRepository(
                overrideLifecycleManager =
                    object : DisplayInstanceLifecycleManager {
                        override val displayIds: StateFlow<Set<Int>> = displayIdsFlow
                    },
                createInstanceEagerly = true,
            )

            displayIdsFlow.emit(setOf(DEFAULT_DISPLAY_ID, NON_DEFAULT_DISPLAY_ID))

            assertThat(displayToInstanceMap[DEFAULT_DISPLAY_ID]).isNotNull()
            assertThat(displayToInstanceMap[NON_DEFAULT_DISPLAY_ID]).isNotNull()
        }

    private fun createDisplay(displayId: Int): Display =
    private fun createDisplay(displayId: Int): Display =
        display(type = Display.TYPE_INTERNAL, id = displayId)
        display(type = Display.TYPE_INTERNAL, id = displayId)


+6 −6
Original line number Original line Diff line number Diff line
@@ -104,7 +104,7 @@ class WallpaperPresentationManagerTest : SysuiTestCase() {
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(PROVISIONING)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(PROVISIONING)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(NONE)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(NONE)


            verify(provisioningPresentation).hide()
            verify(provisioningPresentation).dismiss()
            verifyNoInteractions(keyguardPresentationFactory)
            verifyNoInteractions(keyguardPresentationFactory)
        }
        }


@@ -116,7 +116,7 @@ class WallpaperPresentationManagerTest : SysuiTestCase() {
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(PROVISIONING)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(PROVISIONING)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(KEYGUARD)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(KEYGUARD)


            verify(provisioningPresentation).hide()
            verify(provisioningPresentation).dismiss()
            verify(keyguardPresentationFactory).create(eq(testDisplay))
            verify(keyguardPresentationFactory).create(eq(testDisplay))
            verify(keyguardPresentation).show()
            verify(keyguardPresentation).show()
            verifyNoMoreInteractions(keyguardPresentation)
            verifyNoMoreInteractions(keyguardPresentation)
@@ -143,7 +143,7 @@ class WallpaperPresentationManagerTest : SysuiTestCase() {
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(KEYGUARD)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(KEYGUARD)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(NONE)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(NONE)


            verify(keyguardPresentation).hide()
            verify(keyguardPresentation).dismiss()
            verifyNoInteractions(provisioningPresentationFactory)
            verifyNoInteractions(provisioningPresentationFactory)
        }
        }


@@ -155,7 +155,7 @@ class WallpaperPresentationManagerTest : SysuiTestCase() {
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(KEYGUARD)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(KEYGUARD)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(PROVISIONING)
            fakeWallpaperPresentationInteractor._presentationFactoryFlow.emit(PROVISIONING)


            verify(keyguardPresentation).hide()
            verify(keyguardPresentation).dismiss()
            verify(provisioningPresentation).show()
            verify(provisioningPresentation).show()
            verifyNoMoreInteractions(provisioningPresentation)
            verifyNoMoreInteractions(provisioningPresentation)
        }
        }
@@ -168,7 +168,7 @@ class WallpaperPresentationManagerTest : SysuiTestCase() {


            wallpaperPresentationManager.stop()
            wallpaperPresentationManager.stop()


            verify(provisioningPresentation).hide()
            verify(provisioningPresentation).dismiss()
        }
        }


    @Test
    @Test
@@ -179,6 +179,6 @@ class WallpaperPresentationManagerTest : SysuiTestCase() {


            wallpaperPresentationManager.stop()
            wallpaperPresentationManager.stop()


            verify(keyguardPresentation).hide()
            verify(keyguardPresentation).dismiss()
        }
        }
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ object DisplayComponentRepository {
        return repositoryFactory.create(
        return repositoryFactory.create(
            debugName = "DisplayComponentInstanceProvider",
            debugName = "DisplayComponentInstanceProvider",
            instanceProvider,
            instanceProvider,
            createInstanceEagerly = true,
        )
        )
    }
    }
}
}
+7 −8
Original line number Original line Diff line number Diff line
@@ -68,9 +68,8 @@ constructor(
                }
                }
                .distinctUntilChanged()
                .distinctUntilChanged()
                .collect { presentationType ->
                .collect { presentationType ->
                    presentationFactories[presentationType]?.let {
                    presentationFactories[presentationType]?.let { showPresentation(it) }
                        showPresentation(it)
                        ?: run {
                    } ?: run {
                            debugLog(enabled = DEBUG, tag = TAG) {
                            debugLog(enabled = DEBUG, tag = TAG) {
                                "Hiding presentation for type: $presentationType"
                                "Hiding presentation for type: $presentationType"
                            }
                            }
@@ -102,7 +101,7 @@ constructor(
            debugLog(enabled = DEBUG, tag = TAG) {
            debugLog(enabled = DEBUG, tag = TAG) {
                "Hide presentation $it for display ${display.displayId}"
                "Hide presentation $it for display ${display.displayId}"
            }
            }
            it.hide()
            it.dismiss()
        }
        }
        presentation = null
        presentation = null
    }
    }
+5 −3
Original line number Original line Diff line number Diff line
@@ -107,7 +107,7 @@ val Kosmos.fakeDisplayInstanceLifecycleManager by


val Kosmos.fakePerDisplayInstanceRepository by
val Kosmos.fakePerDisplayInstanceRepository by
    Kosmos.Fixture {
    Kosmos.Fixture {
        { lifecycleManager: DisplayInstanceLifecycleManager? ->
        { lifecycleManager: DisplayInstanceLifecycleManager?, createInstanceEagerly: Boolean ->
            PerDisplayInstanceRepositoryImpl(
            PerDisplayInstanceRepositoryImpl(
                debugName = "fakePerDisplayInstanceRepository",
                debugName = "fakePerDisplayInstanceRepository",
                instanceProvider = fakePerDisplayInstanceProviderWithSetupAndTeardown,
                instanceProvider = fakePerDisplayInstanceProviderWithSetupAndTeardown,
@@ -115,6 +115,7 @@ val Kosmos.fakePerDisplayInstanceRepository by
                testScope.backgroundScope,
                testScope.backgroundScope,
                displayRepository,
                displayRepository,
                perDisplayDumpHelper,
                perDisplayDumpHelper,
                createInstanceEagerly = createInstanceEagerly,
            )
            )
        }
        }
    }
    }
@@ -134,9 +135,10 @@ val Kosmos.fakePerDisplaySysUIStateInstanceRepository by
    }
    }


fun Kosmos.createPerDisplayInstanceRepository(
fun Kosmos.createPerDisplayInstanceRepository(
    overrideLifecycleManager: DisplayInstanceLifecycleManager? = null
    overrideLifecycleManager: DisplayInstanceLifecycleManager? = null,
    createInstanceEagerly: Boolean = false,
): PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> {
): PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> {
    return fakePerDisplayInstanceRepository(overrideLifecycleManager)
    return fakePerDisplayInstanceRepository(overrideLifecycleManager, createInstanceEagerly)
}
}


fun Kosmos.createPerDisplayInstanceSysUIStateRepository(
fun Kosmos.createPerDisplayInstanceSysUIStateRepository(