OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "core/frame/VisualViewport.h" | 5 #include "core/frame/VisualViewport.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/frame/BrowserControls.h" | 8 #include "core/frame/BrowserControls.h" |
9 #include "core/frame/FrameHost.h" | 9 #include "core/frame/FrameHost.h" |
10 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
11 #include "core/frame/LocalFrame.h" | 11 #include "core/frame/LocalFrame.h" |
12 #include "core/html/HTMLBodyElement.h" | 12 #include "core/html/HTMLBodyElement.h" |
13 #include "core/html/HTMLElement.h" | 13 #include "core/html/HTMLElement.h" |
14 #include "core/input/EventHandler.h" | 14 #include "core/input/EventHandler.h" |
15 #include "core/layout/LayoutObject.h" | 15 #include "core/layout/LayoutObject.h" |
16 #include "core/layout/api/LayoutViewItem.h" | 16 #include "core/layout/api/LayoutViewItem.h" |
17 #include "core/layout/compositing/PaintLayerCompositor.h" | 17 #include "core/layout/compositing/PaintLayerCompositor.h" |
18 #include "core/page/Page.h" | 18 #include "core/page/Page.h" |
| 19 #include "core/paint/PaintLayer.h" |
19 #include "platform/PlatformGestureEvent.h" | 20 #include "platform/PlatformGestureEvent.h" |
20 #include "platform/geometry/DoublePoint.h" | 21 #include "platform/geometry/DoublePoint.h" |
21 #include "platform/geometry/DoubleRect.h" | 22 #include "platform/geometry/DoubleRect.h" |
22 #include "platform/graphics/CompositorElementId.h" | 23 #include "platform/graphics/CompositorElementId.h" |
23 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" | 24 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" |
24 #include "platform/testing/URLTestHelpers.h" | 25 #include "platform/testing/URLTestHelpers.h" |
25 #include "public/platform/Platform.h" | 26 #include "public/platform/Platform.h" |
26 #include "public/platform/WebCachePolicy.h" | 27 #include "public/platform/WebCachePolicy.h" |
27 #include "public/platform/WebLayerTreeView.h" | 28 #include "public/platform/WebLayerTreeView.h" |
28 #include "public/platform/WebURLLoaderMockFactory.h" | 29 #include "public/platform/WebURLLoaderMockFactory.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \ | 90 EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \ |
90 EXPECT_FLOAT_EQ((expected).width(), (actual).width()); \ | 91 EXPECT_FLOAT_EQ((expected).width(), (actual).width()); \ |
91 EXPECT_FLOAT_EQ((expected).height(), (actual).height()); \ | 92 EXPECT_FLOAT_EQ((expected).height(), (actual).height()); \ |
92 } while (false) | 93 } while (false) |
93 | 94 |
94 using namespace blink; | 95 using namespace blink; |
95 | 96 |
96 using ::testing::_; | 97 using ::testing::_; |
97 using ::testing::PrintToString; | 98 using ::testing::PrintToString; |
98 using ::testing::Mock; | 99 using ::testing::Mock; |
| 100 using blink::URLTestHelpers::toKURL; |
99 | 101 |
100 namespace blink { | 102 namespace blink { |
101 ::std::ostream& operator<<(::std::ostream& os, const WebContextMenuData& data) { | 103 ::std::ostream& operator<<(::std::ostream& os, const WebContextMenuData& data) { |
102 return os << "Context menu location: [" << data.mousePosition.x << ", " | 104 return os << "Context menu location: [" << data.mousePosition.x << ", " |
103 << data.mousePosition.y << "]"; | 105 << data.mousePosition.y << "]"; |
104 } | 106 } |
105 } | 107 } |
106 | 108 |
107 namespace { | 109 namespace { |
108 | 110 |
(...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2073 | 2075 |
2074 webViewImpl()->resize(IntSize(600, 800)); | 2076 webViewImpl()->resize(IntSize(600, 800)); |
2075 | 2077 |
2076 EXPECT_SIZE_EQ(ScrollOffset(), | 2078 EXPECT_SIZE_EQ(ScrollOffset(), |
2077 frameView.layoutViewportScrollableArea()->scrollOffset()); | 2079 frameView.layoutViewportScrollableArea()->scrollOffset()); |
2078 EXPECT_EQ(600, scroller->scrollTop()); | 2080 EXPECT_EQ(600, scroller->scrollTop()); |
2079 | 2081 |
2080 RuntimeEnabledFeatures::setSetRootScrollerEnabled(wasRootScrollerEnabled); | 2082 RuntimeEnabledFeatures::setSetRootScrollerEnabled(wasRootScrollerEnabled); |
2081 } | 2083 } |
2082 | 2084 |
| 2085 static void configureAndroidCompositing(WebSettings* settings) { |
| 2086 settings->setAcceleratedCompositingEnabled(true); |
| 2087 settings->setPreferCompositingToLCDTextEnabled(true); |
| 2088 settings->setViewportMetaEnabled(true); |
| 2089 settings->setViewportEnabled(true); |
| 2090 settings->setMainFrameResizesAreOrientationChanges(true); |
| 2091 settings->setShrinksViewportContentToFit(true); |
| 2092 } |
| 2093 |
| 2094 // Make sure a composited background-attachment:fixed background gets resized |
| 2095 // when using inert (non-layout affecting) browser controls. |
| 2096 TEST_P(VisualViewportTest, ResizeCompositedAndFixedBackground) { |
| 2097 bool originalInertTopControls = |
| 2098 RuntimeEnabledFeatures::inertTopControlsEnabled(); |
| 2099 RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
| 2100 |
| 2101 std::unique_ptr<FrameTestHelpers::TestWebViewClient> |
| 2102 fakeCompositingWebViewClient = |
| 2103 wrapUnique(new FrameTestHelpers::TestWebViewClient()); |
| 2104 FrameTestHelpers::WebViewHelper webViewHelper; |
| 2105 WebViewImpl* webViewImpl = webViewHelper.initialize( |
| 2106 true, nullptr, fakeCompositingWebViewClient.get(), nullptr, |
| 2107 &configureAndroidCompositing); |
| 2108 |
| 2109 int pageWidth = 640; |
| 2110 int pageHeight = 480; |
| 2111 float browserControlsHeight = 50.0f; |
| 2112 int smallestHeight = pageHeight - browserControlsHeight; |
| 2113 |
| 2114 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, pageHeight), |
| 2115 browserControlsHeight, false); |
| 2116 |
| 2117 URLTestHelpers::registerMockedURLLoad(toKURL("http://example.com/foo.png"), |
| 2118 "white-1x1.png"); |
| 2119 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/"); |
| 2120 FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), |
| 2121 "<!DOCTYPE html>" |
| 2122 "<style>" |
| 2123 " body {" |
| 2124 " background: url('foo.png');" |
| 2125 " background-attachment: fixed;" |
| 2126 " background-size: cover;" |
| 2127 " background-repeat: no-repeat;" |
| 2128 " }" |
| 2129 " div { height:1000px; width: 200px; }" |
| 2130 "</style>" |
| 2131 "<div></div>", |
| 2132 baseURL); |
| 2133 webViewImpl->updateAllLifecyclePhases(); |
| 2134 |
| 2135 Document* document = |
| 2136 toLocalFrame(webViewImpl->page()->mainFrame())->document(); |
| 2137 PaintLayerCompositor* compositor = document->layoutView()->compositor(); |
| 2138 |
| 2139 ASSERT_TRUE(compositor->needsFixedRootBackgroundLayer( |
| 2140 document->layoutView()->layer())); |
| 2141 ASSERT_TRUE(compositor->fixedRootBackgroundLayer()); |
| 2142 |
| 2143 ASSERT_EQ(pageWidth, compositor->fixedRootBackgroundLayer()->size().width()); |
| 2144 ASSERT_EQ(pageHeight, |
| 2145 compositor->fixedRootBackgroundLayer()->size().height()); |
| 2146 ASSERT_EQ(pageWidth, document->view()->layoutSize().width()); |
| 2147 ASSERT_EQ(smallestHeight, document->view()->layoutSize().height()); |
| 2148 |
| 2149 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, smallestHeight), |
| 2150 browserControlsHeight, true); |
| 2151 |
| 2152 // The layout size should not have changed. |
| 2153 ASSERT_EQ(pageWidth, document->view()->layoutSize().width()); |
| 2154 ASSERT_EQ(smallestHeight, document->view()->layoutSize().height()); |
| 2155 |
| 2156 // The background layer's size should have changed though. |
| 2157 EXPECT_EQ(pageWidth, compositor->fixedRootBackgroundLayer()->size().width()); |
| 2158 EXPECT_EQ(smallestHeight, |
| 2159 compositor->fixedRootBackgroundLayer()->size().height()); |
| 2160 |
| 2161 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, pageHeight), |
| 2162 browserControlsHeight, true); |
| 2163 |
| 2164 // The background layer's size should change again. |
| 2165 EXPECT_EQ(pageWidth, compositor->fixedRootBackgroundLayer()->size().width()); |
| 2166 EXPECT_EQ(pageHeight, |
| 2167 compositor->fixedRootBackgroundLayer()->size().height()); |
| 2168 |
| 2169 RuntimeEnabledFeatures::setInertTopControlsEnabled(originalInertTopControls); |
| 2170 } |
| 2171 |
| 2172 static void configureAndroidNonCompositing(WebSettings* settings) { |
| 2173 settings->setAcceleratedCompositingEnabled(true); |
| 2174 settings->setPreferCompositingToLCDTextEnabled(false); |
| 2175 settings->setViewportMetaEnabled(true); |
| 2176 settings->setViewportEnabled(true); |
| 2177 settings->setMainFrameResizesAreOrientationChanges(true); |
| 2178 settings->setShrinksViewportContentToFit(true); |
| 2179 } |
| 2180 |
| 2181 // Make sure a non-composited background-attachment:fixed background gets |
| 2182 // resized when using inert (non-layout affecting) browser controls. |
| 2183 TEST_P(VisualViewportTest, ResizeNonCompositedAndFixedBackground) { |
| 2184 bool originalInertTopControls = |
| 2185 RuntimeEnabledFeatures::inertTopControlsEnabled(); |
| 2186 RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
| 2187 |
| 2188 FrameTestHelpers::WebViewHelper webViewHelper; |
| 2189 WebViewImpl* webViewImpl = webViewHelper.initialize( |
| 2190 true, nullptr, nullptr, nullptr, &configureAndroidNonCompositing); |
| 2191 |
| 2192 int pageWidth = 640; |
| 2193 int pageHeight = 480; |
| 2194 float browserControlsHeight = 50.0f; |
| 2195 int smallestHeight = pageHeight - browserControlsHeight; |
| 2196 |
| 2197 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, pageHeight), |
| 2198 browserControlsHeight, false); |
| 2199 |
| 2200 URLTestHelpers::registerMockedURLLoad(toKURL("http://example.com/foo.png"), |
| 2201 "white-1x1.png"); |
| 2202 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/"); |
| 2203 FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), |
| 2204 "<!DOCTYPE html>" |
| 2205 "<style>" |
| 2206 " body {" |
| 2207 " margin: 0px;" |
| 2208 " background: url('foo.png');" |
| 2209 " background-attachment: fixed;" |
| 2210 " background-size: cover;" |
| 2211 " background-repeat: no-repeat;" |
| 2212 " }" |
| 2213 " div { height:1000px; width: 200px; }" |
| 2214 "</style>" |
| 2215 "<div></div>", |
| 2216 baseURL); |
| 2217 webViewImpl->updateAllLifecyclePhases(); |
| 2218 |
| 2219 Document* document = |
| 2220 toLocalFrame(webViewImpl->page()->mainFrame())->document(); |
| 2221 PaintLayerCompositor* compositor = document->layoutView()->compositor(); |
| 2222 |
| 2223 ASSERT_FALSE(compositor->needsFixedRootBackgroundLayer( |
| 2224 document->layoutView()->layer())); |
| 2225 ASSERT_FALSE(compositor->fixedRootBackgroundLayer()); |
| 2226 |
| 2227 document->view()->setTracksPaintInvalidations(true); |
| 2228 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, smallestHeight), |
| 2229 browserControlsHeight, true); |
| 2230 |
| 2231 // The layout size should not have changed. |
| 2232 ASSERT_EQ(pageWidth, document->view()->layoutSize().width()); |
| 2233 ASSERT_EQ(smallestHeight, document->view()->layoutSize().height()); |
| 2234 |
| 2235 const RasterInvalidationTracking* invalidationTracking = |
| 2236 document->layoutView() |
| 2237 ->layer() |
| 2238 ->graphicsLayerBacking() |
| 2239 ->getRasterInvalidationTracking(); |
| 2240 // If no invalidations occured, this will be a nullptr. |
| 2241 ASSERT_TRUE(invalidationTracking); |
| 2242 |
| 2243 const auto* rasterInvalidations = |
| 2244 &invalidationTracking->trackedRasterInvalidations; |
| 2245 |
| 2246 bool rootLayerScrolling = GetParam(); |
| 2247 |
| 2248 // Without root-layer-scrolling, the LayoutView is the size of the document |
| 2249 // content so invalidating it for background-attachment: fixed |
| 2250 // overinvalidates as we should only need to invalidate the viewport size. |
| 2251 int expectedHeight = rootLayerScrolling ? 430 : 1000; |
| 2252 |
| 2253 // The entire viewport should have been invalidated. |
| 2254 EXPECT_EQ(1u, rasterInvalidations->size()); |
| 2255 EXPECT_EQ(IntRect(0, 0, 640, expectedHeight), (*rasterInvalidations)[0].rect); |
| 2256 document->view()->setTracksPaintInvalidations(false); |
| 2257 |
| 2258 invalidationTracking = document->layoutView() |
| 2259 ->layer() |
| 2260 ->graphicsLayerBacking() |
| 2261 ->getRasterInvalidationTracking(); |
| 2262 ASSERT_FALSE(invalidationTracking); |
| 2263 |
| 2264 document->view()->setTracksPaintInvalidations(true); |
| 2265 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, pageHeight), |
| 2266 browserControlsHeight, true); |
| 2267 |
| 2268 invalidationTracking = document->layoutView() |
| 2269 ->layer() |
| 2270 ->graphicsLayerBacking() |
| 2271 ->getRasterInvalidationTracking(); |
| 2272 ASSERT_TRUE(invalidationTracking); |
| 2273 rasterInvalidations = &invalidationTracking->trackedRasterInvalidations; |
| 2274 |
| 2275 // Once again, the entire page should have been invalidated. |
| 2276 expectedHeight = rootLayerScrolling ? 480 : 1000; |
| 2277 EXPECT_EQ(1u, rasterInvalidations->size()); |
| 2278 EXPECT_EQ(IntRect(0, 0, 640, expectedHeight), (*rasterInvalidations)[0].rect); |
| 2279 |
| 2280 document->view()->setTracksPaintInvalidations(false); |
| 2281 RuntimeEnabledFeatures::setInertTopControlsEnabled(originalInertTopControls); |
| 2282 } |
| 2283 |
| 2284 // Make sure a browser control resize with background-attachment:not-fixed |
| 2285 // background doesn't cause invalidation or layout. |
| 2286 TEST_P(VisualViewportTest, ResizeNonFixedBackgroundNoLayoutOrInvalidation) { |
| 2287 bool originalInertTopControls = |
| 2288 RuntimeEnabledFeatures::inertTopControlsEnabled(); |
| 2289 RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
| 2290 |
| 2291 std::unique_ptr<FrameTestHelpers::TestWebViewClient> |
| 2292 fakeCompositingWebViewClient = |
| 2293 wrapUnique(new FrameTestHelpers::TestWebViewClient()); |
| 2294 FrameTestHelpers::WebViewHelper webViewHelper; |
| 2295 WebViewImpl* webViewImpl = webViewHelper.initialize( |
| 2296 true, nullptr, fakeCompositingWebViewClient.get(), nullptr, |
| 2297 &configureAndroidCompositing); |
| 2298 |
| 2299 int pageWidth = 640; |
| 2300 int pageHeight = 480; |
| 2301 float browserControlsHeight = 50.0f; |
| 2302 int smallestHeight = pageHeight - browserControlsHeight; |
| 2303 |
| 2304 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, pageHeight), |
| 2305 browserControlsHeight, false); |
| 2306 |
| 2307 URLTestHelpers::registerMockedURLLoad(toKURL("http://example.com/foo.png"), |
| 2308 "white-1x1.png"); |
| 2309 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/"); |
| 2310 // This time the background is the default attachment. |
| 2311 FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), |
| 2312 "<!DOCTYPE html>" |
| 2313 "<style>" |
| 2314 " body {" |
| 2315 " margin: 0px;" |
| 2316 " background: url('foo.png');" |
| 2317 " background-size: cover;" |
| 2318 " background-repeat: no-repeat;" |
| 2319 " }" |
| 2320 " div { height:1000px; width: 200px; }" |
| 2321 "</style>" |
| 2322 "<div></div>", |
| 2323 baseURL); |
| 2324 webViewImpl->updateAllLifecyclePhases(); |
| 2325 |
| 2326 Document* document = |
| 2327 toLocalFrame(webViewImpl->page()->mainFrame())->document(); |
| 2328 |
| 2329 // A resize will do a layout synchronously so manually check that we don't |
| 2330 // setNeedsLayout from viewportSizeChanged. |
| 2331 document->view()->viewportSizeChanged(false, true); |
| 2332 unsigned needsLayoutObjects = 0; |
| 2333 unsigned totalObjects = 0; |
| 2334 bool isSubtree = false; |
| 2335 EXPECT_FALSE(document->view()->needsLayout()); |
| 2336 document->view()->countObjectsNeedingLayout(needsLayoutObjects, totalObjects, |
| 2337 isSubtree); |
| 2338 EXPECT_EQ(0u, needsLayoutObjects); |
| 2339 |
| 2340 // Do a real resize to check for invalidations. |
| 2341 document->view()->setTracksPaintInvalidations(true); |
| 2342 webViewImpl->resizeWithBrowserControls(WebSize(pageWidth, smallestHeight), |
| 2343 browserControlsHeight, true); |
| 2344 |
| 2345 // The layout size should not have changed. |
| 2346 ASSERT_EQ(pageWidth, document->view()->layoutSize().width()); |
| 2347 ASSERT_EQ(smallestHeight, document->view()->layoutSize().height()); |
| 2348 |
| 2349 const RasterInvalidationTracking* invalidationTracking = |
| 2350 document->layoutView() |
| 2351 ->layer() |
| 2352 ->graphicsLayerBacking() |
| 2353 ->getRasterInvalidationTracking(); |
| 2354 |
| 2355 // No invalidations should have occured in FrameView scrolling. If |
| 2356 // root-layer-scrolls is on, an invalidation is necessary for now, see the |
| 2357 // comment and TODO in FrameView::viewportSizeChanged. |
| 2358 // http://crbug.com/568847. |
| 2359 bool rootLayerScrolling = GetParam(); |
| 2360 if (rootLayerScrolling) |
| 2361 EXPECT_TRUE(invalidationTracking); |
| 2362 else |
| 2363 EXPECT_FALSE(invalidationTracking); |
| 2364 |
| 2365 document->view()->setTracksPaintInvalidations(false); |
| 2366 RuntimeEnabledFeatures::setInertTopControlsEnabled(originalInertTopControls); |
| 2367 } |
| 2368 |
2083 } // namespace | 2369 } // namespace |
OLD | NEW |