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

Commit 235e6594 authored by Louis Chang's avatar Louis Chang
Browse files

Ensure listeners got notified whenever positioned a task to front

Task listeners not always get notified when a task move to front
because the event was only scheduled in Task#moveTaskToFront().
Now we are doing that while positioning tasks.

Also moved #updateTaskMovement to Task#positionChildAt() vs.
invoked in several places.

Note that the intermediate tasks-to-front changes of a certain
procedure would all be sent to listeners. For example, now the
#onTaskMovedToFront would be called twice when starting a task
from recents, because the home task was moved to front before
moving the target task to top.

Bug: 134632511
Test: atest TaskStackChangedListenerTest
Change-Id: I6dbb3d4af18ecf9949ab26ce8b1f60d1ae300852
parent 729b60c0
Loading
Loading
Loading
Loading
+14 −23
Original line number Diff line number Diff line
@@ -425,8 +425,7 @@ class Task extends WindowContainer<WindowContainer> {
    int maxRecents;

    /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
     * determining the order when restoring. Sign indicates whether last task movement was to front
     * (positive) or back (negative). Absolute value indicates time. */
     *  determining the order when restoring. */
    long mLastTimeMoved;

    /** If original intent did not allow relinquishing task identity, save that information */
@@ -952,6 +951,11 @@ class Task extends WindowContainer<WindowContainer> {
        removeImmediately();
        if (isLeafTask()) {
            mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);

            final TaskDisplayArea taskDisplayArea = getDisplayArea();
            if (taskDisplayArea != null) {
                taskDisplayArea.onLeafTaskRemoved(mTaskId);
            }
        }
    }

@@ -1525,15 +1529,14 @@ class Task extends WindowContainer<WindowContainer> {
        mStackSupervisor.updateTopResumedActivityIfNeeded();
    }

    void updateTaskMovement(boolean toFront) {
    void updateTaskMovement(boolean toTop, int position) {
        EventLogTags.writeWmTaskMoved(mTaskId, toTop ? 1 : 0, position);
        final TaskDisplayArea taskDisplayArea = getDisplayArea();
        if (taskDisplayArea != null && isLeafTask()) {
            taskDisplayArea.onLeafTaskMoved(this, toTop);
        }
        if (isPersistable) {
            mLastTimeMoved = System.currentTimeMillis();
            // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
            // recently will be most negative, tasks sent to the bottom before that will be less
            // negative. Similarly for recent tasks moved to the top which will be most positive.
            if (!toFront) {
                mLastTimeMoved *= -1;
            }
        }
        mRootWindowContainer.invalidateTaskLayers();
    }
@@ -3180,6 +3183,7 @@ class Task extends WindowContainer<WindowContainer> {

    @Override
    void positionChildAt(int position, WindowContainer child, boolean includingParents) {
        final boolean toTop = position >= (mChildren.size() - 1);
        position = getAdjustedChildPosition(child, position);
        super.positionChildAt(position, child, includingParents);

@@ -3187,10 +3191,9 @@ class Task extends WindowContainer<WindowContainer> {
        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "positionChildAt: child=" + child
                + " position=" + position + " parent=" + this);

        final int toTop = position >= (mChildren.size() - 1) ? 1 : 0;
        final Task task = child.asTask();
        if (task != null) {
            EventLogTags.writeWmTaskMoved(task.mTaskId, toTop, position);
            task.updateTaskMovement(toTop, position);
        }
    }

@@ -6896,9 +6899,6 @@ class Task extends WindowContainer<WindowContainer> {
            if (!deferResume) {
                mRootWindowContainer.resumeFocusedStacksTopActivities();
            }
            EventLogTags.writeWmTaskToFront(tr.mUserId, tr.mTaskId);
            mAtmService.getTaskChangeNotificationController()
                    .notifyTaskMovedToFront(tr.getTaskInfo());
        } finally {
            mDisplayContent.continueUpdateImeTarget();
        }
@@ -7284,7 +7284,6 @@ class Task extends WindowContainer<WindowContainer> {
            Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position);
        }
        positionChildAt(position, task, includingParents);
        task.updateTaskMovement(toTop);
        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();


@@ -7421,7 +7420,6 @@ class Task extends WindowContainer<WindowContainer> {
        }

        positionChildAt(POSITION_TOP, child, true /* includingParents */);
        child.updateTaskMovement(true);

        final DisplayContent displayContent = getDisplayContent();
        displayContent.layoutAndAssignWindowLayersIfNeeded();
@@ -7434,7 +7432,6 @@ class Task extends WindowContainer<WindowContainer> {
        final Task nextFocusableStack = getDisplayArea().getNextFocusableStack(
                child.getRootTask(), true /* ignoreCurrent */);
        positionChildAtBottom(child, nextFocusableStack == null /* includingParents */);
        child.updateTaskMovement(true);
    }

    @VisibleForTesting
@@ -7459,12 +7456,6 @@ class Task extends WindowContainer<WindowContainer> {
        }

        final boolean isTop = getTopChild() == child;

        final Task task = child.asTask();
        if (task != null) {
            task.updateTaskMovement(isTop);
        }

        if (isTop) {
            final DisplayContent displayContent = getDisplayContent();
            displayContent.layoutAndAssignWindowLayersIfNeeded();
+32 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -152,6 +153,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
     */
    private boolean mRemoved;


    /**
     * The id of a leaf task that most recently being moved to front.
     */
    private int mLastLeafTaskToFrontId;

    TaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name,
            int displayAreaFeature) {
        super(service, Type.ANY, name, displayAreaFeature);
@@ -382,7 +389,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
                    this /* child */, true /* includingParents */);
        }

        child.updateTaskMovement(moveToTop);
        child.updateTaskMovement(moveToTop, targetPosition);

        mDisplayContent.layoutAndAssignWindowLayersIfNeeded();

