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

Commit 57ad7127 authored by Yunfan Chen's avatar Yunfan Chen Committed by Automerger Merge Worker
Browse files

Merge "Introduce InsetsSizeOverride" into tm-qpr-dev am: dd1b8480

parents 8becb21a dd1b8480
Loading
Loading
Loading
Loading
+114 −25
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package android.view;

import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;

import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Arrays;
import java.util.Objects;

/**
@@ -52,7 +56,9 @@ public class InsetsFrameProvider implements Parcelable {
    public static final int SOURCE_FRAME = 2;

    private static final int HAS_INSETS_SIZE = 1;
    private static final int HAS_IME_INSETS_SIZE = 2;
    private static final int HAS_INSETS_SIZE_OVERRIDE = 2;

    private static Rect sTmpRect = new Rect();

    /**
     * The type of insets to provide.
@@ -77,29 +83,25 @@ public class InsetsFrameProvider implements Parcelable {
    public Insets insetsSize = null;

    /**
     * The provided frame based on the source frame. The result will be used as the insets
     * size to IME window. Only one side should be set.
     * If null, the size set in insetsSize will be applied to all window types. If it contains
     * element of some types, the insets reported to the window with that types will be overridden.
     */
    public Insets imeInsetsSize = null;
    public InsetsSizeOverride[] insetsSizeOverrides = null;

    public InsetsFrameProvider(int type) {
        this(type, SOURCE_FRAME, null, null);
    }

    public InsetsFrameProvider(int type, Insets insetsSize) {
        this(type, SOURCE_FRAME, insetsSize, insetsSize);
    }

    public InsetsFrameProvider(int type, Insets insetsSize, Insets imeInsetsSize) {
        this(type, SOURCE_FRAME, insetsSize, imeInsetsSize);
        this(type, SOURCE_FRAME, insetsSize, null);
    }

    public InsetsFrameProvider(int type, int source, Insets insetsSize,
            Insets imeInsetsSize) {
            InsetsSizeOverride[] insetsSizeOverride) {
        this.type = type;
        this.source = source;
        this.insetsSize = insetsSize;
        this.imeInsetsSize = imeInsetsSize;
        this.insetsSizeOverrides = insetsSizeOverride;
    }

    @Override
