diff options
author | jdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-18 03:36:51 +0000 |
---|---|---|
committer | jdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-18 03:36:51 +0000 |
commit | 8bdbd6e62c27ac313dfa856427d2c7f6798725a1 (patch) | |
tree | 24812b40b6f2ab8cd9938d6c1b5c5ff926e22746 /android_webview | |
parent | 84d217f481e9f1c79d054251168f201018feeac8 (diff) | |
download | chromium_src-8bdbd6e62c27ac313dfa856427d2c7f6798725a1.zip chromium_src-8bdbd6e62c27ac313dfa856427d2c7f6798725a1.tar.gz chromium_src-8bdbd6e62c27ac313dfa856427d2c7f6798725a1.tar.bz2 |
[Android WebView] Defer scrolls until provided a valid content size
With the synchronous compositor, valid scroll offsets may be improperly
clamped before the frame swap message provides the view a valid content size.
Allow for deferred application of the view container scroll offset until a valid
content size is received by AwScrollOffsetManager.
BUG=293770
Review URL: https://chromiumcodereview.appspot.com/23480086
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223780 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r-- | android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java | 23 | ||||
-rw-r--r-- | android_webview/javatests/src/org/chromium/android_webview/test/AwScrollOffsetManagerTest.java | 48 |
2 files changed, 71 insertions, 0 deletions
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 1eca5aa..e849520 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java +++ b/android_webview/java/src/org/chromium/android_webview/AwScrollOffsetManager.java @@ -69,6 +69,12 @@ public class AwScrollOffsetManager { private int mDeferredNativeScrollX; private int mDeferredNativeScrollY; + // Whether (and to what value) to update the container view scroll offset after we've received + // a valid content size. + private boolean mApplyDeferredContainerScrollOnValidContentSize; + private int mDeferredContainerScrollX; + private int mDeferredContainerScrollY; + // The velocity of the last recorded fling, private int mLastFlingVelocityX; private int mLastFlingVelocityY; @@ -117,6 +123,12 @@ public class AwScrollOffsetManager { public void setContentSize(int width, int height) { mContentWidth = width; mContentHeight = height; + + if (mApplyDeferredContainerScrollOnValidContentSize && + mContentWidth != 0 && mContentHeight != 0) { + mApplyDeferredContainerScrollOnValidContentSize = false; + scrollContainerViewTo(mDeferredContainerScrollX, mDeferredContainerScrollY); + } } // Called when the physical size of the view changes. @@ -144,6 +156,14 @@ public class AwScrollOffsetManager { // Called by the native side to attempt to scroll the container view. public void scrollContainerViewTo(int x, int y) { + if (mContentWidth == 0 && mContentHeight == 0) { + mApplyDeferredContainerScrollOnValidContentSize = true; + mDeferredContainerScrollX = x; + mDeferredContainerScrollY = y; + return; + } + mApplyDeferredContainerScrollOnValidContentSize = false; + mNativeScrollX = x; mNativeScrollY = y; @@ -235,6 +255,9 @@ public class AwScrollOffsetManager { if (x == mNativeScrollX && y == mNativeScrollY) return; + // Updating the native scroll will override any pending scroll originally sent from native. + mApplyDeferredContainerScrollOnValidContentSize = false; + // The scrollNativeTo call should be a simple store, so it's OK to assume it always // succeeds. mNativeScrollX = x; diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwScrollOffsetManagerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwScrollOffsetManagerTest.java index b692820..176c451 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwScrollOffsetManagerTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwScrollOffsetManagerTest.java @@ -214,6 +214,54 @@ public class AwScrollOffsetManagerTest extends InstrumentationTestCase { assertEquals(0, delegate.getNativeScrollY()); } + + @SmallTest + @Feature({"AndroidWebView"}) + public void testScrollDeferredOnInvalidContentSize() { + TestScrollOffsetManagerDelegate delegate = new TestScrollOffsetManagerDelegate(); + OverScroller scroller = new OverScroller(getInstrumentation().getContext()); + AwScrollOffsetManager offsetManager = new AwScrollOffsetManager(delegate, scroller); + + offsetManager.setContentSize(0, 0); + offsetManager.setContainerViewSize(VIEW_WIDTH, VIEW_HEIGHT); + + final int firstScrollX = MAX_HORIZONTAL_OFFSET + 10; + final int firstScrollY = MAX_VERTICAL_OFFSET + 11; + int expectedCallCount = delegate.getOverScrollCallCount(); + offsetManager.scrollContainerViewTo(firstScrollX, firstScrollY); + assertEquals(expectedCallCount, delegate.getOverScrollCallCount()); + assertEquals(0, delegate.getOverScrollDeltaX() + delegate.getScrollX()); + assertEquals(0, delegate.getOverScrollDeltaY() + delegate.getScrollY()); + + // Repeated scrolls will also be deferred, overwriting any previous deferred scroll offset. + final int secondScrollX = MAX_HORIZONTAL_OFFSET; + final int secondScrollY = MAX_VERTICAL_OFFSET; + offsetManager.scrollContainerViewTo(secondScrollX, secondScrollY); + assertEquals(expectedCallCount, delegate.getOverScrollCallCount()); + assertEquals(0, delegate.getOverScrollDeltaX() + delegate.getScrollX()); + assertEquals(0, delegate.getOverScrollDeltaY() + delegate.getScrollY()); + + // Setting a valid size will release the deferred container scroll offset. + expectedCallCount++; + offsetManager.setContentSize(CONTENT_WIDTH, CONTENT_HEIGHT); + assertEquals(expectedCallCount, delegate.getOverScrollCallCount()); + assertEquals(secondScrollX, delegate.getOverScrollDeltaX() + delegate.getScrollX()); + assertEquals(secondScrollY, delegate.getOverScrollDeltaY() + delegate.getScrollY()); + offsetManager.onContainerViewOverScrolled(secondScrollX, secondScrollY, false, false); + + assertEquals(secondScrollX, delegate.getOverScrollDeltaX()); + assertEquals(secondScrollY, delegate.getOverScrollDeltaY()); + assertEquals(MAX_HORIZONTAL_OFFSET, delegate.getScrollX()); + assertEquals(MAX_VERTICAL_OFFSET, delegate.getScrollY()); + + // Subsequently setting valid content sizes should not release another scroll update. + offsetManager.setContentSize(CONTENT_WIDTH + 10, CONTENT_HEIGHT + 10); + assertEquals(expectedCallCount, delegate.getOverScrollCallCount()); + offsetManager.setContentSize(CONTENT_WIDTH, CONTENT_HEIGHT); + assertEquals(expectedCallCount, delegate.getOverScrollCallCount()); + } + + @SmallTest @Feature({"AndroidWebView"}) public void testDelegateCanOverrideScroll() { |