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

Commit 66c1b9ad authored by Evan Rosky's avatar Evan Rosky Committed by [1;3C
Browse files

Improve support for reparent operations in app transitions

This addresses several issues that come up when reparenting
is part of an app-transition (as happens during split-screen).

1. If a windowingMode change is part of a WCTransaction, bundle
   it up with the other changes before calling a single
   onConfigurationChange. This is needed for change transitions
   because they freeze during onConfigurationChange so if the
   bounds has already changed in a prior onConfigChange, it
   won't freeze the correct start-bounds.

2. Actually unset task-org if the task is reparented out of
   an organizable parent (ie. it becomes non-root). Also unset
   the last OrganizedWindowingMode properly.

3. Because tasks can go into and out-of organized mode, maintain
   consistent surface positioning through reparent operations by
   updating the position on reparent if either the before or after
   state is organized. Why? If we are going from non-organized
   to organized, the initial position should be relative to the
   parent where we started organizing -- esp. because there is
   a delay before the organizer gets the leash, so during that
   time the surface can pop if not updated. In the other direction,
   because the task is no-longer organized, WM needs to sync its
   surface info.

Bug: 151881448
Test: tests pass -- android-on-chrome tests pass
Change-Id: I16e74ea0cc79a6c76ac08a3cbd55416e034753c0
parent 54ae0a7c
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -3655,13 +3655,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    @Override
    protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
        if (!mSurfaceAnimator.hasLeash()) {
            t.reparent(mSurfaceControl, newParent);
        }
    }

    void logStartActivity(int tag, Task task) {
        final Uri data = intent.getData();
        final String strData = data != null ? data.toSafeString() : null;
+21 −4
Original line number Diff line number Diff line
@@ -2384,6 +2384,15 @@ class Task extends WindowContainer<WindowContainer> {

        saveLaunchingStateIfNeeded();
        final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */);
        if (taskOrgChanged) {
            updateSurfacePosition(getSyncTransaction());
            if (!isOrganized()) {
                // Surface-size update was skipped before (since internally it no-ops if
                // isOrganized() is true); however, now that this is not organized, the surface
                // size needs to be updated by WM.
                updateSurfaceSize(getSyncTransaction());
            }
        }
        // If the task organizer has changed, then it will already be receiving taskAppeared with
        // the latest task-info thus the task-info won't have changed.
        if (!taskOrgChanged && isOrganized()) {
@@ -3367,7 +3376,7 @@ class Task extends WindowContainer<WindowContainer> {

        final int boundsChange = super.setBounds(bounds);
        mRotation = rotation;
        updateSurfacePosition();
        updateSurfacePositionNonOrganized();
        return boundsChange;
    }

@@ -3742,6 +3751,12 @@ class Task extends WindowContainer<WindowContainer> {
        return getAppAnimationLayer(ANIMATION_LAYER_HOME);
    }

    @Override
    void resetSurfacePositionForAnimationLeash(SurfaceControl.Transaction t) {
        if (isOrganized()) return;
        super.resetSurfacePositionForAnimationLeash(t);
    }

    @Override
    Rect getAnimationBounds(int appStackClipMode) {
        // TODO(b/131661052): we should remove appStackClipMode with hierarchical animations.
@@ -4960,7 +4975,9 @@ class Task extends WindowContainer<WindowContainer> {
     */
    boolean updateTaskOrganizerState(boolean forceUpdate) {
        if (!isRootTask()) {
            return false;
            final boolean result = setTaskOrganizer(null);
            mLastTaskOrganizerWindowingMode = -1;
            return result;
        }

        final int windowingMode = getWindowingMode();
@@ -4979,7 +4996,7 @@ class Task extends WindowContainer<WindowContainer> {
        final ITaskOrganizer org =
                mWmService.mAtmService.mTaskOrganizerController.getTaskOrganizer(windowingMode);
        final boolean result = setTaskOrganizer(org);
        mLastTaskOrganizerWindowingMode = windowingMode;
        mLastTaskOrganizerWindowingMode = org != null ? windowingMode : -1;
        return result;
    }

@@ -7622,7 +7639,7 @@ class Task extends WindowContainer<WindowContainer> {

    private void updateSurfaceBounds() {
        updateSurfaceSize(getSyncTransaction());
        updateSurfacePosition();
        updateSurfacePositionNonOrganized();
        scheduleAnimation();
    }

+14 −14
Original line number Diff line number Diff line
@@ -320,7 +320,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
    @Override
    public void onConfigurationChanged(Configuration newParentConfig) {
        super.onConfigurationChanged(newParentConfig);
        updateSurfacePosition();
        updateSurfacePositionNonOrganized();
        scheduleAnimation();
    }

@@ -418,7 +418,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());
        getSyncTransaction().show(mSurfaceControl);
        onSurfaceShown(getSyncTransaction());
        updateSurfacePosition();
        updateSurfacePositionNonOrganized();
    }

    /**
@@ -2022,7 +2022,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
    }

    protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
        mSurfaceAnimator.reparent(t, newParent);
        // Don't reparent active leashes since the animator won't know about the change.
        if (mSurfaceFreezer.hasLeash() || mSurfaceAnimator.hasLeash()) return;
        t.reparent(getSurfaceControl(), newParent);
    }

    void assignChildLayers(Transaction t) {
@@ -2703,14 +2705,19 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        }
    }

    final void updateSurfacePosition() {
    final void updateSurfacePositionNonOrganized() {
        // Avoid fighting with the organizer over Surface position.
        if (isOrganized()) return;
        updateSurfacePosition(getSyncTransaction());
    }

    /**
     * Only for use internally (see PROTECTED annotation). This should only be used over
     * {@link #updateSurfacePositionNonOrganized} when the surface position needs to be
     * updated even if organized (eg. while changing to organized).
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
    void updateSurfacePosition(Transaction t) {
        // Avoid fighting with the organizer over Surface position.
        if (isOrganized()) return;

        if (mSurfaceControl == null || mSurfaceAnimator.hasLeash()) {
            return;
        }
@@ -2750,13 +2757,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
    }

    void getRelativePosition(Point outPos) {
        // In addition to updateSurfacePosition, we keep other code that sets
        // position from fighting with the organizer
        if (isOrganized()) {
            outPos.set(0, 0);
            return;
        }

        final Rect dispBounds = getBounds();
        outPos.set(dispBounds.left, dispBounds.top);
        final WindowContainer parent = getParent();
+19 −7
Original line number Diff line number Diff line
@@ -241,13 +241,26 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        final int configMask = change.getConfigSetMask() & CONTROLLABLE_CONFIGS;
        final int windowMask = change.getWindowSetMask() & CONTROLLABLE_WINDOW_CONFIGS;
        int effects = 0;
        final int windowingMode = change.getWindowingMode();
        if (configMask != 0) {
            Configuration c = new Configuration(container.getRequestedOverrideConfiguration());
            if (windowingMode > -1 && windowingMode != container.getWindowingMode()) {
                // Special handling for when we are setting a windowingMode in the same transaction.
                // Setting the windowingMode is going to call onConfigurationChanged so we don't
                // need it called right now. Additionally, some logic requires everything in the
                // configuration to change at the same time (ie. surface-freezer requires bounds
                // and mode to change at the same time).
                final Configuration c = container.getRequestedOverrideConfiguration();
                c.setTo(change.getConfiguration(), configMask, windowMask);
            } else {
                final Configuration c =
                        new Configuration(container.getRequestedOverrideConfiguration());
                c.setTo(change.getConfiguration(), configMask, windowMask);
                container.onRequestedOverrideConfigurationChanged(c);
                // TODO(b/145675353): remove the following once we could apply new bounds to the
                // pinned stack together with its children.
            resizePinnedStackIfNeeded(container, configMask, windowMask, c);
            }
            resizePinnedStackIfNeeded(container, configMask, windowMask,
                    container.getRequestedOverrideConfiguration());
            effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
        }
        if ((change.getChangeMask() & WindowContainerTransaction.Change.CHANGE_FOCUSABLE) != 0) {
@@ -256,7 +269,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
            }
        }

        final int windowingMode = change.getWindowingMode();
        if (windowingMode > -1) {
            container.setWindowingMode(windowingMode);
        }
+1 −1
Original line number Diff line number Diff line
@@ -5397,7 +5397,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    void prepareSurfaces() {
        mIsDimming = false;
        applyDims();
        updateSurfacePosition();
        updateSurfacePositionNonOrganized();
        // Send information to SufaceFlinger about the priority of the current window.
        updateFrameRateSelectionPriorityIfNeeded();