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

Commit 99ff985a authored by Tracy Zhou's avatar Tracy Zhou
Browse files

Use movement of the motion events on the screen instead of on the

trackpad since they are proportional

This simplifies the logic we have to track the movements in the code.
Also a slight fix to not cancel back gesture on pointer down from trackpad

Bug: 255697805
Test: 3 finger swipe to go back with the flag turned on
Change-Id: Ie85ad1d61f846ece8e515ddd456bd1729a45354e
parent 9222c803
Loading
Loading
Loading
Loading
+0 −31
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.plugins;

import android.view.MotionEvent;

/** Handles both trackpad and touch events and report displacements in both axis's. */
public interface MotionEventsHandlerBase {

    void onMotionEvent(MotionEvent ev);

    float getDisplacementX(MotionEvent ev);

    float getDisplacementY(MotionEvent ev);

    String dump();
}
+0 −3
Original line number Diff line number Diff line
@@ -48,9 +48,6 @@ public interface NavigationEdgeBackPlugin extends Plugin {
    /** Sets the base LayoutParams for the UI. */
    void setLayoutParams(WindowManager.LayoutParams layoutParams);

    /** Sets the motion events handler for the plugin. */
    default void setMotionEventsHandler(MotionEventsHandlerBase motionEventsHandler) {}

    /** Updates the UI based on the motion events passed in device coordinates. */
    void onMotionEvent(MotionEvent motionEvent);

+1 −6
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import androidx.core.view.isVisible
import androidx.dynamicanimation.animation.DynamicAnimation
import com.android.internal.util.LatencyTracker
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.MotionEventsHandlerBase
import com.android.systemui.plugins.NavigationEdgeBackPlugin
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -592,10 +591,6 @@ class BackPanelController internal constructor(
        windowManager.addView(mView, layoutParams)
    }

    override fun setMotionEventsHandler(motionEventsHandler: MotionEventsHandlerBase?) {
        // TODO(255697805): Integrate MotionEventHandler for trackpad.
    }

    private fun isDragAwayFromEdge(velocityPxPerSecThreshold: Int = 0) = velocityTracker!!.run {
        computeCurrentVelocity(PX_PER_SEC)
        val velocity = xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1)
+4 −10
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.navigationbar.gestural;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;

import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
import static com.android.systemui.navigationbar.gestural.Utilities.getTrackpadScale;
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;

import android.annotation.NonNull;
@@ -272,7 +271,6 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
    private LogArray mGestureLogOutsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);

    private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
    private final MotionEventsHandler mMotionEventsHandler;

    private final NavigationEdgeBackPlugin.BackCallback mBackCallback =
            new NavigationEdgeBackPlugin.BackCallback() {
@@ -404,7 +402,6 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack

        mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(
                mContext.getMainThreadHandler(), mContext, this::onNavigationSettingsChanged);
        mMotionEventsHandler = new MotionEventsHandler(featureFlags, getTrackpadScale(context));

        updateCurrentUserResources();
    }
