summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2013-04-30 08:47:43 -0400
committerJohn Spurlock <jspurlock@google.com>2013-05-08 12:22:16 -0400
commitad3e6cb4db99ad33fcfc61f236d37cd83446866d (patch)
tree1c5e6c6bbac7884e2f0b78148da2b883cb179afb /policy
parent3b9831f6a2f991fb492d052cc07817db402f2340 (diff)
downloadframeworks_base-ad3e6cb4db99ad33fcfc61f236d37cd83446866d.zip
frameworks_base-ad3e6cb4db99ad33fcfc61f236d37cd83446866d.tar.gz
frameworks_base-ad3e6cb4db99ad33fcfc61f236d37cd83446866d.tar.bz2
Navigation hideybar via new system ui opt-in flag.
Apps using SYSTEM_UI_FLAG_HIDE_NAVIGATION to hide the nav bar or SYSTEM_UI_FLAG_FULLSCREEN to hide the status bar can now opt into hideybars by also using a new public sysui flag: View.SYSTEM_UI_FLAG_ALLOW_OVERLAY When opting in, apps accept the fact that bars can be overlayed over their content, but gain the ability to use the entire gesture space - something that was not possible before, particularly when hiding the nav bar. Swiping from the nav bar edge of the screen will reveal the new hidey version of the nav bar, if applicable. Bug: 8682181 Change-Id: I6405bee50e6516667ba6b9a62d4f1e43490b5562
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java251
-rw-r--r--policy/src/com/android/internal/policy/impl/SystemGestures.java85
2 files changed, 264 insertions, 72 deletions
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 2b0e27a..c81f863 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -103,6 +103,7 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.HashSet;
import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -552,13 +553,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
MyOrientationListener mOrientationListener;
- private static final int HIDEYBARS_NONE = 0;
- private static final int HIDEYBARS_SHOWING = 1;
- private static final int HIDEYBARS_HIDING = 2;
- private int mHideybars;
+ private static final int HIDEYBAR_NONE = 0;
+ private static final int HIDEYBAR_SHOWING = 1;
+ private static final int HIDEYBAR_HIDING = 2;
+ private int mStatusHideybar;
+ private int mNavigationHideybar;
private InputChannel mSystemGestureInputChannel;
- private InputEventReceiver mSystemGestures;
+ private SystemGestures mSystemGestures;
IStatusBarService getStatusBarService() {
synchronized (mServiceAquireLock) {
@@ -919,8 +921,27 @@ public class PhoneWindowManager implements WindowManagerPolicy {
new SystemGestures.Callbacks() {
@Override
public void onSwipeFromTop() {
- showHideybars();
- }});
+ showHideybars(mStatusBar);
+ }
+ @Override
+ public void onSwipeFromBottom() {
+ if (mNavigationBarOnBottom) {
+ showHideybars(mNavigationBar);
+ }
+ }
+ @Override
+ public void onSwipeFromRight() {
+ if (!mNavigationBarOnBottom) {
+ showHideybars(mNavigationBar);
+ }
+ }
+ @Override
+ public void onDebug() {
+ if (OverlayTesting.ENABLED) {
+ OverlayTesting.toggleForceOverlay(mFocusedWindow, mContext);
+ }
+ }
+ });
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
@@ -2500,10 +2521,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public int adjustSystemUiVisibilityLw(int visibility) {
- if (mHideybars == HIDEYBARS_SHOWING && 0 == (visibility & View.STATUS_BAR_OVERLAY)) {
- mHideybars = HIDEYBARS_HIDING;
+ if (mStatusHideybar == HIDEYBAR_SHOWING &&
+ 0 == (visibility & View.STATUS_BAR_OVERLAY)) {
+ mStatusHideybar = HIDEYBAR_HIDING;
mStatusBar.hideLw(true);
}
+ if (mNavigationHideybar == HIDEYBAR_SHOWING &&
+ 0 == (visibility & View.NAVIGATION_BAR_OVERLAY)) {
+ mNavigationHideybar = HIDEYBAR_HIDING;
+ mNavigationBar.hideLw(true);
+ }
// Reset any bits in mForceClearingStatusBarVisibility that
// are now clear.
mResettingSystemUiFlags &= visibility;
@@ -2605,8 +2632,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mUnrestrictedScreenHeight = displayHeight - overscanTop - overscanBottom;
mRestrictedScreenLeft = mUnrestrictedScreenLeft;
mRestrictedScreenTop = mUnrestrictedScreenTop;
- mRestrictedScreenWidth = mUnrestrictedScreenWidth;
- mRestrictedScreenHeight = mUnrestrictedScreenHeight;
+ mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth;
+ mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight;
mDockLeft = mContentLeft = mStableLeft = mStableFullscreenLeft
= mCurLeft = mUnrestrictedScreenLeft;
mDockTop = mContentTop = mStableTop = mStableFullscreenTop
@@ -2632,12 +2659,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// For purposes of putting out fake window up to steal focus, we will
// drive nav being hidden only by whether it is requested.
boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+ boolean overlayAllowed = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_ALLOW_OVERLAY) != 0;
// When the navigation bar isn't visible, we put up a fake
// input window to catch all touch events. This way we can
// detect when the user presses anywhere to bring back the nav
// bar and ensure the application doesn't see the event.
- if (navVisible) {
+ if (navVisible || overlayAllowed) {
if (mHideNavFakeWindow != null) {
mHideNavFakeWindow.dismiss();
mHideNavFakeWindow = null;
@@ -2654,7 +2682,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// then take that into account.
navVisible |= !mCanHideNavigationBar;
+ boolean updateSysUiVisibility = false;
if (mNavigationBar != null) {
+ boolean navBarHideyShowing = mNavigationHideybar == HIDEYBAR_SHOWING;
// Force the navigation bar to its appropriate place and
// size. We need to do this directly, instead of relying on
// it to bubble up from the nav bar, because this needs to
@@ -2666,7 +2696,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
- mNavigationBarHeightForRotation[displayRotation];
mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom);
mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top;
- if (navVisible) {
+ if (navBarHideyShowing) {
+ mNavigationBar.showLw(true);
+ } else if (navVisible) {
mNavigationBar.showLw(true);
mDockBottom = mTmpNavigationFrame.top;
mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop;
@@ -2687,7 +2719,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
- mNavigationBarWidthForRotation[displayRotation];
mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight);
mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
- if (navVisible) {
+ if (navBarHideyShowing) {
+ mNavigationBar.showLw(true);
+ } else if (navVisible) {
mNavigationBar.showLw(true);
mDockRight = mTmpNavigationFrame.left;
mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft;
@@ -2714,6 +2748,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame);
if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+ if (mNavigationHideybar == HIDEYBAR_HIDING && !mNavigationBar.isVisibleLw()) {
+ // Finished animating out, clean up and reset alpha
+ mNavigationHideybar = HIDEYBAR_NONE;
+ updateSysUiVisibility = true;
+ }
}
if (DEBUG_LAYOUT) Slog.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
mDockLeft, mDockTop, mDockRight, mDockBottom));
@@ -2767,12 +2806,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// we can tell the app that it is covered by it.
mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
}
- if (mHideybars == HIDEYBARS_HIDING && !mStatusBar.isVisibleLw()) {
- // Hideybars have finished animating out, cleanup and reset alpha
- mHideybars = HIDEYBARS_NONE;
- updateSystemUiVisibilityLw();
+
+ if (mStatusHideybar == HIDEYBAR_HIDING && !mStatusBar.isVisibleLw()) {
+ // Finished animating out, clean up and reset alpha
+ mStatusHideybar = HIDEYBAR_NONE;
+ updateSysUiVisibility = true;
}
}
+ if (updateSysUiVisibility) {
+ updateSystemUiVisibilityLw();
+ }
}
}
@@ -3347,7 +3390,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
// has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
// case though.
- if (mHideybars == HIDEYBARS_SHOWING) {
+ if (mStatusHideybar == HIDEYBAR_SHOWING) {
if (mStatusBar.showLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT;
}
@@ -4099,18 +4142,32 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
- private void showHideybars() {
+ private void showHideybars(WindowState swipeTarget) {
synchronized(mLock) {
- if (mHideybars == HIDEYBARS_SHOWING) {
- if (DEBUG) Slog.d(TAG, "Not showing hideybars, already shown");
- return;
- }
- if (mStatusBar.isDisplayedLw()) {
- if (DEBUG) Slog.d(TAG, "Not showing hideybars, status bar already visible");
- return;
+ boolean sb = checkShowHideybar("status", mStatusHideybar, mStatusBar);
+ boolean nb = checkShowHideybar("navigation", mNavigationHideybar, mNavigationBar);
+ if (sb || nb) {
+ WindowState hideyTarget = sb ? mStatusBar : mNavigationBar;
+ if (sb ^ nb && hideyTarget != swipeTarget) {
+ if (DEBUG) Slog.d(TAG, "Not showing hideybar, wrong swipe target");
+ return;
+ }
+ mStatusHideybar = sb ? HIDEYBAR_SHOWING : mStatusHideybar;
+ mNavigationHideybar = nb ? HIDEYBAR_SHOWING : mNavigationHideybar;
+ updateSystemUiVisibilityLw();
}
- mHideybars = HIDEYBARS_SHOWING;
- updateSystemUiVisibilityLw();
+ }
+ }
+
+ private boolean checkShowHideybar(String tag, int hideybar, WindowState win) {
+ if (hideybar == HIDEYBAR_SHOWING) {
+ if (DEBUG) Slog.d(TAG, "Not showing " + tag + " hideybar, already shown");
+ return false;
+ } else if (win.isDisplayedLw()) {
+ if (DEBUG) Slog.d(TAG, "Not showing " + tag + " hideybar, bar already visible");
+ return false;
+ } else {
+ return true;
}
}
@@ -4941,31 +4998,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
}
-
- boolean hideybarsAllowed =
- (mFocusedWindow.getAttrs().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
- || mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
- if (mHideybars == HIDEYBARS_SHOWING) {
- if (!hideybarsAllowed) {
- mHideybars = HIDEYBARS_NONE;
- if ((tmpVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
- // hideybars for View.SYSTEM_UI_FLAG_FULLSCREEN: clear the clearable flags
- int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
- if (newVal != mResettingSystemUiFlags) {
- mResettingSystemUiFlags = newVal;
- mWindowManagerFuncs.reevaluateStatusBarVisibility();
- }
- }
- } else {
- // hideybars for WM.LP.FLAG_FULLSCREEN: show transparent status bar
- tmpVisibility |= View.STATUS_BAR_OVERLAY;
- if ((mLastSystemUiFlags & View.STATUS_BAR_OVERLAY) == 0) {
- mStatusBar.showLw(true);
- }
- }
- }
- final int visibility = tmpVisibility;
- int diff = visibility ^ mLastSystemUiFlags;
+ final int visibility = updateHideybarsLw(tmpVisibility);
+ final int diff = visibility ^ mLastSystemUiFlags;
final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
if (diff == 0 && mLastFocusNeedsMenu == needsMenu
&& mFocusedApp == mFocusedWindow.getAppToken()) {
@@ -4992,6 +5026,115 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return diff;
}
+ private int updateHideybarsLw(int tmpVisibility) {
+ if (OverlayTesting.ENABLED) {
+ tmpVisibility = OverlayTesting.applyForced(mFocusedWindow, tmpVisibility);
+ }
+ boolean statusBarHasFocus =
+ mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
+ if (statusBarHasFocus) {
+ // prevent status bar interaction from clearing certain flags
+ int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_ALLOW_OVERLAY;
+ tmpVisibility = (tmpVisibility & ~flags) | (mLastSystemUiFlags & flags);
+ }
+ boolean overlayAllowed = (tmpVisibility & View.SYSTEM_UI_FLAG_ALLOW_OVERLAY) != 0;
+ if (mStatusHideybar == HIDEYBAR_SHOWING) {
+ // status hideybar requested
+ boolean hideStatusBarWM =
+ (mFocusedWindow.getAttrs().flags
+ & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
+ boolean hideStatusBarSysui =
+ (tmpVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
+
+ boolean statusHideyAllowed =
+ hideStatusBarWM
+ || (hideStatusBarSysui && overlayAllowed)
+ || statusBarHasFocus;
+
+ if (!statusHideyAllowed) {
+ mStatusHideybar = HIDEYBAR_NONE;
+ if (hideStatusBarSysui) {
+ // clear the clearable flags instead
+ int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
+ if (newVal != mResettingSystemUiFlags) {
+ mResettingSystemUiFlags = newVal;
+ mWindowManagerFuncs.reevaluateStatusBarVisibility();
+ }
+ }
+ } else {
+ // show status hideybar
+ tmpVisibility |= View.STATUS_BAR_OVERLAY;
+ if ((mLastSystemUiFlags & View.STATUS_BAR_OVERLAY) == 0) {
+ mStatusBar.showLw(true);
+ }
+ }
+ }
+ if (mNavigationHideybar == HIDEYBAR_SHOWING) {
+ // navigation hideybar requested
+ boolean hideNavigationBarSysui =
+ (tmpVisibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
+ boolean navigationHideyAllowed =
+ hideNavigationBarSysui && overlayAllowed;
+ if (!navigationHideyAllowed) {
+ mNavigationHideybar = HIDEYBAR_NONE;
+ } else {
+ // show navigation hideybar
+ tmpVisibility |= View.NAVIGATION_BAR_OVERLAY;
+ if ((mLastSystemUiFlags & View.NAVIGATION_BAR_OVERLAY) == 0) {
+ mNavigationBar.showLw(true);
+ }
+ }
+ }
+ return tmpVisibility;
+ }
+
+ // TODO temporary helper that allows testing overlay bars on existing apps
+ private static final class OverlayTesting {
+ static final boolean ENABLED = true;
+ private static final HashSet<String> sForced = new HashSet<String>();
+
+ private static String parseActivity(WindowState win) {
+ if (win != null && win.getAppToken() != null) {
+ String str = win.getAppToken().toString();
+ int end = str.lastIndexOf(' ');
+ if (end > 0) {
+ int start = str.lastIndexOf(' ', end - 1);
+ if (start > -1) {
+ return str.substring(start + 1, end);
+ }
+ }
+ }
+ return null;
+ }
+
+ public static int applyForced(WindowState focused, int vis) {
+ if (sForced.contains(parseActivity(focused))) {
+ vis |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_ALLOW_OVERLAY;
+ }
+ return vis;
+ }
+
+ public static void toggleForceOverlay(WindowState focused, Context context) {
+ String activity = parseActivity(focused);
+ if (activity != null) {
+ String action;
+ if (sForced.contains(activity)) {
+ sForced.remove(activity);
+ action = "Force overlay disabled";
+ } else {
+ sForced.add(activity);
+ action = "Force overlay enabled";
+ }
+ android.widget.Toast.makeText(context,
+ action + " for " + activity, android.widget.Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
// Use this instead of checking config_showNavigationBar so that it can be consistently
// overridden by qemu.hw.mainkeys in the emulator.
@Override
diff --git a/policy/src/com/android/internal/policy/impl/SystemGestures.java b/policy/src/com/android/internal/policy/impl/SystemGestures.java
index 083fcbc..c9731a5 100644
--- a/policy/src/com/android/internal/policy/impl/SystemGestures.java
+++ b/policy/src/com/android/internal/policy/impl/SystemGestures.java
@@ -36,15 +36,24 @@ public class SystemGestures extends InputEventReceiver {
private static final int MAX_TRACKED_POINTERS = 32; // max per input system
private static final int UNTRACKED_POINTER = -1;
+ private static final int SWIPE_NONE = 0;
+ private static final int SWIPE_FROM_TOP = 1;
+ private static final int SWIPE_FROM_BOTTOM = 2;
+ private static final int SWIPE_FROM_RIGHT = 3;
+
private final int mSwipeStartThreshold;
private final int mSwipeEndThreshold;
private final Callbacks mCallbacks;
private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS];
+ private final float[] mDownX = new float[MAX_TRACKED_POINTERS];
private final float[] mDownY = new float[MAX_TRACKED_POINTERS];
private final long[] mDownTime = new long[MAX_TRACKED_POINTERS];
+ int screenHeight;
+ int screenWidth;
private int mDownPointers;
- private boolean mSwipeFromTopFireable;
+ private boolean mSwipeFireable;
+ private boolean mDebugFireable;
public SystemGestures(InputChannel inputChannel, Looper looper,
Context context, Callbacks callbacks) {
@@ -73,23 +82,41 @@ public class SystemGestures extends InputEventReceiver {
private void onPointerMotionEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- mSwipeFromTopFireable = true;
+ mSwipeFireable = true;
+ mDebugFireable = true;
mDownPointers = 0;
captureDown(event, 0);
break;
case MotionEvent.ACTION_POINTER_DOWN:
captureDown(event, event.getActionIndex());
+ if (mDebugFireable) {
+ mDebugFireable = event.getPointerCount() < 5;
+ if (!mDebugFireable) {
+ if (DEBUG) Slog.d(TAG, "Firing debug");
+ mCallbacks.onDebug();
+ }
+ }
break;
case MotionEvent.ACTION_MOVE:
- if (mSwipeFromTopFireable && detectSwipeFromTop(event)) {
- mSwipeFromTopFireable = false;
- if (DEBUG) Slog.d(TAG, "Firing onSwipeFromTop");
- mCallbacks.onSwipeFromTop();
+ if (mSwipeFireable) {
+ final int swipe = detectSwipe(event);
+ mSwipeFireable = swipe == SWIPE_NONE;
+ if (swipe == SWIPE_FROM_TOP) {
+ if (DEBUG) Slog.d(TAG, "Firing onSwipeFromTop");
+ mCallbacks.onSwipeFromTop();
+ } else if (swipe == SWIPE_FROM_BOTTOM) {
+ if (DEBUG) Slog.d(TAG, "Firing onSwipeFromBottom");
+ mCallbacks.onSwipeFromBottom();
+ } else if (swipe == SWIPE_FROM_RIGHT) {
+ if (DEBUG) Slog.d(TAG, "Firing onSwipeFromRight");
+ mCallbacks.onSwipeFromRight();
+ }
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mSwipeFromTopFireable = false;
+ mSwipeFireable = false;
+ mDebugFireable = false;
break;
default:
if (DEBUG) Slog.d(TAG, "Ignoring " + event);
@@ -102,9 +129,11 @@ public class SystemGestures extends InputEventReceiver {
if (DEBUG) Slog.d(TAG, "pointer " + pointerId +
" down pointerIndex=" + pointerIndex + " trackingIndex=" + i);
if (i != UNTRACKED_POINTER) {
+ mDownX[i] = event.getX(pointerIndex);
mDownY[i] = event.getY(pointerIndex);
mDownTime[i] = event.getEventTime();
- if (DEBUG) Slog.d(TAG, "pointer " + pointerId + " down y=" + mDownY[i]);
+ if (DEBUG) Slog.d(TAG, "pointer " + pointerId +
+ " down x=" + mDownX[i] + " y=" + mDownY[i]);
}
}
@@ -121,7 +150,7 @@ public class SystemGestures extends InputEventReceiver {
return mDownPointers - 1;
}
- private boolean detectSwipeFromTop(MotionEvent move) {
+ private int detectSwipe(MotionEvent move) {
final int historySize = move.getHistorySize();
final int pointerCount = move.getPointerCount();
for (int p = 0; p < pointerCount; p++) {
@@ -130,30 +159,50 @@ public class SystemGestures extends InputEventReceiver {
if (i != UNTRACKED_POINTER) {
for (int h = 0; h < historySize; h++) {
final long time = move.getHistoricalEventTime(h);
+ final float x = move.getHistoricalX(p, h);
final float y = move.getHistoricalY(p, h);
- if (detectSwipeFromTop(i, time, y)) {
- return true;
+ final int swipe = detectSwipe(i, time, x, y);
+ if (swipe != SWIPE_NONE) {
+ return swipe;
}
}
- if (detectSwipeFromTop(i, move.getEventTime(), move.getY(p))) {
- return true;
+ final int swipe = detectSwipe(i, move.getEventTime(), move.getX(p), move.getY(p));
+ if (swipe != SWIPE_NONE) {
+ return swipe;
}
}
}
- return false;
+ return SWIPE_NONE;
}
- private boolean detectSwipeFromTop(int i, long time, float y) {
+ private int detectSwipe(int i, long time, float x, float y) {
+ final float fromX = mDownX[i];
final float fromY = mDownY[i];
final long elapsed = time - mDownTime[i];
if (DEBUG) Slog.d(TAG, "pointer " + mDownPointerId[i]
- + " moved from.y=" + fromY + " to.y=" + y + " in " + elapsed);
- return fromY <= mSwipeStartThreshold
+ + " moved (" + fromX + "->" + x + "," + fromY + "->" + y + ") in " + elapsed);
+ if (fromY <= mSwipeStartThreshold
&& y > fromY + mSwipeEndThreshold
- && elapsed < SWIPE_TIMEOUT_MS;
+ && elapsed < SWIPE_TIMEOUT_MS) {
+ return SWIPE_FROM_TOP;
+ }
+ if (fromY >= screenHeight - mSwipeStartThreshold
+ && y < fromY - mSwipeEndThreshold
+ && elapsed < SWIPE_TIMEOUT_MS) {
+ return SWIPE_FROM_BOTTOM;
+ }
+ if (fromX >= screenWidth - mSwipeStartThreshold
+ && x < fromX - mSwipeEndThreshold
+ && elapsed < SWIPE_TIMEOUT_MS) {
+ return SWIPE_FROM_RIGHT;
+ }
+ return SWIPE_NONE;
}
interface Callbacks {
void onSwipeFromTop();
+ void onSwipeFromBottom();
+ void onSwipeFromRight();
+ void onDebug();
}
}