From 8353a381c61dcd6cd21cc70129739b3b03c75750 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Thu, 6 Apr 2023 09:47:52 -0700 Subject: [PATCH] Support 3-finger swipe down on the home screen to pull down notifications Fixes: 276605497 Test: 3-finger swipe down to pull down notifications. 3-finger swipe up to pull up overview Change-Id: I4c1e0df15a94905fa197849f5667a5446c259ffe --- .../com/android/quickstep/InputConsumer.java | 2 + .../quickstep/TouchInteractionService.java | 11 ++- .../StatusBarInputConsumer.java | 76 +++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java diff --git a/quickstep/src/com/android/quickstep/InputConsumer.java b/quickstep/src/com/android/quickstep/InputConsumer.java index c455dc7462..64c92959e4 100644 --- a/quickstep/src/com/android/quickstep/InputConsumer.java +++ b/quickstep/src/com/android/quickstep/InputConsumer.java @@ -40,6 +40,7 @@ public interface InputConsumer { int TYPE_SYSUI_OVERLAY = 1 << 10; int TYPE_ONE_HANDED = 1 << 11; int TYPE_TASKBAR_STASH = 1 << 12; + int TYPE_STATUS_BAR = 1 << 13; String[] NAMES = new String[] { "TYPE_NO_OP", // 0 @@ -55,6 +56,7 @@ public interface InputConsumer { "TYPE_SYSUI_OVERLAY", // 10 "TYPE_ONE_HANDED", // 11 "TYPE_TASKBAR_STASH", // 12 + "TYPE_STATUS_BAR", // 13 }; InputConsumer NO_OP = () -> TYPE_NO_OP; diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 93363a0ff2..1cf682bffc 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -26,6 +26,7 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE; import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe; import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS; +import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.GestureState.DEFAULT_STATE; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER; @@ -106,6 +107,7 @@ import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer; import com.android.quickstep.inputconsumers.ProgressDelegateInputConsumer; import com.android.quickstep.inputconsumers.ResetGestureInputConsumer; import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; +import com.android.quickstep.inputconsumers.StatusBarInputConsumer; import com.android.quickstep.inputconsumers.SysUiOverlayInputConsumer; import com.android.quickstep.inputconsumers.TaskbarStashInputConsumer; import com.android.quickstep.util.ActiveGestureLog; @@ -857,7 +859,14 @@ public class TouchInteractionService extends Service getBaseContext(), mDeviceState, mInputMonitorCompat); } - + if (ENABLE_TRACKPAD_GESTURE.get() && mGestureState.isTrackpadGesture() + && mGestureState.getActivityInterface().isResumed() + && !previousGestureState.isRecentsAnimationRunning()) { + reasonString = newCompoundString(reasonPrefix) + .append(SUBSTRING_PREFIX) + .append("Trackpad 3-finger gesture, using StatusBarInputConsumer"); + base = new StatusBarInputConsumer(getBaseContext(), base, mInputMonitorCompat); + } if (mDeviceState.isScreenPinningActive()) { reasonString = newCompoundString(reasonPrefix) diff --git a/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java new file mode 100644 index 0000000000..f3d2a60b15 --- /dev/null +++ b/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 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.quickstep.inputconsumers; + +import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_MOVE; + +import android.content.Context; +import android.graphics.PointF; +import android.view.MotionEvent; +import android.view.ViewConfiguration; + +import com.android.quickstep.InputConsumer; +import com.android.quickstep.SystemUiProxy; +import com.android.systemui.shared.system.InputMonitorCompat; + +/** Allows the status bar to be pull down for notification shade */ +public class StatusBarInputConsumer extends DelegateInputConsumer { + + private final SystemUiProxy mSystemUiProxy; + private final float mTouchSlop; + private final PointF mDown = new PointF(); + + public StatusBarInputConsumer(Context context, InputConsumer delegate, + InputMonitorCompat inputMonitor) { + super(delegate, inputMonitor); + + mSystemUiProxy = SystemUiProxy.INSTANCE.get(context); + mTouchSlop = 2 * ViewConfiguration.get(context).getScaledTouchSlop(); + } + + @Override + public int getType() { + return TYPE_STATUS_BAR | mDelegate.getType(); + } + + @Override + public void onMotionEvent(MotionEvent ev) { + if (mState != STATE_ACTIVE) { + mDelegate.onMotionEvent(ev); + + switch (ev.getActionMasked()) { + case ACTION_DOWN -> mDown.set(ev.getX(), ev.getY()); + case ACTION_MOVE -> { + float displacementY = ev.getY() - mDown.y; + if (displacementY > mTouchSlop) { + setActive(ev); + ev.setAction(ACTION_DOWN); + dispatchTouchEvent(ev); + } + } + } + } else { + dispatchTouchEvent(ev); + } + } + + private void dispatchTouchEvent(MotionEvent ev) { + if (mSystemUiProxy.isActive()) { + mSystemUiProxy.onStatusBarMotionEvent(ev); + } + } +}