Skip to content

Commit 73bde11

Browse files
Jim MillerAndroid (Google) Code Review
authored andcommitted
Merge "Fix 6547012: ignore events outside the home/back/recent navigation area" into jb-dev
2 parents 2af7b91 + 960892c commit 73bde11

File tree

5 files changed

+112
-58
lines changed

5 files changed

+112
-58
lines changed

core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -476,19 +476,12 @@ void invalidateGlobalRegion(TargetDrawable drawable) {
476476

477477
/**
478478
* Dispatches a trigger event to listener. Ignored if a listener is not set.
479-
* @param whichHandle the handle that triggered the event.
479+
* @param whichTarget the target that was triggered.
480480
*/
481-
private void dispatchTriggerEvent(int whichHandle) {
481+
private void dispatchTriggerEvent(int whichTarget) {
482482
vibrate();
483483
if (mOnTriggerListener != null) {
484-
mOnTriggerListener.onTrigger(this, whichHandle);
485-
}
486-
}
487-
488-
private void dispatchGrabbedEvent(int whichHandler) {
489-
vibrate();
490-
if (mOnTriggerListener != null) {
491-
mOnTriggerListener.onGrabbed(this, whichHandler);
484+
mOnTriggerListener.onTrigger(this, whichTarget);
492485
}
493486
}
494487

@@ -514,7 +507,7 @@ private void doFinish() {
514507

515508
// Inform listener of any active targets. Typically only one will be active.
516509
if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
517-
dispatchTriggerEvent(mActiveTarget);
510+
dispatchTriggerEvent(activeTarget);
518511
}
519512

520513
// Animate handle back to the center based on current state.
@@ -791,7 +784,7 @@ private void moveHandleTo(float x, float y, boolean animate) {
791784
}
792785

793786
private void handleDown(MotionEvent event) {
794-
if (!trySwitchToFirstTouchState(event.getX(), event.getY())) {
787+
if (!trySwitchToFirstTouchState(event.getX(), event.getY())) {
795788
mDragging = false;
796789
mTargetAnimations.cancel();
797790
ping();
@@ -903,7 +896,6 @@ private void handleMove(MotionEvent event) {
903896
if (target.hasState(TargetDrawable.STATE_FOCUSED)) {
904897
target.setState(TargetDrawable.STATE_FOCUSED);
905898
}
906-
dispatchGrabbedEvent(activeTarget);
907899
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
908900
String targetContentDescription = getTargetDescription(activeTarget);
909901
announceText(targetContentDescription);
@@ -950,7 +942,7 @@ private void setGrabbedState(int newState) {
950942
} else {
951943
mOnTriggerListener.onGrabbed(this, OnTriggerListener.CENTER_HANDLE);
952944
}
953-
mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState);
945+
mOnTriggerListener.onGrabbedStateChange(this, newState);
954946
}
955947
}
956948
}

packages/SystemUI/src/com/android/systemui/SearchPanelView.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public void onReleased(View v, int handle) {
129129
}
130130

131131
public void onGrabbedStateChange(View v, int handle) {
132-
if (OnTriggerListener.NO_HANDLE == handle) {
132+
if (mTarget == -1 && OnTriggerListener.NO_HANDLE == handle) {
133133
mBar.hideSearchPanel();
134134
}
135135
}
@@ -147,8 +147,8 @@ public void onFinishFinalAnimation() {
147147
startAssistActivity();
148148
break;
149149
}
150+
mBar.hideSearchPanel();
150151
}
151-
mBar.hideSearchPanel();
152152
}
153153
};
154154

packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616

1717
package com.android.systemui.statusbar;
1818

19-
import android.util.Slog;
19+
import android.graphics.RectF;
2020
import android.view.MotionEvent;
21-
import android.view.Surface;
2221
import android.view.View;
2322

