From 66dcca807408b5b65c9b65a183b8abab75717ffc Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Mon, 8 Mar 2021 16:46:56 -0800 Subject: [PATCH] Fix touches for manage menu The manage menu can overlap the expanded view (TaskView). To fix this we need to adjust the touchableRegion in TaskView. This CL adds a method to specify a region that is not touchable on the TaskView. Also removes some code associated with old method of doing this when we had ActivityView. Test: manual - 1) expand bubble, tap "manage" 2) make sure you can tap each of the three menu options 3) make sure tapping outside the menu hides the menu 4) make sure interaction with TaskView is normal after manage menu is hidden Fixes: 171233619 Change-Id: I3ef75b84f1b5f5b24aa19b192c7c2b7545b91cad --- .../src/com/android/wm/shell/TaskView.java | 14 +++++ .../wm/shell/bubbles/BubbleStackView.java | 51 +++---------------- 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java index 46884fefd69cc..7d65a08ce7980 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java @@ -83,6 +83,7 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, private boolean mIsInitialized; private Listener mListener; private Executor mListenerExecutor; + private Rect mObscuredTouchRect; private final Rect mTmpRect = new Rect(); private final Rect mTmpRootRect = new Rect(); @@ -160,6 +161,15 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, options.setRemoveWithTaskOrganizer(true); } + /** + * Indicates a region of the view that is not touchable. + * + * @param obscuredRect the obscured region of the view. + */ + public void setObscuredTouchRect(Rect obscuredRect) { + mObscuredTouchRect = obscuredRect; + } + /** * Call when view position or size has changed. Do not call when animating. */ @@ -384,6 +394,10 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, mTmpRect.set(mTmpLocation[0], mTmpLocation[1], mTmpLocation[0] + getWidth(), mTmpLocation[1] + getHeight()); inoutInfo.touchableRegion.op(mTmpRect, Region.Op.DIFFERENCE); + + if (mObscuredTouchRect != null) { + inoutInfo.touchableRegion.union(mObscuredTouchRect); + } } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 64a44ca9e7e98..16ede735660f3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -41,7 +41,6 @@ import android.graphics.Paint; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; -import android.graphics.Region; import android.os.Bundle; import android.provider.Settings; import android.util.Log; @@ -1046,6 +1045,7 @@ public class BubbleStackView extends FrameLayout } }; + // TODO: Create ManageMenuView and move setup / animations there private void setUpManageMenu() { if (mManageMenu != null) { removeView(mManageMenu); @@ -2146,50 +2146,6 @@ public class BubbleStackView extends FrameLayout } /** - * This method is called by {@link android.app.ActivityView} because the BubbleStackView has a - * higher Z-index than the ActivityView (so that dragged-out bubbles are visible over the AV). - * ActivityView is asking BubbleStackView to subtract the stack's bounds from the provided - * touchable region, so that the ActivityView doesn't consume events meant for the stack. Due to - * the special nature of ActivityView, it does not respect the standard - * {@link #dispatchTouchEvent} and {@link #onInterceptTouchEvent} methods typically used for - * this purpose. - * - * BubbleStackView is MATCH_PARENT, so that bubbles can be positioned via their translation - * properties for performance reasons. This means that the default implementation of this method - * subtracts the entirety of the screen from the ActivityView's touchable region, resulting in - * it not receiving any touch events. This was previously addressed by returning false in the - * stack's {@link View#canReceivePointerEvents()} method, but this precluded the use of any - * touch handlers in the stack or its child views. - * - * To support touch handlers, we're overriding this method to leave the ActivityView's touchable - * region alone. The only touchable part of the stack that can ever overlap the AV is a - * dragged-out bubble that is animating back into the row of bubbles. It's not worth continually - * updating the touchable region to allow users to grab a bubble while it completes its ~50ms - * animation back to the bubble row. - * - * NOTE: Any future additions to the stack that obscure the ActivityView region will need their - * bounds subtracted here in order to receive touch events. - */ - @Override - public void subtractObscuredTouchableRegion(Region touchableRegion, View view) { - // If the notification shade is expanded, or the manage menu is open, or we are showing - // manage bubbles user education, we shouldn't let the ActivityView steal any touch events - // from any location. - if (!mIsExpanded - || mShowingManage - || (mManageEduView != null - && mManageEduView.getVisibility() == VISIBLE)) { - touchableRegion.setEmpty(); - } - } - - /** - * If you're here because you're not receiving touch events on a view that is a descendant of - * BubbleStackView, and you think BSV is intercepting them - it's not! You need to subtract the - * bounds of the view in question in {@link #subtractObscuredTouchableRegion}. The ActivityView - * consumes all touch events within its bounds, even for views like the BubbleStackView that are - * above it. It ignores typical view touch handling methods like this one and - * dispatchTouchEvent. */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { @@ -2539,6 +2495,11 @@ public class BubbleStackView extends FrameLayout } mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect); + if (mExpandedBubble.getExpandedView().getTaskView() != null) { + mExpandedBubble.getExpandedView().getTaskView().setObscuredTouchRect(mShowingManage + ? new Rect(0, 0, getWidth(), getHeight()) + : null); + } final boolean isLtr = getResources().getConfiguration().getLayoutDirection() == LAYOUT_DIRECTION_LTR;