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

Commit c85f1ba3 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Pause surface position for bounds change transaction

Currently the entering pip bounds is applied at the end of enter
animation. There could be 2 flickering cases:
1. There is an offset from display cutout while the activity is
   fullscreen. The offset should be gone once the task no longer
   overlap with display cutout. But the position change applies
   before the app redraws. Which looks like shift left and then
   right in a short time.
2. Before the window frame is recomputed, the surface position is
   updated with pip bounds, e.g. (0,0)-(200,1000)=(-200,-1000).

So this change updates the window surface position until the app
has reported its draw transaction, and then applies them at once.

Replaced mResizedWhileGone because it was never read for a long time.

Bug: 331315278
Test: Assume the target app support auto-pip and it doesn't draw
      under display cutout.
      E.g. LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
      Enter PiP from 90 degrees to home with 0 degrees.
      The pip content won't shift horizontally a few frames.
Change-Id: I1cd79ccb05ac61edf37dffbbec8cfe37cb85b1f3
parent df5244aa
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4559,7 +4559,10 @@ class Task extends TaskFragment {
        }
        final WindowState w = getTopVisibleAppMainWindow();
        if (w != null) {
            w.mIsSurfacePositionPaused = true;
            w.applyWithNextDraw((d) -> {
                w.mIsSurfacePositionPaused = false;
                w.updateSurfacePosition(d);
                d.merge(t);
            });
        } else {
+0 −3
Original line number Diff line number Diff line
@@ -2645,9 +2645,6 @@ public class WindowManagerService extends IWindowManager.Stub
            if (displayPolicy.areSystemBarsForcedConsumedLw()) {
                result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
            }
            if (!win.isGoneForLayout()) {
                win.mResizedWhileGone = false;
            }

            if (outFrames != null && outMergedConfiguration != null) {
                final boolean shouldReportActivityWindowInfo;
+6 −5
Original line number Diff line number Diff line
@@ -839,9 +839,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
    }

    private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) {
        int effects = applyChanges(tr, c);
        final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();
        // Check bounds change transaction at the beginning because it may pause updating window
        // surface position. Then the following changes won't apply intermediate position.
        if (t != null) {
            tr.setMainWindowSizeChangeTransaction(t);
        }

        int effects = applyChanges(tr, c);
        if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {
            if (tr.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, c.getHidden())) {
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
@@ -874,10 +879,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
            tr.forAllActivities(a -> { a.setWindowingMode(childWindowingMode); });
        }

        if (t != null) {
            tr.setMainWindowSizeChangeTransaction(t);
        }

        Rect enterPipBounds = c.getEnterPipBounds();
        if (enterPipBounds != null) {
            tr.mDisplayContent.mPinnedTaskController.setEnterPipBounds(enterPipBounds);
+7 −6
Original line number Diff line number Diff line
@@ -668,9 +668,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    private final Transaction mTmpTransaction;

    /**
     * Whether the window was resized by us while it was gone for layout.
     * Whether the surface position of window is paused to update. Currently it is only used for
     * {@link Task#setMainWindowSizeChangeTransaction(Transaction)} to synchronize position.
     */
    boolean mResizedWhileGone = false;
    boolean mIsSurfacePositionPaused;

    /**
     * During seamless rotation we have two phases, first the old window contents
@@ -2190,9 +2191,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            ProtoLog.d(WM_DEBUG_RESIZE, "onResize: Resizing %s", this);
            resizingWindows.add(this);
        }
        if (isGoneForLayout()) {
            mResizedWhileGone = true;
        }

        super.onResize();
    }
@@ -4163,6 +4161,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        pw.println(prefix + "mHasSurface=" + mHasSurface
                + " isReadyForDisplay()=" + isReadyForDisplay()
                + " mWindowRemovalAllowed=" + mWindowRemovalAllowed);
        if (mIsSurfacePositionPaused) {
            pw.println(prefix + "mIsSurfacePositionPaused=true");
        }
        if (mInvGlobalScale != 1f) {
            pw.println(prefix + "mCompatFrame=" + mWindowFrames.mCompatFrame.toShortString(sTmpSB));
        }
@@ -5255,7 +5256,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    @Override
    @VisibleForTesting
    void updateSurfacePosition(Transaction t) {
        if (mSurfaceControl == null) {
        if (mSurfaceControl == null || mIsSurfacePositionPaused) {
            return;
        }
        if (mActivityRecord != null && mActivityRecord.isConfigurationDispatchPaused()) {