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

Commit 4ffcb718 authored by Riddle Hsu's avatar Riddle Hsu Committed by Chris Li
Browse files

Put starting surface in task for embedded activity

So the layer and position won't be disturbed by the parent activity.
It also isolates the container effect such as the window won't be
affected if the task fragment has crop.

Bug: 201261613
Bug: 189385912
Test: atest ActivityRecordTests#testStartingWindowInTaskFragment
Change-Id: Ifa866d26d31c655662f13aa5978078aa511ad116
parent 6825cd59
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -1482,7 +1482,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                // The starting window should keep covering its task when the activity is
                // reparented to a task fragment that may not fill the task bounds.
                associateStartingDataWithTask();
                overrideConfigurationPropagation(mStartingWindow, task);
                attachStartingSurfaceToAssociatedTask();
            }
            mImeInsetsFrozenUntilStartInput = false;
        }
@@ -2383,11 +2383,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    void attachStartingWindow(@NonNull WindowState startingWindow) {
        startingWindow.mStartingData = mStartingData;
        mStartingWindow = startingWindow;
        if (mStartingData != null && mStartingData.mAssociatedTask != null) {
            // Associate the configuration of starting window with the task.
            overrideConfigurationPropagation(startingWindow, mStartingData.mAssociatedTask);
            attachStartingSurfaceToAssociatedTask();
        }
    }

    private void attachStartingSurfaceToAssociatedTask() {
        // Associate the configuration of starting window with the task.
        overrideConfigurationPropagation(mStartingWindow, mStartingData.mAssociatedTask);
        getSyncTransaction().reparent(mStartingWindow.mSurfaceControl,
                mStartingData.mAssociatedTask.mSurfaceControl);
    }

    private void associateStartingDataWithTask() {
+5 −7
Original line number Diff line number Diff line
@@ -1770,17 +1770,15 @@ public class WindowManagerService extends IWindowManager.Stub
            final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
            win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);

            if (type == TYPE_APPLICATION_STARTING && activity != null) {
                activity.attachStartingWindow(win);
                ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
                        activity, win);
            }

            boolean imMayMove = true;

            win.mToken.addWindow(win);
            displayPolicy.addWindowLw(win, attrs);
            if (type == TYPE_INPUT_METHOD) {
            if (type == TYPE_APPLICATION_STARTING && activity != null) {
                activity.attachStartingWindow(win);
                ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
                        activity, win);
            } else if (type == TYPE_INPUT_METHOD) {
                displayContent.setInputMethodWindowLocked(win);
                imMayMove = false;
            } else if (type == TYPE_INPUT_METHOD_DIALOG) {
+32 −1
Original line number Diff line number Diff line
@@ -308,6 +308,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    @NonNull WindowToken mToken;
    // The same object as mToken if this is an app window and null for non-app windows.
    ActivityRecord mActivityRecord;
    /** Non-null if this is a starting window. */
    StartingData mStartingData;

    // mAttrs.flags is tested in animation without being locked. If the bits tested are ever
    // modified they will need to be locked.
@@ -5485,6 +5487,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return mWillReplaceWindow;
    }

    private boolean isStartingWindowAssociatedToTask() {
        return mStartingData != null && mStartingData.mAssociatedTask != null;
    }

    private void applyDims() {
        if (!mAnimatingExit && mAppDied) {
            mIsDimming = true;
@@ -5634,7 +5640,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            outPoint.offset(-parent.mWindowFrames.mFrame.left + mTmpPoint.x,
                    -parent.mWindowFrames.mFrame.top + mTmpPoint.y);
        } else if (parentWindowContainer != null) {
            final Rect parentBounds = parentWindowContainer.getBounds();
            final Rect parentBounds = isStartingWindowAssociatedToTask()
                    ? mStartingData.mAssociatedTask.getBounds()
                    : parentWindowContainer.getBounds();
            outPoint.offset(-parentBounds.left, -parentBounds.top);
        }

@@ -5717,6 +5725,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    @Override
    void assignLayer(Transaction t, int layer) {
        if (isStartingWindowAssociatedToTask()) {
            // The starting window should cover the task.
            t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
            return;
        }
        // See comment in assignRelativeLayerForImeTargetChild
        if (needsRelativeLayeringToIme()) {
            getDisplayContent().assignRelativeLayerForImeTargetChild(t, this);
@@ -5729,6 +5742,24 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return mIsDimming;
    }

    @Override
    protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
        if (isStartingWindowAssociatedToTask()) {
            // Its surface is already put in task. Don't reparent when transferring starting window
            // across activities.
            return;
        }
        super.reparentSurfaceControl(t, newParent);
    }

    @Override
    public SurfaceControl getAnimationLeashParent() {
        if (isStartingWindowAssociatedToTask()) {
            return mStartingData.mAssociatedTask.mSurfaceControl;
        }
        return super.getAnimationLeashParent();
    }

    // TODO(b/70040778): We should aim to eliminate the last user of TYPE_APPLICATION_MEDIA
    // then we can drop all negative layering on the windowing side and simply inherit
    // the default implementation here.
+5 −1
Original line number Diff line number Diff line
@@ -2700,8 +2700,8 @@ public class ActivityRecordTests extends WindowTestsBase {
        final WindowState startingWindow = createWindowState(
                new WindowManager.LayoutParams(TYPE_APPLICATION_STARTING), activity1);
        activity1.addWindow(startingWindow);
        activity1.attachStartingWindow(startingWindow);
        activity1.mStartingData = mock(StartingData.class);
        activity1.attachStartingWindow(startingWindow);
        final Task task = activity1.getTask();
        final Rect taskBounds = task.getBounds();
        final int width = taskBounds.width();
@@ -2729,6 +2729,10 @@ public class ActivityRecordTests extends WindowTestsBase {
        assertTrue(activity2.isResizeable());
        activity1.reparent(taskFragment1, POSITION_TOP);

        verify(activity1.getSyncTransaction()).reparent(eq(startingWindow.mSurfaceControl),
                eq(task.mSurfaceControl));
        assertEquals(activity1.mStartingData, startingWindow.mStartingData);
        assertEquals(task.mSurfaceControl, startingWindow.getAnimationLeashParent());
        assertEquals(task, activity1.mStartingData.mAssociatedTask);
        assertEquals(taskFragment1.getBounds(), activity1.getBounds());
        // The activity was resized by task fragment, but starting window must still cover the task.