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

Commit e0fd816d authored by Pragya Bajoria's avatar Pragya Bajoria
Browse files

Connect DesktopTaskChangeListener with DesktopRepository. This migrates...

Connect DesktopTaskChangeListener with DesktopRepository. This migrates existing code from FreeformTaskListener.

Bug: 332682201
Test: atest DesktopTaskChangeListenerTest
Test: atest FreeformTaskListenerTests
Test: atest FreeformTaskTransitionObserverTest
Flag: EXEMPT (already flag-guarded)
Change-Id: I6b5fb097bfcd186423b30ec33271d40e9d764818
parent c9ba5f85
Loading
Loading
Loading
Loading
+238 −139

File changed.

Preview size limit exceeded, changes collapsed.

+58 −5
Original line number Diff line number Diff line
@@ -17,21 +17,60 @@
package com.android.wm.shell.desktopmode

import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.window.DesktopModeFlags
import com.android.wm.shell.freeform.TaskChangeListener

/** Manages tasks handling specific to Android Desktop Mode. */
class DesktopTaskChangeListener: TaskChangeListener {
class DesktopTaskChangeListener(
    private val desktopRepository: DesktopRepository,
) : TaskChangeListener {

  override fun onTaskOpening(taskInfo: RunningTaskInfo) {
    // TODO: b/367268953 - Connect this with DesktopRepository.
    if (!isFreeformTask(taskInfo) && desktopRepository.isActiveTask(taskInfo.taskId)) {
      desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
      return
    }
    if (isFreeformTask(taskInfo)) {
      desktopRepository.addOrMoveFreeformTaskToTop(taskInfo.displayId, taskInfo.taskId)
      if (taskInfo.isVisible) {
        desktopRepository.addActiveTask(taskInfo.displayId, taskInfo.taskId)
        desktopRepository.updateTaskVisibility(taskInfo.displayId, taskInfo.taskId, visible = true)
      }
    }
  }

  override fun onTaskChanging(taskInfo: RunningTaskInfo) {
    // TODO: b/367268953 - Connect this with DesktopRepository.
    if (!desktopRepository.isActiveTask(taskInfo.taskId)) return

    // Case 1: Freeform task is changed in Desktop Mode.
    if (isFreeformTask(taskInfo)) {
      if (taskInfo.isVisible) {
        desktopRepository.addActiveTask(taskInfo.displayId, taskInfo.taskId)
      }
      desktopRepository.updateTaskVisibility(
          taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible)
    } else {
      // Case 2: Freeform task is changed outside Desktop Mode.
      desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
    }
  }

  // This method should only be used for scenarios where the task info changes are not propagated to
  // [DesktopTaskChangeListener#onTaskChanging] via [TransitionsObserver].
  // Any changes to [DesktopRepository] from this method should be made carefully to minimize risk
  // of race conditions and possible duplications with [onTaskChanging].
  override fun onNonTransitionTaskChanging(taskInfo: RunningTaskInfo) {
    // TODO: b/367268953 - Propapagate usages from FreeformTaskListener to this method.
  }

  override fun onTaskMovingToFront(taskInfo: RunningTaskInfo) {
    // TODO: b/367268953 - Connect this with DesktopRepository.
    if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
    if (!isFreeformTask(taskInfo)) {
      desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
    }
    // TODO: b/367268953 - Connect this with DesktopRepository for handling
    // task moving to front for tasks in windowing mode.
  }

  override fun onTaskMovingToBack(taskInfo: RunningTaskInfo) {
@@ -39,6 +78,20 @@ class DesktopTaskChangeListener: TaskChangeListener {
  }

  override fun onTaskClosing(taskInfo: RunningTaskInfo) {
    // TODO: b/367268953 - Connect this with DesktopRepository.
    if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
    // TODO: b/370038902 - Handle Activity#finishAndRemoveTask.
    if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue() ||
        desktopRepository.isClosingTask(taskInfo.taskId)) {
      // A task that's vanishing should be removed:
      // - If it's closed by the X button which means it's marked as a closing task.
      desktopRepository.removeClosingTask(taskInfo.taskId)
      desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
    } else {
      desktopRepository.updateTaskVisibility(taskInfo.displayId, taskInfo.taskId, visible = false)
      desktopRepository.minimizeTask(taskInfo.displayId, taskInfo.taskId)
    }
  }

  private fun isFreeformTask(taskInfo: RunningTaskInfo): Boolean =
      taskInfo.windowingMode == WINDOWING_MODE_FREEFORM
}
+21 −10
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.wm.shell.freeform;

import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;

import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FREEFORM;

import android.app.ActivityManager.RunningTaskInfo;
@@ -54,6 +53,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
    private final Optional<DesktopTasksController> mDesktopTasksController;
    private final WindowDecorViewModel mWindowDecorationViewModel;
    private final LaunchAdjacentController mLaunchAdjacentController;
    private final Optional<TaskChangeListener> mTaskChangeListener;