@@ -405,6 +412,30 @@ final class TaskDisplayArea extends DisplayArea<Task> {
        }
    }

    void onLeafTaskRemoved(int taskId) {
        if (mLastLeafTaskToFrontId == taskId) {
            mLastLeafTaskToFrontId = INVALID_TASK_ID;
        }
    }

    void onLeafTaskMoved(Task t, boolean toTop) {
        if (!toTop) {
            if (t.mTaskId == mLastLeafTaskToFrontId) {
                mLastLeafTaskToFrontId = INVALID_TASK_ID;
            }
            return;
        }
        if (t.mTaskId == mLastLeafTaskToFrontId || t.topRunningActivityLocked() == null) {
            return;
        }

        mLastLeafTaskToFrontId = t.mTaskId;
        EventLogTags.writeWmTaskToFront(t.mUserId, t.mTaskId);
        // Notifying only when a leak task moved to front. Or the listeners would be notified
        // couple times from the leaf task all the way up to the root task.
        mAtmService.getTaskChangeNotificationController().notifyTaskMovedToFront(t.getTaskInfo());
    }

    @Override
    boolean forAllTaskDisplayAreas(Function<TaskDisplayArea, Boolean> callback,
            boolean traverseTopToBottom) {
+3 −9
Original line number Diff line number Diff line
@@ -219,19 +219,13 @@ public class TaskStackChangedListenerTest {
        activity.setDetachedFromWindowLatch(onDetachedFromWindowLatch);
        final int id = activity.getTaskId();

        // Test for onTaskCreated.
        waitForCallback(taskCreatedLaunchLatch);
        // Test for onTaskCreated and onTaskMovedToFront
        waitForCallback(taskMovedToFrontLatch);
        assertEquals(0, taskCreatedLaunchLatch.getCount());
        assertEquals(id, params[0]);
        ComponentName componentName = (ComponentName) params[1];
        assertEquals(ActivityTaskChangeCallbacks.class.getName(), componentName.getClassName());

        // Test for onTaskMovedToFront.
        assertEquals(1, taskMovedToFrontLatch.getCount());
        mService.moveTaskToFront(null, getInstrumentation().getContext().getPackageName(), id, 0,
                null);
        waitForCallback(taskMovedToFrontLatch);
        assertEquals(activity.getTaskId(), params[0]);

        // Test for onTaskRemovalStarted.
        assertEquals(1, taskRemovalStartedLatch.getCount());
        assertEquals(1, taskRemovedLatch.getCount());