Changeset 143355 in webkit
- Timestamp:
- Feb 19, 2013 10:42:27 AM (11 years ago)
- Location:
- trunk/Source/WebKit/chromium
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/chromium/ChangeLog
r143347 r143355 1 2013-02-19 Alexandre Elias <aelias@chromium.org> 2 3 [chromium] Fix races in double-tap zoom minimum scale policy 4 https://bugs.webkit.org/show_bug.cgi?id=110183 5 6 Reviewed by Adam Barth. 7 8 Double-tap zoom on Android is supposed to return to minimum scale 9 if no pinch zoom occurred since the last double-tap. Because both 10 pinch zoom and the result of double-tap zoom gets passed in from CC 11 via applyScrollAndScale, this logic was brittle and prone to races 12 depending on when the animation update was received. This patch 13 keeps track of what the target double-tap scale is to make it more 14 robust. 15 16 I also fixed double-tap zoom test mocking to exercise the entire 17 page scale animation flow (our previous way of testing was hiding the 18 raciness), and added a new test case in DivAutoZoomMultipleParamsTest. 19 20 * src/WebViewImpl.cpp: 21 (WebKit::WebViewImpl::WebViewImpl): 22 (WebKit::WebViewImpl::startPageScaleAnimation): 23 (WebKit): 24 (WebKit::WebViewImpl::enableFakeDoubleTapAnimationForTesting): 25 (WebKit::WebViewImpl::computeScaleAndScrollForHitRect): 26 (WebKit::WebViewImpl::animateZoomAroundPoint): 27 (WebKit::WebViewImpl::didCommitLoad): 28 (WebKit::WebViewImpl::applyScrollAndScale): 29 * src/WebViewImpl.h: 30 (WebViewImpl): 31 (WebKit::WebViewImpl::fakeDoubleTapAnimationPendingForTesting): 32 (WebKit::WebViewImpl::fakeDoubleTapTargetPositionForTesting): 33 (WebKit::WebViewImpl::fakeDoubleTapPageScaleFactorForTesting): 34 (WebKit::WebViewImpl::fakeDoubleTapUseAnchorForTesting): 35 * tests/WebFrameTest.cpp: 36 1 37 2013-02-19 Joshua Bell <jsbell@chromium.org> 2 38 -
trunk/Source/WebKit/chromium/src/WebViewImpl.cpp
r142977 r143355 400 400 , m_pageScaleFactorIsSet(false) 401 401 , m_savedPageScaleFactor(0) 402 , m_doubleTapZoomInEffect(false) 403 , m_shouldUseDoubleTapTimeZero(false) 402 , m_doubleTapZoomPageScaleFactor(0) 403 , m_doubleTapZoomPending(false) 404 , m_enableFakeDoubleTapAnimationForTesting(false) 405 , m_fakeDoubleTapPageScaleFactor(0) 406 , m_fakeDoubleTapUseAnchor(false) 404 407 , m_contextMenuAllowed(false) 405 408 , m_doingDragAndDrop(false) … … 857 860 } 858 861 859 voidWebViewImpl::startPageScaleAnimation(const IntPoint& targetPosition, bool useAnchor, float newScale, double durationInSeconds)862 bool WebViewImpl::startPageScaleAnimation(const IntPoint& targetPosition, bool useAnchor, float newScale, double durationInSeconds) 860 863 { 861 864 WebPoint clampedPoint = targetPosition; 862 if (!useAnchor) 865 if (!useAnchor) { 863 866 clampedPoint = clampOffsetAtScale(targetPosition, newScale); 864 if ((!durationInSeconds && !useAnchor) || m_shouldUseDoubleTapTimeZero) { 865 setPageScaleFactor(newScale, clampedPoint); 866 return; 867 } 868 if (!m_layerTreeView) 869 return; 870 871 m_layerTreeView->startPageScaleAnimation(targetPosition, useAnchor, newScale, durationInSeconds); 867 if (!durationInSeconds) { 868 setPageScaleFactor(newScale, clampedPoint); 869 return false; 870 } 871 } 872 if (useAnchor && newScale == pageScaleFactor()) 873 return false; 874 875 if (m_enableFakeDoubleTapAnimationForTesting) { 876 m_fakeDoubleTapTargetPosition = targetPosition; 877 m_fakeDoubleTapUseAnchor = useAnchor; 878 m_fakeDoubleTapPageScaleFactor = newScale; 879 } else { 880 if (!m_layerTreeView) 881 return false; 882 m_layerTreeView->startPageScaleAnimation(targetPosition, useAnchor, newScale, durationInSeconds); 883 } 884 return true; 885 } 886 887 void WebViewImpl::enableFakeDoubleTapAnimationForTesting(bool enable) 888 { 889 m_enableFakeDoubleTapAnimationForTesting = enable; 872 890 } 873 891 #endif … … 1152 1170 1153 1171 return WebRect(newX, source.y, newWidth, source.height); 1154 }1155 1156 void WebViewImpl::shouldUseAnimateDoubleTapTimeZeroForTesting(bool setToZero)1157 {1158 m_shouldUseDoubleTapTimeZero = setToZero;1159 1172 } 1160 1173 … … 1216 1229 } 1217 1230 1218 if (zoomType == DoubleTap && (rect.isEmpty() || scaleUnchanged || m_doubleTapZoomInEffect)) { 1231 bool stillAtPreviousDoubleTapScale = (pageScaleFactor() == m_doubleTapZoomPageScaleFactor 1232 && m_doubleTapZoomPageScaleFactor != m_minimumPageScaleFactor) 1233 || m_doubleTapZoomPending; 1234 if (zoomType == DoubleTap && (rect.isEmpty() || scaleUnchanged || stillAtPreviousDoubleTapScale)) { 1219 1235 // Zoom out to minimum scale. 1220 1236 scale = m_minimumPageScaleFactor; 1221 1237 scroll = WebPoint(hitRect.x, hitRect.y); 1222 1238 isAnchor = true; 1223 m_doubleTapZoomInEffect = false;1224 1239 } else { 1225 if (zoomType == DoubleTap && scale != m_minimumPageScaleFactor)1226 m_doubleTapZoomInEffect = true;1227 else1228 m_doubleTapZoomInEffect = false;1229 1240 // FIXME: If this is being called for auto zoom during find in page, 1230 1241 // then if the user manually zooms in it'd be nice to preserve the … … 1344 1355 1345 1356 bool isDoubleTap = (zoomType == DoubleTap); 1346 double durationInSeconds = (isDoubleTap && !m_shouldUseDoubleTapTimeZero) ? doubleTapZoomAnimationDurationInSeconds : 0; 1347 startPageScaleAnimation(scroll, isAnchor, scale, durationInSeconds); 1357 double durationInSeconds = isDoubleTap ? doubleTapZoomAnimationDurationInSeconds : 0; 1358 bool isAnimating = startPageScaleAnimation(scroll, isAnchor, scale, durationInSeconds); 1359 1360 if (isDoubleTap && isAnimating) { 1361 m_doubleTapZoomPageScaleFactor = scale; 1362 m_doubleTapZoomPending = true; 1363 } 1348 1364 #endif 1349 1365 } … … 3768 3784 #endif 3769 3785 m_observedNewNavigation = false; 3770 if (*isNewNavigation && !isNavigationWithinPage) {3786 if (*isNewNavigation && !isNavigationWithinPage) 3771 3787 m_pageScaleFactorIsSet = false; 3772 m_doubleTapZoomInEffect = false;3773 }3774 3788 3775 3789 // Make sure link highlight from previous page is cleared. … … 4218 4232 4219 4233 setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scrollPoint); 4220 m_doubleTapZoom InEffect= false;4234 m_doubleTapZoomPending = false; 4221 4235 } 4222 4236 } -
trunk/Source/WebKit/chromium/src/WebViewImpl.h
r142913 r143355 403 403 404 404 bool detectContentOnTouch(const WebPoint&); 405 voidstartPageScaleAnimation(const WebCore::IntPoint& targetPosition, bool useAnchor, float newScale, double durationInSeconds);405 bool startPageScaleAnimation(const WebCore::IntPoint& targetPosition, bool useAnchor, float newScale, double durationInSeconds); 406 406 407 407 void numberOfWheelEventHandlersChanged(unsigned); … … 583 583 void animateZoomAroundPoint(const WebCore::IntPoint&, AutoZoomType); 584 584 585 void shouldUseAnimateDoubleTapTimeZeroForTesting(bool); 585 void enableFakeDoubleTapAnimationForTesting(bool); 586 bool fakeDoubleTapAnimationPendingForTesting() const { return m_doubleTapZoomPending; } 587 WebCore::IntPoint fakeDoubleTapTargetPositionForTesting() const { return m_fakeDoubleTapTargetPosition; } 588 float fakeDoubleTapPageScaleFactorForTesting() const { return m_fakeDoubleTapPageScaleFactor; } 589 bool fakeDoubleTapUseAnchorForTesting() const { return m_fakeDoubleTapUseAnchor; } 586 590 587 591 void enterFullScreenForElement(WebCore::Element*); … … 763 767 WebCore::IntSize m_savedScrollOffset; 764 768 765 // Whether the current scale was achieved by zooming in with double tap. 766 bool m_doubleTapZoomInEffect; 769 // The scale moved to by the latest double tap zoom, if any. 770 float m_doubleTapZoomPageScaleFactor; 771 // Have we sent a double-tap zoom and not yet heard back the scale? 772 bool m_doubleTapZoomPending; 767 773 768 774 // Used for testing purposes. 769 bool m_shouldUseDoubleTapTimeZero; 775 bool m_enableFakeDoubleTapAnimationForTesting; 776 WebCore::IntPoint m_fakeDoubleTapTargetPosition; 777 float m_fakeDoubleTapPageScaleFactor; 778 bool m_fakeDoubleTapUseAnchor; 770 779 771 780 bool m_contextMenuAllowed; -
trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp
r143295 r143355 596 596 } 597 597 598 TEST_F(WebFrameTest, DivAutoZoomParamsTest CompositorScaling)598 TEST_F(WebFrameTest, DivAutoZoomParamsTest) 599 599 { 600 600 registerMockedHttpURLLoad("get_scale_for_auto_zoom_into_div_test.html"); … … 657 657 { 658 658 webViewImpl->animateZoomAroundPoint(point, WebViewImpl::DoubleTap); 659 webViewImpl->mainFrameImpl()->frameView()->layout(); 659 EXPECT_TRUE(webViewImpl->fakeDoubleTapAnimationPendingForTesting()); 660 WebCore::IntSize scrollDelta = webViewImpl->fakeDoubleTapTargetPositionForTesting() - webViewImpl->mainFrameImpl()->frameView()->scrollPosition(); 661 float scaleDelta = webViewImpl->fakeDoubleTapPageScaleFactorForTesting() / webViewImpl->pageScaleFactor(); 662 webViewImpl->applyScrollAndScale(scrollDelta, scaleDelta); 660 663 scale = webViewImpl->pageScaleFactor(); 661 664 } 662 665 663 TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest CompositorScaling)666 TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest) 664 667 { 665 668 registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html"); … … 680 683 681 684 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(m_webView); 682 webViewImpl-> shouldUseAnimateDoubleTapTimeZeroForTesting(true);685 webViewImpl->enableFakeDoubleTapAnimationForTesting(true); 683 686 684 687 WebRect topDiv(200, 100, 200, 150); … … 702 705 simulateDoubleTap(webViewImpl, bottomPoint, scale); 703 706 EXPECT_FLOAT_EQ(1, scale); 704 } 705 706 TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTestCompositorScaling) 707 simulateDoubleTap(webViewImpl, bottomPoint, scale); 708 EXPECT_FLOAT_EQ(webViewImpl->minimumPageScaleFactor(), scale); 709 710 // If we didn't yet get an auto-zoom update and a second double-tap arrives, should go back to minimum scale. 711 webViewImpl->applyScrollAndScale(WebSize(), 1.1f); 712 webViewImpl->animateZoomAroundPoint(topPoint, WebViewImpl::DoubleTap); 713 EXPECT_TRUE(webViewImpl->fakeDoubleTapAnimationPendingForTesting()); 714 simulateDoubleTap(webViewImpl, bottomPoint, scale); 715 EXPECT_FLOAT_EQ(webViewImpl->minimumPageScaleFactor(), scale); 716 } 717 718 TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) 707 719 { 708 720 registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html"); … … 720 732 721 733 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(m_webView); 722 webViewImpl-> shouldUseAnimateDoubleTapTimeZeroForTesting(true);734 webViewImpl->enableFakeDoubleTapAnimationForTesting(true); 723 735 724 736 WebRect div(200, 100, 200, 150); … … 769 781 770 782 #if ENABLE(TEXT_AUTOSIZING) 771 TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest CompositorScaling)783 TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) 772 784 { 773 785 registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html"); … … 785 797 786 798 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(m_webView); 787 webViewImpl-> shouldUseAnimateDoubleTapTimeZeroForTesting(true);799 webViewImpl->enableFakeDoubleTapAnimationForTesting(true); 788 800 webViewImpl->page()->settings()->setTextAutosizingFontScaleFactor(textAutosizingFontScaleFactor); 789 801 … … 870 882 871 883 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(m_webView); 872 webViewImpl-> shouldUseAnimateDoubleTapTimeZeroForTesting(true);884 webViewImpl->enableFakeDoubleTapAnimationForTesting(true); 873 885 874 886 WebRect editBoxWithText(200, 200, 250, 20);
Note: See TracChangeset
for help on using the changeset viewer.