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

Commit f848e9d4 authored by Vinit Nayak's avatar Vinit Nayak
Browse files

Disabled back gesture when quickswitching if needed

We allow quickswitching apps in different
orientations by touchiing in the same region on
the device. To avoid conflicting touches between
the swipe gesture and the back gesture, we disable
the back if the rotation of the swipe location and
rotation of current device do not match.

Fixes: 150250451
Test: Tested quickswitch manually with
test apps fixed to different rotations.
Ensured back only showed when rotation of
touch and display matched.

Change-Id: If3b4d15eb4b66ce688b91d44a2ec16b3610ecf0a
parent d6503d5c
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -26,7 +26,7 @@ import com.android.systemui.shared.recents.IPinnedStackAnimationListener;


/**
/**
 * Temporary callbacks into SystemUI.
 * Temporary callbacks into SystemUI.
 * Next id = 25
 * Next id = 26
 */
 */
interface ISystemUiProxy {
interface ISystemUiProxy {


@@ -140,4 +140,10 @@ interface ISystemUiProxy {
     * Sets listener to get pinned stack animation callbacks.
     * Sets listener to get pinned stack animation callbacks.
     */
     */
    void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) = 24;
    void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) = 24;

    /**
     * Notifies that quickstep will switch to a new task
     * @param rotation indicates which Surface.Rotation the gesture was started in
     */
    void onQuickSwitchToNewTask(int rotation) = 25;
}
}
+21 −0
Original line number Original line Diff line number Diff line
@@ -55,6 +55,7 @@ import android.os.UserHandle;
import android.util.Log;
import android.util.Log;
import android.view.InputMonitor;
import android.view.InputMonitor;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager;


