summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/webkit/WebViewCore.java16
-rw-r--r--core/java/android/webkit/WebViewInputDispatcher.java12
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java104
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java26
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java4
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java7
9 files changed, 142 insertions, 67 deletions
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index ba42ff5181bd..1164649a3f5e 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -669,7 +669,7 @@ public final class WebViewCore {
int x, int y);
private native boolean nativeMouseClick(int nativeClass);
- private native boolean nativeHandleTouchEvent(int nativeClass, int action,
+ private native int nativeHandleTouchEvent(int nativeClass, int action,
int[] idArray, int[] xArray, int[] yArray, int count,
int actionIndex, int metaState);
@@ -968,6 +968,9 @@ public final class WebViewCore {
static final int ACTION_LONGPRESS = 0x100;
static final int ACTION_DOUBLETAP = 0x200;
+ private static final int TOUCH_FLAG_HIT_HANDLER = 0x1;
+ private static final int TOUCH_FLAG_PREVENT_DEFAULT = 0x2;
+
static class TouchEventData {
int mAction;
int[] mIds; // Ids of the touch points
@@ -1784,7 +1787,8 @@ public final class WebViewCore {
}
@Override
- public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags) {
+ public boolean dispatchWebKitEvent(WebViewInputDispatcher dispatcher,
+ MotionEvent event, int eventType, int flags) {
if (mNativeClass == 0) {
return false;
}
@@ -1811,10 +1815,16 @@ public final class WebViewCore {
xArray[i] = (int) event.getX(i);
yArray[i] = (int) event.getY(i);
}
- return nativeHandleTouchEvent(mNativeClass,
+ int touchFlags = nativeHandleTouchEvent(mNativeClass,
event.getActionMasked(),
idArray, xArray, yArray, count,
event.getActionIndex(), event.getMetaState());
+ if (touchFlags == 0
+ && event.getActionMasked() != MotionEvent.ACTION_CANCEL
+ && (flags & WebViewInputDispatcher.FLAG_PRIVATE) == 0) {
+ dispatcher.skipWebkitForRemainingTouchStream();
+ }
+ return (touchFlags & TOUCH_FLAG_PREVENT_DEFAULT) > 0;
}
default:
diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java
index feff16ec0443..d8065e951681 100644
--- a/core/java/android/webkit/WebViewInputDispatcher.java
+++ b/core/java/android/webkit/WebViewInputDispatcher.java
@@ -686,7 +686,7 @@ final class WebViewInputDispatcher {
+ ", eventType=" + eventType + ", flags=" + flags);
}
boolean preventDefault = mWebKitCallbacks.dispatchWebKitEvent(
- event, eventType, flags);
+ this, event, eventType, flags);
if (DEBUG) {
Log.d(TAG, "dispatchWebKitEvent: preventDefault=" + preventDefault);
}
@@ -710,6 +710,12 @@ final class WebViewInputDispatcher {
mWebKitDispatchEventQueue.mHead = d;
}
+ // Called by WebKit when it doesn't care about the rest of the touch stream
+ public void skipWebkitForRemainingTouchStream() {
+ // Just treat this like a timeout
+ handleWebKitTimeout();
+ }
+
// Runs on UI thread in response to the web kit thread appearing to be unresponsive.
private void handleWebKitTimeout() {
synchronized (mLock) {
@@ -1081,12 +1087,14 @@ final class WebViewInputDispatcher {
/**
* Dispatches an event to web kit.
+ * @param dispatcher The WebViewInputDispatcher sending the event
* @param event The event.
* @param eventType The event type.
* @param flags The event's dispatch flags.
* @return True if web kit wants to prevent default event handling.
*/
- public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags);
+ public boolean dispatchWebKitEvent(WebViewInputDispatcher dispatcher,
+ MotionEvent event, int eventType, int flags);
}
// Runs on UI thread.
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index d6fb84747575..8cd63efd414f 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -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);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 28283ef41807..90f94fc1fdc4 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -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();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
index a90192e842c7..96afbb602a68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
@@ -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];
+ mDelegateView.getLocationOnScreen(mTempPoint);
+ final float delegateX = mTempPoint[0];
+ final float delegateY = mTempPoint[1];
- event.offsetLocation(deltaX, deltaY);
- mDelegateView.dispatchTouchEvent(event);
- event.offsetLocation(-deltaX, -deltaY);
- }
- return false;
+ 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;
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 4bb2d1d4036f..9c773a58623d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -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;
@@ -113,6 +114,14 @@ public class NavigationBarView extends LinearLayout {
}
@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);
@@ -330,6 +340,12 @@ public class NavigationBarView extends LinearLayout {
}
@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(
"onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
index 25fdf07fffdf..30d49ca86d84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
@@ -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);
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 4ee0d2535c7b..a99ae269e2d9 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3506,6 +3506,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (screenOnListener != null) {
if (mKeyguardMediator != null) {
+ try {
+ mWindowManager.setEventDispatching(true);
+ } catch (RemoteException unhandled) {
+ }
mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
@Override public void onShown(IBinder windowToken) {
if (windowToken != null) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index d9e0ec6976d0..b1612a159af7 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -6621,15 +6621,14 @@ public class WindowManagerService extends IWindowManager.Stub
public void setEventDispatching(boolean enabled) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
- "resumeKeyDispatching()")) {
+ "setEventDispatching()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized (mWindowMap) {
mInputMonitor.setEventDispatchingLw(enabled);
+ sendScreenStatusToClientsLocked();
}
-
- sendScreenStatusToClients();
}
public IBinder getFocusedWindowClientToken() {
@@ -6735,7 +6734,7 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.systemReady();
}
- private void sendScreenStatusToClients() {
+ private void sendScreenStatusToClientsLocked() {
final ArrayList<WindowState> windows = mWindows;
final int count = windows.size();
boolean on = mPowerManager.isScreenOn();