Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1907)

Unified Diff: android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java

Issue 20990009: Handle root layer fling Java-side in android_webview. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix findbugs Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java
diff --git a/android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java b/android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java
index 4564b42ff04c4f76e2bf45c42611cd21bae64bb0..86f693b3fc198f38b75026c65b7e9ff6da8ff23d 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java
@@ -4,6 +4,10 @@
package org.chromium.android_webview;
+import android.widget.OverScroller;
+
+import com.google.common.annotations.VisibleForTesting;
+
import org.chromium.base.CalledByNative;
/**
@@ -12,6 +16,7 @@ import org.chromium.base.CalledByNative;
*
* Unless otherwise values (sizes, scroll offsets) are in physical pixels.
*/
+@VisibleForTesting
public class AwScrollOffsetManager {
// The unit of all the values in this delegate are physical pixels.
public interface Delegate {
@@ -24,8 +29,11 @@ public class AwScrollOffsetManager {
// operation, the native side shouldn't synchronously alter the scroll offset from within
// this call.
void scrollNativeTo(int x, int y);
+
int getContainerViewScrollX();
int getContainerViewScrollY();
+
+ void invalidate();
}
private final Delegate mDelegate;
@@ -42,14 +50,24 @@ public class AwScrollOffsetManager {
private int mContainerViewWidth;
private int mContainerViewHeight;
+ // Whether we're in the middle of processing a touch event.
private boolean mProcessingTouchEvent;
+ // Whether (and to what value) to update the native side scroll offset after we've finished
+ // provessing a touch event.
private boolean mApplyDeferredNativeScroll;
private int mDeferredNativeScrollX;
private int mDeferredNativeScrollY;
- public AwScrollOffsetManager(Delegate delegate) {
+ // The velocity of the last recorded fling,
+ private int mLastFlingVelocityX;
+ private int mLastFlingVelocityY;
+
+ private OverScroller mScroller;
+
+ public AwScrollOffsetManager(Delegate delegate, OverScroller overScroller) {
mDelegate = delegate;
+ mScroller = overScroller;
}
//----- Scroll range and extent calculation methods -------------------------------------------
@@ -133,12 +151,25 @@ public class AwScrollOffsetManager {
}
// Called by the native side to over-scroll the container view.
- public void overscrollBy(int deltaX, int deltaY) {
+ public void overScrollBy(int deltaX, int deltaY) {
+ // TODO(mkosiba): Once http://crbug.com/260663 and http://crbug.com/261239 are fixed it
+ // should be possible to uncomment the following asserts:
+ // if (deltaX < 0) assert mDelegate.getContainerViewScrollX() == 0;
+ // if (deltaX > 0) assert mDelegate.getContainerViewScrollX() ==
+ // computeMaximumHorizontalScrollOffset();
+ scrollBy(deltaX, deltaY);
+ }
+
+ private void scrollBy(int deltaX, int deltaY) {
+ if (deltaX == 0 && deltaY == 0) return;
+
final int scrollX = mDelegate.getContainerViewScrollX();
final int scrollY = mDelegate.getContainerViewScrollY();
final int scrollRangeX = computeMaximumHorizontalScrollOffset();
final int scrollRangeY = computeMaximumVerticalScrollOffset();
+ // The android.view.View.overScrollBy method is used for both scrolling and over-scrolling
+ // which is why we use it here.
mDelegate.overScrollContainerViewBy(deltaX, deltaY, scrollX, scrollY,
scrollRangeX, scrollRangeY, mProcessingTouchEvent);
}
@@ -201,4 +232,62 @@ public class AwScrollOffsetManager {
mDelegate.scrollNativeTo(x, y);
}
+
+ // Called at the beginning of every fling gesture.
+ public void onFlingStartGesture(int velocityX, int velocityY) {
+ mLastFlingVelocityX = velocityX;
+ mLastFlingVelocityY = velocityY;
+ }
+
+ // Called whenever some other touch interaction requires the fling gesture to be canceled.
+ public void onFlingCancelGesture() {
+ // TODO(mkosiba): Support speeding up a fling by flinging again.
+ // http://crbug.com/265841
+ mScroller.forceFinished(true);
+ }
+
+ // Called when a fling gesture is not handled by the renderer.
+ // We explicitly ask the renderer not to handle fling gestures targeted at the root
+ // scroll layer.
+ public void onUnhandledFlingStartEvent() {
+ flingScroll(-mLastFlingVelocityX, -mLastFlingVelocityY);
+ }
+
+ // Starts the fling animation. Called both as a response to a fling gesture and as via the
+ // public WebView#flingScroll(int, int) API.
+ public void flingScroll(int velocityX, int velocityY) {
+ final int scrollX = mDelegate.getContainerViewScrollX();
+ final int scrollY = mDelegate.getContainerViewScrollY();
+ final int rangeX = computeMaximumHorizontalScrollOffset();
+ final int rangeY = computeMaximumVerticalScrollOffset();
+
+ mScroller.fling(scrollX, scrollY, velocityX, velocityY,
+ 0, rangeX, 0, rangeY);
+ mDelegate.invalidate();
+ }
+
+ // Called immediately before the draw to update the scroll offset.
+ public void computeScrollAndAbsorbGlow(OverScrollGlow overScrollGlow) {
+ final boolean stillAnimating = mScroller.computeScrollOffset();
+ if (!stillAnimating) return;
+
+ final int oldX = mDelegate.getContainerViewScrollX();
+ final int oldY = mDelegate.getContainerViewScrollY();
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+
+ int rangeX = computeMaximumHorizontalScrollOffset();
+ int rangeY = computeMaximumVerticalScrollOffset();
+
+ if (overScrollGlow != null) {
+ overScrollGlow.absorbGlow(x, y, oldX, oldY, rangeX, rangeY,
+ mScroller.getCurrVelocity());
+ }
+
+ // The mScroller is configured not to go outside of the scrollable range, so this call
+ // should never result in attempting to scroll outside of the scrollable region.
+ scrollBy(x - oldX, y - oldY);
+
+ mDelegate.invalidate();
+ }
}

Powered by Google App Engine
This is Rietveld 408576698