import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.policy.ScreenDecorationsUtils;
@@ -416,6 +417,19 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
            }
            }
        }
        }


        @Override
        public void onQuickSwitchToNewTask(@Surface.Rotation int rotation) {
            if (!verifyCaller("onQuickSwitchToNewTask")) {
                return;
            }
            long token = Binder.clearCallingIdentity();
            try {
                mHandler.post(() -> notifyQuickSwitchToNewTask(rotation));
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        private boolean verifyCaller(String reason) {
        private boolean verifyCaller(String reason) {
            final int callerId = Binder.getCallingUserHandle().getIdentifier();
            final int callerId = Binder.getCallingUserHandle().getIdentifier();
            if (callerId != mCurrentBoundedUserId) {
            if (callerId != mCurrentBoundedUserId) {
@@ -785,6 +799,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
        }
        }
    }
    }


    private void notifyQuickSwitchToNewTask(@Surface.Rotation int rotation) {
        for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
            mConnectionCallbacks.get(i).onQuickSwitchToNewTask(rotation);
        }
    }

    public void notifyQuickScrubStarted() {
    public void notifyQuickScrubStarted() {
        for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
        for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
            mConnectionCallbacks.get(i).onQuickScrubStarted();
            mConnectionCallbacks.get(i).onQuickScrubStarted();
@@ -850,6 +870,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
    public interface OverviewProxyListener {
    public interface OverviewProxyListener {
        default void onConnectionChanged(boolean isConnected) {}
        default void onConnectionChanged(boolean isConnected) {}
        default void onQuickStepStarted() {}
        default void onQuickStepStarted() {}
        default void onQuickSwitchToNewTask(@Surface.Rotation int rotation) {}
        default void onOverviewShown(boolean fromHome) {}
        default void onOverviewShown(boolean fromHome) {}
        default void onQuickScrubStarted() {}
        default void onQuickScrubStarted() {}
        /** Notify changes in the nav bar button alpha */
        /** Notify changes in the nav bar button alpha */
+88 −1
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.view.Display.INVALID_DISPLAY;


import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PointF;
@@ -26,10 +27,14 @@ import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.input.InputManager;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;
import android.view.ISystemGestureExclusionListener;
import android.view.ISystemGestureExclusionListener;
import android.view.InputChannel;
import android.view.InputChannel;
@@ -40,6 +45,7 @@ import android.view.InputMonitor;
import android.view.KeyCharacterMap;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerGlobal;
@@ -53,8 +59,10 @@ import com.android.systemui.plugins.NavigationEdgeBackPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto;
import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto;
@@ -72,6 +80,8 @@ public class EdgeBackGestureHandler implements DisplayListener,
    private static final String TAG = "EdgeBackGestureHandler";
    private static final String TAG = "EdgeBackGestureHandler";
    private static final int MAX_LONG_PRESS_TIMEOUT = SystemProperties.getInt(
    private static final int MAX_LONG_PRESS_TIMEOUT = SystemProperties.getInt(
            "gestures.back_timeout", 250);
            "gestures.back_timeout", 250);
    private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";



    private ISystemGestureExclusionListener mGestureExclusionListener =
    private ISystemGestureExclusionListener mGestureExclusionListener =
            new ISystemGestureExclusionListener.Stub() {
            new ISystemGestureExclusionListener.Stub() {
@@ -88,6 +98,33 @@ public class EdgeBackGestureHandler implements DisplayListener,
                }
                }
            };
            };


    private OverviewProxyService.OverviewProxyListener mQuickSwitchListener =
            new OverviewProxyService.OverviewProxyListener() {
                @Override
                public void onQuickSwitchToNewTask(@Surface.Rotation int rotation) {
                    mStartingQuickstepRotation = rotation;
                    updateDisabledForQuickstep();
                }
            };

    private TaskStackChangeListener mTaskStackChangeListener = new TaskStackChangeListener() {
        @Override
        public void onRecentTaskListFrozenChanged(boolean frozen) {
            if (!frozen) {
                mStartingQuickstepRotation = -1;
                mDisabledForQuickstep = false;
            }
        }
    };

    private final ContentObserver mFixedRotationObserver = new ContentObserver(
            new Handler(Looper.getMainLooper())) {
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            updatedFixedRotation();
        }
    };

    private final Context mContext;
    private final Context mContext;
    private final OverviewProxyService mOverviewProxyService;
    private final OverviewProxyService mOverviewProxyService;
    private PluginManager mPluginManager;
    private PluginManager mPluginManager;
@@ -110,6 +147,11 @@ public class EdgeBackGestureHandler implements DisplayListener,
    private final float mTouchSlop;
    private final float mTouchSlop;
    // Duration after which we consider the event as longpress.
    // Duration after which we consider the event as longpress.
    private final int mLongPressTimeout;
    private final int mLongPressTimeout;
    private int mStartingQuickstepRotation = -1;
    // We temporarily disable back gesture when user is quickswitching
    // between apps of different orientations
    private boolean mDisabledForQuickstep;
    private boolean mFixedRotationFlagEnabled;


    private final PointF mDownPoint = new PointF();
    private final PointF mDownPoint = new PointF();
    private final PointF mEndPoint = new PointF();
    private final PointF mEndPoint = new PointF();
@@ -193,6 +235,13 @@ public class EdgeBackGestureHandler implements DisplayListener,
     */
     */
    public void onNavBarAttached() {
    public void onNavBarAttached() {
        mIsAttached = true;
        mIsAttached = true;
        updatedFixedRotation();
        if (mFixedRotationFlagEnabled) {
            setRotationCallbacks(true);
        }
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(FIXED_ROTATION_TRANSFORM_SETTING_NAME),
                false /* notifyForDescendants */, mFixedRotationObserver, UserHandle.USER_ALL);
        updateIsEnabled();
        updateIsEnabled();
    }
    }


@@ -201,9 +250,25 @@ public class EdgeBackGestureHandler implements DisplayListener,
     */
     */
    public void onNavBarDetached() {
    public void onNavBarDetached() {
        mIsAttached = false;
        mIsAttached = false;
        if (mFixedRotationFlagEnabled) {
            setRotationCallbacks(false);
        }
        mContext.getContentResolver().unregisterContentObserver(mFixedRotationObserver);
        updateIsEnabled();
        updateIsEnabled();
    }
    }


    private void setRotationCallbacks(boolean enable) {
        if (enable) {
            ActivityManagerWrapper.getInstance().registerTaskStackListener(
                    mTaskStackChangeListener);
            mOverviewProxyService.addCallback(mQuickSwitchListener);
        } else {
            ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
                    mTaskStackChangeListener);
            mOverviewProxyService.removeCallback(mQuickSwitchListener);
        }
    }

    public void onNavigationModeChanged(int mode, Context currentUserContext) {
    public void onNavigationModeChanged(int mode, Context currentUserContext) {
        mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode);
        mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode);
        updateIsEnabled();
        updateIsEnabled();
