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

Commit da8539a8 authored by Alina Zaidi's avatar Alina Zaidi
Browse files

Add Enter to DW from Overview logging

Flag: EXEMPT minor change
Bug: b/346320631
Test: locally tested, unit test added
Change-Id: Id813b3f957e9e188918e52199a183747999a44eb
parent 95a2f061
Loading
Loading
Loading
Loading
+50 −20
Original line number Original line Diff line number Diff line
@@ -35,15 +35,16 @@ import androidx.core.util.plus
import androidx.core.util.putAll
import androidx.core.util.putAll
import com.android.internal.logging.InstanceId
import com.android.internal.logging.InstanceId
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.protolog.common.ProtoLog
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_HANDLE_MENU_BUTTON
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_HANDLE_MENU_BUTTON
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.DesktopModeStatus
import com.android.wm.shell.shared.DesktopModeStatus
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.TransitionUtil
@@ -80,6 +81,9 @@ class DesktopModeLoggerTransitionObserver(
    // animation was cancelled, we restore these tasks to calculate the post-Transition state
    // animation was cancelled, we restore these tasks to calculate the post-Transition state
    private val tasksSavedForRecents: SparseArray<TaskInfo> = SparseArray()
    private val tasksSavedForRecents: SparseArray<TaskInfo> = SparseArray()


    // Caching whether the previous transition was exit to overview.
    private var wasPreviousTransitionExitToOverview: Boolean = false

    // The instanceId for the current logging session
    // The instanceId for the current logging session
    private var loggerInstanceId: InstanceId? = null
    private var loggerInstanceId: InstanceId? = null


@@ -101,7 +105,7 @@ class DesktopModeLoggerTransitionObserver(
        finishTransaction: SurfaceControl.Transaction
        finishTransaction: SurfaceControl.Transaction
    ) {
    ) {
        // this was a new recents animation
        // this was a new recents animation
        if (info.isRecentsTransition() && tasksSavedForRecents.isEmpty()) {
        if (info.isExitToRecentsTransition() && tasksSavedForRecents.isEmpty()) {
            KtProtoLog.v(
            KtProtoLog.v(
                WM_SHELL_DESKTOP_MODE,
                WM_SHELL_DESKTOP_MODE,
                "DesktopModeLogger: Recents animation running, saving tasks for later"
                "DesktopModeLogger: Recents animation running, saving tasks for later"
@@ -143,6 +147,7 @@ class DesktopModeLoggerTransitionObserver(
            preTransitionVisibleFreeformTasks = visibleFreeformTaskInfos,
            preTransitionVisibleFreeformTasks = visibleFreeformTaskInfos,
            postTransitionVisibleFreeformTasks = postTransitionVisibleFreeformTasks
            postTransitionVisibleFreeformTasks = postTransitionVisibleFreeformTasks
        )
        )
        wasPreviousTransitionExitToOverview = info.isExitToRecentsTransition()
    }
    }


    override fun onTransitionStarting(transition: IBinder) {}
    override fun onTransitionStarting(transition: IBinder) {}
@@ -309,21 +314,40 @@ class DesktopModeLoggerTransitionObserver(
    }
    }


    /** Get [EnterReason] for this session enter */
    /** Get [EnterReason] for this session enter */
    private fun getEnterReason(transitionInfo: TransitionInfo): EnterReason {
    private fun getEnterReason(transitionInfo: TransitionInfo): EnterReason =
        return when (transitionInfo.type) {
        when {
            WindowManager.TRANSIT_WAKE -> EnterReason.SCREEN_ON
            transitionInfo.type == WindowManager.TRANSIT_WAKE -> EnterReason.SCREEN_ON
            Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP -> EnterReason.APP_HANDLE_DRAG
            transitionInfo.type == Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP ->
            TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON -> EnterReason.APP_HANDLE_MENU_BUTTON
                EnterReason.APP_HANDLE_DRAG
            TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW -> EnterReason.APP_FROM_OVERVIEW
            transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON ->
            TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT -> EnterReason.KEYBOARD_SHORTCUT_ENTER
                EnterReason.APP_HANDLE_MENU_BUTTON
            WindowManager.TRANSIT_OPEN -> EnterReason.APP_FREEFORM_INTENT
            transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW ->
            else -> EnterReason.UNKNOWN_ENTER
                EnterReason.APP_FROM_OVERVIEW
            transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT ->
                EnterReason.KEYBOARD_SHORTCUT_ENTER
            // NOTE: the below condition also applies for EnterReason quickswitch
            transitionInfo.type == WindowManager.TRANSIT_TO_FRONT -> EnterReason.OVERVIEW
            // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
            // next transition involving freeform windows.
            // TODO(b/346564416): Modify logging for cancelled recents once it transition is
            //  changed. Also see how to account to time difference between actual enter time and
            //  time of this log. Also account for the missed session when exit happens just after
            //  a cancelled recents.
            wasPreviousTransitionExitToOverview -> EnterReason.OVERVIEW
            transitionInfo.type == WindowManager.TRANSIT_OPEN -> EnterReason.APP_FREEFORM_INTENT
            else -> {
                ProtoLog.w(
                    WM_SHELL_DESKTOP_MODE,
                    "Unknown enter reason for transition type ${transitionInfo.type}",
                    transitionInfo.type
                )
                EnterReason.UNKNOWN_ENTER
            }
            }
        }
        }


    /** Get [ExitReason] for this session exit */
    /** Get [ExitReason] for this session exit */
    private fun getExitReason(transitionInfo: TransitionInfo): ExitReason {
    private fun getExitReason(transitionInfo: TransitionInfo): ExitReason =
        return when {
         when {
            transitionInfo.type == WindowManager.TRANSIT_SLEEP -> ExitReason.SCREEN_OFF
            transitionInfo.type == WindowManager.TRANSIT_SLEEP -> ExitReason.SCREEN_OFF
            transitionInfo.type == WindowManager.TRANSIT_CLOSE -> ExitReason.TASK_FINISHED
            transitionInfo.type == WindowManager.TRANSIT_CLOSE -> ExitReason.TASK_FINISHED
            transitionInfo.type == TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG -> ExitReason.DRAG_TO_EXIT
            transitionInfo.type == TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG -> ExitReason.DRAG_TO_EXIT
@@ -331,8 +355,14 @@ class DesktopModeLoggerTransitionObserver(
                ExitReason.APP_HANDLE_MENU_BUTTON_EXIT
                ExitReason.APP_HANDLE_MENU_BUTTON_EXIT
            transitionInfo.type == TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT ->
            transitionInfo.type == TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT ->
                ExitReason.KEYBOARD_SHORTCUT_EXIT
                ExitReason.KEYBOARD_SHORTCUT_EXIT
            transitionInfo.isRecentsTransition() -> ExitReason.RETURN_HOME_OR_OVERVIEW
            transitionInfo.isExitToRecentsTransition() -> ExitReason.RETURN_HOME_OR_OVERVIEW
            else -> ExitReason.UNKNOWN_EXIT
            else -> {
                ProtoLog.w(
                    WM_SHELL_DESKTOP_MODE,
                    "Unknown exit reason for transition type ${transitionInfo.type}",
                    transitionInfo.type
                )
                ExitReason.UNKNOWN_EXIT
            }
            }
        }
        }


@@ -357,7 +387,7 @@ class DesktopModeLoggerTransitionObserver(
        return this.windowingMode == WINDOWING_MODE_FREEFORM
        return this.windowingMode == WINDOWING_MODE_FREEFORM
    }
    }


    private fun TransitionInfo.isRecentsTransition(): Boolean {
    private fun TransitionInfo.isExitToRecentsTransition(): Boolean {
        return this.type == WindowManager.TRANSIT_TO_FRONT &&
        return this.type == WindowManager.TRANSIT_TO_FRONT &&
            this.flags == WindowManager.TRANSIT_FLAG_IS_RECENTS
            this.flags == WindowManager.TRANSIT_FLAG_IS_RECENTS
    }
    }
+164 −1
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Context
import android.os.IBinder
import android.os.IBinder
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
import android.view.SurfaceControl
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS
import android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS
import android.view.WindowManager.TRANSIT_NONE
import android.view.WindowManager.TRANSIT_NONE
@@ -182,7 +183,7 @@ class DesktopModeLoggerTransitionObserverTest {
  }
  }


  @Test
  @Test
  fun transitEnterDesktopFromAppFromOverview_logTaskAddedAndEnterReasonUnknown() {
  fun transitEnterDesktopFromAppFromOverview_logTaskAddedAndEnterReasonAppFromOverview() {
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val transitionInfo =
    val transitionInfo =
        TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW, 0)
        TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW, 0)
@@ -217,6 +218,168 @@ class DesktopModeLoggerTransitionObserverTest {
    verifyZeroInteractions(desktopModeEventLogger)
    verifyZeroInteractions(desktopModeEventLogger)
  }
  }


  @Test
  fun transitToFront_logTaskAddedAndEnterReasonOverview() {
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val transitionInfo = TransitionInfoBuilder(TRANSIT_TO_FRONT, 0).addChange(change).build()

    callOnTransitionReady(transitionInfo)
    val sessionId = transitionObserver.getLoggerSessionId()

    assertThat(sessionId).isNotNull()
    verify(desktopModeEventLogger, times(1))
        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
    verifyZeroInteractions(desktopModeEventLogger)
  }

  @Test
  fun transitToFront_previousTransitionExitToOverview_logTaskAddedAndEnterReasonOverview() {
    // previous exit to overview transition
    val previousSessionId = 1
    // add a freeform task
    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    transitionObserver.setLoggerSessionId(previousSessionId)
    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val previousTransitionInfo =
        TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
            .addChange(previousChange)
            .build()

    callOnTransitionReady(previousTransitionInfo)

    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
    verify(desktopModeEventLogger, times(1))
        .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))

    // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
    // next transition involving freeform windows

    // TRANSIT_TO_FRONT
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val transitionInfo = TransitionInfoBuilder(TRANSIT_TO_FRONT, 0).addChange(change).build()

    callOnTransitionReady(transitionInfo)
    val sessionId = transitionObserver.getLoggerSessionId()

    assertThat(sessionId).isNotNull()
    verify(desktopModeEventLogger, times(1))
        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
    verifyZeroInteractions(desktopModeEventLogger)
  }

  @Test
  fun transitChange_previousTransitionExitToOverview_logTaskAddedAndEnterReasonOverview() {
    // previous exit to overview transition
    val previousSessionId = 1
    // add a freeform task
    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    transitionObserver.setLoggerSessionId(previousSessionId)
    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val previousTransitionInfo =
        TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
            .addChange(previousChange)
            .build()

    callOnTransitionReady(previousTransitionInfo)

    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
    verify(desktopModeEventLogger, times(1))
        .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))

    // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
    // next transition involving freeform windows

    // TRANSIT_CHANGE
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val transitionInfo = TransitionInfoBuilder(TRANSIT_CHANGE, 0).addChange(change).build()

    callOnTransitionReady(transitionInfo)
    val sessionId = transitionObserver.getLoggerSessionId()

    assertThat(sessionId).isNotNull()
    verify(desktopModeEventLogger, times(1))
        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
    verifyZeroInteractions(desktopModeEventLogger)
  }

  @Test
  fun transitOpen_previousTransitionExitToOverview_logTaskAddedAndEnterReasonOverview() {
    // previous exit to overview transition
    val previousSessionId = 1
    // add a freeform task
    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    transitionObserver.setLoggerSessionId(previousSessionId)
    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val previousTransitionInfo =
        TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
            .addChange(previousChange)
            .build()

    callOnTransitionReady(previousTransitionInfo)

    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
    verify(desktopModeEventLogger, times(1))
        .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))

    // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
    // next transition involving freeform windows

    // TRANSIT_OPEN
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN, 0).addChange(change).build()

    callOnTransitionReady(transitionInfo)
    val sessionId = transitionObserver.getLoggerSessionId()

    assertThat(sessionId).isNotNull()
    verify(desktopModeEventLogger, times(1))
        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
    verifyZeroInteractions(desktopModeEventLogger)
  }

  @Test
  @Suppress("ktlint:standard:max-line-length")
  fun transitEnterDesktopFromAppFromOverview_previousTransitionExitToOverview_logTaskAddedAndEnterReasonAppFromOverview() {
    // Tests for AppFromOverview precedence in compared to cancelled Overview

    // previous exit to overview transition
    val previousSessionId = 1
    // add a freeform task
    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    transitionObserver.setLoggerSessionId(previousSessionId)
    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val previousTransitionInfo =
      TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
              .addChange(previousChange)
              .build()

    callOnTransitionReady(previousTransitionInfo)

    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
    verify(desktopModeEventLogger, times(1))
            .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))

    // TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val transitionInfo =
      TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW, 0)
              .addChange(change)
              .build()

    callOnTransitionReady(transitionInfo)
    val sessionId = transitionObserver.getLoggerSessionId()

    assertThat(sessionId).isNotNull()
    verify(desktopModeEventLogger, times(1))
            .logSessionEnter(eq(sessionId!!), eq(EnterReason.APP_FROM_OVERVIEW))
    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
    verifyZeroInteractions(desktopModeEventLogger)
  }

  @Test
  @Test
  fun transitEnterDesktopFromUnknown_logTaskAddedAndEnterReasonUnknown() {
  fun transitEnterDesktopFromUnknown_logTaskAddedAndEnterReasonUnknown() {
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))