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

Commit 9ed37d13 authored by Ryan Lin's avatar Ryan Lin Committed by Android (Google) Code Review
Browse files

Merge "Extract Mirror windowcontrol to a single class"

parents 70a3ce1a 7bc9d86c
Loading
Loading
Loading
Loading
+197 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.accessibility;

import static android.view.WindowManager.LayoutParams;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.Log;
import android.util.MathUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;

import com.android.systemui.R;

/**
 * Contains a movable control UI to manipulate mirrored window's position, size and scale. The
 * window type of the UI is {@link LayoutParams#TYPE_APPLICATION_SUB_PANEL} and the window type
 * of the window token should be {@link LayoutParams#TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY} to
 * ensure it is above all windows and won't be mirrored. It is not movable to the navigation bar.
 */
public abstract class MirrorWindowControl {
    private static final String TAG = "MirrorWindowControl";
    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG) | false;

    /**
     * A delegate handling a mirrored window's offset.
     */
    public interface MirrorWindowDelegate {
        /**
         * Moves the window with specified offset.
         *
         * @param xOffset the amount in pixels to offset the window in the X coordinate, in current
         *                display pixels.
         * @param yOffset the amount in pixels to offset the window in the Y coordinate, in current
         *                display pixels.
         */
        void move(int xOffset, int yOffset);
    }

    protected final Context mContext;
    private final Rect mDraggableBound = new Rect();
    final Point mTmpPoint = new Point();

    @Nullable
    protected MirrorWindowDelegate mMirrorWindowDelegate;
    protected View mControlsView;
    /**
     * The left top position of the control UI. Initialized when the control UI is visible.
     *
     * @see #setDefaultPosition(LayoutParams)
     */
    private final Point mControlPosition = new Point();
    private final WindowManager mWindowManager;

    MirrorWindowControl(Context context) {
        mContext = context;
        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    }

    public void setWindowDelegate(@Nullable MirrorWindowDelegate windowDelegate) {
        mMirrorWindowDelegate = windowDelegate;
    }

    /**
     * Shows the control UI.
     *
     * @param binder the window token of the
     * {@link LayoutParams#TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY}  window.
     */
    public final void showControl(IBinder binder) {
        if (mControlsView != null) {
            Log.w(TAG, "control view is visible");
            return;
        }
        final Point  viewSize = mTmpPoint;
        mControlsView = onCreateView(LayoutInflater.from(mContext), viewSize);

        final LayoutParams lp = new LayoutParams();
        final int defaultSize = mContext.getResources().getDimensionPixelSize(
                R.dimen.magnification_controls_size);
        lp.width = viewSize.x <= 0 ? defaultSize : viewSize.x;
        lp.height = viewSize.y <= 0 ? defaultSize : viewSize.y;
        lp.token = binder;
        setDefaultParams(lp);
        setDefaultPosition(lp);
        mWindowManager.addView(mControlsView, lp);
        updateDraggableBound(lp.width, lp.height);
    }

    private void setDefaultParams(LayoutParams lp) {
        lp.gravity = Gravity.TOP | Gravity.LEFT;
        lp.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
                | LayoutParams.FLAG_NOT_FOCUSABLE;
        lp.type = LayoutParams.TYPE_APPLICATION_SUB_PANEL;
        lp.format = PixelFormat.RGBA_8888;
        lp.setTitle(getWindowTitle());
    }

    private void setDefaultPosition(LayoutParams layoutParams) {
        final Point displaySize = mTmpPoint;
        mContext.getDisplay().getSize(displaySize);
        layoutParams.x = displaySize.x - layoutParams.width;
        layoutParams.y = displaySize.y - layoutParams.height;
        mControlPosition.set(layoutParams.x, layoutParams.y);
    }

    /**
     * Removes the UI from the scene.
     */
    public final void destroyControl() {
        if (mControlsView != null) {
            mWindowManager.removeView(mControlsView);
            mControlsView = null;
        }
    }

    /**
     * Moves the control view with specified offset.
     *
     * @param xOffset the amount in pixels to offset the UI in the X coordinate, in current
     *                display pixels.
     * @param yOffset the amount in pixels to offset the UI in the Y coordinate, in current
     *                display pixels.
     */
    public void move(int xOffset, int yOffset) {
        if (mControlsView == null) {
            Log.w(TAG, "control view is not available yet or destroyed");
            return;
        }
        final Point nextPosition = mTmpPoint;
        nextPosition.set(mControlPosition.x, mControlPosition.y);
        mTmpPoint.offset(xOffset, yOffset);
        setPosition(mTmpPoint);
    }

    private void setPosition(Point point) {
        constrainFrameToDraggableBound(point);
        if (point.equals(mControlPosition)) {
            return;
        }
        mControlPosition.set(point.x, point.y);
        LayoutParams lp = (LayoutParams) mControlsView.getLayoutParams();
        lp.x = mControlPosition.x;
        lp.y = mControlPosition.y;
        mWindowManager.updateViewLayout(mControlsView, lp);
    }

    private void constrainFrameToDraggableBound(Point point) {
        point.x = MathUtils.constrain(point.x, mDraggableBound.left, mDraggableBound.right);
        point.y = MathUtils.constrain(point.y, mDraggableBound.top, mDraggableBound.bottom);
    }

    private void updateDraggableBound(int viewWidth, int viewHeight) {
        final Point size = mTmpPoint;
        mContext.getDisplay().getSize(size);
        mDraggableBound.set(0, 0, size.x - viewWidth, size.y - viewHeight);
        if (DBG) {
            Log.d(TAG, "updateDraggableBound :" + mDraggableBound);
        }
    }

    abstract String getWindowTitle();

    /**
     * Called when the UI is going to show.
     *
     * @param inflater The LayoutInflater object used to inflate the view.
     * @param viewSize The {@link Point} to specify view's width with {@link Point#x)} and height
     *                with {@link Point#y)} .The value should be greater than 0, otherwise will
     *                 fall back to the default size.
     * @return the View for the control's UI.
     */
    @NonNull
    abstract View onCreateView(@NonNull LayoutInflater inflater, @NonNull Point viewSize);
}
+221 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.accessibility;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;

