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

Commit ecee059e authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Do not use stale relayout window infos" into main

parents 7c3c1a32 5bc12208
Loading
Loading
Loading
Loading
+70 −21
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
import static android.os.Trace.TRACE_TAG_VIEW;
import static android.util.SequenceUtils.getInitSeq;
import static android.util.SequenceUtils.isIncomingSeqNewer;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.DragEvent.ACTION_DRAG_LOCATION;
@@ -128,6 +130,7 @@ import static com.android.text.flags.Flags.disableHandwritingInitiatorForIme;
import static com.android.window.flags.Flags.activityWindowInfoFlag;
import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay;
import static com.android.window.flags.Flags.insetsControlChangedItem;
import static com.android.window.flags.Flags.insetsControlSeq;
import static com.android.window.flags.Flags.setScPropertiesInClient;
import android.Manifest;
@@ -892,6 +895,12 @@ public final class ViewRootImpl implements ViewParent,
    /** Non-{@code null} if {@link #mActivityConfigCallback} is not {@code null}. */
    @Nullable
    private ActivityWindowInfo mLastReportedActivityWindowInfo;
    @Nullable
    private final ClientWindowFrames mLastReportedFrames = insetsControlSeq()
            ? new ClientWindowFrames()
            : null;
    private int mLastReportedInsetsStateSeq = getInitSeq();
    private int mLastReportedActiveControlsSeq = getInitSeq();
    boolean mScrollMayChange;
    @SoftInputModeFlags
@@ -1596,8 +1605,6 @@ public final class ViewRootImpl implements ViewParent,
                        attachedFrame = null;
                    }
                    if (mTranslator != null) {
                        mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
                        mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls.get());
                        mTranslator.translateRectInScreenToAppWindow(attachedFrame);
                    }
                    mTmpFrames.attachedFrame = attachedFrame;
@@ -1620,8 +1627,7 @@ public final class ViewRootImpl implements ViewParent,
                mAttachInfo.mAlwaysConsumeSystemBars =
                        (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0;
                mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars;
                mInsetsController.onStateChanged(mTempInsets);
                mInsetsController.onControlsChanged(mTempControls.get());
                handleInsetsControlChanged(mTempInsets, mTempControls);
                final InsetsState state = mInsetsController.getState();
                final Rect displayCutoutSafe = mTempRect;
                state.getDisplayCutoutSafe(displayCutoutSafe);
@@ -2219,17 +2225,18 @@ public final class ViewRootImpl implements ViewParent,
            return;
        }
        onClientWindowFramesChanged(frames);
        CompatibilityInfo.applyOverrideScaleIfNeeded(mergedConfiguration);
        final Rect frame = frames.frame;
        final Rect displayFrame = frames.displayFrame;
        final Rect attachedFrame = frames.attachedFrame;
        if (mTranslator != null) {
            mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
            mTranslator.translateRectInScreenToAppWindow(frame);
            mTranslator.translateRectInScreenToAppWindow(displayFrame);
            mTranslator.translateRectInScreenToAppWindow(attachedFrame);
        }
        mInsetsController.onStateChanged(insetsState);
        onInsetsStateChanged(insetsState);
        final float compatScale = frames.compatScale;
        final boolean frameChanged = !mWinFrame.equals(frame);
        final boolean shouldReportActivityWindowInfoChanged =
