Merge "Fix 6547012: ignore events outside the home/back/recent navigation area" into jb-dev
This commit is contained in:
@@ -476,19 +476,12 @@ public class MultiWaveView extends View {
|
||||
|
||||
/**
|
||||
* Dispatches a trigger event to listener. Ignored if a listener is not set.
|
||||
* @param whichHandle the handle that triggered the event.
|
||||
* @param whichTarget the target that was triggered.
|
||||
*/
|
||||
private void dispatchTriggerEvent(int whichHandle) {
|
||||
private void dispatchTriggerEvent(int whichTarget) {
|
||||
vibrate();
|
||||
if (mOnTriggerListener != null) {
|
||||
mOnTriggerListener.onTrigger(this, whichHandle);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchGrabbedEvent(int whichHandler) {
|
||||
vibrate();
|
||||
if (mOnTriggerListener != null) {
|
||||
mOnTriggerListener.onGrabbed(this, whichHandler);
|
||||
mOnTriggerListener.onTrigger(this, whichTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +507,7 @@ public class MultiWaveView extends View {
|
||||
|
||||
// Inform listener of any active targets. Typically only one will be active.
|
||||
if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
|
||||
dispatchTriggerEvent(mActiveTarget);
|
||||
dispatchTriggerEvent(activeTarget);
|
||||
}
|
||||
|
||||
// Animate handle back to the center based on current state.
|
||||
@@ -791,7 +784,7 @@ public class MultiWaveView extends View {
|
||||
}
|
||||
|
||||
private void handleDown(MotionEvent event) {
|
||||
if (!trySwitchToFirstTouchState(event.getX(), event.getY())) {
|
||||
if (!trySwitchToFirstTouchState(event.getX(), event.getY())) {
|
||||
mDragging = false;
|
||||
mTargetAnimations.cancel();
|
||||
ping();
|
||||
@@ -903,7 +896,6 @@ public class MultiWaveView extends View {
|
||||
if (target.hasState(TargetDrawable.STATE_FOCUSED)) {
|
||||
target.setState(TargetDrawable.STATE_FOCUSED);
|
||||
}
|
||||
dispatchGrabbedEvent(activeTarget);
|
||||
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
|
||||
String targetContentDescription = getTargetDescription(activeTarget);
|
||||
announceText(targetContentDescription);
|
||||
@@ -950,7 +942,7 @@ public class MultiWaveView extends View {
|
||||
} else {
|
||||
mOnTriggerListener.onGrabbed(this, OnTriggerListener.CENTER_HANDLE);
|
||||
}
|
||||
mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState);
|
||||
mOnTriggerListener.onGrabbedStateChange(this, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public class SearchPanelView extends FrameLayout implements
|
||||
}
|
||||
|
||||
public void onGrabbedStateChange(View v, int handle) {
|
||||
if (OnTriggerListener.NO_HANDLE == handle) {
|
||||
if (mTarget == -1 && OnTriggerListener.NO_HANDLE == handle) {
|
||||
mBar.hideSearchPanel();
|
||||
}
|
||||
}
|
||||
@@ -147,8 +147,8 @@ public class SearchPanelView extends FrameLayout implements
|
||||
startAssistActivity();
|
||||
break;
|
||||
}
|
||||
mBar.hideSearchPanel();
|
||||
}
|
||||
mBar.hideSearchPanel();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import android.util.Slog;
|
||||
import android.graphics.RectF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.R;
|
||||
@@ -29,8 +28,12 @@ public class DelegateViewHelper {
|
||||
private BaseStatusBar mBar;
|
||||
private int[] mTempPoint = new int[2];
|
||||
private float[] mDownPoint = new float[2];
|
||||
private int mOrientation;
|
||||
private float mTriggerThreshhold;
|
||||
private boolean mPanelShowing;
|
||||
|
||||
RectF mInitialTouch = new RectF();
|
||||
private boolean mStarted;
|
||||
private boolean mSwapXY = false;
|
||||
|
||||
public DelegateViewHelper(View sourceView) {
|
||||
setSourceView(sourceView);
|
||||
@@ -44,49 +47,53 @@ public class DelegateViewHelper {
|
||||
mBar = phoneStatusBar;
|
||||
}
|
||||
|
||||
public void setOrientation(int orientation) {
|
||||
mOrientation = orientation;
|
||||
}
|
||||
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (mBar.shouldDisableNavbarGestures()) {
|
||||
if (mSourceView == null || mDelegateView == null || mBar.shouldDisableNavbarGestures()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSourceView.getLocationOnScreen(mTempPoint);
|
||||
final float sourceX = mTempPoint[0];
|
||||
final float sourceY = mTempPoint[1];
|
||||
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE;
|
||||
mDownPoint[0] = event.getX();
|
||||
mDownPoint[1] = event.getY();
|
||||
mStarted = mInitialTouch.contains(mDownPoint[0] + sourceX, mDownPoint[1] + sourceY);
|
||||
break;
|
||||
}
|
||||
if (mDelegateView != null) {
|
||||
if (mDelegateView.getVisibility() != View.VISIBLE
|
||||
&& event.getAction() != MotionEvent.ACTION_CANCEL) {
|
||||
final boolean isVertical = (mOrientation == Surface.ROTATION_90
|
||||
|| mOrientation == Surface.ROTATION_270);
|
||||
final int historySize = event.getHistorySize();
|
||||
for (int k = 0; k < historySize + 1; k++) {
|
||||
float x = k < historySize ? event.getHistoricalX(k) : event.getX();
|
||||
float y = k < historySize ? event.getHistoricalY(k) : event.getY();
|
||||
final float distance = isVertical ? (mDownPoint[0] - x) : (mDownPoint[1] - y);
|
||||
if (distance > mTriggerThreshhold) {
|
||||
mBar.showSearchPanel();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mPanelShowing && event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
final int historySize = event.getHistorySize();
|
||||
for (int k = 0; k < historySize + 1; k++) {
|
||||
float x = k < historySize ? event.getHistoricalX(k) : event.getX();
|
||||
float y = k < historySize ? event.getHistoricalY(k) : event.getY();
|
||||
final float distance = mSwapXY ? (mDownPoint[0] - x) : (mDownPoint[1] - y);
|
||||
if (distance > mTriggerThreshhold) {
|
||||
mBar.showSearchPanel();
|
||||
mPanelShowing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mSourceView.getLocationOnScreen(mTempPoint);
|
||||
float deltaX = mTempPoint[0];
|
||||
float deltaY = mTempPoint[1];
|
||||
|
||||
mDelegateView.getLocationOnScreen(mTempPoint);
|
||||
deltaX -= mTempPoint[0];
|
||||
deltaY -= mTempPoint[1];
|
||||
|
||||
event.offsetLocation(deltaX, deltaY);
|
||||
mDelegateView.dispatchTouchEvent(event);
|
||||
event.offsetLocation(-deltaX, -deltaY);
|
||||
}
|
||||
return false;
|
||||
|
||||
mDelegateView.getLocationOnScreen(mTempPoint);
|
||||
final float delegateX = mTempPoint[0];
|
||||
final float delegateY = mTempPoint[1];
|
||||
|
||||
float deltaX = sourceX - delegateX;
|
||||
float deltaY = sourceY - delegateY;
|
||||
event.offsetLocation(deltaX, deltaY);
|
||||
mDelegateView.dispatchTouchEvent(event);
|
||||
event.offsetLocation(-deltaX, -deltaY);
|
||||
return mPanelShowing;
|
||||
}
|
||||
|
||||
public void setSourceView(View view) {
|
||||
@@ -96,4 +103,35 @@ public class DelegateViewHelper {
|
||||
.getDimension(R.dimen.navbar_search_up_threshhold);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the initial touch region based on a list of views. This is meant to be called by
|
||||
* a container widget on children over which the initial touch should be detected. Note this
|
||||
* will compute a minimum bound that contains all specified views.
|
||||
*
|
||||
* @param views
|
||||
*/
|
||||
public void setInitialTouchRegion(View ... views) {
|
||||
RectF bounds = new RectF();
|
||||
int p[] = new int[2];
|
||||
for (int i = 0; i < views.length; i++) {
|
||||
View view = views[i];
|
||||
if (view == null) continue;
|
||||
view.getLocationOnScreen(p);
|
||||
if (i == 0) {
|
||||
bounds.set(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
|
||||
} else {
|
||||
bounds.union(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
|
||||
}
|
||||
}
|
||||
mInitialTouch.set(bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* When rotation is set to NO_SENSOR, then this allows swapping x/y for gesture detection
|
||||
* @param swap
|
||||
*/
|
||||
public void setSwapXY(boolean swap) {
|
||||
mSwapXY = swap;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.app.StatusBarManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -112,6 +113,14 @@ public class NavigationBarView extends LinearLayout {
|
||||
mDelegateHelper.setBar(phoneStatusBar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mDelegateHelper != null) {
|
||||
mDelegateHelper.onInterceptTouchEvent(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
return mDelegateHelper.onInterceptTouchEvent(event);
|
||||
@@ -292,6 +301,7 @@ public class NavigationBarView extends LinearLayout {
|
||||
setLowProfile(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishInflate() {
|
||||
mRotatedViews[Surface.ROTATION_0] =
|
||||
mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
|
||||
@@ -329,6 +339,12 @@ public class NavigationBarView extends LinearLayout {
|
||||
setNavigationIconHints(mNavigationIconHints, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
mDelegateHelper.setInitialTouchRegion(getHomeButton(), getBackButton(), getRecentsButton());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
if (DEBUG) Slog.d(TAG, String.format(
|
||||
|
||||
@@ -55,17 +55,25 @@ public class TabletStatusBarView extends FrameLayout {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mDelegateHelper != null) {
|
||||
mDelegateHelper.onInterceptTouchEvent(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
// Find the view we wish to grab events from in order to detect search gesture.
|
||||
// Depending on the device, this will be one of the id's listed below.
|
||||
// If we don't find one, we'll use the view provided in the constructor above (this view).
|
||||
View view = null;
|
||||
if ((view = findViewById(R.id.navigationArea)) != null) {
|
||||
mDelegateHelper.setSourceView(view);
|
||||
} else if ((view = findViewById(R.id.nav_buttons)) != null) {
|
||||
mDelegateHelper.setSourceView(view);
|
||||
View view = findViewById(R.id.navigationArea);
|
||||
if (view == null) {
|
||||
view = findViewById(R.id.nav_buttons);
|
||||
}
|
||||
mDelegateHelper.setSourceView(view);
|
||||
mDelegateHelper.setInitialTouchRegion(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,8 +108,8 @@ public class TabletStatusBarView extends FrameLayout {
|
||||
if (TabletStatusBar.DEBUG) {
|
||||
Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event");
|
||||
}
|
||||
if (mDelegateHelper != null) {
|
||||
return mDelegateHelper.onInterceptTouchEvent(ev);
|
||||
if (mDelegateHelper != null && mDelegateHelper.onInterceptTouchEvent(ev)) {
|
||||
return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user