import com.android.systemui.R;

/**
 * A basic control to move the mirror window.
 */
class SimpleMirrorWindowControl extends MirrorWindowControl implements View.OnClickListener,
        View.OnTouchListener, View.OnLongClickListener {

    private static final String TAG = "SimpleMirrorWindowControl";
    private static final int MOVE_FRAME_DURATION_MS = 100;
    private final int mMoveFrameAmountShort;
    private final int mMoveFrameAmountLong;

    private boolean mIsDragState;
    private boolean mShouldSetTouchStart;

    @Nullable private MoveWindowTask mMoveWindowTask;
    private PointF mLastDrag = new PointF();
    private final Handler mHandler;

    SimpleMirrorWindowControl(Context context, Handler handler) {
        super(context);
        mHandler = handler;
        final Resources resource = context.getResources();
        mMoveFrameAmountShort = resource.getDimensionPixelSize(
                R.dimen.magnification_frame_move_short);
        mMoveFrameAmountLong = resource.getDimensionPixelSize(
                R.dimen.magnification_frame_move_long);
    }

    @Override
    String getWindowTitle() {
        return mContext.getString(R.string.magnification_controls_title);
    }

    @Override
    View onCreateView(LayoutInflater layoutInflater, Point viewSize) {
        final View view = layoutInflater.inflate(R.layout.magnifier_controllers, null);
        final View leftControl = view.findViewById(R.id.left_control);
        final View upControl = view.findViewById(R.id.up_control);
        final View rightControl = view.findViewById(R.id.right_control);
        final View bottomControl = view.findViewById(R.id.down_control);

        leftControl.setOnClickListener(this);
        upControl.setOnClickListener(this);
        rightControl.setOnClickListener(this);
        bottomControl.setOnClickListener(this);

        leftControl.setOnLongClickListener(this);
        upControl.setOnLongClickListener(this);
        rightControl.setOnLongClickListener(this);
        bottomControl.setOnLongClickListener(this);

        leftControl.setOnTouchListener(this);
        upControl.setOnTouchListener(this);
        rightControl.setOnTouchListener(this);
        bottomControl.setOnTouchListener(this);

        view.setOnTouchListener(this);
        view.setOnLongClickListener(this::onViewRootLongClick);
        return view;
    }

    private Point findOffset(View v, int moveFrameAmount) {
        final Point offset = mTmpPoint;
        offset.set(0, 0);
        if (v.getId() == R.id.left_control) {
            mTmpPoint.x = -moveFrameAmount;
        } else if (v.getId() == R.id.up_control) {
            mTmpPoint.y = -moveFrameAmount;
        } else if (v.getId() == R.id.right_control) {
            mTmpPoint.x = moveFrameAmount;
        } else if (v.getId() == R.id.down_control) {
            mTmpPoint.y = moveFrameAmount;
        } else {
            Log.w(TAG, "findOffset move is zero ");
        }
        return mTmpPoint;
    }

    @Override
    public void onClick(View v) {
        if (mMirrorWindowDelegate != null) {
            Point offset = findOffset(v, mMoveFrameAmountShort);
            mMirrorWindowDelegate.move(offset.x, offset.y);
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (handleDragState(event)) {
            return true;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mMoveWindowTask != null) {
                    mMoveWindowTask.cancel();
                    mMoveWindowTask = null;
                }
                break;
        }
        return false;
    }

    @Override
    public boolean onLongClick(View v) {
        Point offset = findOffset(v, mMoveFrameAmountLong);
        mMoveWindowTask = new MoveWindowTask(mMirrorWindowDelegate, mHandler, offset.x, offset.y,
                MOVE_FRAME_DURATION_MS);
        mMoveWindowTask.schedule();
        return true;
    }

    private boolean onViewRootLongClick(View view) {
        mIsDragState = true;
        mShouldSetTouchStart = true;
        return true;
    }

    private boolean handleDragState(final MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                if (mIsDragState) {
                    if (mShouldSetTouchStart) {
                        mLastDrag.set(event.getRawX(), event.getRawY());
                        mShouldSetTouchStart = false;
                    }
                    int xDiff = (int) (event.getRawX() - mLastDrag.x);
                    int yDiff = (int) (event.getRawY() - mLastDrag.y);
                    move(xDiff, yDiff);
                    mLastDrag.set(event.getRawX(), event.getRawY());
                    return true;
                }
                return false;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mIsDragState) {
                    mIsDragState = false;
                    return true;
                }
                return false;
            default:
                return false;
        }
    }

    /**
     * A timer task to move the mirror window periodically.
     */
    static class MoveWindowTask implements Runnable {
        private final MirrorWindowDelegate mMirrorWindowDelegate;
        private final int mXOffset;
        private final int mYOffset;
        private final Handler mHandler;
        /** Time in milliseconds between successive task executions.*/
        private long mPeriod;
        private boolean mCancel;

        MoveWindowTask(@NonNull MirrorWindowDelegate windowDelegate, Handler handler, int xOffset,
                int yOffset, long period) {
            mMirrorWindowDelegate = windowDelegate;
            mXOffset = xOffset;
            mYOffset = yOffset;
            mHandler = handler;
            mPeriod = period;
        }

        @Override
        public void run() {
            if (mCancel) {
                return;
            }
            mMirrorWindowDelegate.move(mXOffset, mYOffset);
            schedule();
        }

        /**
         * Schedules the specified task periodically and immediately.
         */
        void schedule() {
            mHandler.postDelayed(this, mPeriod);
            mCancel = false;
        }

        void cancel() {
            mHandler.removeCallbacks(this);
            mCancel = true;
        }
    }
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -86,7 +86,7 @@ public class WindowMagnification extends SystemUI {


    private void enableMagnification() {
    private void enableMagnification() {
        if (mWindowMagnificationController == null) {
        if (mWindowMagnificationController == null) {
            mWindowMagnificationController = new WindowMagnificationController(mContext, mHandler);
            mWindowMagnificationController = new WindowMagnificationController(mContext, null);
        }
        }
        mWindowMagnificationController.createWindowMagnification();
        mWindowMagnificationController.createWindowMagnification();
    }
    }
+24 −105
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.accessibility;


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


import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
@@ -25,7 +26,6 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Binder;
import android.os.Handler;
import android.view.Display;
import android.view.Display;
import android.view.Gravity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
@@ -44,16 +44,13 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
/**
/**
 * Class to handle adding and removing a window magnification.
 * Class to handle adding and removing a window magnification.
 */
 */
public class WindowMagnificationController implements View.OnClickListener,
public class WindowMagnificationController implements View.OnTouchListener, SurfaceHolder.Callback,
        View.OnLongClickListener, View.OnTouchListener, SurfaceHolder.Callback {
        MirrorWindowControl.MirrorWindowDelegate {
    private final int mBorderSize;
    private final int mBorderSize;
    private final int mMoveFrameAmountShort;
    private final int mMoveFrameAmountLong;


    private final Context mContext;
    private final Context mContext;
    private final Point mDisplaySize = new Point();
    private final Point mDisplaySize = new Point();
    private final int mDisplayId;
    private final int mDisplayId;
    private final Handler mHandler;
    private final Rect mMagnificationFrame = new Rect();
    private final Rect mMagnificationFrame = new Rect();
    private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
    private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();


@@ -66,13 +63,6 @@ public class WindowMagnificationController implements View.OnClickListener,
    // The root of the mirrored content
    // The root of the mirrored content
    private SurfaceControl mMirrorSurface;
    private SurfaceControl mMirrorSurface;


    private boolean mIsPressedDown;

    private View mLeftControl;
    private View mUpControl;
    private View mRightControl;
    private View mBottomControl;

    private View mDragView;
    private View mDragView;
    private View mLeftDrag;
    private View mLeftDrag;
    private View mTopDrag;
    private View mTopDrag;
@@ -80,20 +70,18 @@ public class WindowMagnificationController implements View.OnClickListener,
    private View mBottomDrag;
    private View mBottomDrag;


    private final PointF mLastDrag = new PointF();
    private final PointF mLastDrag = new PointF();
    private final Point mMoveWindowOffset = new Point();


    private View mMirrorView;
    private View mMirrorView;
    private SurfaceView mMirrorSurfaceView;
    private SurfaceView mMirrorSurfaceView;
    private View mControlsView;
    private View mOverlayView;
    private View mOverlayView;
    // The boundary of magnification frame.
    // The boundary of magnification frame.
    private final Rect mMagnificationFrameBoundary = new Rect();
    private final Rect mMagnificationFrameBoundary = new Rect();


    private MoveMirrorRunnable mMoveMirrorRunnable = new MoveMirrorRunnable();
    @Nullable
    private MirrorWindowControl mMirrorWindowControl;


    WindowMagnificationController(Context context, Handler handler) {
    WindowMagnificationController(Context context, MirrorWindowControl mirrorWindowControl) {
        mContext = context;
        mContext = context;
        mHandler = handler;
        Display display = mContext.getDisplay();
        Display display = mContext.getDisplay();
        display.getRealSize(mDisplaySize);
        display.getRealSize(mDisplaySize);
        mDisplayId = mContext.getDisplayId();
        mDisplayId = mContext.getDisplayId();
@@ -102,10 +90,12 @@ public class WindowMagnificationController implements View.OnClickListener,


        Resources r = context.getResources();
        Resources r = context.getResources();
        mBorderSize = (int) r.getDimension(R.dimen.magnification_border_size);
        mBorderSize = (int) r.getDimension(R.dimen.magnification_border_size);
        mMoveFrameAmountShort = (int) r.getDimension(R.dimen.magnification_frame_move_short);
        mMoveFrameAmountLong = (int) r.getDimension(R.dimen.magnification_frame_move_long);


        mScale = r.getInteger(R.integer.magnification_default_scale);
        mScale = r.getInteger(R.integer.magnification_default_scale);
        mMirrorWindowControl = mirrorWindowControl;
        if (mMirrorWindowControl != null) {
            mMirrorWindowControl.setWindowDelegate(this);
        }
    }
    }


    /**
    /**
@@ -176,9 +166,8 @@ public class WindowMagnificationController implements View.OnClickListener,
            mMirrorView = null;
            mMirrorView = null;
        }
        }


        if (mControlsView != null) {
        if (mMirrorWindowControl != null) {
            mWm.removeView(mControlsView);
            mMirrorWindowControl.destroyControl();
            mControlsView = null;
        }
        }
    }
    }


@@ -238,40 +227,9 @@ public class WindowMagnificationController implements View.OnClickListener,
    }
    }


    private void createControls() {
    private void createControls() {
        int controlsSize = (int) mContext.getResources().getDimension(
        if (mMirrorWindowControl != null) {
                R.dimen.magnification_controls_size);
            mMirrorWindowControl.showControl(mOverlayView.getWindowToken());

        }
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(controlsSize, controlsSize,
                WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.RGBA_8888);
        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
        lp.token = mOverlayView.getWindowToken();
        lp.setTitle(mContext.getString(R.string.magnification_controls_title));

        mControlsView = LayoutInflater.from(mContext).inflate(R.layout.magnifier_controllers, null);
        mWm.addView(mControlsView, lp);

        mLeftControl = mControlsView.findViewById(R.id.left_control);
        mUpControl = mControlsView.findViewById(R.id.up_control);
        mRightControl = mControlsView.findViewById(R.id.right_control);
        mBottomControl = mControlsView.findViewById(R.id.down_control);

        mLeftControl.setOnClickListener(this);
        mUpControl.setOnClickListener(this);
        mRightControl.setOnClickListener(this);
        mBottomControl.setOnClickListener(this);

        mLeftControl.setOnLongClickListener(this);
        mUpControl.setOnLongClickListener(this);
        mRightControl.setOnLongClickListener(this);
        mBottomControl.setOnLongClickListener(this);

        mLeftControl.setOnTouchListener(this);
        mUpControl.setOnTouchListener(this);
        mRightControl.setOnTouchListener(this);
        mBottomControl.setOnTouchListener(this);
    }
    }


    private void setInitialStartBounds() {
    private void setInitialStartBounds() {
@@ -330,41 +288,15 @@ public class WindowMagnificationController implements View.OnClickListener,
        t.setGeometry(mMirrorSurface, sourceBounds, mTmpRect, Surface.ROTATION_0);
        t.setGeometry(mMirrorSurface, sourceBounds, mTmpRect, Surface.ROTATION_0);
    }
    }


    @Override
    public void onClick(View v) {
        setMoveOffset(v, mMoveFrameAmountShort);
        moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y);
    }

    @Override
    public boolean onLongClick(View v) {
        mIsPressedDown = true;
        setMoveOffset(v, mMoveFrameAmountLong);
        mHandler.post(mMoveMirrorRunnable);
        return true;
    }

    @Override
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mLeftControl || v == mUpControl || v == mRightControl || v == mBottomControl) {
        if (v == mDragView || v == mLeftDrag || v == mTopDrag || v == mRightDrag
            return handleControlTouchEvent(event);
        } else if (v == mDragView || v == mLeftDrag || v == mTopDrag || v == mRightDrag
                || v == mBottomDrag) {
                || v == mBottomDrag) {
            return handleDragTouchEvent(event);
            return handleDragTouchEvent(event);
        }
        }
        return false;
        return false;
    }
    }


    private boolean handleControlTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mIsPressedDown = false;
                break;
        }
        return false;
    }

    private boolean handleDragTouchEvent(MotionEvent event) {
    private boolean handleDragTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_DOWN:
@@ -380,20 +312,6 @@ public class WindowMagnificationController implements View.OnClickListener,
        return false;
        return false;
    }
    }


    private void setMoveOffset(View v, int moveFrameAmount) {
        mMoveWindowOffset.set(0, 0);

        if (v == mLeftControl) {
            mMoveWindowOffset.x = -moveFrameAmount;
        } else if (v == mUpControl) {
            mMoveWindowOffset.y = -moveFrameAmount;
        } else if (v == mRightControl) {
            mMoveWindowOffset.x = moveFrameAmount;
        } else if (v == mBottomControl) {
            mMoveWindowOffset.y = moveFrameAmount;
        }
    }

    private void moveMirrorWindow(int xOffset, int yOffset) {
    private void moveMirrorWindow(int xOffset, int yOffset) {
        if (updateMagnificationFramePosition(xOffset, yOffset)) {
        if (updateMagnificationFramePosition(xOffset, yOffset)) {
            modifyWindowMagnification(mTransaction);
            modifyWindowMagnification(mTransaction);
@@ -461,6 +379,7 @@ public class WindowMagnificationController implements View.OnClickListener,
        }
        }
        return false;
        return false;
    }
    }

    @Override
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    public void surfaceCreated(SurfaceHolder holder) {
        createMirror();
        createMirror();
@@ -474,13 +393,13 @@ public class WindowMagnificationController implements View.OnClickListener,
    public void surfaceDestroyed(SurfaceHolder holder) {
    public void surfaceDestroyed(SurfaceHolder holder) {
    }
    }


    class MoveMirrorRunnable implements Runnable {
    @Override
    @Override
        public void run() {
    public void move(int xOffset, int yOffset) {
            if (mIsPressedDown) {
        if (mMirrorSurfaceView == null) {
                moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y);
            return;
                mHandler.postDelayed(mMoveMirrorRunnable, 100);
            }
        }
        }
        mMagnificationFrame.offset(xOffset, yOffset);
        modifyWindowMagnification(mTransaction);
        mTransaction.apply();
    }
    }
}
}
+148 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading