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

Commit 590eccaf authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

[9/n] Add log for active and inactive desk

Before multiple desktops, desktop windowing session is active only if
there is at least one freeform window open. Now, desktop can be active
and empty. Log desk session enter and exit from DesksTransitionObserver.

Session exit will be marked as pending in DesksTransitionObserver so any
task removal changes are logged to the correct session. After any task
info changes are logged, session exit will be logged in
DesktopModeLoggerTransitionObserver.

Flag: EXEMPT logging
Fix: 423560267
Test: atest DesktopModeEventLoggerTest
      atest DesksTransitionObserverTest
Change-Id: Ica9a44d9b4be7b11d7dcfe4f3846c80c3750a071
parent 04397eba
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.wm.shell.dagger;

import static android.window.DesktopExperienceFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS;
import static android.window.DesktopExperienceFlags.ENABLE_INORDER_TRANSITION_CALLBACKS_FOR_DESKTOP;
import static android.window.DesktopExperienceFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS;
import static android.window.DesktopModeFlags.ENABLE_DESKTOP_SYSTEM_DIALOGS_TRANSITIONS;
import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS_BUGFIX;
import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY;
@@ -1535,13 +1535,14 @@ public abstract class WMShellModule {
            @NonNull ShellController shellController,
            @NonNull DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
            @NonNull @ShellMainThread CoroutineScope mainScope,
            DesktopState desktopState
            DesktopState desktopState,
            @NonNull DesktopModeEventLogger desktopModeEventLogger
    ) {
        if (desktopState.canEnterDesktopModeOrShowAppHandle()) {
            return Optional.of(
                    new DesksTransitionObserver(desktopUserRepositories, desksOrganizer,
                            transitions, shellController, desktopWallpaperActivityTokenProvider,
                            mainScope));
                            mainScope, desktopModeEventLogger));
        }
        return Optional.empty();
    }
+159 −25
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.wm.shell.desktopmode

