summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
author Orhan Uysal <uysalorhan@google.com> 2025-01-22 11:44:47 +0000
committer Orhan Uysal <uysalorhan@google.com> 2025-01-22 15:49:50 +0000
commit5e8a4fea4533866c0dcbd4e295121fa089d6c0a4 (patch)
treea1dbf5ab593b09edd6b6845e006cac5e6a7941cb /libs
parent8dd4d54115eb397fe29a8763a81e7c0a59c479e8 (diff)
Pipe onTaskVanished into DesktopModeLogger,,,
In some cases apps may get killed and we don't get a change for the task being closed in that transition. This results in logging going out of sync and also leaking taskInfo objects. This cl pipes onTaskVanished into the observer to fix those cases. Bug: 367713257 Test: Manually lmk apps, see that app vanishing is being logged Flag: EXEMPT Bug fix Change-Id: If4d813105e2c94ac90fd9de8ff5e2a4c9529ace4
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt87
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java17
4 files changed, 83 insertions, 30 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 67e345365d26..c32e6b61d113 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -394,6 +394,7 @@ public abstract class WMShellModule {
ShellTaskOrganizer shellTaskOrganizer,
Optional<DesktopUserRepositories> desktopUserRepositories,
Optional<DesktopTasksController> desktopTasksController,
+ DesktopModeLoggerTransitionObserver desktopModeLoggerTransitionObserver,
LaunchAdjacentController launchAdjacentController,
WindowDecorViewModel windowDecorViewModel,
Optional<TaskChangeListener> taskChangeListener) {
@@ -406,6 +407,7 @@ public abstract class WMShellModule {
shellTaskOrganizer,
desktopUserRepositories,
desktopTasksController,
+ desktopModeLoggerTransitionObserver,
launchAdjacentController,
windowDecorViewModel,
taskChangeListener);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index a43358603bc3..3b051694ae81 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -167,6 +167,29 @@ class DesktopModeLoggerTransitionObserver(
override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {}
+ fun onTaskVanished(taskInfo: RunningTaskInfo) {
+ // At this point the task should have been cleared up due to transition. If it's not yet
+ // cleared up, it might be one of the edge cases where transitions don't give the correct
+ // signal.
+ if (visibleFreeformTaskInfos.containsKey(taskInfo.taskId)) {
+ val postTransitionFreeformTasks: SparseArray<TaskInfo> = SparseArray()
+ postTransitionFreeformTasks.putAll(visibleFreeformTaskInfos)
+ postTransitionFreeformTasks.remove(taskInfo.taskId)
+ ProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopModeLogger: processing tasks after task vanished %s",
+ postTransitionFreeformTasks.size(),
+ )
+ identifyLogEventAndUpdateState(
+ transition = null,
+ transitionInfo = null,
+ preTransitionVisibleFreeformTasks = visibleFreeformTaskInfos,
+ postTransitionVisibleFreeformTasks = postTransitionFreeformTasks,
+ newFocusedFreeformTask = null,
+ )
+ }
+ }
+
// Returns null if there was no change in focused task
private fun getNewFocusedFreeformTask(info: TransitionInfo): TaskInfo? {
val freeformWindowChanges =
@@ -253,8 +276,8 @@ class DesktopModeLoggerTransitionObserver(
* state and update it
*/
private fun identifyLogEventAndUpdateState(
- transition: IBinder,
- transitionInfo: TransitionInfo,
+ transition: IBinder?,
+ transitionInfo: TransitionInfo?,
preTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
postTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
newFocusedFreeformTask: TaskInfo?,
@@ -310,8 +333,8 @@ class DesktopModeLoggerTransitionObserver(
/** Compare the old and new state of taskInfos and identify and log the changes */
private fun identifyAndLogTaskUpdates(
- transition: IBinder,
- transitionInfo: TransitionInfo,
+ transition: IBinder?,
+ transitionInfo: TransitionInfo?,
preTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
postTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
newFocusedFreeformTask: TaskInfo?,
@@ -384,22 +407,24 @@ class DesktopModeLoggerTransitionObserver(
}
private fun getMinimizeReason(
- transition: IBinder,
- transitionInfo: TransitionInfo,
+ transition: IBinder?,
+ transitionInfo: TransitionInfo?,
taskInfo: TaskInfo,
): MinimizeReason? {
- if (transitionInfo.type == Transitions.TRANSIT_MINIMIZE) {
+ if (transitionInfo?.type == Transitions.TRANSIT_MINIMIZE) {
return MinimizeReason.MINIMIZE_BUTTON
}
- val minimizingTask = desktopTasksLimiter.getOrNull()?.getMinimizingTask(transition)
+ val minimizingTask =
+ transition?.let { desktopTasksLimiter.getOrNull()?.getMinimizingTask(transition) }
if (minimizingTask?.taskId == taskInfo.taskId) {
return minimizingTask.minimizeReason
}
return null
}
- private fun getUnminimizeReason(transition: IBinder, taskInfo: TaskInfo): UnminimizeReason? {
- val unminimizingTask = desktopTasksLimiter.getOrNull()?.getUnminimizingTask(transition)
+ private fun getUnminimizeReason(transition: IBinder?, taskInfo: TaskInfo): UnminimizeReason? {
+ val unminimizingTask =
+ transition?.let { desktopTasksLimiter.getOrNull()?.getUnminimizingTask(transition) }
if (unminimizingTask?.taskId == taskInfo.taskId) {
return unminimizingTask.unminimizeReason
}
@@ -441,24 +466,24 @@ class DesktopModeLoggerTransitionObserver(
}
/** Get [EnterReason] for this session enter */
- private fun getEnterReason(transitionInfo: TransitionInfo): EnterReason {
+ private fun getEnterReason(transitionInfo: TransitionInfo?): EnterReason {
val enterReason =
when {
- transitionInfo.type == WindowManager.TRANSIT_WAKE
+ transitionInfo?.type == WindowManager.TRANSIT_WAKE
// If there is a screen lock, desktop window entry is after dismissing keyguard
||
- (transitionInfo.type == WindowManager.TRANSIT_TO_BACK &&
+ (transitionInfo?.type == WindowManager.TRANSIT_TO_BACK &&
wasPreviousTransitionExitByScreenOff) -> EnterReason.SCREEN_ON
- transitionInfo.type == TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP ->
+ transitionInfo?.type == TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP ->
EnterReason.APP_HANDLE_DRAG
- transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON ->
+ transitionInfo?.type == TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON ->
EnterReason.APP_HANDLE_MENU_BUTTON
- transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW ->
+ transitionInfo?.type == TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW ->
EnterReason.APP_FROM_OVERVIEW
- transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT ->
+ 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
+ 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.
@@ -469,12 +494,13 @@ class DesktopModeLoggerTransitionObserver(
// after
// a cancelled recents.
wasPreviousTransitionExitToOverview -> EnterReason.OVERVIEW
- transitionInfo.type == WindowManager.TRANSIT_OPEN -> EnterReason.APP_FREEFORM_INTENT
+ transitionInfo?.type == WindowManager.TRANSIT_OPEN ->
+ EnterReason.APP_FREEFORM_INTENT
else -> {
ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"Unknown enter reason for transition type: %s",
- transitionInfo.type,
+ transitionInfo?.type,
)
EnterReason.UNKNOWN_ENTER
}
@@ -484,30 +510,31 @@ class DesktopModeLoggerTransitionObserver(
}
/** Get [ExitReason] for this session exit */
- private fun getExitReason(transitionInfo: TransitionInfo): ExitReason =
+ private fun getExitReason(transitionInfo: TransitionInfo?): ExitReason =
when {
- transitionInfo.type == WindowManager.TRANSIT_SLEEP -> {
+ transitionInfo?.type == WindowManager.TRANSIT_SLEEP -> {
wasPreviousTransitionExitByScreenOff = true
ExitReason.SCREEN_OFF
}
// TODO(b/384490301): differentiate back gesture / button exit from clicking the close
// button located in the window top corner.
- transitionInfo.type == WindowManager.TRANSIT_TO_BACK -> ExitReason.TASK_MOVED_TO_BACK
- 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_HANDLE_MENU_BUTTON ->
+ transitionInfo?.type == WindowManager.TRANSIT_TO_BACK -> ExitReason.TASK_MOVED_TO_BACK
+ 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_HANDLE_MENU_BUTTON ->
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
- transitionInfo.isExitToRecentsTransition() -> ExitReason.RETURN_HOME_OR_OVERVIEW
- transitionInfo.type == Transitions.TRANSIT_MINIMIZE -> ExitReason.TASK_MINIMIZED
+ transitionInfo?.isExitToRecentsTransition() == true ->
+ ExitReason.RETURN_HOME_OR_OVERVIEW
+ transitionInfo?.type == Transitions.TRANSIT_MINIMIZE -> ExitReason.TASK_MINIMIZED
else -> {
ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"Unknown exit reason for transition type: %s",
- transitionInfo.type,
+ transitionInfo?.type,
)
ExitReason.UNKNOWN_EXIT
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index b38a853321a7..897e2d1601a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -29,6 +29,7 @@ import android.window.DesktopModeFlags;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.LaunchAdjacentController;
+import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
@@ -52,6 +53,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
private final ShellTaskOrganizer mShellTaskOrganizer;
private final Optional<DesktopUserRepositories> mDesktopUserRepositories;
private final Optional<DesktopTasksController> mDesktopTasksController;
+ private final DesktopModeLoggerTransitionObserver mDesktopModeLoggerTransitionObserver;
private final WindowDecorViewModel mWindowDecorationViewModel;
private final LaunchAdjacentController mLaunchAdjacentController;
private final Optional<TaskChangeListener> mTaskChangeListener;
@@ -64,6 +66,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
ShellTaskOrganizer shellTaskOrganizer,
Optional<DesktopUserRepositories> desktopUserRepositories,
Optional<DesktopTasksController> desktopTasksController,
+ DesktopModeLoggerTransitionObserver desktopModeLoggerTransitionObserver,
LaunchAdjacentController launchAdjacentController,
WindowDecorViewModel windowDecorationViewModel,
Optional<TaskChangeListener> taskChangeListener) {
@@ -72,6 +75,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
mWindowDecorationViewModel = windowDecorationViewModel;
mDesktopUserRepositories = desktopUserRepositories;
mDesktopTasksController = desktopTasksController;
+ mDesktopModeLoggerTransitionObserver = desktopModeLoggerTransitionObserver;
mLaunchAdjacentController = launchAdjacentController;
mTaskChangeListener = taskChangeListener;
if (shellInit != null) {
@@ -130,6 +134,9 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
repository.removeTask(taskInfo.displayId, taskInfo.taskId);
}
}
+ // TODO: b/367268649 - This listener shouldn't need to call the transition observer directly
+ // for logging once the logic in the observer is moved.
+ mDesktopModeLoggerTransitionObserver.onTaskVanished(taskInfo);
mWindowDecorationViewModel.onTaskVanished(taskInfo);
updateLaunchAdjacentController();
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
index 6c16b3220a07..4174bbd89b76 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
@@ -46,6 +46,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.LaunchAdjacentController;
+import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
@@ -89,6 +90,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
@Mock
private DesktopTasksController mDesktopTasksController;
@Mock
+ private DesktopModeLoggerTransitionObserver mDesktopModeLoggerTransitionObserver;
+ @Mock
private LaunchAdjacentController mLaunchAdjacentController;
@Mock
private TaskChangeListener mTaskChangeListener;
@@ -114,6 +117,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mTaskOrganizer,
Optional.of(mDesktopUserRepositories),
Optional.of(mDesktopTasksController),
+ mDesktopModeLoggerTransitionObserver,
mLaunchAdjacentController,
mWindowDecorViewModel,
Optional.of(mTaskChangeListener));
@@ -283,6 +287,19 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
}
@Test
+ public void onTaskVanished_withDesktopModeLogger_forwards() {
+ ActivityManager.RunningTaskInfo task =
+ new TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+ task.isVisible = true;
+ mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
+
+ mFreeformTaskListener.onTaskVanished(task);
+
+ verify(mDesktopModeLoggerTransitionObserver).onTaskVanished(task);
+ }
+
+
+ @Test
public void onTaskInfoChanged_withDesktopController_forwards() {
ActivityManager.RunningTaskInfo task =
new TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FREEFORM).build();