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

Commit 74c29079 authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge "Implement pinch to resize."

parents ff619a98 7c10e48b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -390,9 +390,9 @@ public final class SystemUiDeviceConfigFlags {
    public static final String CHOOSER_TARGET_RANKING_ENABLED = "chooser_target_ranking_enabled";

    /**
     * (boolean) Whether to enable user-drag resizing for PIP.
     * (boolean) Whether to enable pinch resizing for PIP.
     */
    public static final String PIP_USER_RESIZE = "pip_user_resize";
    public static final String PIP_PINCH_RESIZE = "pip_pinch_resize";

    /**
     * (float) Bottom height in DP for Back Gesture.
+143 −29
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
 */
package com.android.systemui.pip.phone;

import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_USER_RESIZE;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_PINCH_RESIZE;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_BOTTOM;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
@@ -46,6 +46,7 @@ import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ViewConfiguration;

import com.android.internal.policy.TaskResizingAlgorithm;
@@ -67,6 +68,8 @@ import java.util.function.Function;
public class PipResizeGestureHandler {

    private static final String TAG = "PipResizeGestureHandler";
    private static final float PINCH_THRESHOLD = 0.05f;
    private static final float STARTING_SCALE_FACTOR = 1.0f;

    private static final int INVALID_SYSUI_STATE_MASK =
            SYSUI_STATE_GLOBAL_ACTIONS_SHOWING
@@ -83,6 +86,7 @@ public class PipResizeGestureHandler {
    private final int mDisplayId;
    private final Executor mMainExecutor;
    private final SysUiState mSysUiState;
    private final ScaleGestureDetector mScaleGestureDetector;
    private final Region mTmpRegion = new Region();

    private final PointF mDownPoint = new PointF();
@@ -105,8 +109,10 @@ public class PipResizeGestureHandler {
    private boolean mAllowGesture;
    private boolean mIsAttached;
    private boolean mIsEnabled;
    private boolean mEnableUserResize;
    private boolean mEnablePinchResize;
    private boolean mThresholdCrossed;
    private boolean mUsingPinchToZoom = false;
    private float mScaleFactor = STARTING_SCALE_FACTOR;

    private InputMonitor mInputMonitor;
    private InputEventReceiver mInputEventReceiver;
@@ -136,17 +142,73 @@ public class PipResizeGestureHandler {
        context.getDisplay().getRealSize(mMaxSize);
        reloadResources();

        mEnableUserResize = DeviceConfig.getBoolean(
        mScaleGestureDetector = new ScaleGestureDetector(context,
                new ScaleGestureDetector.OnScaleGestureListener() {
                    @Override
                    public boolean onScale(ScaleGestureDetector detector) {
                        mScaleFactor *= detector.getScaleFactor();

                        if (!mThresholdCrossed
                                && (mScaleFactor > (STARTING_SCALE_FACTOR + PINCH_THRESHOLD)
                                || mScaleFactor < (STARTING_SCALE_FACTOR - PINCH_THRESHOLD))) {
                            mThresholdCrossed = true;
                            mInputMonitor.pilferPointers();
                        }
                        if (mThresholdCrossed) {
                            int height = Math.min(mMaxSize.y, Math.max(mMinSize.y,
                                    (int) (mScaleFactor * mLastDownBounds.height())));
                            int width = Math.min(mMaxSize.x, Math.max(mMinSize.x,
                                    (int) (mScaleFactor * mLastDownBounds.width())));
                            int top, bottom, left, right;

                            if ((mCtrlType & CTRL_TOP) != 0) {
                                top = mLastDownBounds.bottom - height;
                                bottom = mLastDownBounds.bottom;
                            } else {
                                top = mLastDownBounds.top;
                                bottom = mLastDownBounds.top + height;
                            }

                            if ((mCtrlType & CTRL_LEFT) != 0) {
                                left = mLastDownBounds.right - width;
                                right = mLastDownBounds.right;
                            } else {
                                left = mLastDownBounds.left;
                                right = mLastDownBounds.left + width;
                            }

                            mLastResizeBounds.set(left, top, right, bottom);
                            mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds,
                                    mLastResizeBounds,
                                    null);
                        }
                        return true;
                    }

                    @Override
                    public boolean onScaleBegin(ScaleGestureDetector detector) {
                        setCtrlTypeForPinchToZoom();
                        return true;
                    }

                    @Override
                    public void onScaleEnd(ScaleGestureDetector detector) {
                        mScaleFactor = STARTING_SCALE_FACTOR;
                        finishResize();
                    }
                });

        mEnablePinchResize = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_SYSTEMUI,
                PIP_USER_RESIZE,
                /* defaultValue = */ true);
                PIP_PINCH_RESIZE,
                /* defaultValue = */ false);
        deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mMainExecutor,
                new DeviceConfig.OnPropertiesChangedListener() {
                    @Override
                    public void onPropertiesChanged(DeviceConfig.Properties properties) {
                        if (properties.getKeyset().contains(PIP_USER_RESIZE)) {
                            mEnableUserResize = properties.getBoolean(
                                    PIP_USER_RESIZE, /* defaultValue = */ true);
                        if (properties.getKeyset().contains(PIP_PINCH_RESIZE)) {
                            mEnablePinchResize = properties.getBoolean(
                                    PIP_PINCH_RESIZE, /* defaultValue = */ false);
                        }
                    }
                });
@@ -193,7 +255,7 @@ public class PipResizeGestureHandler {
    }

    private void updateIsEnabled() {
        boolean isEnabled = mIsAttached && mEnableUserResize;
        boolean isEnabled = mIsAttached;
        if (isEnabled == mIsEnabled) {
            return;
        }
@@ -211,7 +273,11 @@ public class PipResizeGestureHandler {

    private void onInputEvent(InputEvent ev) {
        if (ev instanceof MotionEvent) {
            onMotionEvent((MotionEvent) ev);
            if (mUsingPinchToZoom) {
                mScaleGestureDetector.onTouchEvent((MotionEvent) ev);
            } else {
                onDragCornerResize((MotionEvent) ev);
            }
        }
    }

@@ -254,8 +320,51 @@ public class PipResizeGestureHandler {
    }

    public boolean willStartResizeGesture(MotionEvent ev) {
        return mEnableUserResize && isInValidSysUiState()
                && isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY());
        if (isInValidSysUiState()) {
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    // Always pass the DOWN event to the ScaleGestureDetector
                    mScaleGestureDetector.onTouchEvent(ev);
                    if (isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY())) {
                        return true;
                    }
                    break;

                case MotionEvent.ACTION_POINTER_DOWN:
                    if (mEnablePinchResize && ev.getPointerCount() == 2) {
                        mUsingPinchToZoom = true;
                        return true;
                    }
                    break;

                default:
                    break;
            }
        }
        return false;
    }

    private void setCtrlTypeForPinchToZoom() {
        final Rect currentPipBounds = mMotionHelper.getBounds();
        mLastDownBounds.set(mMotionHelper.getBounds());

        Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds);
        mDisplayBounds.set(movementBounds.left,
                movementBounds.top,
                movementBounds.right + currentPipBounds.width(),
                movementBounds.bottom + currentPipBounds.height());

        if (currentPipBounds.left == mDisplayBounds.left) {
            mCtrlType |= CTRL_RIGHT;
        } else {
            mCtrlType |= CTRL_LEFT;
        }

        if (currentPipBounds.top > mDisplayBounds.top + mDisplayBounds.height()) {
            mCtrlType |= CTRL_TOP;
        } else {
            mCtrlType |= CTRL_BOTTOM;
        }
    }

    private void setCtrlType(int x, int y) {
@@ -295,7 +404,7 @@ public class PipResizeGestureHandler {
        return (mSysUiState.getFlags() & INVALID_SYSUI_STATE_MASK) == 0;
    }

    private void onMotionEvent(MotionEvent ev) {
    private void onDragCornerResize(MotionEvent ev) {
        int action = ev.getActionMasked();
        float x = ev.getX();
        float y = ev.getY();
@@ -345,6 +454,13 @@ public class PipResizeGestureHandler {
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    finishResize();
                    break;
            }
        }
    }

    private void finishResize() {
        if (!mLastResizeBounds.isEmpty()) {
            mUserResizeBounds.set(mLastResizeBounds);
            mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
@@ -360,13 +476,11 @@ public class PipResizeGestureHandler {
        } else {
            resetState();
        }
                    break;
            }
        }
    }

    private void resetState() {
        mCtrlType = CTRL_NONE;
        mUsingPinchToZoom = false;
        mAllowGesture = false;
        mThresholdCrossed = false;
    }
@@ -397,7 +511,7 @@ public class PipResizeGestureHandler {
        pw.println(innerPrefix + "mAllowGesture=" + mAllowGesture);
        pw.println(innerPrefix + "mIsAttached=" + mIsAttached);
        pw.println(innerPrefix + "mIsEnabled=" + mIsEnabled);
        pw.println(innerPrefix + "mEnableUserResize=" + mEnableUserResize);
        pw.println(innerPrefix + "mEnablePinchResize=" + mEnablePinchResize);
        pw.println(innerPrefix + "mThresholdCrossed=" + mThresholdCrossed);
    }

+1 −2
Original line number Diff line number Diff line
@@ -650,8 +650,7 @@ public class PipTouchHandler {
        }

        MotionEvent ev = (MotionEvent) inputEvent;
        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN
                && mPipResizeGestureHandler.willStartResizeGesture(ev)) {
        if (mPipResizeGestureHandler.willStartResizeGesture(ev)) {
            // Initialize the touch state for the gesture, but immediately reset to invalidate the
            // gesture
            mTouchState.onTouchEvent(ev);