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

Commit 4e04eb24 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Move visible insets calculation to client

As otherwise they may be out of sync, leading to shifting when the
IME disappears.

Bug: 111084606
Test: InsetsSourceTest, InsetsStateTest, InsetsSourceProviderTest
Change-Id: Ifd7dfa6694efccf8693fd46bec1a9dea879790ff
parent 2134fc50
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimationCallback.AnimationBounds;
import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

@@ -298,6 +299,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        return mLastInsets;
    }

    /**
     * @see InsetsState#calculateVisibleInsets(Rect, Rect, int)
     */
    public Rect calculateVisibleInsets(Rect legacyVisibleInsets,
            @SoftInputModeFlags int softInputMode) {
        return mState.calculateVisibleInsets(mFrame, legacyVisibleInsets, softInputMode);
    }

    /**
     * Called when the server has dispatched us a new set of inset controls.
     */
+30 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Parcel;
@@ -23,6 +24,7 @@ import android.os.Parcelable;
import android.view.InsetsState.InternalInsetsType;

import java.io.PrintWriter;
import java.util.Objects;

/**
 * Represents the state of a single window generating insets for clients.
@@ -34,6 +36,7 @@ public class InsetsSource implements Parcelable {

    /** Frame of the source in screen coordinate space */
    private final Rect mFrame;
    private @Nullable Rect mVisibleFrame;
    private boolean mVisible;

    private final Rect mTmpFrame = new Rect();
@@ -54,6 +57,10 @@ public class InsetsSource implements Parcelable {
        mFrame.set(frame);
    }

    public void setVisibleFrame(@Nullable Rect visibleFrame) {
        mVisibleFrame = visibleFrame != null ? new Rect(visibleFrame) : visibleFrame;
    }

    public void setVisible(boolean visible) {
        mVisible = visible;
    }
@@ -66,6 +73,10 @@ public class InsetsSource implements Parcelable {
        return mFrame;
    }

    public @Nullable Rect getVisibleFrame() {
        return mVisibleFrame;
    }

    public boolean isVisible() {
        return mVisible;
    }
@@ -79,10 +90,22 @@ public class InsetsSource implements Parcelable {
     *         source.
     */
    public Insets calculateInsets(Rect relativeFrame, boolean ignoreVisibility) {
        return calculateInsets(relativeFrame, mFrame, ignoreVisibility);
    }

    /**
     * Like {@link #calculateInsets(Rect, boolean)}, but will return visible insets.
     */
    public Insets calculateVisibleInsets(Rect relativeFrame) {
        return calculateInsets(relativeFrame, mVisibleFrame != null ? mVisibleFrame : mFrame,
                false /* ignoreVisibility */);
    }

    private Insets calculateInsets(Rect relativeFrame, Rect frame, boolean ignoreVisibility) {
        if (!ignoreVisibility && !mVisible) {
            return Insets.NONE;
        }
        if (!mTmpFrame.setIntersect(mFrame, relativeFrame)) {
        if (!mTmpFrame.setIntersect(frame, relativeFrame)) {
            return Insets.NONE;
        }

@@ -110,6 +133,9 @@ public class InsetsSource implements Parcelable {
        pw.print(prefix);
        pw.print("InsetsSource type="); pw.print(InsetsState.typeToString(mType));
        pw.print(" frame="); pw.print(mFrame.toShortString());
        if (mVisibleFrame != null) {
            pw.print(" visibleFrmae="); pw.print(mVisibleFrame.toShortString());
        }
        pw.print(" visible="); pw.print(mVisible);
        pw.println();
    }
@@ -123,6 +149,7 @@ public class InsetsSource implements Parcelable {

        if (mType != that.mType) return false;
        if (mVisible != that.mVisible) return false;
        if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
        return mFrame.equals(that.mFrame);
    }

@@ -137,6 +164,7 @@ public class InsetsSource implements Parcelable {
    public InsetsSource(Parcel in) {
        mType = in.readInt();
        mFrame = in.readParcelable(null /* loader */);
        mVisibleFrame = in.readParcelable(null /* loader */);
        mVisible = in.readBoolean();
    }

@@ -149,6 +177,7 @@ public class InsetsSource implements Parcelable {
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mType);
        dest.writeParcelable(mFrame, 0 /* flags*/);
        dest.writeParcelable(mVisibleFrame, 0 /* flags */);
        dest.writeBoolean(mVisible);
    }

+29 −0
Original line number Diff line number Diff line
@@ -19,12 +19,14 @@ package android.view;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.ViewRootImpl.sNewInsetsMode;
import static android.view.WindowInsets.Type.IME;
import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.SIZE;
import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.indexOf;
import static android.view.WindowInsets.Type.isVisibleInsetsType;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -41,6 +43,7 @@ import android.util.SparseIntArray;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -186,6 +189,32 @@ public class InsetsState implements Parcelable {
                        : systemBars());
    }

    public Rect calculateVisibleInsets(Rect frame, Rect legacyVisibleInsets,
            @SoftInputModeFlags int softInputMode) {
        if (sNewInsetsMode == NEW_INSETS_MODE_NONE) {
            return legacyVisibleInsets;
        }

        Insets insets = Insets.NONE;
        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
            InsetsSource source = mSources.get(type);
            if (source == null) {
                continue;
            }
            if (sNewInsetsMode != NEW_INSETS_MODE_FULL && type != ITYPE_IME) {
                continue;
            }

            // Ignore everything that's not a system bar or IME.
            int publicType = InsetsState.toPublicType(type);
            if (!isVisibleInsetsType(publicType, softInputMode)) {
                continue;
            }
            insets = Insets.max(source.calculateVisibleInsets(frame), insets);
        }
        return insets.toRect();
    }

    private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
            Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray typeSideMap,
            @Nullable boolean[] typeVisibilityMap) {
+9 −2
Original line number Diff line number Diff line
@@ -2103,6 +2103,12 @@ public final class ViewRootImpl implements ViewParent,
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }

    private void updateVisibleInsets() {
        Rect visibleInsets = mInsetsController.calculateVisibleInsets(mPendingVisibleInsets,
                mWindowAttributes.softInputMode);
        mAttachInfo.mVisibleInsets.set(visibleInsets);
    }

    InsetsController getInsetsController() {
        return mInsetsController;
    }
@@ -2251,7 +2257,7 @@ public final class ViewRootImpl implements ViewParent,
                    insetsChanged = true;
                }
                if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) {
                    mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                    updateVisibleInsets();
                    if (DEBUG_LAYOUT) Log.v(mTag, "Visible insets changing to: "
                            + mAttachInfo.mVisibleInsets);
                }
@@ -2317,6 +2323,7 @@ public final class ViewRootImpl implements ViewParent,

        if (mApplyInsetsRequested) {
            mApplyInsetsRequested = false;
            updateVisibleInsets();
            dispatchApplyInsets(host);
            if (mLayoutRequested) {
                // Short-circuit catching a new layout request here, so
@@ -2501,7 +2508,7 @@ public final class ViewRootImpl implements ViewParent,
                    contentInsetsChanged = true;
                }
                if (visibleInsetsChanged) {
                    mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                    updateVisibleInsets();
                    if (DEBUG_LAYOUT) Log.v(mTag, "Visible insets changing to: "
                            + mAttachInfo.mVisibleInsets);
                }
+14 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT;
import static android.view.WindowInsets.Type.all;
import static android.view.WindowInsets.Type.indexOf;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;

import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -40,6 +42,7 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.util.SparseArray;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethod;

@@ -1289,6 +1292,17 @@ public final class WindowInsets {
        public static @InsetsType int all() {
            return 0xFFFFFFFF;
        }

        /**
         * Checks whether the specified type is considered to be part of visible insets.
         * @hide
         */
        public static boolean isVisibleInsetsType(int type,
                @SoftInputModeFlags int softInputModeFlags) {
            int softInputMode = softInputModeFlags & SOFT_INPUT_MASK_ADJUST;
            return (type & Type.systemBars()) != 0
                    || (softInputMode != SOFT_INPUT_ADJUST_NOTHING && (type & Type.ime()) != 0);
        }
    }

    /**
Loading