2423
import com.android.systemui.R;
@@ -29,8 +28,12 @@ public class DelegateViewHelper {
2928
private BaseStatusBar mBar;
3029
private int[] mTempPoint = new int[2];
3130
private float[] mDownPoint = new float[2];
32-
private int mOrientation;
3331
private float mTriggerThreshhold;
32+
private boolean mPanelShowing;
33+
34+
RectF mInitialTouch = new RectF();
35+
private boolean mStarted;
36+
private boolean mSwapXY = false;
3437

3538
public DelegateViewHelper(View sourceView) {
3639
setSourceView(sourceView);
@@ -44,49 +47,53 @@ public void setBar(BaseStatusBar phoneStatusBar) {
4447
mBar = phoneStatusBar;
4548
}
4649

47-
public void setOrientation(int orientation) {
48-
mOrientation = orientation;
49-
}
50-
5150
public boolean onInterceptTouchEvent(MotionEvent event) {
52-
if (mBar.shouldDisableNavbarGestures()) {
51+
if (mSourceView == null || mDelegateView == null || mBar.shouldDisableNavbarGestures()) {
5352
return false;
5453
}
54+
55+
mSourceView.getLocationOnScreen(mTempPoint);
56+
final float sourceX = mTempPoint[0];
57+
final float sourceY = mTempPoint[1];
58+
59+
5560
switch (event.getAction()) {
5661
case MotionEvent.ACTION_DOWN:
62+
mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE;
5763
mDownPoint[0] = event.getX();
5864
mDownPoint[1] = event.getY();
65+
mStarted = mInitialTouch.contains(mDownPoint[0] + sourceX, mDownPoint[1] + sourceY);
5966
break;
6067
}
61-
if (mDelegateView != null) {
62-
if (mDelegateView.getVisibility() != View.VISIBLE
63-
&& event.getAction() != MotionEvent.ACTION_CANCEL) {
64-
final boolean isVertical = (mOrientation == Surface.ROTATION_90
65-
|| mOrientation == Surface.ROTATION_270);
66-
final int historySize = event.getHistorySize();
67-
for (int k = 0; k < historySize + 1; k++) {
68-
float x = k < historySize ? event.getHistoricalX(k) : event.getX();
69-
float y = k < historySize ? event.getHistoricalY(k) : event.getY();
70-
final float distance = isVertical ? (mDownPoint[0] - x) : (mDownPoint[1] - y);
71-
if (distance > mTriggerThreshhold) {
72-
mBar.showSearchPanel();
73-
break;
74-
}
68+
69+
if (!mStarted) {
70+
return false;
71+
}
72+
73+
if (!mPanelShowing && event.getAction() == MotionEvent.ACTION_MOVE) {
74+
final int historySize = event.getHistorySize();
75+
for (int k = 0; k < historySize + 1; k++) {
76+
float x = k < historySize ? event.getHistoricalX(k) : event.getX();
77+
float y = k < historySize ? event.getHistoricalY(k) : event.getY();
78+
final float distance = mSwapXY ? (mDownPoint[0] - x) : (mDownPoint[1] - y);
79+
if (distance > mTriggerThreshhold) {
80+
mBar.showSearchPanel();
81+
mPanelShowing = true;
82+
break;
7583
}
7684
}
77-
mSourceView.getLocationOnScreen(mTempPoint);
78-
float deltaX = mTempPoint[0];
79-
float deltaY = mTempPoint[1];
85+
}
8086

81-
mDelegateView.getLocationOnScreen(mTempPoint);
82-
deltaX -= mTempPoint[0];
83-
deltaY -= mTempPoint[1];
87+
mDelegateView.getLocationOnScreen(mTempPoint);
88+
final float delegateX = mTempPoint[0];
89+
final float delegateY = mTempPoint[1];
8490

85-
event.offsetLocation(deltaX, deltaY);
86-
mDelegateView.dispatchTouchEvent(event);
87-
event.offsetLocation(-deltaX, -deltaY);
88-
}
89-
return false;
91+
float deltaX = sourceX - delegateX;
92+
float deltaY = sourceY - delegateY;
93+
event.offsetLocation(deltaX, deltaY);
94+
mDelegateView.dispatchTouchEvent(event);
95+
event.offsetLocation(-deltaX, -deltaY);
96+
return mPanelShowing;
9097
}
9198

9299
public void setSourceView(View view) {
@@ -96,4 +103,35 @@ public void setSourceView(View view) {
96103
.getDimension(R.dimen.navbar_search_up_threshhold);
97104
}
98105
}
106+
107+
/**
108+
* Selects the initial touch region based on a list of views. This is meant to be called by
109+
* a container widget on children over which the initial touch should be detected. Note this
110+
* will compute a minimum bound that contains all specified views.
111+
*
112+
* @param views
113+
*/
114+
public void setInitialTouchRegion(View ... views) {
115+
RectF bounds = new RectF();
116+
int p[] = new int[2];
117+
for (int i = 0; i < views.length; i++) {
118+
View view = views[i];
119+
if (view == null) continue;
120+
view.getLocationOnScreen(p);
121+
if (i == 0) {
122+
bounds.set(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
123+
} else {
124+
bounds.union(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
125+
}
126+
}
127+
mInitialTouch.set(bounds);
128+
}
129+
130+
/**
131+
* When rotation is set to NO_SENSOR, then this allows swapping x/y for gesture detection
132+
* @param swap
133+
*/
134+
public void setSwapXY(boolean swap) {
135+
mSwapXY = swap;
136+
}
99137
}

packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import android.content.Context;
2424
import android.content.res.Resources;
2525
import android.graphics.Rect;
26+
import android.graphics.RectF;
2627
import android.graphics.drawable.Drawable;
2728
import android.os.Handler;
2829
import android.os.Message;
@@ -112,6 +113,14 @@ public void setBar(BaseStatusBar phoneStatusBar) {
112113
mDelegateHelper.setBar(phoneStatusBar);
113114
}
114115

116+
@Override
117+
public boolean onTouchEvent(MotionEvent event) {
118+
if (mDelegateHelper != null) {
119+
mDelegateHelper.onInterceptTouchEvent(event);
120+
}
121+
return true;
122+
}
123+
115124
@Override
116125
public boolean onInterceptTouchEvent(MotionEvent event) {
117126
return mDelegateHelper.onInterceptTouchEvent(event);
@@ -292,6 +301,7 @@ public void setHidden(final boolean hide) {
292301
setLowProfile(false);
293302
}
294303

304+
@Override
295305
public void onFinishInflate() {
296306
mRotatedViews[Surface.ROTATION_0] =
297307
mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
@@ -329,6 +339,12 @@ public void reorient() {
329339
setNavigationIconHints(mNavigationIconHints, true);
330340
}
331341

342+
@Override
343+
protected void onLayout(boolean changed, int l, int t, int r, int b) {
344+
super.onLayout(changed, l, t, r, b);
345+
mDelegateHelper.setInitialTouchRegion(getHomeButton(), getBackButton(), getRecentsButton());
346+
}
347+
332348
@Override
333349
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
334350
if (DEBUG) Slog.d(TAG, String.format(

packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,25 @@ public void setBar(BaseStatusBar phoneStatusBar) {
5555
}
5656

5757
@Override
58-
protected void onFinishInflate() {
59-
super.onFinishInflate();
58+
public boolean onTouchEvent(MotionEvent event) {
59+
if (mDelegateHelper != null) {
60+
mDelegateHelper.onInterceptTouchEvent(event);
61+
}
62+
return true;
63+
}
64+
65+
@Override
66+
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
67+
super.onLayout(changed, left, top, right, bottom);
6068
// Find the view we wish to grab events from in order to detect search gesture.
6169
// Depending on the device, this will be one of the id's listed below.
6270
// If we don't find one, we'll use the view provided in the constructor above (this view).
63-
View view = null;
64-
if ((view = findViewById(R.id.navigationArea)) != null) {
65-
mDelegateHelper.setSourceView(view);
66-
} else if ((view = findViewById(R.id.nav_buttons)) != null) {
67-
mDelegateHelper.setSourceView(view);
71+
View view = findViewById(R.id.navigationArea);
72+
if (view == null) {
73+
view = findViewById(R.id.nav_buttons);
6874
}
75+
mDelegateHelper.setSourceView(view);
76+
mDelegateHelper.setInitialTouchRegion(view);
6977
}
7078

7179
@Override
@@ -100,8 +108,8 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
100108
if (TabletStatusBar.DEBUG) {
101109
Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event");
102110
}
103-
if (mDelegateHelper != null) {
104-
return mDelegateHelper.onInterceptTouchEvent(ev);
111+
if (mDelegateHelper != null && mDelegateHelper.onInterceptTouchEvent(ev)) {
112+
return true;
105113
}
106114
return super.onInterceptTouchEvent(ev);
107115
}

0 commit comments

Comments
 (0)