import android.app.ActivityManager.RunningTaskInfo
import android.util.Size
import android.view.InputDevice.SOURCE_MOUSE
import android.view.InputDevice.SOURCE_TOUCHSCREEN
import android.view.MotionEvent
@@ -30,6 +29,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.internal.util.FrameworkStatsLog
import com.android.wm.shell.EventLogTags
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.desktopmode.data.DesktopRepository.Companion.INVALID_DESK_ID
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.windowdecor.DragPositioningCallback.INPUT_METHOD_TYPE_MOUSE
@@ -46,10 +46,58 @@ class DesktopModeEventLogger {

    /** The session id for the current desktop mode session */
    @VisibleForTesting val currentSessionId: AtomicInteger = AtomicInteger(NO_SESSION_ID)
    @VisibleForTesting val deskToSessionId = mutableMapOf<Int, Int>()
    private val pendingLogSessionExit = mutableMapOf<Int, ExitReason>()

    private fun generateSessionId() = 1 + random.nextInt(1 shl 20)

    // Caching whether the previous transition was exit due to screen off. This helps check if a
    // following enter reason could be Screen On.
    private var wasPreviousTransitionExitByScreenOff: Boolean = false

    /** Logs enter into desktop mode with [enterReason]. */
    fun logSessionEnter(deskId: Int, enterReason: EnterReason) {
        if (deskToSessionId.containsKey(deskId)) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopModeLogger: Existing desktop session: %s found on desk: %s mode enter",
                deskToSessionId[deskId],
                deskId,
            )
        }
        val sessionId = generateSessionId()
        deskToSessionId[deskId] = sessionId

        val reason =
            if (wasPreviousTransitionExitByScreenOff && enterReason == EnterReason.UNKNOWN_ENTER) {
                wasPreviousTransitionExitByScreenOff = false
                EnterReason.SCREEN_ON
            } else {
                enterReason
            }

        ProtoLog.v(
            WM_SHELL_DESKTOP_MODE,
            "DesktopModeLogger: Logging session enter, session: %s deskId: %s reason: %s",
            sessionId,
            deskId,
            reason.name,
        )
        FrameworkStatsLog.write(
            DESKTOP_MODE_ATOM_ID,
            /* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__ENTER,
            /* enterReason */ reason.reason,
            /* exitReason */ 0,
            /* session_id */ sessionId,
        )
        EventLogTags.writeWmShellEnterDesktopMode(reason.reason, sessionId)
    }

    /** Logs enter into desktop mode with [enterReason] */
    @Deprecated(
        "Use logSessionEnter(deskId, enterReason) instead",
        ReplaceWith("logSessionEnter(deskId, enterReason)"),
    )
    fun logSessionEnter(enterReason: EnterReason) {
        val sessionId = generateSessionId()
        val previousSessionId = currentSessionId.getAndSet(sessionId)
@@ -78,7 +126,84 @@ class DesktopModeEventLogger {
        EventLogTags.writeWmShellEnterDesktopMode(enterReason.reason, sessionId)
    }

    /** Logs exit from all desktop mode sessions with [ExitReason.SCREEN_OFF]. */
    fun logScreenOff() {
        val exitReason = ExitReason.SCREEN_OFF
        deskToSessionId.forEach { deskId, sessionId ->
            ProtoLog.v(
                WM_SHELL_DESKTOP_MODE,
                "DesktopModeLogger: Logging session exit, session: %s deskId: %s reason: %s",
                sessionId,
                deskId,
                exitReason.name,
            )
            FrameworkStatsLog.write(
                DESKTOP_MODE_ATOM_ID,
                /* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__EXIT,
                /* enterReason */ 0,
                /* exitReason */ exitReason.reason,
                /* session_id */ sessionId,
            )
            EventLogTags.writeWmShellExitDesktopMode(exitReason.reason, sessionId)
        }
        wasPreviousTransitionExitByScreenOff = true
        deskToSessionId.clear()
    }

    /** Queue pending exit from a desk id with active session with [ExitReason]. */
    fun logPendingSessionExit(deskId: Int, exitReason: ExitReason) {
        val sessionId = deskToSessionId.getOrElse(deskId, { NO_SESSION_ID })
        if (sessionId == NO_SESSION_ID) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopModeLogger: No session id found for logging exit from deskId: %s",
                deskId,
            )
            return
        }

        ProtoLog.v(
            WM_SHELL_DESKTOP_MODE,
            "DesktopModeLogger: Logging session pending exit, session: %s deskId: %s reason: %s",
            sessionId,
            deskId,
            exitReason.name,
        )

        pendingLogSessionExit[deskId] = exitReason
    }

    /** Logs all pending exit from all desktop mode sessions with [ExitReason]. */
    fun logSessionExitIfNeeded() {
        pendingLogSessionExit.forEach { deskId, exitReason ->
            val sessionId = deskToSessionId.getOrElse(deskId, { NO_SESSION_ID })
            if (sessionId != NO_SESSION_ID) {
                ProtoLog.v(
                    WM_SHELL_DESKTOP_MODE,
                    "DesktopModeLogger: Logging session exit, session: %s deskId: %s reason: %s",
                    sessionId,
                    deskId,
                    exitReason.name,
                )
                FrameworkStatsLog.write(
                    DESKTOP_MODE_ATOM_ID,
                    /* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__EXIT,
                    /* enterReason */ 0,
                    /* exitReason */ exitReason.reason,
                    /* session_id */ sessionId,
                )
                EventLogTags.writeWmShellExitDesktopMode(exitReason.reason, sessionId)
            }
            deskToSessionId.remove(deskId)
        }
        pendingLogSessionExit.clear()
    }

    /** Logs exit from desktop mode session with [exitReason] */
    @Deprecated(
        "Use logSessionExit(deskId, enterReason) instead",
        ReplaceWith("logSessionExit(deskId, enterReason)"),
    )
    fun logSessionExit(exitReason: ExitReason) {
        val sessionId = currentSessionId.getAndSet(NO_SESSION_ID)
        if (sessionId == NO_SESSION_ID) {
@@ -106,12 +231,16 @@ class DesktopModeEventLogger {
    }

    /** Logs that a task with [taskUpdate] was added in a desktop mode session */
    fun logTaskAdded(taskUpdate: TaskUpdate) {
        val sessionId = currentSessionId.get()
    fun logTaskAdded(taskUpdate: TaskUpdate, deskId: Int? = INVALID_DESK_ID) {
        val sessionId =
            deskId
                ?.takeIf { it != INVALID_DESK_ID }
                ?.let { deskToSessionId.getOrDefault(it, NO_SESSION_ID) } ?: currentSessionId.get()
        if (sessionId == NO_SESSION_ID) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopModeLogger: No session id found for logging task added",
                "DesktopModeLogger: No session id found for logging task added in deskId: %s",
                deskId,
            )
            return
        }
@@ -130,12 +259,16 @@ class DesktopModeEventLogger {
    }

    /** Logs that a task with [taskUpdate] was removed from a desktop mode session */
    fun logTaskRemoved(taskUpdate: TaskUpdate) {
        val sessionId = currentSessionId.get()
    fun logTaskRemoved(taskUpdate: TaskUpdate, deskId: Int? = INVALID_DESK_ID) {
        val sessionId =
            deskId
                ?.takeIf { it != INVALID_DESK_ID }
                ?.let { deskToSessionId.getOrDefault(it, NO_SESSION_ID) } ?: currentSessionId.get()
        if (sessionId == NO_SESSION_ID) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopModeLogger: No session id found for logging task removed",
                "DesktopModeLogger: No session id found for logging task removed in deskId: %s",
                deskId,
            )
            return
        }
@@ -154,8 +287,11 @@ class DesktopModeEventLogger {
    }

    /** Logs that a task with [taskUpdate] had it's info changed in a desktop mode session */
    fun logTaskInfoChanged(taskUpdate: TaskUpdate) {
        val sessionId = currentSessionId.get()
    fun logTaskInfoChanged(taskUpdate: TaskUpdate, deskId: Int? = INVALID_DESK_ID) {
        val sessionId =
            deskId
                ?.takeIf { it != INVALID_DESK_ID }
                ?.let { deskToSessionId.getOrDefault(it, NO_SESSION_ID) } ?: currentSessionId.get()
        if (sessionId == NO_SESSION_ID) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
@@ -178,7 +314,7 @@ class DesktopModeEventLogger {
    }

    /**
     * Logs that a task resize event is starting with [taskSizeUpdate] within a Desktop mode
     * Logs that a task resize event is starting with [TaskSizeUpdate] within a Desktop mode
     * session.
     */
    fun logTaskResizingStarted(
@@ -188,11 +324,14 @@ class DesktopModeEventLogger {
        taskWidth: Int? = null,
        taskHeight: Int? = null,
        displayController: DisplayController? = null,
        displayLayoutSize: Size? = null,
        deskId: Int?,
    ) {
        if (!DesktopModeFlags.ENABLE_RESIZING_METRICS.isTrue) return

        val sessionId = currentSessionId.get()
        val sessionId =
            deskId
                ?.takeIf { it != INVALID_DESK_ID }
                ?.let { deskToSessionId.getOrDefault(it, NO_SESSION_ID) } ?: currentSessionId.get()
        if (sessionId == NO_SESSION_ID) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
@@ -209,7 +348,6 @@ class DesktopModeEventLogger {
                taskWidth,
                taskHeight,
                displayController = displayController,
                displayLayoutSize = displayLayoutSize,
            )

        ProtoLog.v(
@@ -235,11 +373,14 @@ class DesktopModeEventLogger {
        taskWidth: Int? = null,
        taskHeight: Int? = null,
        displayController: DisplayController? = null,
        displayLayoutSize: Size? = null,
        deskId: Int?,
    ) {
        if (!DesktopModeFlags.ENABLE_RESIZING_METRICS.isTrue) return

        val sessionId = currentSessionId.get()
        val sessionId =
            deskId
                ?.takeIf { it != INVALID_DESK_ID }
                ?.let { deskToSessionId.getOrDefault(it, NO_SESSION_ID) } ?: currentSessionId.get()
        if (sessionId == NO_SESSION_ID) {
            ProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
@@ -256,7 +397,6 @@ class DesktopModeEventLogger {
                taskWidth,
                taskHeight,
                displayController,
                displayLayoutSize,
            )

        ProtoLog.v(
@@ -280,7 +420,6 @@ class DesktopModeEventLogger {
        taskWidth: Int? = null,
        taskHeight: Int? = null,
        displayController: DisplayController? = null,
        displayLayoutSize: Size? = null,
    ): TaskSizeUpdate {
        val taskBounds = taskInfo.configuration.windowConfiguration.bounds

@@ -288,14 +427,9 @@ class DesktopModeEventLogger {
        val width = taskWidth ?: taskBounds.width()

        val displaySize =
            when {
                displayLayoutSize != null -> displayLayoutSize.height * displayLayoutSize.width
                displayController != null ->
                    displayController.getDisplayLayout(taskInfo.displayId)?.let {
            displayController?.getDisplayLayout(taskInfo.displayId)?.let {
                it.height() * it.width()
            }
                else -> null
            }

        return TaskSizeUpdate(
            resizeTrigger,
+74 −37

File changed.

Preview size limit exceeded, changes collapsed.

+7 −0
Original line number Diff line number Diff line
@@ -2565,6 +2565,7 @@ class DesktopTasksController(
    fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo, interaction: ToggleTaskSizeInteraction) {
        val repository = userRepositories.getProfile(taskInfo.userId)
        val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
        val deskId = repository.getDeskIdForTask(taskInfo.taskId)
        desktopModeEventLogger.logTaskResizingStarted(
            interaction.resizeTrigger,
            interaction.inputMethod,
@@ -2572,6 +2573,7 @@ class DesktopTasksController(
            currentTaskBounds.width(),
            currentTaskBounds.height(),
            displayController,
            deskId,
        )
        val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
        val destinationBounds = Rect()
@@ -2626,6 +2628,7 @@ class DesktopTasksController(
            destinationBounds.width(),
            destinationBounds.height(),
            displayController,
            deskId,
        )
        toggleResizeDesktopTaskTransitionHandler.startTransition(
            wct,
@@ -2742,6 +2745,8 @@ class DesktopTasksController(
        resizeTrigger: ResizeTrigger,
        inputMethod: InputMethod,
    ) {
        val repository = userRepositories.getProfile(taskInfo.userId)
        val deskId = repository.getDeskIdForTask(taskInfo.taskId)
        desktopModeEventLogger.logTaskResizingStarted(
            resizeTrigger,
            inputMethod,
@@ -2749,6 +2754,7 @@ class DesktopTasksController(
            currentDragBounds.width(),
            currentDragBounds.height(),
            displayController,
            deskId,
        )

        val destinationBounds = getSnapBounds(taskInfo.displayId, position)
@@ -2759,6 +2765,7 @@ class DesktopTasksController(
            destinationBounds.width(),
            destinationBounds.height(),
            displayController,
            deskId,
        )

        if (DesktopExperienceFlags.ENABLE_TILE_RESIZING.isTrue()) {
+29 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ import android.window.TransitionInfo.FLAG_MOVED_TO_TOP
import android.window.WindowContainerTransaction
import com.android.app.tracing.traceSection
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
@@ -51,6 +54,7 @@ class DesksTransitionObserver(
    private val shellController: ShellController,
    private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
    @ShellMainThread private val mainScope: CoroutineScope,
    private val desktopModeEventLogger: DesktopModeEventLogger,
) {
    private val deskTransitions = mutableMapOf<IBinder, MutableSet<DeskTransition>>()

@@ -132,6 +136,9 @@ class DesksTransitionObserver(
                val deskId = deskTransition.deskId
                val displayId = deskTransition.displayId
                deskTransition.runOnTransitEnd?.invoke()
                if (repository.isDeskActive(deskTransition.deskId)) {
                    desktopModeEventLogger.logPendingSessionExit(deskId, deskTransition.exitReason)
                }
                repository.removeDesk(deskTransition.deskId)
                deskTransition.onDeskRemovedListener?.onDeskRemoved(displayId, deskId)
            }
@@ -151,6 +158,10 @@ class DesksTransitionObserver(
                    displayId = deskTransition.displayId,
                    deskId = deskTransition.deskId,
                )
                desktopModeEventLogger.logSessionEnter(
                    deskTransition.deskId,
                    deskTransition.enterReason,
                )
                deskTransition.runOnTransitEnd?.invoke()
            }
            is DeskTransition.ActivateDeskWithTask -> {
@@ -170,6 +181,10 @@ class DesksTransitionObserver(
                        displayId = deskTransition.displayId,
                        deskId = deskTransition.deskId,
                    )
                    desktopModeEventLogger.logSessionEnter(
                        deskTransition.deskId,
                        deskTransition.enterReason,
                    )
                } else {
                    logW("ActivateDeskWithTask: did not find desk change")
                }
@@ -232,6 +247,10 @@ class DesksTransitionObserver(
            return
        }
        desktopRepository.setDeskInactive(deskId = deskTransition.deskId)
        desktopModeEventLogger.logPendingSessionExit(
            deskTransition.deskId,
            deskTransition.exitReason,
        )
    }

    private fun handleChangeDeskDisplay(deskTransition: DeskTransition.ChangeDeskDisplay) {
@@ -371,6 +390,10 @@ class DesksTransitionObserver(
                            )
                            // Always let the organizer deactivate to clear the launch root.
                            desksOrganizer.deactivateDesk(wct, activeDeskId, skipReorder = true)
                            desktopModeEventLogger.logPendingSessionExit(
                                activeDeskId,
                                ExitReason.UNKNOWN_EXIT,
                            )
                            if (!keepActiveInRepository) {
                                repository.setDeskInactive(activeDeskId)
                            }
@@ -400,6 +423,10 @@ class DesksTransitionObserver(
                            logD("Reactivating desk=%d", activeDeskId)
                            desksToActivate.add(activeDeskId)
                            desksOrganizer.activateDesk(wct, activeDeskId, skipReorder = false)
                            desktopModeEventLogger.logSessionEnter(
                                activeDeskId,
                                EnterReason.UNKNOWN_ENTER,
                            )
                        } else {
                            logD("Dismissing desktop wallpaper")
                            val container =
@@ -485,6 +512,7 @@ class DesksTransitionObserver(
                    )
                    // Always let the organizer deactivate to clear the launch root.
                    desksOrganizer.deactivateDesk(wct, deskId, skipReorder = true)
                    desktopModeEventLogger.logPendingSessionExit(deskId, ExitReason.UNKNOWN_EXIT)
                    if (!keepActiveInRepository) {
                        // The desk was independently deactivated (such as when Home is brought
                        // to front during CTS), make sure the repository state reflects that too.
@@ -515,6 +543,7 @@ class DesksTransitionObserver(
                    )
                    desksOrganizer.activateDesk(wct, deskId, skipReorder = true)
                    repository.setActiveDesk(displayId, deskId)
                    desktopModeEventLogger.logSessionEnter(deskId, EnterReason.UNKNOWN_ENTER)
                }
                else -> {
                    logW(
Loading