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

Commit 9d933254 authored by Ebru Kurnaz's avatar Ebru Kurnaz
Browse files

Fix possibile deadlock with registering listeners for sys decor.

Bug: 420913840
Test: DisplayRepositoryTest
Flag: com.android.window.flags.enable_sys_decors_callbacks_via_wm
Change-Id: I0102e44121790ac5be2de301717ac38935733041
parent 4ebc0fd0
Loading
Loading
Loading
Loading
+19 −16
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.app.displaylib

import com.android.app.tracing.TraceUtils.traceAsync
import com.android.internal.annotations.GuardedBy
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
@@ -52,7 +53,6 @@ constructor(
    private val bgApplicationScope: CoroutineScope,
    private val displayRepository: DisplaysWithDecorationsRepository,
) {

    private val mutex = Mutex()
    private var collectorJob: Job? = null
    private val displayDecorationListenersWithDispatcher =
@@ -69,15 +69,18 @@ constructor(
        listener: DisplayDecorationListener,
        dispatcher: CoroutineDispatcher,
    ) {
        var initialDisplayIdsForListener: Set<Int> = emptySet()
        bgApplicationScope.launch {
            mutex.withLock {
                displayDecorationListenersWithDispatcher[listener] = dispatcher
                initialDisplayIdsForListener =
                    displayRepository.displayIdsWithSystemDecorations.value
                startCollectingIfNeeded(initialDisplayIdsForListener)
            }
            // Emit all the existing displays with decorations when registering.
                displayRepository.displayIdsWithSystemDecorations.value.forEach { displayId ->
            initialDisplayIdsForListener.forEach { displayId ->
                withContext(dispatcher) { listener.onDisplayAddSystemDecorations(displayId) }
            }
                startCollectingIfNeeded()
            }
        }
    }

@@ -100,11 +103,11 @@ constructor(
    }

    @GuardedBy("mutex")
    private fun startCollectingIfNeeded() {
    private fun startCollectingIfNeeded(lastDisplaysWithDecorations: Set<Int>) {
        if (collectorJob?.isActive == true) {
            return
        }
        var oldDisplays: Set<Int> = displayRepository.displayIdsWithSystemDecorations.value
        var oldDisplays: Set<Int> = lastDisplaysWithDecorations
        collectorJob =
            bgApplicationScope.launch {
                displayRepository.displayIdsWithSystemDecorations.collect { currentDisplays ->