@@ -127,8 +129,8 @@ public class InsetsFrameProvider implements Parcelable {
        if (insetsSize != null) {
            sb.append(", insetsSize=").append(insetsSize);
        }
        if (imeInsetsSize != null) {
            sb.append(", imeInsetsSize=").append(imeInsetsSize);
        if (insetsSizeOverrides != null) {
            sb.append(", insetsSizeOverrides=").append(Arrays.toString(insetsSizeOverrides));
        }
        sb.append("}");
        return sb.toString();
@@ -141,8 +143,8 @@ public class InsetsFrameProvider implements Parcelable {
        if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
            insetsSize = Insets.CREATOR.createFromParcel(in);
        }
        if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
            imeInsetsSize = Insets.CREATOR.createFromParcel(in);
        if ((insetsSizeModified & HAS_INSETS_SIZE_OVERRIDE) != 0) {
            insetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
        }
    }

@@ -152,8 +154,8 @@ public class InsetsFrameProvider implements Parcelable {
        if (insetsSize != null) {
            insetsSizeModified |= HAS_INSETS_SIZE;
        }
        if (imeInsetsSize != null) {
            insetsSizeModified |= HAS_IME_INSETS_SIZE;
        if (insetsSizeOverrides != null) {
            insetsSizeModified |= HAS_INSETS_SIZE_OVERRIDE;
        }
        out.writeInt(insetsSizeModified);
        out.writeInt(type);
@@ -161,8 +163,8 @@ public class InsetsFrameProvider implements Parcelable {
        if (insetsSize != null) {
            insetsSize.writeToParcel(out, flags);
        }
        if (imeInsetsSize != null) {
            imeInsetsSize.writeToParcel(out, flags);
        if (insetsSizeOverrides != null) {
            out.writeTypedArray(insetsSizeOverrides, flags);
        }
    }

@@ -177,16 +179,12 @@ public class InsetsFrameProvider implements Parcelable {
        InsetsFrameProvider other = (InsetsFrameProvider) o;
        return type == other.type && source == other.source
                && Objects.equals(insetsSize, other.insetsSize)
                && Objects.equals(imeInsetsSize, other.imeInsetsSize);
                && Arrays.equals(insetsSizeOverrides, other.insetsSizeOverrides);
    }

    @Override
    public int hashCode() {
        int result = type;
        result = 31 * result + source;
        result = 31 * result + (insetsSize != null ? insetsSize.hashCode() : 0);
        result = 31 * result + (imeInsetsSize != null ? imeInsetsSize.hashCode() : 0);
        return result;
        return Objects.hash(type, source, insetsSize, Arrays.hashCode(insetsSizeOverrides));
    }

    public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
@@ -201,5 +199,96 @@ public class InsetsFrameProvider implements Parcelable {
                    return new InsetsFrameProvider[size];
                }
            };

    public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds,
            Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize,
            @WindowManager.LayoutParams.PrivateFlags int privateFlags) {
        boolean extendByCutout = false;
        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
            inOutFrame.set(displayFrame);
        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
            inOutFrame.set(containerBounds);
        } else {
            extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
        }
        if (insetsSize == null) {
            return;
        }
        // Only one side of the provider shall be applied. Check in the order of left - top -
        // right - bottom, only the first non-zero value will be applied.
        if (insetsSize.left != 0) {
            inOutFrame.right = inOutFrame.left + insetsSize.left;
        } else if (insetsSize.top != 0) {
            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
        } else if (insetsSize.right != 0) {
            inOutFrame.left = inOutFrame.right - insetsSize.right;
        } else if (insetsSize.bottom != 0) {
            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
        } else {
            inOutFrame.setEmpty();
        }

        if (extendByCutout) {
            WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect);
        }
    }

    /**
     * Class to describe the insets size to be provided to window with specific window type. If not
     * used, same insets size will be sent as instructed in the insetsSize and source.
     */
    public static class InsetsSizeOverride implements Parcelable {
        public final int windowType;
        public Insets insetsSize;

        protected InsetsSizeOverride(Parcel in) {
            windowType = in.readInt();
            insetsSize = in.readParcelable(null, android.graphics.Insets.class);
        }

        public InsetsSizeOverride(int type, Insets size) {
            windowType = type;
            insetsSize = size;
        }

        public static final Creator<InsetsSizeOverride> CREATOR =
                new Creator<InsetsSizeOverride>() {
            @Override
            public InsetsSizeOverride createFromParcel(Parcel in) {
                return new InsetsSizeOverride(in);
            }

            @Override
            public InsetsSizeOverride[] newArray(int size) {
                return new InsetsSizeOverride[size];
            }
        };

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(windowType);
            out.writeParcelable(insetsSize, flags);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(32);
            sb.append("TypedInsetsSize: {");
            sb.append("windowType=").append(windowType);
            sb.append(", insetsSize=").append(insetsSize);
            sb.append("}");
            return sb.toString();
        }

        @Override
        public int hashCode() {
            return Objects.hash(windowType, insetsSize);
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -274,7 +274,7 @@ public class WindowLayout {
        }

        if (extendedByCutout) {
            extendFrameByCutout(attrs.gravity, displayCutoutSafe, outDisplayFrame, outFrame,
            extendFrameByCutout(displayCutoutSafe, outDisplayFrame, outFrame,
                    mTempRect);
        }

@@ -291,7 +291,7 @@ public class WindowLayout {
                + " requestedVisibilities=" + requestedVisibilities);
    }

    public static void extendFrameByCutout(int gravity, Rect displayCutoutSafe,
    public static void extendFrameByCutout(Rect displayCutoutSafe,
            Rect displayFrame, Rect inOutFrame, Rect tempRect) {
        if (displayCutoutSafe.contains(inOutFrame)) {
            return;
+1 −1
Original line number Diff line number Diff line
@@ -578,7 +578,7 @@ message InsetsSourceProviderProto {
    optional WindowStateProto pending_control_target = 6;
    optional WindowStateProto fake_control_target = 7;
    optional .android.view.SurfaceControlProto captured_leash = 8;
    optional .android.graphics.RectProto ime_overridden_frame = 9;
    optional .android.graphics.RectProto ime_overridden_frame = 9 [deprecated=true];
    optional bool is_leash_ready_for_dispatching = 10;
    optional bool client_visible = 11;
    optional bool server_visible = 12;
+10 −7
Original line number Diff line number Diff line
@@ -1362,7 +1362,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
        setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
        setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
    }

    /**
@@ -1371,15 +1371,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * @param type The type of inset this window provides.
     * @param win The window.
     * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
     *                      the window should be taken.
     * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
     *                         {@code null} if the normal frame should be taken.
     *                      the window should be taken. Only for non-WindowState providers, nav bar
     *                      and status bar.
     * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
     *                               given window types, or {@code null} if the normal frame should
     *                               be taken.
     */
    void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
                    overrideFrameProviders) {
        mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
                imeFrameProvider);
                overrideFrameProviders);
    }

    InsetsStateController getInsetsStateController() {
@@ -3865,7 +3868,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
        }
        mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
                mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
                mDisplayPolicy.getImeSourceFrameProvider(), null);
        computeImeTarget(true /* updateImeTarget */);
        updateImeControlTarget();
    }