@@ -624,7 +621,6 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
            Trace.beginSection("setEdgeBackPlugin");
            mEdgeBackPlugin = edgeBackPlugin;
            mEdgeBackPlugin.setBackCallback(mBackCallback);
            mEdgeBackPlugin.setMotionEventsHandler(mMotionEventsHandler);
            mEdgeBackPlugin.setLayoutParams(createLayoutParams());
            updateDisplaySize();
        } finally {
@@ -871,7 +867,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
    }

    private void onMotionEvent(MotionEvent ev) {
        mMotionEventsHandler.onMotionEvent(ev);
        boolean isTrackpadEvent = isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev);
        int action = ev.getActionMasked();
        if (action == MotionEvent.ACTION_DOWN) {
            if (DEBUG_MISSING_GESTURE) {
@@ -881,7 +877,6 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
            // Verify if this is in within the touch region and we aren't in immersive mode, and
            // either the bouncer is showing or the notification panel is hidden
            mInputEventReceiver.setBatchingEnabled(false);
            boolean isTrackpadEvent = isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev);
            if (isTrackpadEvent) {
                // TODO: show the back arrow based on the direction of the swipe.
                mIsOnLeftEdge = false;
@@ -921,7 +916,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
            if (!mThresholdCrossed) {
                mEndPoint.x = (int) ev.getX();
                mEndPoint.y = (int) ev.getY();
                if (action == MotionEvent.ACTION_POINTER_DOWN) {
                if (action == MotionEvent.ACTION_POINTER_DOWN && !isTrackpadEvent) {
                    if (mAllowGesture) {
                        logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH);
                        if (DEBUG_MISSING_GESTURE) {
@@ -947,8 +942,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
                        mLogGesture = false;
                        return;
                    }
                    float dx = Math.abs(mMotionEventsHandler.getDisplacementX(ev));
                    float dy = Math.abs(mMotionEventsHandler.getDisplacementY(ev));
                    float dx = Math.abs(ev.getX() - mDownPoint.x);
                    float dy = Math.abs(ev.getY() - mDownPoint.y);
                    if (dy > dx && dy > mTouchSlop) {
                        if (mAllowGesture) {
                            logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_VERTICAL_MOVE);
@@ -1086,7 +1081,6 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
        pw.println("  mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
        pw.println("  mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
        pw.println("  mEdgeBackPlugin=" + mEdgeBackPlugin);
        pw.println("  mMotionEventsHandler=" + mMotionEventsHandler);
        if (mEdgeBackPlugin != null) {
            mEdgeBackPlugin.dump(pw);
        }
+0 −114
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.navigationbar.gestural;

import static android.view.MotionEvent.AXIS_GESTURE_X_OFFSET;
import static android.view.MotionEvent.AXIS_GESTURE_Y_OFFSET;

import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;

import android.graphics.PointF;
import android.view.MotionEvent;

import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.MotionEventsHandlerBase;

/** Handles both trackpad and touch events and report displacements in both axis's. */
public class MotionEventsHandler implements MotionEventsHandlerBase {

    private final boolean mIsTrackpadGestureBackEnabled;
    private final int mScale;

    private final PointF mDownPos = new PointF();
    private final PointF mLastPos = new PointF();
    private float mCurrentTrackpadOffsetX = 0;
    private float mCurrentTrackpadOffsetY = 0;

    public MotionEventsHandler(FeatureFlags featureFlags, int scale) {
        mIsTrackpadGestureBackEnabled = featureFlags.isEnabled(Flags.TRACKPAD_GESTURE_BACK);
        mScale = scale;
    }

    @Override
    public void onMotionEvent(MotionEvent ev) {
        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                onActionDown(ev);
                break;
            case MotionEvent.ACTION_MOVE:
                onActionMove(ev);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                onActionUp(ev);
                break;
            default:
                break;
        }
    }

    private void onActionDown(MotionEvent ev) {
        reset();
        if (!isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev)) {
            mDownPos.set(ev.getX(), ev.getY());
            mLastPos.set(mDownPos);
        }
    }

    private void onActionMove(MotionEvent ev) {
        updateMovements(ev);
    }

    private void onActionUp(MotionEvent ev) {
        updateMovements(ev);
    }

    private void updateMovements(MotionEvent ev) {
        if (isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev)) {
            mCurrentTrackpadOffsetX += ev.getAxisValue(AXIS_GESTURE_X_OFFSET) * mScale;
            mCurrentTrackpadOffsetY += ev.getAxisValue(AXIS_GESTURE_Y_OFFSET) * mScale;
        } else {
            mLastPos.set(ev.getX(), ev.getY());
        }
    }

    private void reset() {
        mDownPos.set(0, 0);
        mLastPos.set(0, 0);
        mCurrentTrackpadOffsetX = 0;
        mCurrentTrackpadOffsetY = 0;
    }

    @Override
    public float getDisplacementX(MotionEvent ev) {
        return isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev) ? mCurrentTrackpadOffsetX
                : mLastPos.x - mDownPos.x;
    }

    @Override
    public float getDisplacementY(MotionEvent ev) {
        return isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev) ? mCurrentTrackpadOffsetY
                : mLastPos.y - mDownPos.y;
    }

    @Override
    public String dump() {
        return "mDownPos: " + mDownPos + ", mLastPos: " + mLastPos + ", mCurrentTrackpadOffsetX: "
                + mCurrentTrackpadOffsetX + ", mCurrentTrackpadOffsetY: " + mCurrentTrackpadOffsetY;
    }
}
Loading