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

Commit 1903cab1 authored by Mihai Popa's avatar Mihai Popa
Browse files

[Magnifier-53] Add API around outofbounds behavior

The CL adds a public API to enable customizing magnifier's behavior when
the coordinates passed to #show would position the magnifier outside the
main application window.

Bug: 72211470
Test: manual testing
Test: atest CtsWidgetTestCases:android.widget.cts.MagnifierTest
Change-Id: I9de26e446354d0ad987a4509089fbec4ee5ef7d3
parent 14540159
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -54347,6 +54347,7 @@ package android.widget {
    method public int getSourceWidth();
    method public int getWidth();
    method public float getZoom();
    method public boolean isForcePositionWithinWindowSystemInsetsBounds();
    method public void setZoom(float);
    method public void show(float, float);
    method public void show(float, float, float, float);
@@ -54359,6 +54360,7 @@ package android.widget {
    method public android.widget.Magnifier.Builder setCornerRadius(float);
    method public android.widget.Magnifier.Builder setDefaultSourceToMagnifierOffset(int, int);
    method public android.widget.Magnifier.Builder setElevation(float);
    method public android.widget.Magnifier.Builder setForcePositionWithinWindowSystemInsetsBounds(boolean);
    method public android.widget.Magnifier.Builder setSize(int, int);
    method public android.widget.Magnifier.Builder setZoom(float);
  }
+44 −0
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ public final class Magnifier {
    private final int mDefaultHorizontalSourceToMagnifierOffset;
    // The vertical offset between the source and window coords when #show(float, float) is used.
    private final int mDefaultVerticalSourceToMagnifierOffset;
    // Whether the magnifier will be clamped inside the main surface and not overlap system insets.
    private final boolean mForcePositionWithinWindowSystemInsetsBounds;
    // The parent surface for the magnifier surface.
    private SurfaceInfo mParentSurface;
    // The surface where the content will be copied from.
@@ -141,6 +143,8 @@ public final class Magnifier {
                params.mHorizontalDefaultSourceToMagnifierOffset;
        mDefaultVerticalSourceToMagnifierOffset =
                params.mVerticalDefaultSourceToMagnifierOffset;
        mForcePositionWithinWindowSystemInsetsBounds =
                params.mForcePositionWithinWindowSystemInsetsBounds;
        // The view's surface coordinates will not be updated until the magnifier is first shown.
        mViewCoordinatesInSurface = new int[2];
    }
@@ -378,6 +382,17 @@ public final class Magnifier {
        return mDefaultVerticalSourceToMagnifierOffset;
    }

    /**
     * Returns whether the magnifier position will be adjusted such that the magnifier will be
     * fully within the bounds of the main application window, by also avoiding any overlap with
     * system insets (such as the one corresponding to the status bar).
     * @return whether the magnifier position will be adjusted
     * @see Magnifier.Builder#setForcePositionWithinWindowSystemInsetsBounds(boolean)
     */
    public boolean isForcePositionWithinWindowSystemInsetsBounds() {
        return mForcePositionWithinWindowSystemInsetsBounds;
    }

    /**
     * Returns the top left coordinates of the magnifier, relative to the surface of the
     * main application window. They will be determined by the coordinates of the last
@@ -567,6 +582,11 @@ public final class Magnifier {
     * @return the current window coordinates, after they are clamped inside the parent surface
     */
    private Point getCurrentClampedWindowCoordinates() {
        if (!mForcePositionWithinWindowSystemInsetsBounds) {
            // No position adjustment should be done, so return the raw coordinates.
            return new Point(mWindowCoords);
        }

        final Rect windowBounds;
        if (mParentSurface.mIsMainWindowSurface) {
            final Insets systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
@@ -891,6 +911,7 @@ public final class Magnifier {
        private @FloatRange(from = 0f) float mCornerRadius;
        private int mHorizontalDefaultSourceToMagnifierOffset;
        private int mVerticalDefaultSourceToMagnifierOffset;
        private boolean mForcePositionWithinWindowSystemInsetsBounds;

        /**
         * Construct a new builder for {@link Magnifier} objects.
@@ -915,6 +936,7 @@ public final class Magnifier {
            mVerticalDefaultSourceToMagnifierOffset =
                    a.getDimensionPixelSize(R.styleable.Magnifier_magnifierVerticalOffset, 0);
            a.recycle();
            mForcePositionWithinWindowSystemInsetsBounds = true;
        }

        /**
@@ -999,6 +1021,28 @@ public final class Magnifier {
            return this;
        }

        /**
         * Defines the behavior of the magnifier when it is requested to position outside the
         * surface of the main application window. The default value is {@code true}, which means
         * that the position will be adjusted such that the magnifier will be fully within the
         * bounds of the main application window, by also avoiding any overlap with system insets
         * (such as the one corresponding to the status bar). If you require a custom behavior, this
         * flag should be set to {@code false}, meaning that the magnifier will be able to cross the
         * main application surface boundaries (and also overlap the system insets). This should be
         * handled with care, when passing coordinates to {@link #show(float, float)}; note that:
         * <ul>
         *   <li>in a multiwindow context, if the magnifier crosses the boundary between the two
         *   windows, it will not be able to show over the window of the other application</li>
         *   <li>if the magnifier overlaps the status bar, there is no guarantee about which one
         *   will be displayed on top. This should be handled with care.</li>
         * </ul>
         * @param force whether the magnifier position will be adjusted
         */
        public Builder setForcePositionWithinWindowSystemInsetsBounds(boolean force) {
            mForcePositionWithinWindowSystemInsetsBounds = force;
            return this;
        }

        /**
         * Builds a {@link Magnifier} instance based on the configuration of this {@link Builder}.
         */