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

Commit 89006a80 authored by Orhan Uysal's avatar Orhan Uysal
Browse files

Use WorkSerializer in DesktopRepository

To serialize the persistent repository updates.

Bug: 425916459
Test: atest DesktopRepositoryTest
Test: atest DesktopPersistentRepositoryTest
Flag: com.android.window.flags.repository_based_persistence

Change-Id: I0708211be08d9920344951b796a917d2940d72f2
parent 73d957e3
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -26,10 +26,20 @@ import kotlinx.coroutines.channels.ChannelResult
import kotlinx.coroutines.launch

/**
 * A queue that executes coroutines sequentially in a First-In, First-Out (FIFO) order.
 * Serializes the execution of suspendable work, ensuring that tasks are processed
 * sequentially in a First-In, First-Out (FIFO) order.
 *
 * @param scope The [CoroutineScope] the queue will use to launch its worker. Cancelling this scope
 * will terminate the queue.
 * This class is useful for managing operations that need to be executed one after another,
 * preventing race conditions and ensuring a predictable order of execution. It uses a
 * [Channel] to queue incoming work and a single worker coroutine to process the queue.
 *
 * @param scope The [CoroutineScope] the serializer will use to launch its worker coroutine.
 *              Cancelling this scope will terminate the queue and stop all processing.
 * @param capacity The number of elements that can be buffered in the channel.
 *                 See [Channel] for options like [Channel.UNLIMITED], [Channel.BUFFERED], etc.
 *                 Defaults to [Channel.UNLIMITED].
 * @param overflowStrategy The action to take when the buffer is full. See [BufferOverflow].
 *                         Defaults to [BufferOverflow.SUSPEND].
 */
class WorkSerializer(
    scope: CoroutineScope,
@@ -73,7 +83,7 @@ class WorkSerializer(
        if (result.isFailure) {
            ProtoLog.w(
                WM_SHELL,
                "Failed to post work to CoroutineQueue %s",
                "Failed to post work to WorkSerializer %s",
                result.exceptionOrNull()?.stackTraceToString()
            )
        }
@@ -86,6 +96,6 @@ class WorkSerializer(
    fun close() = channel.close()

    fun onUndeliveredElement() {
        ProtoLog.w(WM_SHELL, "An element in CoroutineQueue was undelivered")
        ProtoLog.w(WM_SHELL, "An element in WorkSerializer was undelivered")
    }
}
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -1437,6 +1437,7 @@ public abstract class WMShellModule {
            DesktopPersistentRepository desktopPersistentRepository,
            DesktopRepositoryInitializer desktopRepositoryInitializer,
            @ShellMainThread CoroutineScope mainScope,
            @ShellBackgroundThread CoroutineScope bgScope,
            UserManager userManager,
            DesktopState desktopState,
            DesktopConfig desktopConfig
@@ -1444,7 +1445,7 @@ public abstract class WMShellModule {
        return new DesktopUserRepositories(shellInit, shellController,
                desktopPersistentRepository,
                desktopRepositoryInitializer,
                mainScope, userManager, desktopState, desktopConfig);
                mainScope, bgScope, userManager, desktopState, desktopConfig);
    }

    @WMSingleton
+2 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ class DesktopUserRepositories(
    private val persistentRepository: DesktopPersistentRepository,
    private val repositoryInitializer: DesktopRepositoryInitializer,
    @ShellMainThread private val mainCoroutineScope: CoroutineScope,
    @ShellMainThread private val bgCoroutineScope: CoroutineScope,
    private val userManager: UserManager,
    desktopState: DesktopState,
    desktopConfig: DesktopConfig,
@@ -65,6 +66,7 @@ class DesktopUserRepositories(
                    ?: DesktopRepository(
                            persistentRepository,
                            mainCoroutineScope,
                            bgCoroutineScope,
                            userId,
                            desktopConfig,
                        )
+6 −1
Original line number Diff line number Diff line
@@ -30,9 +30,11 @@ import androidx.core.util.forEach
import androidx.core.util.valueIterator
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.common.WorkSerializer
import com.android.wm.shell.desktopmode.DisplayDeskState
import com.android.wm.shell.desktopmode.data.persistence.DesktopPersistentRepository
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopConfig
import java.io.PrintWriter
@@ -45,6 +47,7 @@ import kotlinx.coroutines.launch
class DesktopRepository(
    private val persistentRepository: DesktopPersistentRepository,
    @ShellMainThread private val mainCoroutineScope: CoroutineScope,
    @ShellBackgroundThread private val bgCoroutineScope: CoroutineScope,
    val userId: Int,
    val desktopConfig: DesktopConfig,
) {
@@ -62,6 +65,8 @@ class DesktopRepository(
    private val activeTasksListeners = ArraySet<ActiveTasksListener>()
    private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>()

    private val persistentUpdateQueue = WorkSerializer(bgCoroutineScope)

    /* Tracks corner/caption regions of desktop tasks, used to determine gesture exclusion. */
    private val desktopExclusionRegions = SparseArray<Region>()

@@ -1172,7 +1177,7 @@ class DesktopRepository(
            return
        }
        if (DesktopExperienceFlags.REPOSITORY_BASED_PERSISTENCE.isTrue) {
            mainCoroutineScope.launch {
            persistentUpdateQueue.post {
                try {
                    logD("updatePersistentRepository user=%d display=%d", userId, displayId)
                    persistentRepository.addOrUpdateRepository(userId, desks)
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Before
@@ -127,6 +128,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
                persistentRepository,
                repositoryInitializer,
                testScope,
                TestScope(),
                userManager,
                desktopState,
                desktopConfig,
Loading