Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.android_webview; | 5 package org.chromium.android_webview; |
| 6 | 6 |
| 7 import android.graphics.Rect; | 7 import android.graphics.Rect; |
| 8 import android.widget.OverScroller; | 8 import android.widget.OverScroller; |
| 9 | 9 |
| 10 import org.chromium.base.VisibleForTesting; | 10 import org.chromium.base.VisibleForTesting; |
| 11 | 11 |
| 12 /** | 12 /** |
| 13 * Takes care of syncing the scroll offset between the Android View system and t he | 13 * Takes care of syncing the scroll offset between the Android View system and t he |
| 14 * InProcessViewRenderer. | 14 * InProcessViewRenderer. |
| 15 * | 15 * |
| 16 * Unless otherwise values (sizes, scroll offsets) are in physical pixels. | 16 * Unless otherwise values (sizes, scroll offsets) are in physical pixels. |
| 17 */ | 17 */ |
| 18 @VisibleForTesting | 18 @VisibleForTesting |
| 19 public class AwScrollOffsetManager { | 19 public class AwScrollOffsetManager { |
| 20 // Values taken from WebViewClassic. | 20 // Values taken from WebViewClassic. |
| 21 | 21 |
| 22 // The amount of content to overlap between two screens when using pageUp/pa geDown methiods. | 22 // The amount of content to overlap between two screens when using pageUp/pa geDown methiods. |
| 23 private static final int PAGE_SCROLL_OVERLAP = 24; | 23 private static final int PAGE_SCROLL_OVERLAP = 24; |
| 24 // Standard animated scroll speed. | 24 // Standard animated scroll speed. |
| 25 private static final int STD_SCROLL_ANIMATION_SPEED_PIX_PER_SEC = 480; | 25 private static final int STD_SCROLL_ANIMATION_SPEED_PIX_PER_SEC = 480; |
| 26 // Time for the longest scroll animation. | 26 // Time for the longest scroll animation. |
| 27 private static final int MAX_SCROLL_ANIMATION_DURATION_MILLISEC = 750; | 27 private static final int MAX_SCROLL_ANIMATION_DURATION_MILLISEC = 750; |
| 28 | 28 |
| 29 private boolean mIsAnimatingScroll = false; | |
|
boliu
2015/05/29 19:42:47
what's the difference between mIsAnimatingScroll a
hush (inactive)
2015/06/05 21:47:22
I was silly there.
mIsAnimatingScroll is equal to
| |
| 30 | |
| 29 /** | 31 /** |
| 30 * The interface that all users of AwScrollOffsetManager should implement. | 32 * The interface that all users of AwScrollOffsetManager should implement. |
| 31 * | 33 * |
| 32 * The unit of all the values in this delegate are physical pixels. | 34 * The unit of all the values in this delegate are physical pixels. |
| 33 */ | 35 */ |
| 34 public interface Delegate { | 36 public interface Delegate { |
| 35 // Call View#overScrollBy on the containerView. | 37 // Call View#overScrollBy on the containerView. |
| 36 void overScrollContainerViewBy(int deltaX, int deltaY, int scrollX, int scrollY, | 38 void overScrollContainerViewBy(int deltaX, int deltaY, int scrollX, int scrollY, |
| 37 int scrollRangeX, int scrollRangeY, boolean isTouchEvent); | 39 int scrollRangeX, int scrollRangeY, boolean isTouchEvent); |
| 38 // Call View#scrollTo on the containerView. | 40 // Call View#scrollTo on the containerView. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 59 private int mMaxVerticalScrollOffset; | 61 private int mMaxVerticalScrollOffset; |
| 60 | 62 |
| 61 // Size of the container view. | 63 // Size of the container view. |
| 62 private int mContainerViewWidth; | 64 private int mContainerViewWidth; |
| 63 private int mContainerViewHeight; | 65 private int mContainerViewHeight; |
| 64 | 66 |
| 65 // Whether we're in the middle of processing a touch event. | 67 // Whether we're in the middle of processing a touch event. |
| 66 private boolean mProcessingTouchEvent; | 68 private boolean mProcessingTouchEvent; |
| 67 | 69 |
| 68 // Don't skip computeScrollAndAbsorbGlow just because isFling is called in b etween. | 70 // Don't skip computeScrollAndAbsorbGlow just because isFling is called in b etween. |
| 69 private boolean mWasFlinging; | 71 private boolean mWasSmoothScrolling; |
|
hush (inactive)
2015/06/05 21:47:22
This field is not needed any more. It is used to g
| |
| 70 | 72 |
| 71 // Whether (and to what value) to update the native side scroll offset after we've finished | 73 // Whether (and to what value) to update the native side scroll offset after we've finished |
| 72 // processing a touch event. | 74 // processing a touch event. |
| 73 private boolean mApplyDeferredNativeScroll; | 75 private boolean mApplyDeferredNativeScroll; |
| 74 private int mDeferredNativeScrollX; | 76 private int mDeferredNativeScrollX; |
| 75 private int mDeferredNativeScrollY; | 77 private int mDeferredNativeScrollY; |
| 76 | 78 |
| 77 private OverScroller mScroller; | 79 private OverScroller mScroller; |
| 78 | 80 |
| 79 public AwScrollOffsetManager(Delegate delegate, OverScroller overScroller) { | 81 public AwScrollOffsetManager(Delegate delegate, OverScroller overScroller) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 final int deltaY = y - scrollY; | 158 final int deltaY = y - scrollY; |
| 157 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); | 159 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); |
| 158 final int scrollRangeY = computeMaximumVerticalScrollOffset(); | 160 final int scrollRangeY = computeMaximumVerticalScrollOffset(); |
| 159 | 161 |
| 160 // We use overScrollContainerViewBy to be compatible with WebViewClassic which used this | 162 // We use overScrollContainerViewBy to be compatible with WebViewClassic which used this |
| 161 // method for handling both over-scroll as well as in-bounds scroll. | 163 // method for handling both over-scroll as well as in-bounds scroll. |
| 162 mDelegate.overScrollContainerViewBy(deltaX, deltaY, scrollX, scrollY, | 164 mDelegate.overScrollContainerViewBy(deltaX, deltaY, scrollX, scrollY, |
| 163 scrollRangeX, scrollRangeY, mProcessingTouchEvent); | 165 scrollRangeX, scrollRangeY, mProcessingTouchEvent); |
| 164 } | 166 } |
| 165 | 167 |
| 166 public boolean isFlingActive() { | 168 // This is used temporarily until animateScrollTo path of Android WebView (p ageUp, pageDown) |
| 167 boolean flinging = mScroller.computeScrollOffset(); | 169 // is unified with Chrome smooth scrolling. |
| 168 mWasFlinging |= flinging; | 170 public boolean isSmoothScrollingActive() { |
| 169 return flinging; | 171 boolean smoothScrolling = mScroller.computeScrollOffset(); |
| 172 mWasSmoothScrolling |= smoothScrolling; | |
| 173 return smoothScrolling; | |
| 170 } | 174 } |
| 171 | 175 |
| 172 // Called by the native side to over-scroll the container view. | 176 // Called by the native side to over-scroll the container view. |
| 173 public void overScrollBy(int deltaX, int deltaY) { | 177 public void overScrollBy(int deltaX, int deltaY) { |
| 174 // TODO(mkosiba): Once http://crbug.com/260663 and http://crbug.com/2612 39 are fixed it | 178 // TODO(mkosiba): Once http://crbug.com/260663 and http://crbug.com/2612 39 are fixed it |
| 175 // should be possible to uncomment the following asserts: | 179 // should be possible to uncomment the following asserts: |
| 176 // if (deltaX < 0) assert mDelegate.getContainerViewScrollX() == 0; | 180 // if (deltaX < 0) assert mDelegate.getContainerViewScrollX() == 0; |
| 177 // if (deltaX > 0) assert mDelegate.getContainerViewScrollX() == | 181 // if (deltaX > 0) assert mDelegate.getContainerViewScrollX() == |
| 178 // computeMaximumHorizontalScrollOffset(); | 182 // computeMaximumHorizontalScrollOffset(); |
| 179 scrollBy(deltaX, deltaY); | 183 scrollBy(deltaX, deltaY); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 mDelegate.scrollNativeTo(x, y); | 255 mDelegate.scrollNativeTo(x, y); |
| 252 } | 256 } |
| 253 | 257 |
| 254 // Called whenever some other touch interaction requires the fling gesture t o be canceled. | 258 // Called whenever some other touch interaction requires the fling gesture t o be canceled. |
| 255 public void onFlingCancelGesture() { | 259 public void onFlingCancelGesture() { |
| 256 // TODO(mkosiba): Support speeding up a fling by flinging again. | 260 // TODO(mkosiba): Support speeding up a fling by flinging again. |
| 257 // http://crbug.com/265841 | 261 // http://crbug.com/265841 |
| 258 mScroller.forceFinished(true); | 262 mScroller.forceFinished(true); |
| 259 } | 263 } |
| 260 | 264 |
| 261 // Called when a fling gesture is not handled by the renderer. | 265 // This is used temporarily until animateScrollTo path of Android WebView (p ageUp, pageDown) |
| 262 // We explicitly ask the renderer not to handle fling gestures targeted at t he root | 266 // is unified with Chrome smooth scrolling. |
| 263 // scroll layer. | 267 public boolean willComputeScroll() { |
| 264 public void onUnhandledFlingStartEvent(int velocityX, int velocityY) { | 268 if (mScroller.isFinished()) mIsAnimatingScroll = false; |
|
boliu
2015/05/29 19:42:47
not quite the same as mIsAnimatingScroll = mScroll
hush (inactive)
2015/06/05 21:47:21
Sorry. Same as I said above. This function should
| |
| 265 flingScroll(-velocityX, -velocityY); | 269 return mIsAnimatingScroll && !mScroller.isFinished(); |
| 266 } | |
| 267 | |
| 268 // Starts the fling animation. Called both as a response to a fling gesture and as via the | |
| 269 // public WebView#flingScroll(int, int) API. | |
| 270 public void flingScroll(int velocityX, int velocityY) { | |
| 271 final int scrollX = mDelegate.getContainerViewScrollX(); | |
| 272 final int scrollY = mDelegate.getContainerViewScrollY(); | |
| 273 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); | |
| 274 final int scrollRangeY = computeMaximumVerticalScrollOffset(); | |
| 275 | |
| 276 mScroller.fling(scrollX, scrollY, velocityX, velocityY, | |
| 277 0, scrollRangeX, 0, scrollRangeY); | |
| 278 mDelegate.invalidate(); | |
| 279 } | 270 } |
| 280 | 271 |
| 281 // Called immediately before the draw to update the scroll offset. | 272 // Called immediately before the draw to update the scroll offset. |
| 282 public void computeScrollAndAbsorbGlow(OverScrollGlow overScrollGlow) { | 273 public void computeScrollAndAbsorbGlow(OverScrollGlow overScrollGlow) { |
| 283 if (!mScroller.computeScrollOffset() && !mWasFlinging) { | 274 if (!mScroller.computeScrollOffset() && !mWasSmoothScrolling) { |
| 284 return; | 275 return; |
| 285 } | 276 } |
| 286 mWasFlinging = false; | 277 mWasSmoothScrolling = false; |
| 287 | 278 |
| 288 final int oldX = mDelegate.getContainerViewScrollX(); | 279 final int oldX = mDelegate.getContainerViewScrollX(); |
| 289 final int oldY = mDelegate.getContainerViewScrollY(); | 280 final int oldY = mDelegate.getContainerViewScrollY(); |
| 290 int x = mScroller.getCurrX(); | 281 int x = mScroller.getCurrX(); |
| 291 int y = mScroller.getCurrY(); | 282 int y = mScroller.getCurrY(); |
| 292 | 283 |
| 293 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); | 284 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); |
| 294 final int scrollRangeY = computeMaximumVerticalScrollOffset(); | 285 final int scrollRangeY = computeMaximumVerticalScrollOffset(); |
| 295 | 286 |
| 296 if (overScrollGlow != null) { | 287 if (overScrollGlow != null) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 316 final int scrollY = mDelegate.getContainerViewScrollY(); | 307 final int scrollY = mDelegate.getContainerViewScrollY(); |
| 317 | 308 |
| 318 x = clampHorizontalScroll(x); | 309 x = clampHorizontalScroll(x); |
| 319 y = clampVerticalScroll(y); | 310 y = clampVerticalScroll(y); |
| 320 | 311 |
| 321 int dx = x - scrollX; | 312 int dx = x - scrollX; |
| 322 int dy = y - scrollY; | 313 int dy = y - scrollY; |
| 323 | 314 |
| 324 if (dx == 0 && dy == 0) return false; | 315 if (dx == 0 && dy == 0) return false; |
| 325 | 316 |
| 317 mIsAnimatingScroll = true; | |
| 318 | |
| 326 mScroller.startScroll(scrollX, scrollY, dx, dy, computeDurationInMilliSe c(dx, dy)); | 319 mScroller.startScroll(scrollX, scrollY, dx, dy, computeDurationInMilliSe c(dx, dy)); |
| 327 mDelegate.invalidate(); | 320 mDelegate.invalidate(); |
| 328 | 321 |
| 329 return true; | 322 return true; |
| 330 } | 323 } |
| 331 | 324 |
| 332 /** | 325 /** |
| 333 * See {@link android.webkit.WebView#pageUp(boolean)} | 326 * See {@link android.webkit.WebView#pageUp(boolean)} |
| 334 */ | 327 */ |
| 335 public boolean pageUp(boolean top) { | 328 public boolean pageUp(boolean top) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 } | 416 } |
| 424 | 417 |
| 425 if (immediate) { | 418 if (immediate) { |
| 426 scrollBy(scrollXDelta, scrollYDelta); | 419 scrollBy(scrollXDelta, scrollYDelta); |
| 427 return true; | 420 return true; |
| 428 } else { | 421 } else { |
| 429 return animateScrollTo(scrollX + scrollXDelta, scrollY + scrollYDelt a); | 422 return animateScrollTo(scrollX + scrollXDelta, scrollY + scrollYDelt a); |
| 430 } | 423 } |
| 431 } | 424 } |
| 432 } | 425 } |
| OLD | NEW |