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

Commit 4f7ebe3b authored by Yunfan Chen's avatar Yunfan Chen
Browse files

Make caption a insets source

This patch introduced setCaptionInsets, and set the Insets in
ViewRootImpl when dispatch the insets if there's a caption.

Modification is made in Window and DecorCaptionView to make caption
overlay with the app content, and pass the value to ViewRootImpl to
apply when dispatch. It is necessary to trigger a dispatch when caption
enabled status chanaged, otherwise sometimes it will not be updated.
Because caption is now updated locally on the client side.

Some old logic to deal with the overlay caption without insets are
removed, including the touch event dispatch override, the color
override.

Bug: 134531136
Test: go/wm-smoke
Test: Manually change the value in dispatchApplyInsets, can observe a
      blank content area when there's a caption bar.
Test: atest InsetsStateTest
Test: atest InsetsControllerTest
Change-Id: I356344a13c8569512d8f51f7ea19a5603f778252
parent 34d23e82
Loading
Loading
Loading
Loading
+28 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.toInternalType;
import static android.view.InsetsState.toPublicType;
@@ -367,6 +368,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    private int mLastLegacySystemUiFlags;
    private DisplayCutout mLastDisplayCutout;
    private boolean mStartingAnimation;
    private int mCaptionInsetsHeight = 0;

    private SyncRtSurfaceTransactionApplier mApplier;

@@ -460,7 +462,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

    @VisibleForTesting
    public boolean onStateChanged(InsetsState state) {
        boolean localStateChanged = !mState.equals(state);
        boolean localStateChanged = !mState.equals(state, true /* excludingCaptionInsets */)
                || !captionInsetsUnchanged();
        if (!localStateChanged && mLastDispachedState.equals(state)) {
            return false;
        }
@@ -470,7 +473,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (localStateChanged) {
            mViewRoot.notifyInsetsChanged();
        }
        if (!mState.equals(mLastDispachedState)) {
        if (!mState.equals(mLastDispachedState, true /* excludingCaptionInsets */)) {
            sendStateToWindowManager();
        }
        return true;
@@ -488,6 +491,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                mState.removeSource(source.getType());
            }
        }
        if (mCaptionInsetsHeight != 0) {
            mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(mFrame.left, mFrame.top,
                    mFrame.right, mFrame.top + mCaptionInsetsHeight));
        }
    }

    private boolean captionInsetsUnchanged() {
        if (mState.peekSource(ITYPE_CAPTION_BAR) == null
                && mCaptionInsetsHeight == 0) {
            return true;
        }
        if (mState.peekSource(ITYPE_CAPTION_BAR) != null
                && mCaptionInsetsHeight
                == mState.peekSource(ITYPE_CAPTION_BAR).getFrame().height()) {
            return true;
        }
        return false;
    }

    /**
@@ -964,6 +984,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        InsetsState tmpState = new InsetsState();
        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
            final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
            if (consumer.getType() == ITYPE_CAPTION_BAR) continue;
            if (consumer.getControl() != null) {
                tmpState.addSource(mState.getSource(consumer.getType()));
            }
@@ -1104,6 +1125,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        return mViewRoot.mWindowAttributes.insetsFlags.appearance;
    }

    @Override
    public void setCaptionInsetsHeight(int height) {
        mCaptionInsetsHeight = height;
    }

    @Override
    public void setSystemBarsBehavior(@Behavior int behavior) {
        mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;

import android.annotation.NonNull;
@@ -118,6 +119,12 @@ public class InsetsSource implements Parcelable {
        if (!getIntersection(frame, relativeFrame, mTmpFrame)) {
            return Insets.NONE;
        }
        // During drag-move and drag-resizing, the caption insets position may not get updated
        // before the app frame get updated. To layout the app content correctly during drag events,
        // we always return the insets with the corresponding height covering the top.
        if (getType() == ITYPE_CAPTION_BAR) {
            return Insets.of(0, frame.height(), 0, 0);
        }

        // TODO: Currently, non-floating IME always intersects at bottom due to issues with cutout.
        // However, we should let the policy decide from the server.
+29 −1
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -498,6 +500,19 @@ public class InsetsState implements Parcelable {

    @Override
    public boolean equals(Object o) {
        return equals(o, false);
    }

    /**
     * An equals method can exclude the caption insets. This is useful because we assemble the
     * caption insets information on the client side, and when we communicate with server, it's
     * excluded.
     * @param excludingCaptionInsets {@code true} if we want to compare two InsetsState objects but
     *                                           ignore the caption insets source value.
     * @return {@code true} if the two InsetsState objects are equal, {@code false} otherwise.
     */
    @VisibleForTesting
    public boolean equals(Object o, boolean excludingCaptionInsets) {
        if (this == o) { return true; }
        if (o == null || getClass() != o.getClass()) { return false; }

@@ -506,11 +521,24 @@ public class InsetsState implements Parcelable {
        if (!mDisplayFrame.equals(state.mDisplayFrame)) {
            return false;
        }
        if (mSources.size() != state.mSources.size()) {
        int size = mSources.size();
        int otherSize = state.mSources.size();
        if (excludingCaptionInsets) {
            if (mSources.get(ITYPE_CAPTION_BAR) != null) {
                size--;
            }
            if (state.mSources.get(ITYPE_CAPTION_BAR) != null) {
                otherSize--;
            }
        }
        if (size != otherSize) {
            return false;
        }
        for (int i = mSources.size() - 1; i >= 0; i--) {
            InsetsSource source = mSources.valueAt(i);
            if (excludingCaptionInsets) {
                if (source.getType() == ITYPE_CAPTION_BAR) continue;
            }
            InsetsSource otherSource = state.mSources.get(source.getType());
            if (otherSource == null) {
                return false;
+9 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ public class PendingInsetsController implements WindowInsetsController {
    private InsetsController mReplayedInsetsController;
    private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
            = new ArrayList<>();
    private int mCaptionInsetsHeight = 0;

    @Override
    public void show(int types) {
@@ -79,6 +80,11 @@ public class PendingInsetsController implements WindowInsetsController {
        return mAppearance;
    }

    @Override
    public void setCaptionInsetsHeight(int height) {
        mCaptionInsetsHeight = height;
    }

    @Override
    public void setSystemBarsBehavior(int behavior) {
        if (mReplayedInsetsController != null) {
@@ -134,6 +140,9 @@ public class PendingInsetsController implements WindowInsetsController {
        if (mAppearanceMask != 0) {
            controller.setSystemBarsAppearance(mAppearance, mAppearanceMask);
        }
        if (mCaptionInsetsHeight != 0) {
            controller.setCaptionInsetsHeight(mCaptionInsetsHeight);
        }
        int size = mRequests.size();
        for (int i = 0; i < size; i++) {
            mRequests.get(i).replay(controller);
+5 −0
Original line number Diff line number Diff line
@@ -28768,6 +28768,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                publicAlternatives = "Use {@link WindowInsets#getInsets(int)}")
        final Rect mStableInsets = new Rect();
        /**
         * Current caption insets to the display coordinate.
         */
        final Rect mCaptionInsets = new Rect();
        final DisplayCutout.ParcelableWrapper mDisplayCutout =
                new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT);
Loading