    private final SparseArray<State> mTasks = new SparseArray<>();

@@ -69,13 +69,15 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
            Optional<DesktopRepository> desktopRepository,
            Optional<DesktopTasksController> desktopTasksController,
            LaunchAdjacentController launchAdjacentController,
            WindowDecorViewModel windowDecorationViewModel) {
            WindowDecorViewModel windowDecorationViewModel,
            Optional<TaskChangeListener> taskChangeListener) {
        mContext = context;
        mShellTaskOrganizer = shellTaskOrganizer;
        mWindowDecorationViewModel = windowDecorationViewModel;
        mDesktopRepository = desktopRepository;
        mDesktopTasksController = desktopTasksController;
        mLaunchAdjacentController = launchAdjacentController;
        mTaskChangeListener = taskChangeListener;
        if (shellInit != null) {
            shellInit.addInitCallback(this::onInit, this);
        }
@@ -100,7 +102,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
        state.mLeash = leash;
        mTasks.put(taskInfo.taskId, state);

        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
        if (!DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS.isTrue() &&
                DesktopModeStatus.canEnterDesktopMode(mContext)) {
            mDesktopRepository.ifPresent(repository -> {
                repository.addOrMoveFreeformTaskToTop(taskInfo.displayId, taskInfo.taskId);
                if (taskInfo.isVisible) {
@@ -119,7 +122,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
                taskInfo.taskId);
        mTasks.remove(taskInfo.taskId);

        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
        if (!DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS.isTrue() &&
                DesktopModeStatus.canEnterDesktopMode(mContext)) {
            mDesktopRepository.ifPresent(repository -> {
                // TODO: b/370038902 - Handle Activity#finishAndRemoveTask.
                if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()
@@ -148,6 +152,12 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
        mWindowDecorationViewModel.onTaskInfoChanged(taskInfo);
        state.mTaskInfo = taskInfo;
        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
            if (DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS.isTrue()) {
                // Pass task info changes to the [TaskChangeListener] since [TransitionsObserver]
                // does not propagate all task info changes.
                mTaskChangeListener.ifPresent(listener ->
                    listener.onNonTransitionTaskChanging(taskInfo));
            } else {
                mDesktopRepository.ifPresent(repository -> {
                    if (taskInfo.isVisible) {
                        repository.addActiveTask(taskInfo.displayId, taskInfo.taskId);
@@ -156,6 +166,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
                        taskInfo.isVisible);
                });
            }
        }
        updateLaunchAdjacentController();
    }

+9 −14
Original line number Diff line number Diff line
@@ -42,9 +42,9 @@ import java.util.Map;
import java.util.Optional;

/**
 * The {@link Transitions.TransitionHandler} that handles freeform task launches, closes,
 * maximizing and restoring transitions. It also reports transitions so that window decorations can
 * be a part of transitions.
 * The {@link Transitions.TransitionHandler} that handles freeform task launches, closes, maximizing
 * and restoring transitions. It also reports transitions so that window decorations can be a part
 * of transitions.
 */
public class FreeformTaskTransitionObserver implements Transitions.TransitionObserver {
    private final Transitions mTransitions;
@@ -89,8 +89,8 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
            // TODO(b/367268953): Remove when DesktopTaskListener is introduced and the repository
            //  is updated from there **before** the |mWindowDecorViewModel| methods are invoked.
            //  Otherwise window decoration relayout won't run with the immersive state up to date.
            mDesktopImmersiveController.ifPresent(h ->
                    h.onTransitionReady(transition, info, startT, finishT));
            mDesktopImmersiveController.ifPresent(
                    h -> h.onTransitionReady(transition, info, startT, finishT));
        }
        // Update focus state first to ensure the correct state can be queried from listeners.
        // TODO(371503964): Remove this once the unified task repository is ready.
@@ -147,8 +147,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        mTaskChangeListener.ifPresent(
            listener -> listener.onTaskOpening(change.getTaskInfo()));
        mTaskChangeListener.ifPresent(listener -> listener.onTaskOpening(change.getTaskInfo()));
        mWindowDecorViewModel.onTaskOpening(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
    }
@@ -157,23 +156,19 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        mTaskChangeListener.ifPresent(
            listener -> listener.onTaskClosing(change.getTaskInfo()));
        mTaskChangeListener.ifPresent(listener -> listener.onTaskClosing(change.getTaskInfo()));
        mWindowDecorViewModel.onTaskClosing(change.getTaskInfo(), startT, finishT);

    }

    private void onChangeTransitionReady(
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        mTaskChangeListener.ifPresent(listener ->
            listener.onTaskChanging(change.getTaskInfo()));
        mTaskChangeListener.ifPresent(listener -> listener.onTaskChanging(change.getTaskInfo()));
        mWindowDecorViewModel.onTaskChanging(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
    }


    private void onToFrontTransitionReady(
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
+21 −12
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.wm.shell.freeform

import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningTaskInfo

/**
 * Interface used by [FreeformTaskTransitionObserver] to manage freeform tasks.
@@ -27,9 +27,18 @@ interface TaskChangeListener {
  /** Notifies a task opening in freeform mode. */
  fun onTaskOpening(taskInfo: RunningTaskInfo)

    /** Notifies a task info update on the given task. */
  /** Notifies a task info update on the given task from Shell Transitions framework. */
  fun onTaskChanging(taskInfo: RunningTaskInfo)

  /**
   * Notifies a task info update on the given task from [FreeformTaskListener].
   *
   * This is used to propagate task info changes since not all task changes are propagated from
   * [TransitionObserver] in [onTaskChanging]. It is recommended to use [onTaskChanging] instead of
   * this method where possible.
   */
  fun onNonTransitionTaskChanging(taskInfo: RunningTaskInfo)

  /** Notifies a task moving to the front. */
  fun onTaskMovingToFront(taskInfo: RunningTaskInfo)

Loading