@@ -2294,28 +2301,71 @@ public final class ViewRootImpl implements ViewParent,
    }
    /** Handles messages {@link #MSG_INSETS_CONTROL_CHANGED}. */
    private void handleInsetsControlChanged(@NonNull InsetsState insetsState,
    @VisibleForTesting
    public void handleInsetsControlChanged(@NonNull InsetsState insetsState,
            @NonNull InsetsSourceControl.Array activeControls) {
        final InsetsSourceControl[] controls = activeControls.get();
        if (mTranslator != null) {
            mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
            mTranslator.translateSourceControlsInScreenToAppWindow(controls);
        }
        // Deliver state change before control change, such that:
        // a) When gaining control, controller can compare with server state to evaluate
        // whether it needs to run animation.
        // b) When loosing control, controller can restore server state by taking last
        // dispatched state as truth.
        onInsetsStateChanged(insetsState);
        onActiveControlsChanged(activeControls);
    }
    private void onClientWindowFramesChanged(@NonNull ClientWindowFrames inOutFrames) {
        if (mLastReportedFrames == null) {
            return;
        }
        if (isIncomingSeqNewer(mLastReportedFrames.seq, inOutFrames.seq)) {
            // Keep track of the latest.
            mLastReportedFrames.setTo(inOutFrames);
        } else {
            // If the last reported frames is newer, use the last reported instead.
            inOutFrames.setTo(mLastReportedFrames);
        }
    }
    private void onInsetsStateChanged(@NonNull InsetsState insetsState) {
        if (insetsControlSeq()) {
            if (isIncomingSeqNewer(mLastReportedInsetsStateSeq, insetsState.getSeq())) {
                mLastReportedInsetsStateSeq = insetsState.getSeq();
            } else {
                // The last reported InsetsState is newer. Skip.
                return;
            }
        }
        if (mTranslator != null) {
            mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
        }
        mInsetsController.onStateChanged(insetsState);
        if (mAdded) {
            mInsetsController.onControlsChanged(controls);
    }
    private void onActiveControlsChanged(@NonNull InsetsSourceControl.Array activeControls) {
        if (!mAdded) {
            // Do not update the last report if window is not added yet.
            activeControls.release();
            return;
        }
        if (insetsControlSeq()) {
            if (isIncomingSeqNewer(mLastReportedActiveControlsSeq, activeControls.getSeq())) {
                mLastReportedActiveControlsSeq = activeControls.getSeq();
            } else {
                // The last reported controls is newer. Skip.
                activeControls.release();
                return;
            }
        }
        final InsetsSourceControl[] controls = activeControls.get();
        if (mTranslator != null) {
            mTranslator.translateSourceControlsInScreenToAppWindow(controls);
        }
        mInsetsController.onControlsChanged(controls);
    }
    private final DisplayListener mDisplayListener = new DisplayListener() {
        @Override
        public void onDisplayChanged(int displayId) {
@@ -9268,6 +9318,8 @@ public final class ViewRootImpl implements ViewParent,
                    mRelayoutSeq, mLastSyncSeqId, mRelayoutResult);
            mRelayoutRequested = true;
            onClientWindowFramesChanged(mTmpFrames);
            if (activityWindowInfoFlag() && mPendingActivityWindowInfo != null) {
                final ActivityWindowInfo outInfo = mRelayoutResult.activityWindowInfo;
                if (outInfo != null) {
@@ -9284,13 +9336,10 @@ public final class ViewRootImpl implements ViewParent,
                mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
                mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
                mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
                mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
                mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls.get());
            }
            mInvCompatScale = 1f / mTmpFrames.compatScale;
            CompatibilityInfo.applyOverrideScaleIfNeeded(mPendingMergedConfiguration);
            mInsetsController.onStateChanged(mTempInsets);
            mInsetsController.onControlsChanged(mTempControls.get());
            handleInsetsControlChanged(mTempInsets, mTempControls);
            mPendingAlwaysConsumeSystemBars =
                    (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
+41 −7
Original line number Diff line number Diff line
@@ -16,13 +16,6 @@

package android.view;

import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
import static android.view.flags.Flags.FLAG_ADD_SCHANDLE_TO_VRI_SURFACE;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
@@ -44,6 +37,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
import static android.view.flags.Flags.FLAG_ADD_SCHANDLE_TO_VRI_SURFACE;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
@@ -53,6 +53,7 @@ import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -63,9 +64,11 @@ import android.app.Instrumentation;
import android.app.UiModeManager;
import android.content.Context;
import android.graphics.ForceDarkType;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Binder;
import android.os.SystemProperties;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -1540,6 +1543,37 @@ public class ViewRootImplTest {
                nativeCreateASurfaceControlFromSurface(mViewRootImpl.mSurface));
    }

    @EnableFlags(Flags.FLAG_INSETS_CONTROL_SEQ)
    @Test
    public void testHandleInsetsControlChanged() {
        mView = new View(sContext);
        attachViewToWindow(mView);

        mViewRootImpl = mView.getViewRootImpl();
        final InsetsController controller = mViewRootImpl.getInsetsController();

        final InsetsState state0 = new InsetsState();
        final InsetsState state1 = new InsetsState();
        state0.setDisplayFrame(new Rect(0, 0, 500, 1000));
        state0.setSeq(10000);
        state1.setDisplayFrame(new Rect(0, 0, 1500, 2000));
        state1.setSeq(10001);
        final InsetsSourceControl.Array array = new InsetsSourceControl.Array();

        sInstrumentation.runOnMainSync(() -> {
            mViewRootImpl.handleInsetsControlChanged(state0, array);
            assertEquals(state0, controller.getLastDispatchedState());

            mViewRootImpl.handleInsetsControlChanged(state1, array);
            assertEquals(state1, controller.getLastDispatchedState());

            // Skip the stale value.
            mViewRootImpl.handleInsetsControlChanged(state0, array);
            assertEquals(state1, controller.getLastDispatchedState());
            assertNotEquals(state0, controller.getLastDispatchedState());
        });
    }

    private boolean setForceDarkSysProp(boolean isForceDarkEnabled) {
        try {
            SystemProperties.set(
+1 −1
Original line number Diff line number Diff line
@@ -3695,7 +3695,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    void fillInsetsSourceControls(@NonNull InsetsSourceControl.Array outArray,
            boolean copyControls) {
        final int lastSeq = mLastReportedInsetsState.getSeq();
        final int lastSeq = mLastReportedActiveControls.getSeq();
        final InsetsSourceControl[] controls =
                getDisplayContent().getInsetsStateController().getControlsForDispatch(this);
        outArray.set(controls, copyControls);