@@ -405,7 +470,8 @@ public class EdgeBackGestureHandler implements DisplayListener,
            mLogGesture = false;
            mLogGesture = false;
            mInRejectedExclusion = false;
            mInRejectedExclusion = false;
            mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
            mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
                    && isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
                    && isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
                    && !mDisabledForQuickstep;
            if (mAllowGesture) {
            if (mAllowGesture) {
                mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
                mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
                mEdgeBackPlugin.onMotionEvent(ev);
                mEdgeBackPlugin.onMotionEvent(ev);
@@ -466,6 +532,11 @@ public class EdgeBackGestureHandler implements DisplayListener,
        Dependency.get(ProtoTracer.class).update();
        Dependency.get(ProtoTracer.class).update();
    }
    }


    private void updateDisabledForQuickstep() {
        int rotation = mContext.getResources().getConfiguration().windowConfiguration.getRotation();
        mDisabledForQuickstep = mStartingQuickstepRotation != rotation;
    }

    @Override
    @Override
    public void onDisplayAdded(int displayId) { }
    public void onDisplayAdded(int displayId) { }


@@ -474,6 +545,10 @@ public class EdgeBackGestureHandler implements DisplayListener,


    @Override
    @Override
    public void onDisplayChanged(int displayId) {
    public void onDisplayChanged(int displayId) {
        if (mStartingQuickstepRotation > -1) {
            updateDisabledForQuickstep();
        }

        if (displayId == mDisplayId) {
        if (displayId == mDisplayId) {
            updateDisplaySize();
            updateDisplaySize();
        }
        }
@@ -502,6 +577,17 @@ public class EdgeBackGestureHandler implements DisplayListener,
        InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
        InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
    }
    }


    private void updatedFixedRotation() {
        boolean oldFlag = mFixedRotationFlagEnabled;
        mFixedRotationFlagEnabled = Settings.Global.getInt(mContext.getContentResolver(),
                FIXED_ROTATION_TRANSFORM_SETTING_NAME, 0) != 0;
        if (oldFlag == mFixedRotationFlagEnabled) {
            return;
        }

        setRotationCallbacks(mFixedRotationFlagEnabled);
    }

    public void setInsets(int leftInset, int rightInset) {
    public void setInsets(int leftInset, int rightInset) {
        mLeftInset = leftInset;
        mLeftInset = leftInset;
        mRightInset = rightInset;
        mRightInset = rightInset;
@@ -514,6 +600,7 @@ public class EdgeBackGestureHandler implements DisplayListener,
        pw.println("EdgeBackGestureHandler:");
        pw.println("EdgeBackGestureHandler:");
        pw.println("  mIsEnabled=" + mIsEnabled);
        pw.println("  mIsEnabled=" + mIsEnabled);
        pw.println("  mAllowGesture=" + mAllowGesture);
        pw.println("  mAllowGesture=" + mAllowGesture);
        pw.println("  mDisabledForQuickstep=" + mDisabledForQuickstep);
        pw.println("  mInRejectedExclusion" + mInRejectedExclusion);
        pw.println("  mInRejectedExclusion" + mInRejectedExclusion);
        pw.println("  mExcludeRegion=" + mExcludeRegion);
        pw.println("  mExcludeRegion=" + mExcludeRegion);
        pw.println("  mUnrestrictedExcludeRegion=" + mUnrestrictedExcludeRegion);
        pw.println("  mUnrestrictedExcludeRegion=" + mUnrestrictedExcludeRegion);