From 9d14dbe89dcda57255afc30bcf9b65bc52e8bdbe Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Fri, 5 Feb 2021 14:01:20 -0800 Subject: [PATCH] Allow pulling down the status bar in visual immersive mode Fixes: 177997773 Test: manual Change-Id: I084253e982de6964d6b06a6ae858fbdcfb99f38d --- .../statusbar/phone/StatusBarWindowView.java | 28 +++++++++++++++++++ .../com/android/server/wm/DisplayPolicy.java | 9 ++++++ 2 files changed, 37 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 779ba1c6ac6db..8465889876b42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.phone; +import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_MOVE; +import static android.view.MotionEvent.ACTION_UP; import static android.view.WindowInsets.Type.systemBars; import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection; @@ -29,6 +32,7 @@ import android.util.Pair; import android.view.Display; import android.view.DisplayCutout; import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; @@ -49,6 +53,8 @@ public class StatusBarWindowView extends FrameLayout { private int mRightInset = 0; private int mTopInset = 0; + private float mTouchDownY = 0; + public StatusBarWindowView(Context context, AttributeSet attrs) { super(context, attrs); } @@ -67,6 +73,28 @@ public class StatusBarWindowView extends FrameLayout { return windowInsets; } + /** + * This is specifically for pulling down the status bar as a consistent motion in the visual + * immersive mode. In the visual immersive mode, after the system detects a system gesture + * motion from the top, we show permanent bars, and then forward the touch events from the + * focused window to the status bar window. However, since the first relayed event is out of + * bound of the status bar view, in order for the touch event to be correctly dispatched down, + * we jot down the position Y of the initial touch down event, offset it to 0 in the y-axis, + * and calculate the movement based on first touch down position. + */ + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (ev.getAction() == ACTION_DOWN && ev.getRawY() > getHeight()) { + mTouchDownY = ev.getRawY(); + ev.setLocation(ev.getRawX(), mTopInset); + } else if (ev.getAction() == ACTION_MOVE && mTouchDownY != 0) { + ev.setLocation(ev.getRawX(), mTopInset + ev.getRawY() - mTouchDownY); + } else if (ev.getAction() == ACTION_UP) { + mTouchDownY = 0; + } + return super.dispatchTouchEvent(ev); + } + private void applyMargins() { final int count = getChildCount(); for (int i = 0; i < count; i++) { diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 30f69dd79f5e2..dc6c55029768d 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -2423,6 +2423,15 @@ public class DisplayPolicy { } else { // Restore visibilities and positions of system bars. controlTarget.showInsets(Type.statusBars() | Type.navigationBars(), false); + // To further allow the pull-down-from-the-top gesture to pull down the notification + // shade as a consistent motion, we reroute the touch events here from the currently + // touched window to the status bar after making it visible. + if (swipeTarget == mStatusBar) { + final boolean transferred = mStatusBar.transferTouch(); + if (!transferred) { + Slog.i(TAG, "Could not transfer touch to the status bar"); + } + } } mImmersiveModeConfirmation.confirmCurrentPrompt(); }