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

Commit d0166532 authored by Mihai Popa's avatar Mihai Popa Committed by Android (Google) Code Review
Browse files

Merge "[Magnifier-16] Clamp to surface against distortion"

parents c41d1482 3589c2c6
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -896,6 +896,26 @@ public final class ViewRootImpl implements ViewParent,
        return mWindowAttributes.getTitle();
    }

    /**
     * @return the width of the root view. Note that this will return {@code -1} until the first
     *         layout traversal, when the width is set.
     *
     * @hide
     */
    public int getWidth() {
        return mWidth;
    }

    /**
     * @return the height of the root view. Note that this will return {@code -1} until the first
     *         layout traversal, when the height is set.
     *
     * @hide
     */
    public int getHeight() {
        return mHeight;
    }

    void destroyHardwareResources() {
        if (mAttachInfo.mThreadedRenderer != null) {
            mAttachInfo.mThreadedRenderer.destroyHardwareResources(mView);
+39 −22
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.widget;

import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.content.Context;
import android.graphics.Bitmap;
@@ -30,9 +29,11 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.PixelCopy;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewRootImpl;

import com.android.internal.util.Preconditions;

@@ -124,7 +125,8 @@ public final class Magnifier {

        configureCoordinates(xPosInView, yPosInView);

        // Clamp startX value to avoid distorting the rendering of the magnifier content.
        // Clamp the startX value to avoid magnifying content which does not belong to the magnified
        // view. This will not take into account overlapping views.
        // For this, we compute:
        // - zeroScrollXInSurface: this is the start x of mView, where this is not masked by a
        //                         potential scrolling container. For example, if mView is a
@@ -221,11 +223,41 @@ public final class Magnifier {
    }

    private void performPixelCopy(final int startXInSurface, final int startYInSurface) {
        final Surface surface = getValidViewSurface();
        if (surface != null) {
            mPixelCopyRequestRect.set(startXInSurface, startYInSurface,
                    startXInSurface + mBitmap.getWidth(), startYInSurface + mBitmap.getHeight());
        // Get the view surface where the content will be copied from.
        final Surface surface;
        final int surfaceWidth;
        final int surfaceHeight;
        if (mView instanceof SurfaceView) {
            final SurfaceHolder surfaceHolder = ((SurfaceView) mView).getHolder();
            surface = surfaceHolder.getSurface();
            surfaceWidth = surfaceHolder.getSurfaceFrame().right;
            surfaceHeight = surfaceHolder.getSurfaceFrame().bottom;
        } else if (mView.getViewRootImpl() != null) {
            final ViewRootImpl viewRootImpl = mView.getViewRootImpl();
            surface = viewRootImpl.mSurface;
            surfaceWidth = viewRootImpl.getWidth();
            surfaceHeight = viewRootImpl.getHeight();
        } else {
            surface = null;
            surfaceWidth = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
            surfaceHeight = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
        }

        if (surface == null || !surface.isValid()) {
            return;
        }

        // Clamp copy coordinates inside the surface to avoid displaying distorted content.
        final int clampedStartXInSurface = Math.max(0,
                Math.min(startXInSurface, surfaceWidth - mWindowWidth));
        final int clampedStartYInSurface = Math.max(0,
                Math.min(startYInSurface, surfaceHeight - mWindowHeight));

        // Perform the pixel copy.
        mPixelCopyRequestRect.set(clampedStartXInSurface,
                clampedStartYInSurface,
                clampedStartXInSurface + mBitmap.getWidth(),
                clampedStartYInSurface + mBitmap.getHeight());
        PixelCopy.request(surface, mPixelCopyRequestRect, mBitmap,
                result -> {
                    getImageView().invalidate();
@@ -234,21 +266,6 @@ public final class Magnifier {
                },
                mPixelCopyHandler);
    }
    }

    @Nullable
    private Surface getValidViewSurface() {
        final Surface surface;
        if (mView instanceof SurfaceView) {
            surface = ((SurfaceView) mView).getHolder().getSurface();
        } else if (mView.getViewRootImpl() != null) {
            surface = mView.getViewRootImpl().mSurface;
        } else {
            surface = null;
        }

        return (surface != null && surface.isValid()) ? surface : null;
    }

    private ImageView getImageView() {
        return mWindow.getContentView().findViewById(