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

Commit a65393e0 authored by Louis Chang's avatar Louis Chang
Browse files

Reland "Deferring visibility updates while applying WCT"

Also fix the regression that activity not resumed when leaving
pip.

Bug: 191891601
Bug: 194040982
Test: atest WindowOrganizerTests
Change-Id: I36a72a408f779c8f29b61e5a83ebabcac8ac33b8
parent a44fcb0d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -352,6 +352,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
     */
    private int mVisibilityTransactionDepth;

    /**
     * Whether to the visibility updates that started from {@code RootWindowContainer} should be
     * deferred.
     */
    private boolean mDeferRootVisibilityUpdate;

    private ActivityMetricsLogger mActivityMetricsLogger;

    /** Check if placing task or activity on specified display is allowed. */
@@ -2297,6 +2303,14 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        return mVisibilityTransactionDepth > 0;
    }

    void setDeferRootVisibilityUpdate(boolean deferUpdate) {
        mDeferRootVisibilityUpdate = deferUpdate;
    }

    boolean isRootVisibilityUpdateDeferred() {
        return mDeferRootVisibilityUpdate;
    }

    /**
     * Called when the state or visibility of an attached activity is changed.
     *
+2 −1
Original line number Diff line number Diff line
@@ -1998,7 +1998,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
     */
    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean notifyClients) {
        if (mTaskSupervisor.inActivityVisibilityUpdate()) {
        if (mTaskSupervisor.inActivityVisibilityUpdate()
                || mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
            // Don't do recursive work.
            return;
        }
+4 −2
Original line number Diff line number Diff line
@@ -4665,9 +4665,11 @@ class Task extends TaskFragment {
            mAtmService.continueWindowLayout();
        }

        if (!mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
            mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
            mRootWindowContainer.resumeFocusedTasksTopActivities();
        }
    }

    void resumeNextFocusAfterReparent() {
        adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
+11 −0
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        int effects = 0;
        ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
        mService.deferWindowLayout();
        mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
        try {
            if (transition != null) {
                // First check if we have a display rotation transition and if so, update it.
@@ -411,6 +412,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                task.setMainWindowSizeChangeTransaction(sft);
            }
            if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
                mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
                // Already calls ensureActivityConfig
                mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
                mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
@@ -432,6 +434,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                mService.addWindowLayoutReasons(LAYOUT_REASON_CONFIG_CHANGED);
            }
        } finally {
            mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
            mService.continueWindowLayout();
        }
    }
@@ -472,7 +475,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                throw new UnsupportedOperationException("Not supported to set multi-window"
                        + " windowing mode during locked task mode.");
            }

            final int prevMode = container.getWindowingMode();
            container.setWindowingMode(windowingMode);
            if (prevMode != container.getWindowingMode()) {
                // The activity in the container may become focusable or non-focusable due to
                // windowing modes changes (such as entering or leaving pinned windowing mode),
                // so also apply the lifecycle effects to this transaction.
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
        }
        return effects;
    }
+19 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ import android.window.ITaskOrganizer;
import android.window.IWindowContainerTransactionCallback;
import android.window.StartingWindowInfo;
import android.window.TaskAppearedInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import androidx.test.filters.SmallTest;
@@ -1275,6 +1276,24 @@ public class WindowOrganizerTests extends WindowTestsBase {
        assertTrue(optionsCaptor.getValue().getOriginalOptions().getTransientLaunch());
    }

    @Test
    public void testResumeTopsWhenLeavingPinned() {
        final ActivityRecord record = makePipableActivity();
        final Task rootTask = record.getRootTask();

        clearInvocations(mWm.mAtmService.mRootWindowContainer);
        final WindowContainerTransaction t = new WindowContainerTransaction();
        WindowContainerToken wct = rootTask.mRemoteToken.toWindowContainerToken();
        t.setWindowingMode(wct, WINDOWING_MODE_PINNED);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();

        clearInvocations(mWm.mAtmService.mRootWindowContainer);
        t.setWindowingMode(wct, WINDOWING_MODE_FULLSCREEN);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
    }

    /**
     * Verifies that task vanished is called for a specific task.
     */