+54 −62
Original line number Diff line number Diff line
@@ -46,9 +46,9 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -1156,7 +1156,7 @@ public class DisplayPolicy {
                break;
            case TYPE_NAVIGATION_BAR:
                mNavigationBar = win;
                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
                final TriConsumer<DisplayFrames, WindowContainer, Rect> navFrameProvider =
                        (displayFrames, windowContainer, inOutFrame) -> {
                            if (!mNavButtonForcedVisible) {
                                final LayoutParams lp =
@@ -1166,19 +1166,22 @@ public class DisplayPolicy {
                                        if (provider.type != ITYPE_NAVIGATION_BAR) {
                                            continue;
                                        }
                                        calculateInsetsFrame(displayFrames, win, inOutFrame,
                                                provider.source, provider.insetsSize,
                                                lp.privateFlags, lp.gravity
                                        );
                                        InsetsFrameProvider.calculateInsetsFrame(
                                                displayFrames.mUnrestricted,
                                                win.getBounds(), displayFrames.mDisplayCutoutSafe,
                                                inOutFrame, provider.source,
                                                provider.insetsSize, lp.privateFlags);
                                    }
                                }
                                inOutFrame.inset(win.mGivenContentInsets);
                            }
                        },

                        (displayFrames, windowContainer, inOutFrame) -> {
                        };
                final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverride =
                        new SparseArray<>();
                // For IME, we don't modify the frame.
                        });
                imeOverride.put(TYPE_INPUT_METHOD, null);
                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
                        navFrameProvider, imeOverride);

                mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
                        (displayFrames, windowContainer, inOutFrame) -> {
@@ -1246,63 +1249,52 @@ public class DisplayPolicy {
                                            final LayoutParams lp =
                                                    win.mAttrs.forRotation(displayFrames.mRotation);
                                            final InsetsFrameProvider ifp =
                                                    lp.providedInsets[index];
                                            calculateInsetsFrame(displayFrames, windowContainer,
                                                    inOutFrame, ifp.source, ifp.insetsSize,
                                                    lp.privateFlags, lp.gravity);
                                                    win.mAttrs.forRotation(displayFrames.mRotation)
                                                            .providedInsets[index];
                                            InsetsFrameProvider.calculateInsetsFrame(
                                                    displayFrames.mUnrestricted,
                                                    windowContainer.getBounds(),
                                                    displayFrames.mDisplayCutoutSafe,
                                                    inOutFrame, ifp.source,
                                                    ifp.insetsSize, lp.privateFlags);
                                        } : null;
                        final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
                                provider.imeInsetsSize != null
                                        ? (displayFrames, windowContainer, inOutFrame) -> {
                                            inOutFrame.inset(win.mGivenContentInsets);
                        final InsetsFrameProvider.InsetsSizeOverride[] overrides =
                                provider.insetsSizeOverrides;
                        final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
                                overrideProviders;
                        if (overrides != null) {
                            overrideProviders = new SparseArray<>();
                            for (int j = overrides.length - 1; j >= 0; j--) {
                                final int overrideIndex = j;
                                final TriConsumer<DisplayFrames, WindowContainer, Rect>
                                        overrideFrameProvider =
                                                (displayFrames, windowContainer, inOutFrame) -> {
                                                    final LayoutParams lp =
                                                    win.mAttrs.forRotation(displayFrames.mRotation);
                                                            win.mAttrs.forRotation(
                                                                    displayFrames.mRotation);
                                                    final InsetsFrameProvider ifp =
                                                    lp.providedInsets[index];
                                            calculateInsetsFrame(displayFrames, windowContainer,
                                                    inOutFrame, ifp.source, ifp.imeInsetsSize,
                                                    lp.privateFlags, lp.gravity);
                                        } : null;
                        mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
                                imeFrameProvider);
                        mInsetsSourceWindowsExceptIme.add(win);
                    }
                }
                break;
        }
                                                            win.mAttrs.providedInsets[index];
                                                    InsetsFrameProvider.calculateInsetsFrame(
                                                            displayFrames.mUnrestricted,
                                                            windowContainer.getBounds(),
                                                            displayFrames.mDisplayCutoutSafe,
                                                            inOutFrame, ifp.source,
                                                            ifp.insetsSizeOverrides[
                                                                    overrideIndex].insetsSize,
                                                            lp.privateFlags);
                                                };
                                overrideProviders.put(overrides[j].windowType,
                                        overrideFrameProvider);
                            }

    private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
            int source, Insets insetsSize, @LayoutParams.PrivateFlags int privateFlags,
            int windowGravity) {
        boolean extendByCutout = false;
        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
            inOutFrame.set(df.mUnrestricted);
        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
            inOutFrame.set(container.getBounds());
                        } else {
            extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
                            overrideProviders = null;
                        }
        if (insetsSize == null) {
            return;
                        mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
                                overrideProviders);
                        mInsetsSourceWindowsExceptIme.add(win);
                    }
        // Only one side of the provider shall be applied. Check in the order of left - top -
        // right - bottom, only the first non-zero value will be applied.
        if (insetsSize.left != 0) {
            inOutFrame.right = inOutFrame.left + insetsSize.left;
        } else if (insetsSize.top != 0) {
            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
        } else if (insetsSize.right != 0) {
            inOutFrame.left = inOutFrame.right - insetsSize.right;
        } else if (insetsSize.bottom != 0) {
            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
        } else {
            inOutFrame.setEmpty();
                }

        if (extendByCutout) {
            WindowLayout.extendFrameByCutout(windowGravity, df.mDisplayCutoutSafe,
                    df.mUnrestricted, inOutFrame, sTmpRect);
                break;
        }
    }

Loading