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

Commit 38d8a63d authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Disabling horizontal swipes if the app has draggable content at the bottom

Bug: 133844237
Change-Id: I67a4140d56f87c464e436d394da77127a965c3e5
parent a1898247
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.WindowManager;

import androidx.annotation.BinderThread;

import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
@@ -84,6 +86,7 @@ import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -268,6 +271,9 @@ public class TouchInteractionService extends Service implements
    private final RectF mSwipeTouchRegion = new RectF();
    private ComponentName mGestureBlockingActivity;

    private Region mExclusionRegion;
    private SystemGestureExclusionListenerCompat mExclusionListener;

    @Override
    public void onCreate() {
        super.onCreate();
@@ -284,14 +290,23 @@ public class TouchInteractionService extends Service implements
            mIsUserUnlocked = false;
            registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
        }
        onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this));

        mDefaultDisplayId = getSystemService(WindowManager.class).getDefaultDisplay()
                .getDisplayId();

        String blockingActivity = getString(R.string.gesture_blocking_activity);
        mGestureBlockingActivity = TextUtils.isEmpty(blockingActivity) ? null :
                ComponentName.unflattenFromString(blockingActivity);

        mExclusionListener = new SystemGestureExclusionListenerCompat(mDefaultDisplayId) {
            @Override
            @BinderThread
            public void onExclusionChanged(Region region) {
                // Assignments are atomic, it should be safe on binder thread
                mExclusionRegion = region;
            }
        };

        onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this));
        sConnected = true;
    }

@@ -370,6 +385,12 @@ public class TouchInteractionService extends Service implements

        disposeEventHandlers();
        initInputMonitor();

        if (mMode == Mode.NO_BUTTON) {
            mExclusionListener.register();
        } else {
            mExclusionListener.unregister();
        }
    }

    @Override
@@ -437,6 +458,7 @@ public class TouchInteractionService extends Service implements
        sConnected = false;
        Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
        SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
        mExclusionListener.unregister();

        super.onDestroy();
    }
@@ -557,10 +579,15 @@ public class TouchInteractionService extends Service implements
        final ActivityControlHelper activityControl =
                mOverviewComponentObserver.getActivityControlHelper();
        boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);

        // mExclusionRegion can change on binder thread, use a local instance here.
        Region exclusionRegion = mExclusionRegion;
        boolean disableHorizontalSwipe = mMode == Mode.NO_BUTTON && exclusionRegion != null
                && exclusionRegion.contains((int) event.getX(), (int) event.getY());
        return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
                mOverviewComponentObserver.getOverviewIntent(), activityControl,
                shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
                mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion);
                mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe);
    }

    private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
+20 −6
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC

    private final float mDragSlop;
    private final float mSquaredTouchSlop;
    private final boolean mDisableHorizontalSwipe;

    // Slop used to check when we start moving window.
    private boolean mPassedDragSlop;
@@ -132,7 +133,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
            InputConsumerController inputConsumer,
            Consumer<OtherActivityInputConsumer> onCompleteCallback,
            SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
            RectF swipeTouchRegion) {
            RectF swipeTouchRegion, boolean disableHorizontalSwipe) {
        super(base);

        mMainThreadHandler = new Handler(Looper.getMainLooper());
@@ -162,6 +163,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
        mSquaredTouchSlop = slop * slop;

        mPassedTouchSlop = mPassedDragSlop = continuingPreviousGesture;
        mDisableHorizontalSwipe = !mPassedTouchSlop && disableHorizontalSwipe;
    }

    @Override
@@ -169,6 +171,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
        return TYPE_OTHER_ACTIVITY;
    }

    private void forceCancelGesture(MotionEvent ev) {
        int action = ev.getAction();
        ev.setAction(ACTION_CANCEL);
        finishTouchTracking(ev);
        ev.setAction(action);
    }

    @Override
    public void onMotionEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
@@ -216,10 +225,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
                    // Cancel interaction in case of multi-touch interaction
                    int ptrIdx = ev.getActionIndex();
                    if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
                        int action = ev.getAction();
                        ev.setAction(ACTION_CANCEL);
                        finishTouchTracking(ev);
                        ev.setAction(action);
                        forceCancelGesture(ev);
                    }
                }
                break;
@@ -258,7 +264,15 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
                }

                if (!mPassedTouchSlop) {
                    if (squaredHypot(displacementX, mLastPos.y - mDownPos.y) >= mSquaredTouchSlop) {
                    float displacementY = mLastPos.y - mDownPos.y;
                    if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) {
                        if (mDisableHorizontalSwipe
                                && Math.abs(displacementX) > Math.abs(displacementY)) {
                            // Horizontal gesture is not allowed in this region
                            forceCancelGesture(ev);
                            break;
                        }

                        mPassedTouchSlop = true;

                        if (mIsDeferredDownTarget) {