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

Commit 05e14ad9 authored by Ebru Kurnaz's avatar Ebru Kurnaz Committed by Android (Google) Code Review
Browse files

Merge "Use WindowManager callback for add/remove system decorations in...

Merge "Use WindowManager callback for add/remove system decorations in DisplayRepository." into main
parents 0fb17e78 13d9b642
Loading
Loading
Loading
Loading
+115 −0
Original line number Diff line number Diff line
@@ -18,11 +18,14 @@ package com.android.systemui.display.data.repository

import android.hardware.display.DisplayManager
import android.os.fakeHandler
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
import android.view.Display
import android.view.Display.DEFAULT_DISPLAY
import android.view.Display.TYPE_EXTERNAL
import android.view.Display.TYPE_INTERNAL
import android.view.IDisplayWindowListener
import android.view.mockIWindowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -37,6 +40,7 @@ import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.mockCommandQueue
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -48,6 +52,7 @@ import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever

@@ -64,6 +69,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
    private val displayListener = kotlinArgumentCaptor<DisplayManager.DisplayListener>()
    private val commandQueueCallbacks = kotlinArgumentCaptor<CommandQueue.Callbacks>()
    private val connectedDisplayListener = kotlinArgumentCaptor<DisplayManager.DisplayListener>()
    private lateinit var wmListener: IDisplayWindowListener

    private val testHandler = kosmos.fakeHandler
    private val testScope = kosmos.testScope
@@ -517,6 +523,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_onStart_emitsDisplaysWithSystemDecorations() =
        testScope.runTest {
            setDisplays(0, 1, 2)
@@ -530,6 +537,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_systemDecorationAdded_emitsIncludingNewDisplayIds() =
        testScope.runTest {
            setDisplays(0)
@@ -543,6 +551,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_systemDecorationAdded_emitsToNewSubscribers() =
        testScope.runTest {
            setDisplays(0)
@@ -558,6 +567,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_systemDecorationRemoved_doesNotEmitRemovedDisplayId() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by latestDisplayIdsWithSystemDecorationsValue()
@@ -570,6 +580,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_systemDecorationsRemoved_nonExistentDisplay_noEffect() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by latestDisplayIdsWithSystemDecorationsValue()
@@ -581,6 +592,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_displayRemoved_doesNotEmitRemovedDisplayId() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by latestDisplayIdsWithSystemDecorationsValue()
@@ -593,6 +605,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_displayRemoved_nonExistentDisplay_noEffect() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by latestDisplayIdsWithSystemDecorationsValue()
@@ -604,6 +617,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_onFlowCollection_commandQueueCallbackRegistered() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by latestDisplayIdsWithSystemDecorationsValue()
@@ -614,6 +628,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_afterFlowCollection_commandQueueCallbackUnregistered() {
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by latestDisplayIdsWithSystemDecorationsValue()
@@ -625,6 +640,100 @@ class DisplayRepositoryTest : SysuiTestCase() {
        verify(commandQueue, times(1)).removeCallback(any())
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_withWmCallback_systemDecorationAdded_emitsIncludingNewDisplayIds() =
        testScope.runTest {
            setDisplays(0)
            whenever(windowManager.shouldShowSystemDecors(0)).thenReturn(true)
            val lastDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            captureWmListener()

            wmListener.onDisplayAddSystemDecorations(2)
            wmListener.onDisplayAddSystemDecorations(3)

            assertThat(lastDisplayIdsWithSystemDecorations).containsExactly(0, 2, 3)
        }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_withWmCallback_systemDecorationAdded_emitsToNewSubscribers() =
        testScope.runTest {
            setDisplays(0)
            whenever(windowManager.shouldShowSystemDecors(0)).thenReturn(true)

            val priorDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            captureWmListener()
            wmListener.onDisplayAddSystemDecorations(1)
            assertThat(priorDisplayIdsWithSystemDecorations).containsExactly(0, 1)

            val lastDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            assertThat(lastDisplayIdsWithSystemDecorations).containsExactly(0, 1)
        }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_withWmCallback_systemDecorationAdded_doesNotEmitRemovedDisplayId() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            captureWmListener()

            wmListener.onDisplayAddSystemDecorations(1)
            wmListener.onDisplayAddSystemDecorations(2)
            wmListener.onDisplayRemoveSystemDecorations(2)

            assertThat(lastDisplayIdsWithSystemDecorations).containsExactly(1)
        }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_withWmCallback_systemDecorationsRemoved_nonExistentDisplay_noEffect() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            captureWmListener()

            wmListener.onDisplayAddSystemDecorations(1)
            wmListener.onDisplayRemoveSystemDecorations(2)

            assertThat(lastDisplayIdsWithSystemDecorations).containsExactly(1)
        }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_withWmCallback_displayRemoved_doesNotEmitRemovedDisplayId() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            captureAddedRemovedListener()
            captureWmListener()

            wmListener.onDisplayAddSystemDecorations(1)
            wmListener.onDisplayAddSystemDecorations(2)
            sendOnDisplayRemoved(2)

            assertThat(lastDisplayIdsWithSystemDecorations).containsExactly(1)
        }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SYS_DECORS_CALLBACKS_VIA_WM)
    fun displayIdsWithSystemDecorations_withWmCallback_displayRemoved_nonExistentDisplay_noEffect() =
        testScope.runTest {
            val lastDisplayIdsWithSystemDecorations by
                collectLastValue(displayRepository.displayIdsWithSystemDecorations)
            captureAddedRemovedListener()
            captureWmListener()

            wmListener.onDisplayAddSystemDecorations(1)
            sendOnDisplayRemoved(2)

            assertThat(lastDisplayIdsWithSystemDecorations).containsExactly(1)
        }

    @Test
    fun getDisplay_slowMappingToDisplay_returnsRegardless() =
        testScope.runTest {
@@ -766,4 +875,10 @@ class DisplayRepositoryTest : SysuiTestCase() {
        val idsToSet = ids.toSet() + DEFAULT_DISPLAY
        setDisplays(idsToSet.map { display(type = TYPE_EXTERNAL, id = it) })
    }

    private fun captureWmListener() {
        val captor = argumentCaptor<IDisplayWindowListener>()
        verify(windowManager).registerDisplayWindowListener(captor.capture())
        wmListener = captor.firstValue
    }
}
+14 −1
Original line number Diff line number Diff line
@@ -18,20 +18,22 @@ package com.android.systemui.display

import android.hardware.display.DisplayManager
import android.os.Handler
import android.view.IWindowManager
import com.android.app.displaylib.DisplayLibBackground
import com.android.app.displaylib.DisplayLibComponent
import com.android.app.displaylib.DisplaysWithDecorationsRepository
import com.android.app.displaylib.PerDisplayRepository
import com.android.app.displaylib.createDisplayLibComponent
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.dagger.SystemUIDisplaySubcomponent.DisplayLib
import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.display.data.repository.DeviceStateRepositoryImpl
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayRepositoryImpl
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepositoryImpl
import com.android.systemui.display.data.repository.DisplaysWithDecorationsRepository
import com.android.systemui.display.data.repository.DisplaysWithDecorationsRepositoryImpl
import com.android.systemui.display.data.repository.FocusedDisplayRepository
import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl
@@ -123,12 +125,14 @@ object DisplayLibModule {
    @SysUISingleton
    fun displayLibComponent(
        displayManager: DisplayManager,
        windowManager: IWindowManager,
        @Background backgroundHandler: Handler,
        @Background bgApplicationScope: CoroutineScope,
        @Background backgroundCoroutineDispatcher: CoroutineDispatcher,
    ): DisplayLibComponent {
        return createDisplayLibComponent(
            displayManager,
            windowManager,
            backgroundHandler,
            bgApplicationScope,
            backgroundCoroutineDispatcher,
@@ -142,4 +146,13 @@ object DisplayLibModule {
    ): com.android.app.displaylib.DisplayRepository {
        return displayLibComponent.displayRepository
    }

    @Provides
    @SysUISingleton
    @DisplayLib
    fun providesDisplaysWithDecorationsRepositoryFromLib(
        displayLibComponent: DisplayLibComponent
    ): DisplaysWithDecorationsRepository {
        return displayLibComponent.displaysWithDecorationsRepository
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -54,4 +54,10 @@ interface SystemUIDisplaySubcomponent {

    /** Annotates the display id inside the subcomponent. */
    @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class DisplayId

    /**
     * Annotates the displaylib implementation of a class.
     * TODO(b/408503553): Remove this annotation once the flag is cleaned up.
     */
    @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class DisplayLib
}
+10 −1
Original line number Diff line number Diff line
@@ -17,7 +17,10 @@
package com.android.systemui.display.data.repository

import com.android.app.displaylib.DisplayRepository as DisplayRepositoryFromLib
import com.android.app.displaylib.DisplaysWithDecorationsRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.display.dagger.SystemUIDisplaySubcomponent.DisplayLib
import com.android.window.flags.Flags.enableSysDecorsCallbacksViaWm
import javax.inject.Inject

/**
@@ -34,7 +37,13 @@ class DisplayRepositoryImpl
constructor(
    private val displayRepositoryFromLib: com.android.app.displaylib.DisplayRepository,
    private val displaysWithDecorationsRepositoryImpl: DisplaysWithDecorationsRepository,
    @DisplayLib
    private val displaysWithDecorationsRepositoryImplFromLib: DisplaysWithDecorationsRepository,
) :
    DisplayRepositoryFromLib by displayRepositoryFromLib,
    DisplaysWithDecorationsRepository by displaysWithDecorationsRepositoryImpl,
    DisplaysWithDecorationsRepository by (if (enableSysDecorsCallbacksViaWm()) {
        displaysWithDecorationsRepositoryImplFromLib
    } else {
        displaysWithDecorationsRepositoryImpl
    }),
    DisplayRepository
+1 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.display.data.repository

import android.view.IWindowManager
import com.android.app.displaylib.DisplaysWithDecorationsRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.CommandQueue
@@ -33,12 +34,6 @@ import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.scan
import kotlinx.coroutines.flow.stateIn

/** Provides the displays with decorations. */
interface DisplaysWithDecorationsRepository {
    /** A [StateFlow] that maintains a set of display IDs that should have system decorations. */
    val displayIdsWithSystemDecorations: StateFlow<Set<Int>>
}

@SysUISingleton
class DisplaysWithDecorationsRepositoryImpl
@Inject
Loading