diff --git a/DEPS b/DEPS index 39cec83..4e5f1d12 100644 --- a/DEPS +++ b/DEPS
@@ -59,11 +59,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'a8d415c24f2215897622715f93b967a0763c9263', + 'skia_revision': '90dabec62f9baa912d5936254ad6e73f20e0a973', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '7382dc2601c2f6793411579e9211397acd347deb', + 'v8_revision': '32a6cc20a29b89674d5892ee75497d5977c887d2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -71,7 +71,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '722bfb51d59188ee086839b69e00296b2d5d2da3', + 'angle_revision': 'b8ee9dd35e6033293bd0644a010a5e3e2e7b484b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -79,11 +79,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'e2febff0f79aab45451c5d20e59e3b55040f2fa6', + 'swiftshader_revision': '3e2b10936c5304477fdadfa233671738008fe154', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '8aa3002c673f36909560575514b9a9474e5e66bf', + 'pdfium_revision': '994f20cfb76f4902491a94c4ef61f55705fc124d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -115,7 +115,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'd62be5b8d84501b0af45ea0b1014bcf88bc448f1', + 'catapult_revision': '14715602e04a3a6e6cf79342f45d2f2595cce0f4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -261,7 +261,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '61a24395b7c197fe15a21758bd1bbbaf05d4bd49', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '370839fe525e79fe84ceb71147661953e632fabd', 'condition': 'checkout_linux', }, @@ -289,7 +289,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '7d1c484ecd93e94c5258dc330602ac37c5efab44', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ab816ce8ff61f206ea9d3734b6736fea9fa07aa5', # DevTools node modules. Used on Linux buildbots only. 'src/third_party/devtools-node-modules': { @@ -605,7 +605,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '34842fa3c36988840c89f5bc6a68503175acf7d9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'a7678667fc726979ca27d2429689d5735cca425d', # commit position 20237 + Var('webrtc_git') + '/src.git' + '@' + '1b8205f9ee8fda98ddb66c464c7e4d8bfa49cf50', # commit position 20237 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/render_thread_manager.cc b/android_webview/browser/render_thread_manager.cc index 9fa7bef1d..a79cb4a 100644 --- a/android_webview/browser/render_thread_manager.cc +++ b/android_webview/browser/render_thread_manager.cc
@@ -318,7 +318,8 @@ ScopedAppGLStateRestore state_restore( draw_info->mode == AwDrawGLInfo::kModeDraw ? ScopedAppGLStateRestore::MODE_DRAW - : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); + : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT, + draw_info->mode < 3 /* save_restore */); ScopedAllowGL allow_gl; if (!hardware_renderer_ && draw_info->mode == AwDrawGLInfo::kModeDraw && !IsInsideHardwareRelease() && HasFrameForHardwareRendererOnRT()) {
diff --git a/android_webview/browser/scoped_app_gl_state_restore.cc b/android_webview/browser/scoped_app_gl_state_restore.cc index 27f3eb4c..696a946 100644 --- a/android_webview/browser/scoped_app_gl_state_restore.cc +++ b/android_webview/browser/scoped_app_gl_state_restore.cc
@@ -75,14 +75,19 @@ class ScopedAppGLStateRestoreImpl { public: - explicit ScopedAppGLStateRestoreImpl(ScopedAppGLStateRestore::CallMode mode); + ScopedAppGLStateRestoreImpl(ScopedAppGLStateRestore::CallMode mode, + bool save_restore); ~ScopedAppGLStateRestoreImpl(); StencilState stencil_state() const { return stencil_state_; } GLint framebuffer_binding_ext() const { return framebuffer_binding_ext_; } private: + void SaveHWUIState(); + void RestoreHWUIState(); + const ScopedAppGLStateRestore::CallMode mode_; + const bool save_restore_; GLint pack_alignment_; GLint unpack_alignment_; @@ -158,13 +163,51 @@ }; ScopedAppGLStateRestoreImpl::ScopedAppGLStateRestoreImpl( - ScopedAppGLStateRestore::CallMode mode) - : mode_(mode) { + ScopedAppGLStateRestore::CallMode mode, + bool save_restore) + : mode_(mode), save_restore_(save_restore) { TRACE_EVENT0("android_webview", "AppGLStateSave"); MakeAppContextCurrent(); ClearGLErrors(true, "Incoming GLError"); + glGetBooleanv(GL_STENCIL_TEST, &stencil_state_.stencil_test_enabled); + glGetIntegerv(GL_STENCIL_FUNC, &stencil_state_.stencil_front_func); + glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_state_.stencil_front_mask); + glGetIntegerv(GL_STENCIL_REF, &stencil_state_.stencil_front_ref); + glGetIntegerv(GL_STENCIL_BACK_FUNC, &stencil_state_.stencil_back_func); + glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &stencil_state_.stencil_back_mask); + glGetIntegerv(GL_STENCIL_BACK_REF, &stencil_state_.stencil_back_ref); + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencil_state_.stencil_clear); + glGetIntegerv(GL_STENCIL_WRITEMASK, &stencil_state_.stencil_front_writemask); + glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, + &stencil_state_.stencil_back_writemask); + glGetIntegerv(GL_STENCIL_FAIL, &stencil_state_.stencil_front_fail_op); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, + &stencil_state_.stencil_front_z_fail_op); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, + &stencil_state_.stencil_front_z_pass_op); + glGetIntegerv(GL_STENCIL_BACK_FAIL, &stencil_state_.stencil_back_fail_op); + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, + &stencil_state_.stencil_back_z_fail_op); + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, + &stencil_state_.stencil_back_z_pass_op); + + glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer_binding_ext_); + + if (save_restore_) { + SaveHWUIState(); + } + + if (mode_ == ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT) { + // Android 5.0.0 specific qualcomm workaround. See crbug.com/434570. + glBindRenderbufferEXT(GL_RENDERBUFFER, 0); + } + + DCHECK(ClearGLErrors(false, NULL)); +} + +void ScopedAppGLStateRestoreImpl::SaveHWUIState() { if (!g_globals_initialized) { g_globals_initialized = true; @@ -183,7 +226,7 @@ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_); - switch(mode_) { + switch (mode_) { case ScopedAppGLStateRestore::MODE_DRAW: DCHECK_EQ(0, vertex_array_buffer_binding_); DCHECK_EQ(0, index_array_buffer_binding_); @@ -229,30 +272,6 @@ glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &enable_sample_alpha_to_coverage_); glGetBooleanv(GL_SAMPLE_COVERAGE, &enable_sample_coverage_); - glGetBooleanv(GL_STENCIL_TEST, &stencil_state_.stencil_test_enabled); - glGetIntegerv(GL_STENCIL_FUNC, &stencil_state_.stencil_front_func); - glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_state_.stencil_front_mask); - glGetIntegerv(GL_STENCIL_REF, &stencil_state_.stencil_front_ref); - glGetIntegerv(GL_STENCIL_BACK_FUNC, &stencil_state_.stencil_back_func); - glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &stencil_state_.stencil_back_mask); - glGetIntegerv(GL_STENCIL_BACK_REF, &stencil_state_.stencil_back_ref); - glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencil_state_.stencil_clear); - glGetIntegerv(GL_STENCIL_WRITEMASK, &stencil_state_.stencil_front_writemask); - glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, - &stencil_state_.stencil_back_writemask); - glGetIntegerv(GL_STENCIL_FAIL, &stencil_state_.stencil_front_fail_op); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, - &stencil_state_.stencil_front_z_fail_op); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, - &stencil_state_.stencil_front_z_pass_op); - glGetIntegerv(GL_STENCIL_BACK_FAIL, &stencil_state_.stencil_back_fail_op); - glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, - &stencil_state_.stencil_back_z_fail_op); - glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, - &stencil_state_.stencil_back_z_pass_op); - - glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer_binding_ext_); - glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_); texture_bindings_.resize(g_gl_max_texture_units); @@ -290,21 +309,21 @@ glGetVertexAttribfv( i, GL_CURRENT_VERTEX_ATTRIB, vertex_attrib_[i].current_vertex_attrib); } - - if (mode_ == ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT) { - // Android 5.0.0 specific qualcomm workaround. See crbug.com/434570. - glBindRenderbufferEXT(GL_RENDERBUFFER, 0); - } - - DCHECK(ClearGLErrors(false, NULL)); } ScopedAppGLStateRestoreImpl::~ScopedAppGLStateRestoreImpl() { TRACE_EVENT0("android_webview", "AppGLStateRestore"); MakeAppContextCurrent(); + if (save_restore_) { + DCHECK(ClearGLErrors(false, NULL)); + RestoreHWUIState(); + } - DCHECK(ClearGLErrors(false, NULL)); + // Do not leak GLError out of chromium. + ClearGLErrors(true, "Chromium GLError"); +} +void ScopedAppGLStateRestoreImpl::RestoreHWUIState() { glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); @@ -412,9 +431,6 @@ glStencilOpSeparate(GL_BACK, stencil_state_.stencil_back_fail_op, stencil_state_.stencil_back_z_fail_op, stencil_state_.stencil_back_z_pass_op); - - // Do not leak GLError out of chromium. - ClearGLErrors(true, "Chromium GLError"); } } // namespace internal @@ -425,8 +441,9 @@ return g_current_instance; } -ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) - : impl_(new internal::ScopedAppGLStateRestoreImpl(mode)) { +ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode, + bool save_restore) + : impl_(new internal::ScopedAppGLStateRestoreImpl(mode, save_restore)) { DCHECK(!g_current_instance); g_current_instance = this; }
diff --git a/android_webview/browser/scoped_app_gl_state_restore.h b/android_webview/browser/scoped_app_gl_state_restore.h index 48ec461..6635a5fa 100644 --- a/android_webview/browser/scoped_app_gl_state_restore.h +++ b/android_webview/browser/scoped_app_gl_state_restore.h
@@ -45,7 +45,7 @@ static ScopedAppGLStateRestore* Current(); - explicit ScopedAppGLStateRestore(CallMode mode); + ScopedAppGLStateRestore(CallMode mode, bool save_restore); ~ScopedAppGLStateRestore(); StencilState stencil_state() const;
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc index 1565c24e..4e462d6 100644 --- a/android_webview/common/crash_reporter/crash_keys.cc +++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -123,6 +123,9 @@ // Accessibility keys. Temporary for http://crbug.com/765490. {"ax_tree_error", kSmallSize}, {"ax_tree_update", kMediumSize}, + + // Temporary for crbug.com/756624. + {"break_iterator", kSmallSize}, }; // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/android_webview/public/browser/draw_gl.h b/android_webview/public/browser/draw_gl.h index 919669518..175d291e 100644 --- a/android_webview/public/browser/draw_gl.h +++ b/android_webview/public/browser/draw_gl.h
@@ -9,7 +9,6 @@ extern "C" { #endif - // 1 is L/L MR1 // // 2 starts at M, and added an imperfect workaround for complex clipping by @@ -20,7 +19,12 @@ // This is a temporary workaround for a lack of WebView support for stencil/ // shader based round rect clipping, and should be removed when webview is // capable of supporting these clips internally when drawing. -static const int kAwDrawGLInfoVersion = 2; +// +// 3 starts during development of P, when android defaults from HWUI to skia as +// the GL renderer. Skia already maintains and restores its GL state, so there +// is no need for WebView to restore this state. Skia also no longer promises +// GL state on entering draw, such as no vertex array buffer binding. +static const int kAwDrawGLInfoVersion = 3; // Holds the information required to trigger an OpenGL drawing operation. struct AwDrawGLInfo {
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java index 26d99e0..f4f1ed3 100644 --- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java +++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
@@ -343,7 +343,7 @@ @TargetApi(Build.VERSION_CODES.M) private boolean canGrant(String webkitPermission) { String androidPermission = sPermissions.get(webkitPermission); - if (androidPermission == NO_ANDROID_PERMISSION) { + if (androidPermission.equals(NO_ANDROID_PERMISSION)) { return true; } return PackageManager.PERMISSION_GRANTED == checkSelfPermission(androidPermission);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 5aae07f..1916aa4 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -196,6 +196,9 @@ "host/ash_window_tree_host.cc", "host/ash_window_tree_host.h", "host/ash_window_tree_host_init_params.h", + "host/ash_window_tree_host_mirroring_delegate.h", + "host/ash_window_tree_host_mirroring_unified.cc", + "host/ash_window_tree_host_mirroring_unified.h", "host/ash_window_tree_host_platform.cc", "host/ash_window_tree_host_platform.h", "host/ash_window_tree_host_unified.cc",
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc index b7c7ec7..6d5e21f9 100644 --- a/ash/display/cursor_window_controller.cc +++ b/ash/display/cursor_window_controller.cc
@@ -150,13 +150,16 @@ if (display.is_valid()) SetDisplay(display); } else { - aura::Window* mirror_window = Shell::Get() - ->window_tree_host_manager() - ->mirror_window_controller() - ->GetWindow(); - if (mirror_window) - display_ = display::Screen::GetScreen()->GetPrimaryDisplay(); - SetContainer(mirror_window); + aura::Window::Windows mirror_windows = Shell::Get() + ->window_tree_host_manager() + ->mirror_window_controller() + ->GetAllRootWindows(); + if (mirror_windows.empty()) { + SetContainer(nullptr); + return; + } + display_ = display::Screen::GetScreen()->GetPrimaryDisplay(); + SetContainer(mirror_windows[0]); } // Updates the hot point based on the current display. UpdateCursorImage();
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index f09f1063..0a8705e 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc
@@ -138,6 +138,22 @@ root_window_destroyed_ = true; } + // Returns true if there exists any overlapping mirroring displays. + bool OverlappingMirroringDisplaysExist() { + const auto& mirroring_displays = + display_manager()->software_mirroring_display_list(); + for (size_t i = 0; i < mirroring_displays.size() - 1; ++i) { + for (size_t j = i + 1; j < mirroring_displays.size(); ++j) { + const gfx::Rect& bounds_1 = mirroring_displays[i].bounds(); + const gfx::Rect& bounds_2 = mirroring_displays[j].bounds(); + if (bounds_1.Intersects(bounds_2)) + return true; + } + } + + return false; + } + private: vector<display::Display> changed_; vector<display::Display> added_; @@ -1350,7 +1366,7 @@ EXPECT_EQ("0,0 500x500", GetDisplayForId(internal_display_id).bounds().ToString()); EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_EQ(11U, display_manager()->mirroring_display_id()); + EXPECT_EQ(11U, display_manager()->GetMirroringDstDisplayIdList()[0]); EXPECT_TRUE(display_manager()->IsInMirrorMode()); // Test display name. @@ -2147,13 +2163,13 @@ void OnDisplayAdded(const display::Display& new_display) override { // Mirror window should already be delete before restoring // the external display. - EXPECT_FALSE(test_api.GetHost()); + EXPECT_TRUE(test_api.GetHosts().empty()); changed_ = true; } void OnDisplayRemoved(const display::Display& old_display) override { // Mirror window should not be created until the external display // is removed. - EXPECT_FALSE(test_api.GetHost()); + EXPECT_TRUE(test_api.GetHosts().empty()); changed_ = true; } @@ -2174,7 +2190,7 @@ UpdateDisplay("300x400,400x500"); MirrorWindowTestApi test_api; - EXPECT_EQ(nullptr, test_api.GetHost()); + EXPECT_TRUE(test_api.GetHosts().empty()); TestDisplayObserver display_observer; display::Screen::GetScreen()->AddObserver(&display_observer); @@ -2187,15 +2203,15 @@ EXPECT_EQ( "0,0 300x400", display::Screen::GetScreen()->GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("400x500", - test_api.GetHost()->GetBoundsInPixels().size().ToString()); - EXPECT_EQ("300x400", - test_api.GetHost()->window()->bounds().size().ToString()); + std::vector<aura::WindowTreeHost*> hosts = test_api.GetHosts(); + EXPECT_EQ(1U, hosts.size()); + EXPECT_EQ("400x500", hosts[0]->GetBoundsInPixels().size().ToString()); + EXPECT_EQ("300x400", hosts[0]->window()->bounds().size().ToString()); EXPECT_TRUE(display_manager()->IsInMirrorMode()); display_manager()->SetMirrorMode(false); EXPECT_TRUE(display_observer.changed_and_reset()); - EXPECT_EQ(nullptr, test_api.GetHost()); + EXPECT_TRUE(test_api.GetHosts().empty()); EXPECT_EQ(2U, display_manager()->GetNumDisplays()); EXPECT_FALSE(display_manager()->IsInMirrorMode()); @@ -2207,28 +2223,28 @@ UpdateDisplay("300x400@0.5,400x500"); EXPECT_FALSE(display_observer.changed_and_reset()); EXPECT_EQ("300x400", - test_api.GetHost()->window()->bounds().size().ToString()); + test_api.GetHosts()[0]->window()->bounds().size().ToString()); UpdateDisplay("310x410*2,400x500"); EXPECT_FALSE(display_observer.changed_and_reset()); EXPECT_EQ("310x410", - test_api.GetHost()->window()->bounds().size().ToString()); + test_api.GetHosts()[0]->window()->bounds().size().ToString()); UpdateDisplay("320x420/r,400x500"); EXPECT_FALSE(display_observer.changed_and_reset()); EXPECT_EQ("320x420", - test_api.GetHost()->window()->bounds().size().ToString()); + test_api.GetHosts()[0]->window()->bounds().size().ToString()); UpdateDisplay("330x440/r,400x500"); EXPECT_FALSE(display_observer.changed_and_reset()); EXPECT_EQ("330x440", - test_api.GetHost()->window()->bounds().size().ToString()); + test_api.GetHosts()[0]->window()->bounds().size().ToString()); // Overscan insets are ignored. UpdateDisplay("400x600/o,600x800/o"); EXPECT_FALSE(display_observer.changed_and_reset()); EXPECT_EQ("400x600", - test_api.GetHost()->window()->bounds().size().ToString()); + test_api.GetHosts()[0]->window()->bounds().size().ToString()); display::Screen::GetScreen()->RemoveObserver(&display_observer); } @@ -2255,14 +2271,16 @@ EXPECT_EQ(1U, display_manager()->GetNumDisplays()); WindowTreeHostManager* window_tree_host_manager = ash::Shell::Get()->window_tree_host_manager(); - EXPECT_TRUE( - window_tree_host_manager->mirror_window_controller()->GetWindow()); + EXPECT_EQ(1U, window_tree_host_manager->mirror_window_controller() + ->GetAllRootWindows() + .size()); UpdateDisplay("600x400"); EXPECT_FALSE(display_manager()->IsInMirrorMode()); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_FALSE( - window_tree_host_manager->mirror_window_controller()->GetWindow()); + EXPECT_TRUE(window_tree_host_manager->mirror_window_controller() + ->GetAllRootWindows() + .empty()); } // Make sure this does not cause any crashes. See http://crbug.com/412910 @@ -2270,7 +2288,7 @@ UpdateDisplay("300x400,400x500"); MirrorWindowTestApi test_api; - EXPECT_EQ(nullptr, test_api.GetHost()); + EXPECT_TRUE(test_api.GetHosts().empty()); display::ManagedDisplayInfo secondary_info = display_manager()->GetDisplayInfo( @@ -2695,6 +2713,346 @@ EXPECT_EQ("400x500", screen->GetPrimaryDisplay().size().ToString()); } +// Validate that setting an invalid matrix will fall back to the default +// horizontal unified desktop layout. +TEST_F(DisplayManagerTest, UnifiedDesktopInvalidMatrices) { + // Don't check root window destruction in unified mode. + Shell::GetPrimaryRootWindow()->RemoveObserver(this); + + UpdateDisplay("400x500,300x200"); + display_manager()->SetUnifiedDesktopEnabled(true); + display::Screen* screen = display::Screen::GetScreen(); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(2u, list.size()); + { + // Create an empty matrix. + display::UnifiedDesktopLayoutMatrix matrix; + display_manager()->SetUnifiedDesktopMatrix(matrix); + // The result is still a valid default horizontal layout. + EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size()); + + // 2 x 1 empty matrix. + matrix.resize(2u); + display_manager()->SetUnifiedDesktopMatrix(matrix); + // The result is still a valid default horizontal layout. + EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size()); + } + + { + // 2 x 1 vertical matrix with invalid IDs. + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(2u); + matrix[0].emplace_back(list[0]); + matrix[1].emplace_back(-100); + display_manager()->SetUnifiedDesktopMatrix(matrix); + // The result is still a valid default horizontal layout. + EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size()); + } + + { + // Matrix with a missing ID. + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(2u); + matrix[0].emplace_back(list[0]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + // The result is still a valid default horizontal layout. + EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size()); + } + + // Switch to 3 displays. + UpdateDisplay("500x300,400x500,500x300"); + list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(3u, list.size()); + { + // Create a matrix with unequal rows + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[0]); + matrix[1].emplace_back(list[1]); + matrix[1].emplace_back(list[2]); // Typo; meant to say matrix[2]. + display_manager()->SetUnifiedDesktopMatrix(matrix); + // The result is still a valid default horizontal layout. + EXPECT_EQ(gfx::Size(1239, 300), screen->GetPrimaryDisplay().size()); + } + + { + // Create a matrix with repeated IDs. + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[0]); + matrix[1].emplace_back(list[1]); + matrix[2].emplace_back(list[1]); // Typo; meant to say list[2]. + display_manager()->SetUnifiedDesktopMatrix(matrix); + // The result is still a valid default horizontal layout. + EXPECT_EQ(gfx::Size(1239, 300), screen->GetPrimaryDisplay().size()); + } +} + +TEST_F(DisplayManagerTest, UnifiedDesktopVerticalLayout2x1) { + // Don't check root window destruction in unified mode. + Shell::GetPrimaryRootWindow()->RemoveObserver(this); + + UpdateDisplay("400x500,300x200"); + display_manager()->SetUnifiedDesktopEnabled(true); + display::Screen* screen = display::Screen::GetScreen(); + // This is still a horizontal layout. + EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size()); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(2u, list.size()); + { + // Create a 2 x 1 vertical layout matrix and set it. + // [400 x 500] + // [300 x 200] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(2u); + matrix[0].emplace_back(list[0]); + matrix[1].emplace_back(list[1]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + // 500 + 400 * 200 / 300 ~= 766. + EXPECT_EQ(gfx::Size(400, 766), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[0], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + EXPECT_EQ(500, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + EXPECT_EQ(400 * 200 / 300, + display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); + } + + { + // Change the order of the displays such that the [300 x 200] is on top, + // which should make its bounds used for the default mode. + // [300 x 200] + // [400 x 500] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(2u); + matrix[0].emplace_back(list[1]); + matrix[1].emplace_back(list[0]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + // 200 + 300 * 500 / 400 ~= 574 (Note that we actually scale the max unified + // bounds). + EXPECT_EQ(gfx::Size(300, 574), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[1], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + EXPECT_EQ(199, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + // 300 * 500 / 400. + EXPECT_EQ(375, display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); + } + + { + // Revert to the first matrix, but mark the [300 x 200] display as internal. + // [400 x 500] + // [300 x 200] : Internal + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(2u); + matrix[0].emplace_back(list[0]); + matrix[1].emplace_back(list[1]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + std::vector<display::ManagedDisplayInfo> display_info_list; + display_info_list.emplace_back( + CreateDisplayInfo(list[0], gfx::Rect(0, 0, 400, 500))); + display_info_list.emplace_back( + CreateDisplayInfo(list[1], gfx::Rect(400, 0, 300, 200))); + display::test::ScopedSetInternalDisplayId set_internal(display_manager(), + list[1]); + display_manager()->OnNativeDisplaysChanged(display_info_list); + EXPECT_EQ(gfx::Size(300, 574), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[0], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + // 300 * 500 / 400. + EXPECT_EQ(375, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + EXPECT_EQ(199, display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); + } +} + +TEST_F(DisplayManagerTest, UnifiedDesktopVerticalLayout3x1) { + // Don't check root window destruction in unified mode. + Shell::GetPrimaryRootWindow()->RemoveObserver(this); + + UpdateDisplay("500x300,400x500,500x300"); + display_manager()->SetUnifiedDesktopEnabled(true); + display::Screen* screen = display::Screen::GetScreen(); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(3u, list.size()); + { + // Create a 3 x 1 vertical layout matrix and set it. + // [500 x 300] + // [400 x 500] + // [500 x 300] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[0]); + matrix[1].emplace_back(list[1]); + matrix[2].emplace_back(list[2]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + EXPECT_EQ(gfx::Size(500, 1225), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[0], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[2])); + EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + // 500 * 500 / 400 = 625. + EXPECT_EQ(625, display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(2)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); + } + + { + // We can change the order however we want. + // [400 x 500] + // [500 x 300] + // [500 x 300] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[1]); + matrix[1].emplace_back(list[0]); + matrix[2].emplace_back(list[2]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + EXPECT_EQ(gfx::Size(400, 980), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[1], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[2])); + EXPECT_EQ(500, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + // 400 * 300 / 500 = 240. + EXPECT_EQ(240, display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_EQ(240, display_manager()->GetUnifiedDesktopRowMaxHeight(2)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); + } +} + +TEST_F(DisplayManagerTest, UnifiedDesktopGridLayout2x2) { + // Don't check root window destruction in unified mode. + Shell::GetPrimaryRootWindow()->RemoveObserver(this); + + UpdateDisplay("500x300,400x500,300x600,200x300"); + display_manager()->SetUnifiedDesktopEnabled(true); + display::Screen* screen = display::Screen::GetScreen(); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(4u, list.size()); + // Create a 2 x 2 vertical layout matrix and set it. + // [500 x 300] [400 x 500] + // [300 x 600] [200 x 300] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(2u); + matrix[0].emplace_back(list[0]); + matrix[0].emplace_back(list[1]); + matrix[1].emplace_back(list[2]); + matrix[1].emplace_back(list[3]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + EXPECT_EQ(gfx::Size(739, 933), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[0], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[2])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[3])); + EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + EXPECT_EQ(633, display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); +} + +TEST_F(DisplayManagerTest, UnifiedDesktopGridLayout3x2) { + // Don't check root window destruction in unified mode. + Shell::GetPrimaryRootWindow()->RemoveObserver(this); + + UpdateDisplay("500x300,400x500,300x600,200x300,700x200,350x480"); + display_manager()->SetUnifiedDesktopEnabled(true); + display::Screen* screen = display::Screen::GetScreen(); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(6u, list.size()); + // Create a 3 x 2 vertical layout matrix and set it. + // [500 x 300] [400 x 500] + // [300 x 600] [200 x 300] + // [700 x 200] [350 x 480] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[0]); + matrix[0].emplace_back(list[1]); + matrix[1].emplace_back(list[2]); + matrix[1].emplace_back(list[3]); + matrix[2].emplace_back(list[4]); + matrix[2].emplace_back(list[5]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + EXPECT_EQ(gfx::Size(739, 1108), screen->GetPrimaryDisplay().size()); + // Display in top-left cell is considered primary. + EXPECT_EQ( + list[0], + display_manager()->GetPrimaryMirroringDisplayForUnifiedDesktop()->id()); + + // Validate display rows and max heights. + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[0])); + EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[1])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[2])); + EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[3])); + EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[4])); + EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix( + list[5])); + EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(0)); + EXPECT_EQ(633, display_manager()->GetUnifiedDesktopRowMaxHeight(1)); + EXPECT_EQ(175, display_manager()->GetUnifiedDesktopRowMaxHeight(2)); + EXPECT_FALSE(OverlappingMirroringDisplaysExist()); +} + TEST_F(DisplayManagerTest, DockMode) { const int64_t internal_id = 1; const int64_t external_id = 2;
diff --git a/ash/display/display_util.cc b/ash/display/display_util.cc index d2d154c..8d3c107 100644 --- a/ash/display/display_util.cc +++ b/ash/display/display_util.cc
@@ -148,24 +148,22 @@ host->MoveCursorToLocationInPixels(point_in_host); if (update_last_location_now) { - gfx::Point new_point_in_screen; + gfx::Point new_point_in_screen = point_in_native; + host->ConvertScreenInPixelsToDIP(&new_point_in_screen); + ::wm::ConvertPointToScreen(host->window(), &new_point_in_screen); + if (Shell::Get()->display_manager()->IsInUnifiedMode()) { - new_point_in_screen = point_in_host; - // First convert to the unified host. - host->ConvertPixelsToDIP(&new_point_in_screen); - // Then convert to the unified screen. - Shell::GetPrimaryRootWindow()->GetHost()->ConvertPixelsToDIP( + // In unified desktop mode, the mirroring host converts the point to the + // unified host's pixel coordinates, so we also need to apply the unified + // host transform to get a point in the unified screen coordinates to take + // into account any device scale factors or ui scaling. + Shell::GetPrimaryRootWindow()->GetHost()->ConvertScreenInPixelsToDIP( &new_point_in_screen); - } else { - new_point_in_screen = point_in_native; - host->ConvertScreenInPixelsToDIP(&new_point_in_screen); - ::wm::ConvertPointToScreen(host->window(), &new_point_in_screen); } aura::Env::GetInstance()->set_last_mouse_location(new_point_in_screen); } } - void ShowDisplayErrorNotification(const base::string16& message, bool allow_feedback) { // Always remove the notification to make sure the notification appears
diff --git a/ash/display/mirror_window_controller.cc b/ash/display/mirror_window_controller.cc index d2bdaea..45ca92e3 100644 --- a/ash/display/mirror_window_controller.cc +++ b/ash/display/mirror_window_controller.cc
@@ -124,7 +124,8 @@ MirrorWindowController::MirroringHostInfo::~MirroringHostInfo() {} MirrorWindowController::MirrorWindowController() - : multi_display_mode_(display::DisplayManager::EXTENDED), + : current_event_targeter_src_host_(nullptr), + multi_display_mode_(display::DisplayManager::EXTENDED), screen_position_client_(new MirroringScreenPositionClient(this)) {} MirrorWindowController::~MirrorWindowController() { @@ -162,6 +163,8 @@ AshWindowTreeHostInitParams init_params; init_params.initial_bounds = display_info.bounds_in_native(); init_params.display_id = display_info.id(); + init_params.mirroring_delegate = this; + init_params.mirroring_unified = display_manager->IsInUnifiedMode(); init_params.device_scale_factor = display_info.device_scale_factor(); init_params.ui_scale_factor = display_info.configured_ui_scale(); MirroringHostInfo* host_info = new MirroringHostInfo; @@ -315,30 +318,16 @@ } } -aura::Window* MirrorWindowController::GetWindow() { - display::DisplayManager* display_manager = Shell::Get()->display_manager(); - if (!display_manager->IsInMirrorMode() || mirroring_host_info_map_.empty()) - return nullptr; - DCHECK_EQ(1U, mirroring_host_info_map_.size()); - return mirroring_host_info_map_.begin() - ->second->ash_host->AsWindowTreeHost() - ->window(); -} - display::Display MirrorWindowController::GetDisplayForRootWindow( const aura::Window* root) const { for (const auto& pair : mirroring_host_info_map_) { if (pair.second->ash_host->AsWindowTreeHost()->window() == root) { // Sanity check to catch an error early. - int64_t id = pair.first; - const display::Displays& list = - Shell::Get()->display_manager()->software_mirroring_display_list(); - auto iter = std::find_if( - list.begin(), list.end(), - [id](const display::Display& display) { return display.id() == id; }); - DCHECK(iter != list.end()); - if (iter != list.end()) - return *iter; + const int64_t id = pair.first; + const display::Display* display = GetMirroringDisplayById(id); + DCHECK(display); + if (display) + return *display; } } return display::Display(); @@ -357,6 +346,23 @@ return root_windows; } +const display::Display* MirrorWindowController::GetMirroringDisplayById( + int64_t display_id) const { + const display::Displays& list = + Shell::Get()->display_manager()->software_mirroring_display_list(); + for (const auto& display : list) { + if (display.id() == display_id) + return &display; + } + + return nullptr; +} + +void MirrorWindowController::SetCurrentEventTargeterSourceHost( + aura::WindowTreeHost* targeter_src_host) { + current_event_targeter_src_host_ = targeter_src_host; +} + void MirrorWindowController::CloseAndDeleteHost(MirroringHostInfo* host_info, bool delay_host_deletion) { aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost();
diff --git a/ash/display/mirror_window_controller.h b/ash/display/mirror_window_controller.h index a5648a3..5b4eb12b 100644 --- a/ash/display/mirror_window_controller.h +++ b/ash/display/mirror_window_controller.h
@@ -12,14 +12,12 @@ #include <vector> #include "ash/ash_export.h" -#include "base/compiler_specific.h" +#include "ash/host/ash_window_tree_host_mirroring_delegate.h" #include "base/macros.h" -#include "base/memory/ref_counted.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host_observer.h" #include "ui/display/manager/display_manager.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/native_widget_types.h" +#include "ui/display/manager/managed_display_info.h" namespace aura { class Window; @@ -44,7 +42,9 @@ // An object that copies the content of the primary root window to a // mirror window. This also draws a mouse cursor as the mouse cursor // is typically drawn by the window system. -class ASH_EXPORT MirrorWindowController : public aura::WindowTreeHostObserver { +class ASH_EXPORT MirrorWindowController + : public aura::WindowTreeHostObserver, + public AshWindowTreeHostMirroringDelegate { public: MirrorWindowController(); ~MirrorWindowController() override; @@ -64,10 +64,6 @@ // aura::WindowTreeHostObserver overrides: void OnHostResized(aura::WindowTreeHost* host) override; - // Return the root window used to mirror the content. NULL if the - // display is not mirrored by the compositor path. - aura::Window* GetWindow(); - // Returns the display::Display for the mirroring root window. display::Display GetDisplayForRootWindow(const aura::Window* root) const; @@ -77,6 +73,16 @@ // Returns all root windows hosting mirroring displays. aura::Window::Windows GetAllRootWindows() const; + // AshWindowTreeHostMirroringDelegate: + const display::Display* GetMirroringDisplayById( + int64_t display_id) const override; + void SetCurrentEventTargeterSourceHost( + aura::WindowTreeHost* targeter_src_host) override; + + const aura::WindowTreeHost* current_event_targeter_src_host() const { + return current_event_targeter_src_host_; + } + private: friend class MirrorWindowTestApi; @@ -93,6 +99,8 @@ typedef std::map<int64_t, MirroringHostInfo*> MirroringHostInfoMap; MirroringHostInfoMap mirroring_host_info_map_; + aura::WindowTreeHost* current_event_targeter_src_host_; + display::DisplayManager::MultiDisplayMode multi_display_mode_; std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_;
diff --git a/ash/display/mirror_window_controller_unittest.cc b/ash/display/mirror_window_controller_unittest.cc index 22975b2e..d44c231 100644 --- a/ash/display/mirror_window_controller_unittest.cc +++ b/ash/display/mirror_window_controller_unittest.cc
@@ -259,7 +259,7 @@ EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_TRUE(display_manager()->IsInMirrorMode()); - EXPECT_EQ(external_id, display_manager()->mirroring_display_id()); + EXPECT_EQ(external_id, display_manager()->GetMirroringDstDisplayIdList()[0]); // dock mode. display_info_list.clear(); @@ -277,14 +277,14 @@ display_manager()->OnNativeDisplaysChanged(display_info_list); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_TRUE(display_manager()->IsInMirrorMode()); - EXPECT_EQ(external_id, display_manager()->mirroring_display_id()); + EXPECT_EQ(external_id, display_manager()->GetMirroringDstDisplayIdList()[0]); } TEST_F(MirrorOnBootTest, MirrorOnBoot) { EXPECT_TRUE(display_manager()->IsInMirrorMode()); RunAllPendingInMessageLoop(); MirrorWindowTestApi test_api; - EXPECT_TRUE(test_api.GetHost()); + EXPECT_EQ(1U, test_api.GetHosts().size()); } } // namespace ash
diff --git a/ash/display/mirror_window_test_api.cc b/ash/display/mirror_window_test_api.cc index 982b88ea..4f6840bd 100644 --- a/ash/display/mirror_window_test_api.cc +++ b/ash/display/mirror_window_test_api.cc
@@ -14,12 +14,15 @@ namespace ash { -const aura::WindowTreeHost* MirrorWindowTestApi::GetHost() const { - aura::Window* window = Shell::Get() - ->window_tree_host_manager() - ->mirror_window_controller() - ->GetWindow(); - return window ? window->GetHost() : NULL; +std::vector<aura::WindowTreeHost*> MirrorWindowTestApi::GetHosts() const { + std::vector<aura::WindowTreeHost*> hosts; + for (auto* window : Shell::Get() + ->window_tree_host_manager() + ->mirror_window_controller() + ->GetAllRootWindows()) { + hosts.emplace_back(window->GetHost()); + } + return hosts; } ui::CursorType MirrorWindowTestApi::GetCurrentCursorType() const {
diff --git a/ash/display/mirror_window_test_api.h b/ash/display/mirror_window_test_api.h index ed951c8..4582b07 100644 --- a/ash/display/mirror_window_test_api.h +++ b/ash/display/mirror_window_test_api.h
@@ -5,6 +5,8 @@ #ifndef ASH_DISPLAY_MIRROR_WINDOW_TEST_API_H_ #define ASH_DISPLAY_MIRROR_WINDOW_TEST_API_H_ +#include <vector> + #include "base/macros.h" namespace aura { @@ -27,7 +29,7 @@ MirrorWindowTestApi() {} ~MirrorWindowTestApi() {} - const aura::WindowTreeHost* GetHost() const; + std::vector<aura::WindowTreeHost*> GetHosts() const; ui::CursorType GetCurrentCursorType() const;
diff --git a/ash/display/root_window_transformers.cc b/ash/display/root_window_transformers.cc index d4eca71..56eb506 100644 --- a/ash/display/root_window_transformers.cc +++ b/ash/display/root_window_transformers.cc
@@ -221,14 +221,33 @@ public: PartialBoundsRootWindowTransformer(const gfx::Rect& screen_bounds, const display::Display& display) { + const display::DisplayManager* display_manager = + Shell::Get()->display_manager(); + display::ManagedDisplayInfo display_info = + display_manager->GetDisplayInfo(display.id()); + // Physical root bounds. + root_bounds_ = gfx::Rect(display_info.bounds_in_native().size()); + + // |screen_bounds| is the unified desktop logical bounds. + // Calculate the unified height scale value, and apply the same scale on the + // row physical height to get the row logical height. display::Display unified_display = display::Screen::GetScreen()->GetPrimaryDisplay(); - display::ManagedDisplayInfo display_info = - Shell::Get()->display_manager()->GetDisplayInfo(display.id()); - root_bounds_ = gfx::Rect(display_info.bounds_in_native().size()); - float scale = root_bounds_.height() / - static_cast<float>(screen_bounds.height()) / - unified_display.device_scale_factor(); + const int unified_physical_height = + unified_display.GetSizeInPixel().height(); + const int unified_logical_height = screen_bounds.height(); + const float unified_height_scale = + static_cast<float>(unified_logical_height) / unified_physical_height; + + const int row_index = + display_manager->GetMirroringDisplayRowIndexInUnifiedMatrix( + display.id()); + const int row_physical_height = + display_manager->GetUnifiedDesktopRowMaxHeight(row_index); + const int row_logical_height = row_physical_height * unified_height_scale; + const float dsf = unified_display.device_scale_factor(); + const float scale = root_bounds_.height() / (dsf * row_logical_height); + transform_.Scale(scale, scale); transform_.Translate(-SkIntToMScalar(display.bounds().x()), -SkIntToMScalar(display.bounds().y()));
diff --git a/ash/display/root_window_transformers_unittest.cc b/ash/display/root_window_transformers_unittest.cc index 8f88f79..fe42450f 100644 --- a/ash/display/root_window_transformers_unittest.cc +++ b/ash/display/root_window_transformers_unittest.cc
@@ -127,7 +127,7 @@ DCHECK(display_manager()->IsInMirrorMode()); const display::ManagedDisplayInfo& mirror_display_info = display_manager()->GetDisplayInfo( - display_manager()->mirroring_display_id()); + display_manager()->GetMirroringDstDisplayIdList()[0]); const display::ManagedDisplayInfo& source_display_info = display_manager()->GetDisplayInfo( display::Screen::GetScreen()->GetPrimaryDisplay().id());
diff --git a/ash/display/unified_mouse_warp_controller.cc b/ash/display/unified_mouse_warp_controller.cc index 2a11a3a..d530c19 100644 --- a/ash/display/unified_mouse_warp_controller.cc +++ b/ash/display/unified_mouse_warp_controller.cc
@@ -35,32 +35,26 @@ ->GetAshWindowTreeHostForDisplayId(display_id); } -// Find a WindowTreeHost used for mirroring displays that contains -// the |point_in_screen|. Returns nullptr if such WTH does not exist. -aura::WindowTreeHost* FindMirroringWindowTreeHostFromScreenPoint( - const gfx::Point& point_in_screen) { - display::Displays mirroring_display_list = - Shell::Get()->display_manager()->software_mirroring_display_list(); - auto iter = display::FindDisplayContainingPoint(mirroring_display_list, - point_in_screen); - if (iter == mirroring_display_list.end()) - return nullptr; - return GetMirroringAshWindowTreeHostForDisplayId(iter->id()) - ->AsWindowTreeHost(); +const aura::WindowTreeHost* GetMirroringSourceHostForCurrentEvent() { + return Shell::Get() + ->window_tree_host_manager() + ->mirror_window_controller() + ->current_event_targeter_src_host(); } } // namespace UnifiedMouseWarpController::UnifiedMouseWarpController() : current_cursor_display_id_(display::kInvalidDisplayId), - update_location_for_test_(false) {} + update_location_for_test_(false), + display_boundaries_computed_(false) {} UnifiedMouseWarpController::~UnifiedMouseWarpController() {} bool UnifiedMouseWarpController::WarpMouseCursor(ui::MouseEvent* event) { // Mirroring windows are created asynchronously, so compute the edge // beounds when we received an event instead of in constructor. - if (first_edge_bounds_in_native_.IsEmpty()) + if (!display_boundaries_computed_) ComputeBounds(); aura::Window* target = static_cast<aura::Window*>(event->target()); @@ -70,46 +64,44 @@ // transform back to the host coordinates. target->GetHost()->GetRootTransform().TransformPoint(&point_in_unified_host); - if (current_cursor_display_id_ != display::kInvalidDisplayId) { - aura::client::CursorClient* cursor_client = - aura::client::GetCursorClient(target->GetRootWindow()); - if (cursor_client) { - display::Displays mirroring_display_list = - Shell::Get()->display_manager()->software_mirroring_display_list(); - auto iter = display::FindDisplayContainingPoint(mirroring_display_list, - point_in_unified_host); - if (iter != mirroring_display_list.end() && - current_cursor_display_id_ != iter->id()) { - cursor_client->SetDisplay(*iter); - current_cursor_display_id_ = display::kInvalidDisplayId; - } - } - } - // A native event may not exist in unit test. if (!event->HasNativeEvent()) return false; - gfx::Point point_in_native = - ui::EventSystemLocationFromNative(event->native_event()); - // TODO(dnicoara): crbug.com/415680 Move cursor warping into Ozone once Ozone // has access to the logical display layout. // Native events in Ozone are in the native window coordinate system. We need // to translate them to get the global position. - aura::WindowTreeHost* host = - FindMirroringWindowTreeHostFromScreenPoint(point_in_unified_host); + const auto* host = GetMirroringSourceHostForCurrentEvent(); if (!host) return false; + + gfx::Point point_in_native = + ui::EventSystemLocationFromNative(event->native_event()); point_in_native.Offset(host->GetBoundsInPixels().x(), host->GetBoundsInPixels().y()); - return WarpMouseCursorInNativeCoords(point_in_native, point_in_unified_host, + // TODO(afakhry): Remove implicit grab. crbug.com/773348. + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow( + const_cast<aura::Window*>(host->window())); + if (current_cursor_display_id_ != display::kInvalidDisplayId && + current_cursor_display_id_ != display.id()) { + aura::client::CursorClient* cursor_client = + aura::client::GetCursorClient(target->GetRootWindow()); + if (cursor_client) { + cursor_client->SetDisplay(display); + current_cursor_display_id_ = display::kInvalidDisplayId; + } + } + + return WarpMouseCursorInNativeCoords(display.id(), point_in_native, + point_in_unified_host, update_location_for_test_); } void UnifiedMouseWarpController::SetEnabled(bool enabled) { - // Mouse warp shuld be always on in Unified mode. + // Mouse warp should be always on in Unified mode. } void UnifiedMouseWarpController::ComputeBounds() { @@ -120,44 +112,56 @@ LOG(ERROR) << "Mirroring Display lost during re-configuration"; return; } - LOG_IF(ERROR, display_list.size() > 2) << "Only two displays are supported"; - const display::Display& first = display_list[0]; - const display::Display& second = display_list[1]; - bool success = - display::ComputeBoundary(first, second, &first_edge_bounds_in_native_, - &second_edge_bounds_in_native_); - DCHECK(success); + for (size_t i = 0; i < display_list.size() - 1; ++i) { + const display::Display& first = display_list[i]; + for (size_t j = i + 1; j < display_list.size(); ++j) { + const display::Display& second = display_list[j]; + gfx::Rect first_edge; + gfx::Rect second_edge; + if (display::ComputeBoundary(first, second, &first_edge, &second_edge)) { + first_edge = GetNativeEdgeBounds( + GetMirroringAshWindowTreeHostForDisplayId(first.id()), first_edge); + second_edge = GetNativeEdgeBounds( + GetMirroringAshWindowTreeHostForDisplayId(second.id()), + second_edge); - first_edge_bounds_in_native_ = - GetNativeEdgeBounds(GetMirroringAshWindowTreeHostForDisplayId(first.id()), - first_edge_bounds_in_native_); + displays_edges_map_[first.id()].emplace_back(first.id(), second.id(), + first_edge); + displays_edges_map_[second.id()].emplace_back(second.id(), first.id(), + second_edge); + } + } + } - second_edge_bounds_in_native_ = GetNativeEdgeBounds( - GetMirroringAshWindowTreeHostForDisplayId(second.id()), - second_edge_bounds_in_native_); + display_boundaries_computed_ = true; } bool UnifiedMouseWarpController::WarpMouseCursorInNativeCoords( + int64_t source_display, const gfx::Point& point_in_native, const gfx::Point& point_in_unified_host, bool update_mouse_location_now) { - bool in_first_edge = first_edge_bounds_in_native_.Contains(point_in_native); - bool in_second_edge = second_edge_bounds_in_native_.Contains(point_in_native); - if (!in_first_edge && !in_second_edge) + const auto edges_iter = displays_edges_map_.find(source_display); + if (edges_iter == displays_edges_map_.end()) return false; - display::Displays display_list = - Shell::Get()->display_manager()->software_mirroring_display_list(); - // Wait updating the cursor until the cursor moves to the new display - // to avoid showing the wrong sized cursor at the source display. - current_cursor_display_id_ = - in_first_edge ? display_list[0].id() : display_list[1].id(); - AshWindowTreeHost* target_ash_host = - GetMirroringAshWindowTreeHostForDisplayId( - in_first_edge ? display_list[1].id() : display_list[0].id()); - MoveCursorTo(target_ash_host, point_in_unified_host, - update_mouse_location_now); - return true; + + const std::vector<DisplayEdge>& potential_edges = edges_iter->second; + for (const auto& edge : potential_edges) { + if (edge.edge_native_bounds_in_source_display.Contains(point_in_native)) { + // Wait updating the cursor until the cursor moves to the new display + // to avoid showing the wrong sized cursor at the source display. + current_cursor_display_id_ = edge.source_display_id; + + AshWindowTreeHost* target_ash_host = + GetMirroringAshWindowTreeHostForDisplayId(edge.target_display_id); + MoveCursorTo(target_ash_host, point_in_unified_host, + update_mouse_location_now); + return true; + } + } + + return false; } } // namespace ash
diff --git a/ash/display/unified_mouse_warp_controller.h b/ash/display/unified_mouse_warp_controller.h index 3ec8911..25824b6f3 100644 --- a/ash/display/unified_mouse_warp_controller.h +++ b/ash/display/unified_mouse_warp_controller.h
@@ -9,6 +9,9 @@ #include <stdint.h> +#include <map> +#include <vector> + #include "base/macros.h" #include "ui/gfx/geometry/rect.h" @@ -38,21 +41,48 @@ // Warps the mouse cursor to an alternate root window when the // mouse location in |event|, hits the edge of the event target's root and // the mouse cursor is considered to be in an alternate display. - // If |update_mouse_location_now| is true, - // Returns true if/ the cursor was moved. - bool WarpMouseCursorInNativeCoords(const gfx::Point& point_in_native, + // If |update_mouse_location_now| is true, the mouse location is updated + // synchronously. + // Returns true if the cursor was moved. + bool WarpMouseCursorInNativeCoords(int64_t source_display, + const gfx::Point& point_in_native, const gfx::Point& point_in_screen, bool update_mouse_location_now); void update_location_for_test() { update_location_for_test_ = true; } - gfx::Rect first_edge_bounds_in_native_; - gfx::Rect second_edge_bounds_in_native_; + struct DisplayEdge { + DisplayEdge(int64_t source_id, + int64_t target_id, + const gfx::Rect& edge_bounds) + : source_display_id(source_id), + target_display_id(target_id), + edge_native_bounds_in_source_display(edge_bounds) {} + + // The ID of the display where the cursor is now. + int64_t source_display_id; + + // The ID of the display with which there's an edge and the cursor would + // move to if it resides in that edge. + int64_t target_display_id; + + // The native bounds of the edge between the source and target displays + // which is part of the source display. + gfx::Rect edge_native_bounds_in_source_display; + }; + + // Maps a display by its ID to all the boundary edges that reside in it with + // the surrounding displays. + std::map<int64_t, std::vector<DisplayEdge>> displays_edges_map_; int64_t current_cursor_display_id_; bool update_location_for_test_; + // True if the edge boundaries between displays (where mouse cursor should + // warp) have been computed. + bool display_boundaries_computed_; + DISALLOW_COPY_AND_ASSIGN(UnifiedMouseWarpController); };
diff --git a/ash/display/unified_mouse_warp_controller_unittest.cc b/ash/display/unified_mouse_warp_controller_unittest.cc index 3bd2db2..24b5c47 100644 --- a/ash/display/unified_mouse_warp_controller_unittest.cc +++ b/ash/display/unified_mouse_warp_controller_unittest.cc
@@ -4,6 +4,8 @@ #include "ash/display/unified_mouse_warp_controller.h" +#include <sstream> + #include "ash/display/display_util.h" #include "ash/display/mirror_window_controller.h" #include "ash/display/mouse_cursor_event_filter.h" @@ -21,6 +23,21 @@ namespace ash { +namespace { + +struct WarpGroup { + // Native point at a warp edge before warping. + gfx::Point native_point_at_edge; + + // Expected DIP point after warping. + gfx::Point expected_point_after_warp; + + // Expected display ID after warping. + int64_t expected_target_display_id; +}; + +} // namespace + class UnifiedMouseWarpControllerTest : public AshTestBase { public: UnifiedMouseWarpControllerTest() {} @@ -32,28 +49,27 @@ } protected: - bool FindMirrroingDisplayIdContainingNativePoint( - const gfx::Point& point_in_native, - int64_t* display_id, - gfx::Point* point_in_mirroring_host, - gfx::Point* point_in_unified_host) { + bool MoveMouseToNativePoint(const gfx::Point& point_in_native, + int64_t* out_original_mirroring_display_id) { for (auto display : display_manager()->software_mirroring_display_list()) { display::ManagedDisplayInfo info = display_manager()->GetDisplayInfo(display.id()); if (info.bounds_in_native().Contains(point_in_native)) { - *display_id = info.id(); - *point_in_unified_host = point_in_native; + *out_original_mirroring_display_id = info.id(); + gfx::Point point_in_mirroring_host = point_in_native; const gfx::Point& origin = info.bounds_in_native().origin(); // Convert to mirroring host. - point_in_unified_host->Offset(-origin.x(), -origin.y()); - *point_in_mirroring_host = *point_in_unified_host; - // Convert from mirroring host to unified host. + point_in_mirroring_host.Offset(-origin.x(), -origin.y()); + + // Move the mouse inside the host. AshWindowTreeHost* ash_host = Shell::Get() ->window_tree_host_manager() ->mirror_window_controller() ->GetAshWindowTreeHostForDisplayId(info.id()); - ash_host->AsWindowTreeHost()->ConvertPixelsToDIP(point_in_unified_host); + ui::test::EventGenerator gen(ash_host->AsWindowTreeHost()->window()); + gen.MoveMouseToWithNative(point_in_mirroring_host, + point_in_mirroring_host); return true; } } @@ -65,16 +81,9 @@ Shell::Get()->mouse_cursor_filter()->mouse_warp_controller_for_test()) ->update_location_for_test(); int64_t orig_mirroring_display_id; - gfx::Point point_in_unified_host; - gfx::Point point_in_mirroring_host; - if (!FindMirrroingDisplayIdContainingNativePoint( - point_in_native, &orig_mirroring_display_id, - &point_in_mirroring_host, &point_in_unified_host)) { + if (!MoveMouseToNativePoint(point_in_native, &orig_mirroring_display_id)) return false; - } - // The location of the ozone's native event is relative to the host. - GetEventGenerator().MoveMouseToWithNative(point_in_unified_host, - point_in_mirroring_host); + aura::Window* root = Shell::GetPrimaryRootWindow(); gfx::Point new_location_in_unified_host = aura::Env::GetInstance()->last_mouse_location(); @@ -98,31 +107,60 @@ event_filter()->mouse_warp_controller_for_test()); } - void BoundaryTestBody(const std::string& displays_with_same_height, - const std::string& displays_with_different_heights) { - UpdateDisplay(displays_with_same_height); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + // |expected_edges| should have a row for each display which contains the + // expected native bounds of the shared edges with that display in the order + // "top", "left", "right", "bottom". + // If |matrix| is empty, default unified layout will be used. + void BoundaryTestBody( + const std::string& displays_specs, + const display::UnifiedDesktopLayoutMatrix& matrix, + const std::vector<std::vector<std::string>>& expected_edges) { + UpdateDisplay(displays_specs); + display_manager()->SetUnifiedDesktopMatrix(matrix); + // Let the UnifiedMouseWarpController compute the bounds by // generating a mouse move event. GetEventGenerator().MoveMouseTo(gfx::Point(0, 0)); - EXPECT_EQ("399,0 1x400", - mouse_warp_controller()->first_edge_bounds_in_native_.ToString()); - EXPECT_EQ( - "0,450 1x400", - mouse_warp_controller()->second_edge_bounds_in_native_.ToString()); + const display::Displays& mirroring_displays = + display_manager()->software_mirroring_display_list(); - // Scaled. - UpdateDisplay(displays_with_different_heights); - root_windows = Shell::GetAllRootWindows(); - // Let the UnifiedMouseWarpController compute the bounds by - // generating a mouse move event. - GetEventGenerator().MoveMouseTo(gfx::Point(1, 1)); + ASSERT_EQ(expected_edges.size(), mirroring_displays.size()); + int index = 0; + for (const auto& display : mirroring_displays) { + const int64_t id = display.id(); + std::stringstream scoped_trace_message; + scoped_trace_message << "Edges of display with ID: " << id + << " at index: " << index; + SCOPED_TRACE(scoped_trace_message.str()); + const auto& display_expected_edges = expected_edges[index++]; + const auto& display_actual_edges = + mouse_warp_controller()->displays_edges_map_.at(id); + ASSERT_EQ(display_expected_edges.size(), display_actual_edges.size()); + for (size_t i = 0; i < display_expected_edges.size(); ++i) { + EXPECT_EQ(display_expected_edges[i], + display_actual_edges[i] + .edge_native_bounds_in_source_display.ToString()); + } + } + } - EXPECT_EQ("399,0 1x400", - mouse_warp_controller()->first_edge_bounds_in_native_.ToString()); - EXPECT_EQ( - "0,450 1x600", - mouse_warp_controller()->second_edge_bounds_in_native_.ToString()); + void WarpTestBody(const std::vector<WarpGroup>& warp_groups) { + for (const auto& group : warp_groups) { + EXPECT_TRUE(TestIfMouseWarpsAt(group.native_point_at_edge)); + + gfx::Point new_location = aura::Env::GetInstance()->last_mouse_location(); + EXPECT_EQ(group.expected_point_after_warp, new_location); + + // Convert screen to the host. + aura::Window* root = Shell::GetPrimaryRootWindow(); + root->GetHost()->ConvertDIPToPixels(&new_location); + + auto iter = display::FindDisplayContainingPoint( + display_manager()->software_mirroring_display_list(), new_location); + EXPECT_FALSE(iter == + display_manager()->software_mirroring_display_list().end()); + EXPECT_EQ(group.expected_target_display_id, iter->id()); + } } void NoWarpTestBody() { @@ -149,22 +187,208 @@ TEST_F(UnifiedMouseWarpControllerTest, BoundaryTest) { { SCOPED_TRACE("1x1"); - BoundaryTestBody("400x400,0+450-700x400", "400x400,0+450-700x600"); + BoundaryTestBody("400x400,0+450-700x400", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x400"}}); + BoundaryTestBody("400x400,0+450-700x600", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x600"}}); } { SCOPED_TRACE("2x1"); - BoundaryTestBody("400x400*2,0+450-700x400", "400x400*2,0+450-700x600"); + BoundaryTestBody("400x400*2,0+450-700x400", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x400"}}); + BoundaryTestBody("400x400*2,0+450-700x600", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x600"}}); } { SCOPED_TRACE("1x2"); - BoundaryTestBody("400x400,0+450-700x400*2", "400x400,0+450-700x600*2"); + BoundaryTestBody("400x400,0+450-700x400*2", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x400"}}); + BoundaryTestBody("400x400,0+450-700x600*2", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x600"}}); } { SCOPED_TRACE("2x2"); - BoundaryTestBody("400x400*2,0+450-700x400*2", "400x400*2,0+450-700x600*2"); + BoundaryTestBody("400x400*2,0+450-700x400*2", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x400"}}); + BoundaryTestBody("400x400*2,0+450-700x600*2", + {}, // Empty matrix (use horizontal layout). + {{"399,0 1x400"}, {"0,450 1x600"}}); } } +TEST_F(UnifiedMouseWarpControllerTest, BoundaryAndWarpSimpleTest) { + const std::vector<std::vector<std::string>> expected_edges = { + // Display 0 edges. + { + "1919,0 1x1080", // Right with display 1. + }, + // Display 1 edges. + { + "1930,0 1x1200", // Left with display 0. + }, + }; + + BoundaryTestBody("0+0-1920x1080,1930+0-1920x1200", + {} /* empty matrix = default */, expected_edges); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(2u, list.size()); + + // Assert mouse warps in all bounds to the correct display. + const std::vector<WarpGroup> warp_groups = { + {{1919, 500}, {1920, 499}, list[1]}, // Display 0 --> 1. + {{1930, 600}, {1918, 540}, list[0]}, // Display 1 --> 0. + }; + WarpTestBody(warp_groups); +} + +TEST_F(UnifiedMouseWarpControllerTest, BoundaryTestGrid) { + // Update displays here first so we get the correct display IDs list. The + // below are the native bounds. + const std::string display_specs = + "0+0-500x300,510+0-400x500,920+0-300x600," + "0+600-200x300,210+600-700x200,920+600-350x480," + "0+1080-300x500,310+1080-600x600,920+1080-400x450"; + UpdateDisplay(display_specs); + display_manager()->SetUnifiedDesktopEnabled(true); + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(9u, list.size()); + + // Test a very general case of a 3 x 3 matrix. + // 0:[500 x 300] 1:[400 x 500] 2:[300 x 600] + // 3:[200 x 300] 4:[700 x 200] 5:[350 x 480] + // 6:[300 x 500] 7:[600 x 600] 8:[400 x 450] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[0]); + matrix[0].emplace_back(list[1]); + matrix[0].emplace_back(list[2]); + matrix[1].emplace_back(list[3]); + matrix[1].emplace_back(list[4]); + matrix[1].emplace_back(list[5]); + matrix[2].emplace_back(list[6]); + matrix[2].emplace_back(list[7]); + matrix[2].emplace_back(list[8]); + + const std::vector<std::vector<std::string>> expected_edges = { + // Display 0 edges. + { + "499,0 1x300", // Right with display 1. + "0,299 121x1", // Bottom with display 3. + "121,299 379x1", // Bottom with display 4. + }, + // Display 1 edges. + { + "510,0 1x500", // Left with display 0. + "909,0 1x500", // Right with display 2. + "510,499 400x1", // Bottom with display 4. + }, + // Display 2 edges. + { + "920,0 1x600", // Left with display 1. + "920,599 34x1", // Bottom with display 4. + "954,599 266x1", // Bottom with display 5. + }, + // Display 3 edges. + { + "0,600 199x1", // Top with display 0. + "199,600 1x300", // Right with display 4. + "0,899 199x1", // Bottom with display 6. + }, + // Display 4 edges. + { + "210,600 416x1", // Top with display 0. + "626,600 264x1", // Top with display 1. + "890,600 18x1", // Top with display 2. + "210,600 1x200", // Left with display 3. + "909,600 1x200", // Right with display 5. + "210,799 102x1", // Bottom with display 6. + "312,799 392x1", // Bottom with display 7. + "704,799 204x1", // Bottom with display 8. + }, + // Display 5 edges. + { + "920,600 350x1", // Top with display 2. + "920,600 1x480", // Left with display 4. + "920,1079 348x1", // Bottom with display 8. + }, + // Display 6 edges. + { + "0,1080 169x1", // Top with display 3. + "169,1080 130x1", // Top with display 4. + "299,1080 1x500", // Right with display 7. + }, + // Display 7 edges. + { + "310,1080 600x1", // Top with display 4. + "310,1080 1x600", // Left with display 6. + "909,1080 1x600", // Right with display 8. + }, + // Display 8 edges. + { + "920,1080 234x1", // Top with display 4. + "1154,1080 166x1", // Top with display 5. + "920,1080 1x450", // Left with display 7. + }, + }; + + BoundaryTestBody(display_specs, matrix, expected_edges); + + ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays()); + + // Assert mouse warps in all bounds to the correct display. + const std::vector<WarpGroup> warp_groups = { + {{499, 10}, {500, 9}, list[1]}, // Display 0 --> 1. + {{10, 299}, {9, 300}, list[3]}, // Display 0 --> 3. + {{130, 299}, {129, 300}, list[4]}, // Display 0 --> 4. + + {{510, 10}, {498, 6}, list[0]}, // Display 1 --> 0. + {{909, 50}, {740, 30}, list[2]}, // Display 1 --> 2. + {{600, 499}, {553, 300}, list[4]}, // Display 1 --> 4. + + {{920, 50}, {738, 24}, list[1]}, // Display 2 --> 1. + {{930, 599}, {744, 300}, list[4]}, // Display 2 --> 4. + {{970, 599}, {764, 300}, list[5]}, // Display 2 --> 5. + + {{10, 600}, {6, 298}, list[0]}, // Display 3 --> 0. + {{199, 700}, {121, 359}, list[4]}, // Display 3 --> 4. + {{100, 899}, {59, 482}, list[6]}, // Display 3 --> 6. + + {{250, 600}, {157, 298}, list[0]}, // Display 4 --> 0. + {{700, 600}, {566, 298}, list[1]}, // Display 4 --> 1. + {{900, 600}, {748, 299}, list[2]}, // Display 4 --> 2. + {{210, 700}, {120, 391}, list[3]}, // Display 4 --> 3. + {{909, 650}, {757, 344}, list[5]}, // Display 4 --> 5. + {{250, 799}, {156, 482}, list[6]}, // Display 4 --> 6. + {{500, 799}, {383, 482}, list[7]}, // Display 4 --> 7. + {{800, 799}, {656, 482}, list[8]}, // Display 4 --> 8. + + {{950, 600}, {768, 299}, list[2]}, // Display 5 --> 2. + {{920, 750}, {756, 355}, list[4]}, // Display 5 --> 4. + {{1000, 1079}, {786, 482}, list[8]}, // Display 5 --> 8. + + {{100, 1080}, {70, 480}, list[3]}, // Display 6 --> 3. + {{200, 1080}, {141, 480}, list[4]}, // Display 6 --> 4. + {{299, 1200}, {214, 566}, list[7]}, // Display 6 --> 7. + + {{500, 1080}, {326, 480}, list[4]}, // Display 7 --> 4. + {{310, 1500}, {212, 730}, list[6]}, // Display 7 --> 6. + {{909, 1500}, {571, 730}, list[8]}, // Display 7 --> 8. + + {{1000, 1080}, {633, 480}, list[4]}, // Display 8 --> 4. + {{1200, 1080}, {792, 481}, list[5]}, // Display 8 --> 5. + {{920, 1500}, {569, 814}, list[7]}, // Display 8 --> 7. + }; + WarpTestBody(warp_groups); +} + // Verifies if the mouse pointer correctly moves to another display in // unified desktop mode. TEST_F(UnifiedMouseWarpControllerTest, WarpMouse) {
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc index 81989e6..37209013 100644 --- a/ash/display/window_tree_host_manager.cc +++ b/ash/display/window_tree_host_manager.cc
@@ -756,8 +756,10 @@ GetDisplayManager()->GetDisplayInfo(display.id()); AshWindowTreeHostInitParams params_with_bounds(init_params); params_with_bounds.initial_bounds = display_info.bounds_in_native(); - params_with_bounds.offscreen = - display.id() == display::DisplayManager::kUnifiedDisplayId; + if (display.id() == display::DisplayManager::kUnifiedDisplayId) { + params_with_bounds.offscreen = true; + params_with_bounds.mirroring_delegate = mirror_window_controller(); + } params_with_bounds.display_id = display.id(); params_with_bounds.device_scale_factor = display.device_scale_factor(); params_with_bounds.ui_scale_factor = display_info.configured_ui_scale();
diff --git a/ash/host/ash_window_tree_host.cc b/ash/host/ash_window_tree_host.cc index 967cc6a..25fc667b 100644 --- a/ash/host/ash_window_tree_host.cc +++ b/ash/host/ash_window_tree_host.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/host/ash_window_tree_host_init_params.h" +#include "ash/host/ash_window_tree_host_mirroring_unified.h" #include "ash/host/ash_window_tree_host_platform.h" #include "ash/host/ash_window_tree_host_unified.h" #include "ash/shell_port.h" @@ -47,6 +48,7 @@ screen_position_client->ConvertHostPointToScreen(root_window, &location); screen_position_client->ConvertPointFromScreen(root_window, &location); wth->ConvertDIPToPixels(&location); + event->set_location(location); event->set_root_location(location); } @@ -60,9 +62,14 @@ if (ash_window_tree_host) return ash_window_tree_host; + if (init_params.mirroring_unified) { + return std::make_unique<AshWindowTreeHostMirroringUnified>( + init_params.initial_bounds, init_params.display_id, + init_params.mirroring_delegate); + } if (init_params.offscreen) { return std::make_unique<AshWindowTreeHostUnified>( - init_params.initial_bounds); + init_params.initial_bounds, init_params.mirroring_delegate); } return std::make_unique<AshWindowTreeHostPlatform>( init_params.initial_bounds);
diff --git a/ash/host/ash_window_tree_host_init_params.h b/ash/host/ash_window_tree_host_init_params.h index 4c85f95..c68d8fee 100644 --- a/ash/host/ash_window_tree_host_init_params.h +++ b/ash/host/ash_window_tree_host_init_params.h
@@ -12,10 +12,15 @@ namespace ash { +class AshWindowTreeHostMirroringDelegate; + struct ASH_EXPORT AshWindowTreeHostInitParams { + // Not owned. + AshWindowTreeHostMirroringDelegate* mirroring_delegate = nullptr; // This corresponds to display::ManagedDisplayInfo::bounds_in_native. gfx::Rect initial_bounds; bool offscreen = false; + bool mirroring_unified = false; int64_t display_id = 0; float device_scale_factor = 0.0f; float ui_scale_factor = 0.0f;
diff --git a/ash/host/ash_window_tree_host_mirroring_delegate.h b/ash/host/ash_window_tree_host_mirroring_delegate.h new file mode 100644 index 0000000..63fd274b --- /dev/null +++ b/ash/host/ash_window_tree_host_mirroring_delegate.h
@@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_HOST_ASH_WINDOW_TREE_HOST_MIRRORING_DELEGATE_H_ +#define ASH_HOST_ASH_WINDOW_TREE_HOST_MIRRORING_DELEGATE_H_ + +#include <stdint.h> + +#include "ash/ash_export.h" +#include "base/macros.h" + +namespace aura { +class WindowTreeHost; +} // namespace aura + +namespace display { +class Display; +} // namespace display + +namespace ash { + +// A delegate for the unified window tree host as well as the mirroring display +// hosts. +class ASH_EXPORT AshWindowTreeHostMirroringDelegate { + public: + AshWindowTreeHostMirroringDelegate() = default; + virtual ~AshWindowTreeHostMirroringDelegate() = default; + + // Returns a pointer to the mirroring display with |display_id| if found, or + // nullptr if not found. + virtual const display::Display* GetMirroringDisplayById( + int64_t display_id) const = 0; + + // Sets the current window tree host that is the source of events which will + // be forwarded by the unified mode event targeter to the unified host. + virtual void SetCurrentEventTargeterSourceHost( + aura::WindowTreeHost* targeter_src_host) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(AshWindowTreeHostMirroringDelegate); +}; + +} // namespace ash + +#endif // ASH_HOST_ASH_WINDOW_TREE_HOST_MIRRORING_DELEGATE_H_
diff --git a/ash/host/ash_window_tree_host_mirroring_unified.cc b/ash/host/ash_window_tree_host_mirroring_unified.cc new file mode 100644 index 0000000..97959c53 --- /dev/null +++ b/ash/host/ash_window_tree_host_mirroring_unified.cc
@@ -0,0 +1,72 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/host/ash_window_tree_host_mirroring_unified.h" + +#include "ash/host/ash_window_tree_host_mirroring_delegate.h" +#include "ui/gfx/geometry/point3_f.h" +#include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/transform.h" + +namespace ash { + +AshWindowTreeHostMirroringUnified::AshWindowTreeHostMirroringUnified( + const gfx::Rect& initial_bounds, + int64_t mirroring_display_id, + AshWindowTreeHostMirroringDelegate* delegate) + : AshWindowTreeHostPlatform(initial_bounds), + mirroring_display_id_(mirroring_display_id), + delegate_(delegate) { + DCHECK(delegate_); +} + +AshWindowTreeHostMirroringUnified::~AshWindowTreeHostMirroringUnified() {} + +gfx::Transform +AshWindowTreeHostMirroringUnified::GetRootTransformForLocalEventCoordinates() + const { + gfx::Transform trans = GetRootTransform(); + + if (!is_shutting_down_) { + const auto* display = + delegate_->GetMirroringDisplayById(mirroring_display_id_); + DCHECK(display); + // Undo the translation in the root window transform, since this transform + // should be applied on local points to this host. + trans.Translate(SkIntToMScalar(display->bounds().x()), + SkIntToMScalar(display->bounds().y())); + } + + return trans; +} + +void AshWindowTreeHostMirroringUnified::ConvertDIPToPixels( + gfx::Point* point) const { + auto point_3f = gfx::Point3F(gfx::PointF(*point)); + // GetRootTransform() returns a transform that takes a point from the + // *unified* host coordinates to the *mirroring* host's pixel coordinates. + // ConvertDIPToPixels() and ConvertDIPToScreenInPixels() are called on local + // points in the *mirroring* host's root window, not on points in the unified + // host's. That's why we use the GetRootTransformForLocalEventCoordinates() + // defined above, which only scales those local points to the right size, and + // leaves the translation to be done by the MirroringScreenPositionClient + // functions. + GetRootTransformForLocalEventCoordinates().TransformPoint(&point_3f); + *point = gfx::ToFlooredPoint(point_3f.AsPointF()); +} + +void AshWindowTreeHostMirroringUnified::ConvertPixelsToDIP( + gfx::Point* point) const { + auto point_3f = gfx::Point3F(gfx::PointF(*point)); + GetInverseRootTransformForLocalEventCoordinates().TransformPoint(&point_3f); + *point = gfx::ToFlooredPoint(point_3f.AsPointF()); +} + +void AshWindowTreeHostMirroringUnified::PrepareForShutdown() { + is_shutting_down_ = true; + + AshWindowTreeHostPlatform::PrepareForShutdown(); +} + +} // namespace ash
diff --git a/ash/host/ash_window_tree_host_mirroring_unified.h b/ash/host/ash_window_tree_host_mirroring_unified.h new file mode 100644 index 0000000..3c67277 --- /dev/null +++ b/ash/host/ash_window_tree_host_mirroring_unified.h
@@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_HOST_ASH_WINDOW_TREE_HOST_MIRRORING_UNIFIED_H_ +#define ASH_HOST_ASH_WINDOW_TREE_HOST_MIRRORING_UNIFIED_H_ + +#include "ash/host/ash_window_tree_host_platform.h" + +namespace ash { + +class AshWindowTreeHostMirroringDelegate; + +// A window tree host for the mirroing displays that constitute the unified +// desktop. This correctly handles coordinates conversion from DIP to pixels and +// vice versa. +class AshWindowTreeHostMirroringUnified : public AshWindowTreeHostPlatform { + public: + AshWindowTreeHostMirroringUnified( + const gfx::Rect& initial_bounds, + int64_t mirroring_display_id, + AshWindowTreeHostMirroringDelegate* delegate); + ~AshWindowTreeHostMirroringUnified() override; + + // aura::WindowTreeHost: + gfx::Transform GetRootTransformForLocalEventCoordinates() const override; + void ConvertDIPToPixels(gfx::Point* point) const override; + void ConvertPixelsToDIP(gfx::Point* point) const override; + + // ash::AshWindowTreeHostPlatform: + void PrepareForShutdown() override; + + private: + int64_t mirroring_display_id_; + + AshWindowTreeHostMirroringDelegate* delegate_; // Not owned. + + bool is_shutting_down_ = false; + + DISALLOW_COPY_AND_ASSIGN(AshWindowTreeHostMirroringUnified); +}; + +} // namespace ash + +#endif // ASH_HOST_ASH_WINDOW_TREE_HOST_MIRRORING_UNIFIED_H_
diff --git a/ash/host/ash_window_tree_host_unified.cc b/ash/host/ash_window_tree_host_unified.cc index 862eca0..ebcc8cd4 100644 --- a/ash/host/ash_window_tree_host_unified.cc +++ b/ash/host/ash_window_tree_host_unified.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "ash/host/ash_window_tree_host_mirroring_delegate.h" #include "ash/host/root_window_transformer.h" #include "base/logging.h" #include "ui/aura/window.h" @@ -20,12 +21,18 @@ class UnifiedEventTargeter : public aura::WindowTargeter { public: - UnifiedEventTargeter(aura::Window* src_root, aura::Window* dst_root) - : src_root_(src_root), dst_root_(dst_root) {} + UnifiedEventTargeter(aura::Window* src_root, + aura::Window* dst_root, + AshWindowTreeHostMirroringDelegate* delegate) + : src_root_(src_root), dst_root_(dst_root), delegate_(delegate) { + DCHECK(delegate); + } ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, ui::Event* event) override { if (root == src_root_ && !event->target()) { + delegate_->SetCurrentEventTargeterSourceHost(src_root_->GetHost()); + if (event->IsLocatedEvent()) { ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event); located_event->ConvertLocationToTarget( @@ -33,6 +40,10 @@ } ignore_result( dst_root_->GetHost()->event_sink()->OnEventFromSource(event)); + + // Reset the source host. + delegate_->SetCurrentEventTargeterSourceHost(nullptr); + return nullptr; } else { NOTREACHED() << "event type:" << event->type(); @@ -40,15 +51,19 @@ } } + private: aura::Window* src_root_; aura::Window* dst_root_; + AshWindowTreeHostMirroringDelegate* delegate_; // Not owned. DISALLOW_COPY_AND_ASSIGN(UnifiedEventTargeter); }; AshWindowTreeHostUnified::AshWindowTreeHostUnified( - const gfx::Rect& initial_bounds) - : AshWindowTreeHostPlatform() { + const gfx::Rect& initial_bounds, + AshWindowTreeHostMirroringDelegate* delegate) + : AshWindowTreeHostPlatform(), delegate_(delegate) { + DCHECK(delegate); std::unique_ptr<ui::PlatformWindow> window(new ui::StubWindow(this)); window->SetBounds(initial_bounds); SetPlatformWindow(std::move(window)); @@ -70,7 +85,7 @@ AshWindowTreeHost* mirroring_ash_host) { aura::Window* src_root = mirroring_ash_host->AsWindowTreeHost()->window(); src_root->SetEventTargeter( - std::make_unique<UnifiedEventTargeter>(src_root, window())); + std::make_unique<UnifiedEventTargeter>(src_root, window(), delegate_)); DCHECK(std::find(mirroring_hosts_.begin(), mirroring_hosts_.end(), mirroring_ash_host) == mirroring_hosts_.end()); mirroring_hosts_.push_back(mirroring_ash_host);
diff --git a/ash/host/ash_window_tree_host_unified.h b/ash/host/ash_window_tree_host_unified.h index 7beafce..bdf60eed 100644 --- a/ash/host/ash_window_tree_host_unified.h +++ b/ash/host/ash_window_tree_host_unified.h
@@ -13,13 +13,16 @@ namespace ash { +class AshWindowTreeHostMirroringDelegate; + // A WTH used for unified desktop mode. This creates an offscreen // compositor whose texture will be copied into each displays' // compositor. class AshWindowTreeHostUnified : public AshWindowTreeHostPlatform, public aura::WindowObserver { public: - explicit AshWindowTreeHostUnified(const gfx::Rect& initial_bounds); + AshWindowTreeHostUnified(const gfx::Rect& initial_bounds, + AshWindowTreeHostMirroringDelegate* delegate); ~AshWindowTreeHostUnified() override; private: @@ -38,6 +41,8 @@ // aura::WindowObserver: void OnWindowDestroying(aura::Window* window) override; + AshWindowTreeHostMirroringDelegate* delegate_; // Not owned. + std::vector<AshWindowTreeHost*> mirroring_hosts_; DISALLOW_COPY_AND_ASSIGN(AshWindowTreeHostUnified);
diff --git a/ash/mus/network_connect_delegate_mus.cc b/ash/mus/network_connect_delegate_mus.cc index 01f044e..1d653689 100644 --- a/ash/mus/network_connect_delegate_mus.cc +++ b/ash/mus/network_connect_delegate_mus.cc
@@ -32,11 +32,6 @@ return false; } -void NetworkConnectDelegateMus::ShowMobileSimDialog() { - // TODO(mash): http://crbug.com/644355 - NOTIMPLEMENTED(); -} - void NetworkConnectDelegateMus::ShowMobileSetupDialog( const std::string& network_id) { // TODO(mash): http://crbug.com/644355
diff --git a/ash/mus/network_connect_delegate_mus.h b/ash/mus/network_connect_delegate_mus.h index be83f3a9..bd94e01b 100644 --- a/ash/mus/network_connect_delegate_mus.h +++ b/ash/mus/network_connect_delegate_mus.h
@@ -24,7 +24,6 @@ void ShowNetworkConfigure(const std::string& network_id) override; void ShowNetworkSettings(const std::string& network_id) override; bool ShowEnrollNetwork(const std::string& network_id) override; - void ShowMobileSimDialog() override; void ShowMobileSetupDialog(const std::string& network_id) override; void ShowNetworkConnectError(const std::string& error_name, const std::string& network_id) override;
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index c440b99..2eabaa1 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -486,7 +486,9 @@ } void WindowManager::OnCursorTouchVisibleChanged(bool enabled) { - ShellPortMash::Get()->OnCursorTouchVisibleChanged(enabled); + // Not applicable to Config::MUS. + if (config_ == Config::MASH) + ShellPortMash::Get()->OnCursorTouchVisibleChanged(enabled); } void WindowManager::OnWmSetClientArea(
diff --git a/ash/screen_util.cc b/ash/screen_util.cc index 77a0390..fdc568a 100644 --- a/ash/screen_util.cc +++ b/ash/screen_util.cc
@@ -50,17 +50,34 @@ // static gfx::Rect ScreenUtil::GetDisplayBoundsWithShelf(aura::Window* window) { - if (Shell::Get()->display_manager()->IsInUnifiedMode()) { - // In unified desktop mode, there is only one shelf in the first display. - const display::Display& first_display = - Shell::Get()->display_manager()->software_mirroring_display_list()[0]; - gfx::SizeF size(first_display.size()); - float scale = window->GetRootWindow()->bounds().height() / size.height(); - size.Scale(scale, scale); - return gfx::Rect(gfx::ToCeiledSize(size)); - } + if (!Shell::Get()->display_manager()->IsInUnifiedMode()) + return window->GetRootWindow()->bounds(); - return window->GetRootWindow()->bounds(); + const display::DisplayManager* display_manager = + Shell::Get()->display_manager(); + // Calculate the unified height scale value. + const int unified_logical_height = window->GetRootWindow()->bounds().height(); + const auto& unified_display_info = display_manager->GetDisplayInfo( + display::Screen::GetScreen()->GetPrimaryDisplay().id()); + const int unified_physical_height = + unified_display_info.bounds_in_native().height(); + const float unified_height_scale = + static_cast<float>(unified_logical_height) / unified_physical_height; + + // In unified desktop mode, there is only one shelf in the primary mirroing + // display which exists in the first row in the top left cell. + const int row_index = 0; + const int row_physical_height = + display_manager->GetUnifiedDesktopRowMaxHeight(row_index); + const int row_logical_height = row_physical_height * unified_height_scale; + + const display::Display* first_display = + display_manager->GetPrimaryMirroringDisplayForUnifiedDesktop(); + DCHECK(first_display); + gfx::SizeF size(first_display->size()); + const float scale = row_logical_height / size.height(); + size.Scale(scale, scale); + return gfx::Rect(gfx::ToCeiledSize(size)); } } // namespace ash
diff --git a/ash/screen_util_unittest.cc b/ash/screen_util_unittest.cc index 2f055274..d6bf080c 100644 --- a/ash/screen_util_unittest.cc +++ b/ash/screen_util_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/screen_util.h" +#include "ash/public/cpp/config.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/wm/window_util.h" @@ -11,6 +12,7 @@ #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/display/manager/display_manager.h" +#include "ui/display/unified_desktop_utils.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" #include "ui/wm/core/coordinate_conversion.h" @@ -128,4 +130,45 @@ ScreenUtil::GetDisplayBoundsWithShelf(window).ToString()); } +TEST_F(ScreenUtilTest, ShelfDisplayBoundsInUnifiedDesktopGrid) { + // TODO: requires unified desktop mode. http://crbug.com/581462. + if (Shell::GetAshConfig() == Config::MASH) + return; + + UpdateDisplay("500x400,400x600,300x600,200x300,600x200,350x400"); + display_manager()->SetUnifiedDesktopEnabled(true); + + views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds( + NULL, CurrentContext(), gfx::Rect(10, 10, 100, 100)); + aura::Window* window = widget->GetNativeWindow(); + + display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); + ASSERT_EQ(6u, list.size()); + // Create a 3 x 2 vertical layout matrix and set it. + // [500 x 400] [400 x 600] + // [300 x 600] [200 x 300] + // [600 x 200] [350 x 400] + display::UnifiedDesktopLayoutMatrix matrix; + matrix.resize(3u); + matrix[0].emplace_back(list[0]); + matrix[0].emplace_back(list[1]); + matrix[1].emplace_back(list[2]); + matrix[1].emplace_back(list[3]); + matrix[2].emplace_back(list[4]); + matrix[2].emplace_back(list[5]); + display_manager()->SetUnifiedDesktopMatrix(matrix); + display::Screen* screen = display::Screen::GetScreen(); + EXPECT_EQ(gfx::Size(766, 1254), screen->GetPrimaryDisplay().size()); + + // Regardless of where the window is, the shelf is always in the top left + // display in the matrix. + EXPECT_EQ(gfx::Rect(0, 0, 499, 400), + ScreenUtil::GetDisplayBoundsWithShelf(window)); + + // Move to the bottom right display. + widget->SetBounds(gfx::Rect(620, 940, 100, 100)); + EXPECT_EQ(gfx::Rect(0, 0, 499, 400), + ScreenUtil::GetDisplayBoundsWithShelf(window)); +} + } // namespace ash
diff --git a/ash/system/power/power_event_observer.cc b/ash/system/power/power_event_observer.cc index 96258e3f..9261fcd 100644 --- a/ash/system/power/power_event_observer.cc +++ b/ash/system/power/power_event_observer.cc
@@ -44,18 +44,16 @@ } // namespace PowerEventObserver::PowerEventObserver() - : screen_locked_(false), waiting_for_lock_screen_animations_(false) { + : session_observer_(this), + screen_locked_(Shell::Get()->session_controller()->IsScreenLocked()), + waiting_for_lock_screen_animations_(false) { chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( this); - chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver( - this); } PowerEventObserver::~PowerEventObserver() { chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( this); - chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver( - this); } void PowerEventObserver::OnLockAnimationsComplete() { @@ -142,21 +140,21 @@ ResumeRenderingRequests(); } -void PowerEventObserver::ScreenIsLocked() { - screen_locked_ = true; - waiting_for_lock_screen_animations_ = true; +void PowerEventObserver::OnLockStateChanged(bool locked) { + if (locked) { + screen_locked_ = true; + waiting_for_lock_screen_animations_ = true; - // The screen is now locked but the pending suspend, if any, will be blocked - // until all the animations have completed. - if (!screen_lock_callback_.is_null()) { - VLOG(1) << "Screen locked due to suspend"; + // The screen is now locked but the pending suspend, if any, will be blocked + // until all the animations have completed. + if (!screen_lock_callback_.is_null()) { + VLOG(1) << "Screen locked due to suspend"; + } else { + VLOG(1) << "Screen locked without suspend"; + } } else { - VLOG(1) << "Screen locked without suspend"; + screen_locked_ = false; } } -void PowerEventObserver::ScreenIsUnlocked() { - screen_locked_ = false; -} - } // namespace ash
diff --git a/ash/system/power/power_event_observer.h b/ash/system/power/power_event_observer.h index 3e6d60c..4d05543 100644 --- a/ash/system/power/power_event_observer.h +++ b/ash/system/power/power_event_observer.h
@@ -6,18 +6,18 @@ #define ASH_SYSTEM_POWER_POWER_EVENT_OBSERVER_H_ #include "ash/ash_export.h" +#include "ash/session/session_observer.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "chromeos/dbus/power_manager_client.h" -#include "chromeos/dbus/session_manager_client.h" namespace ash { // A class that observes power-management-related events. class ASH_EXPORT PowerEventObserver : public chromeos::PowerManagerClient::Observer, - public chromeos::SessionManagerClient::Observer { + public SessionObserver { public: // This class registers/unregisters itself as an observer in ctor/dtor. PowerEventObserver(); @@ -33,9 +33,10 @@ void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; void SuspendDone(const base::TimeDelta& sleep_duration) override; - // chromeos::SessionManagerClient::Observer overrides. - void ScreenIsLocked() override; - void ScreenIsUnlocked() override; + // SessionObserver overrides: + void OnLockStateChanged(bool locked) override; + + ScopedSessionObserver session_observer_; // Is the screen currently locked? bool screen_locked_;
diff --git a/ash/system/power/power_event_observer_unittest.cc b/ash/system/power/power_event_observer_unittest.cc index 8b1870ad..fd8f940e 100644 --- a/ash/system/power/power_event_observer_unittest.cc +++ b/ash/system/power/power_event_observer_unittest.cc
@@ -77,14 +77,14 @@ // It should run the callback when it hears that the screen is locked and the // lock screen animations have completed. - observer_->ScreenIsLocked(); + BlockUserSession(BLOCKED_BY_LOCK_SCREEN); observer_->OnLockAnimationsComplete(); EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks()); // If the system is already locked, no callback should be requested. observer_->SuspendDone(base::TimeDelta()); - observer_->ScreenIsUnlocked(); - observer_->ScreenIsLocked(); + UnblockUserSession(); + BlockUserSession(BLOCKED_BY_LOCK_SCREEN); observer_->OnLockAnimationsComplete(); observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER); EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks()); @@ -114,7 +114,7 @@ observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER); EXPECT_EQ(1, GetNumVisibleCompositors()); - observer_->ScreenIsLocked(); + BlockUserSession(BLOCKED_BY_LOCK_SCREEN); EXPECT_EQ(1, GetNumVisibleCompositors()); observer_->OnLockAnimationsComplete(); @@ -133,7 +133,7 @@ EXPECT_EQ(1, GetNumVisibleCompositors()); observer_->SuspendDone(base::TimeDelta()); - observer_->ScreenIsLocked(); + BlockUserSession(BLOCKED_BY_LOCK_SCREEN); observer_->OnLockAnimationsComplete(); EXPECT_EQ(1, GetNumVisibleCompositors()); } @@ -157,7 +157,7 @@ observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER); EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks()); - observer_->ScreenIsLocked(); + BlockUserSession(BLOCKED_BY_LOCK_SCREEN); observer_->SuspendDone(base::TimeDelta()); observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
diff --git a/ash/system/screen_layout_observer.cc b/ash/system/screen_layout_observer.cc index 14c0a00..4117b91d 100644 --- a/ash/system/screen_layout_observer.cc +++ b/ash/system/screen_layout_observer.cc
@@ -51,18 +51,21 @@ base::string16 GetDisplaySize(int64_t display_id) { display::DisplayManager* display_manager = GetDisplayManager(); - const display::Display* display = - &display_manager->GetDisplayForId(display_id); - // We don't show display size for mirrored display. Fallback // to empty string if this happens on release build. - bool mirroring = display_manager->mirroring_display_id() == display_id; + const display::DisplayIdList id_list = + display_manager->GetMirroringDstDisplayIdList(); + const bool mirroring = + display_manager->IsInMirrorMode() && + std::find(id_list.begin(), id_list.end(), display_id) != id_list.end(); DCHECK(!mirroring); if (mirroring) return base::string16(); - DCHECK(display->is_valid()); - return base::UTF8ToUTF16(display->size().ToString()); + const display::Display& display = + display_manager->GetDisplayForId(display_id); + DCHECK(display.is_valid()); + return base::UTF8ToUTF16(display.size().ToString()); } // Callback to handle a user selecting the notification view. @@ -131,10 +134,11 @@ // Returns the notification message that should be shown when mirror display // mode is entered. base::string16 GetEnterMirrorModeMessage() { + DCHECK(GetDisplayManager()->IsInMirrorMode()); if (display::Display::HasInternalDisplay()) { return l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, - GetDisplayName(GetDisplayManager()->mirroring_display_id())); + GetDisplayName(GetDisplayManager()->GetMirroringDstDisplayIdList()[0])); } return l10n_util::GetStringUTF16(
diff --git a/ash/system/screen_layout_observer_unittest.cc b/ash/system/screen_layout_observer_unittest.cc index e65f12d..0937f34 100644 --- a/ash/system/screen_layout_observer_unittest.cc +++ b/ash/system/screen_layout_observer_unittest.cc
@@ -97,8 +97,9 @@ } base::string16 ScreenLayoutObserverTest::GetMirroringDisplayName() { + DCHECK(display_manager()->IsInMirrorMode()); return base::UTF8ToUTF16(display_manager()->GetDisplayNameForId( - display_manager()->mirroring_display_id())); + display_manager()->GetMirroringDstDisplayIdList()[0])); } const message_center::Notification*
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index b82c286..69d07d0b 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -36,7 +36,10 @@ const size_t kTestMaxAllocation = 4096; bool IsLargeMemoryDevice() { - return base::SysInfo::AmountOfPhysicalMemory() >= 2LL * 1024 * 1024 * 1024; + // Treat any device with 2GiB or more of physical memory as a "large memory + // device". We check for slightly less than 2GiB so that devices with a small + // amount of memory not accessible to the OS still count as "large". + return base::SysInfo::AmountOfPhysicalMemory() >= 2040LL * 1024 * 1024; } bool SetAddressSpaceLimit() { @@ -178,7 +181,7 @@ return; } - EXPECT_TRUE(SetAddressSpaceLimit()); + ASSERT_TRUE(SetAddressSpaceLimit()); // Work out the number of allocations for 6 GB of memory. const int numAllocations = (6 * 1024 * 1024) / (allocSize / 1024);
diff --git a/base/command_line.cc b/base/command_line.cc index 873da81..92d78ae5 100644 --- a/base/command_line.cc +++ b/base/command_line.cc
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/macros.h" +#include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" @@ -177,14 +178,12 @@ : argv_(other.argv_), switches_(other.switches_), begin_args_(other.begin_args_) { - ResetStringPieces(); } CommandLine& CommandLine::operator=(const CommandLine& other) { argv_ = other.argv_; switches_ = other.switches_; begin_args_ = other.begin_args_; - ResetStringPieces(); return *this; } @@ -268,7 +267,6 @@ void CommandLine::InitFromArgv(const StringVector& argv) { argv_ = StringVector(1); switches_.clear(); - switches_by_stringpiece_.clear(); begin_args_ = 1; SetProgram(argv.empty() ? FilePath() : FilePath(argv[0])); AppendSwitchesAndArguments(this, argv); @@ -288,8 +286,7 @@ bool CommandLine::HasSwitch(const base::StringPiece& switch_string) const { DCHECK_EQ(ToLowerASCII(switch_string), switch_string); - return switches_by_stringpiece_.find(switch_string) != - switches_by_stringpiece_.end(); + return ContainsKey(switches_, switch_string); } bool CommandLine::HasSwitch(const char switch_constant[]) const { @@ -318,9 +315,8 @@ CommandLine::StringType CommandLine::GetSwitchValueNative( const base::StringPiece& switch_string) const { DCHECK_EQ(ToLowerASCII(switch_string), switch_string); - auto result = switches_by_stringpiece_.find(switch_string); - return result == switches_by_stringpiece_.end() ? StringType() - : *(result->second); + auto result = switches_.find(switch_string); + return result == switches_.end() ? StringType() : result->second; } void CommandLine::AppendSwitch(const std::string& switch_string) { @@ -346,7 +342,6 @@ switches_.insert(make_pair(switch_key.substr(prefix_length), value)); if (!insertion.second) insertion.first->second = value; - switches_by_stringpiece_[insertion.first->first] = &(insertion.first->second); // Preserve existing switch prefixes in |argv_|; only append one if necessary. if (prefix_length == 0) combined_switch_string = kSwitchPrefixes[0] + combined_switch_string; @@ -489,10 +484,4 @@ return params; } -void CommandLine::ResetStringPieces() { - switches_by_stringpiece_.clear(); - for (const auto& entry : switches_) - switches_by_stringpiece_[entry.first] = &(entry.second); -} - } // namespace base
diff --git a/base/command_line.h b/base/command_line.h index 3d29f8fe..31b22d6 100644 --- a/base/command_line.h +++ b/base/command_line.h
@@ -40,8 +40,7 @@ using CharType = StringType::value_type; using StringVector = std::vector<StringType>; - using SwitchMap = std::map<std::string, StringType>; - using StringPieceSwitchMap = std::map<StringPiece, const StringType*>; + using SwitchMap = std::map<std::string, StringType, std::less<>>; // A constructor for CommandLines that only carry switches and arguments. enum NoProgram { NO_PROGRAM }; @@ -230,11 +229,6 @@ // also quotes parts with '%' in them. StringType GetArgumentsStringInternal(bool quote_placeholders) const; - // Reconstruct |switches_by_stringpiece| to be a mirror of |switches|. - // |switches_by_stringpiece| only contains pointers to objects owned by - // |switches|. - void ResetStringPieces(); - // The singleton CommandLine representing the current process's command line. static CommandLine* current_process_commandline_; @@ -244,12 +238,6 @@ // Parsed-out switch keys and values. SwitchMap switches_; - // A mirror of |switches_| with only references to the actual strings. - // The StringPiece internally holds a pointer to a key in |switches_| while - // the mapped_type points to a value in |switches_|. - // Used for allocation-free lookups. - StringPieceSwitchMap switches_by_stringpiece_; - // The index after the program and switches, any arguments start here. size_t begin_args_; };
diff --git a/build/config/jumbo.gni b/build/config/jumbo.gni index 0a6a3ba5c..b6a7f80 100644 --- a/build/config/jumbo.gni +++ b/build/config/jumbo.gni
@@ -9,9 +9,9 @@ # compilation. use_jumbo_build = false - # A target to exclude from jumbo builds, for optimal round trip time - # when frequently changing a single cpp file. - jumbo_build_excluded = "" + # A list of targets to exclude from jumbo builds, for optimal round trip time + # when frequently changing a set of cpp files. + jumbo_build_excluded = [] # How many files to group at most. Smaller numbers give more # parallellism, higher numbers give less total CPU usage. Higher @@ -59,8 +59,10 @@ if (defined(invoker.never_build_jumbo) && invoker.never_build_jumbo) { use_jumbo_build_for_target = false } - if (target_name == jumbo_build_excluded) { - use_jumbo_build_for_target = false + foreach(excluded_target, jumbo_build_excluded) { + if (target_name == excluded_target) { + use_jumbo_build_for_target = false + } } excluded_sources = []
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 0cc86e7..1845d7e 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -211,7 +211,11 @@ render_pass->CreateAndAppendSharedQuadState(); if (raster_source_->IsSolidColor()) { - float max_contents_scale = GetIdealContentsScale(); + float max_contents_scale = CanHaveTilings() + ? ideal_contents_scale_ + : std::min(kMaxIdealContentsScale, + std::max(GetIdealContentsScale(), + MinimumContentsScale())); // The downstream CA layers use shared_quad_state to generate resources of // the right size even if it is a solid color picture layer.
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 7bf4d58..d10cb1b 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -30,27 +30,6 @@ namespace cc { namespace { -// Reuse canvas setup code from RasterSource by storing it into a PaintRecord -// that can then be transported. This is somewhat more convoluted then it -// should be. -static sk_sp<PaintRecord> SetupForRaster( - const RasterSource* raster_source, - const gfx::Rect& raster_full_rect, - const gfx::Rect& playback_rect, - const gfx::AxisTransform2d& transform) { - PaintRecorder recorder; - PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(raster_full_rect)); - // TODO(enne): The GLES2Decoder is guaranteeing the clear here, but it - // might be nice to figure out how to include the debugging clears for - // this mode. - canvas->translate(-raster_full_rect.x(), -raster_full_rect.y()); - canvas->clipRect(SkRect::MakeFromIRect(gfx::RectToSkIRect(playback_rect))); - canvas->translate(transform.translation().x(), transform.translation().y()); - canvas->scale(transform.scale(), transform.scale()); - return recorder.finishRecordingAsPicture(); -} - static void RasterizeSourceOOP( const RasterSource* raster_source, bool resource_has_previous_content, @@ -66,24 +45,19 @@ gpu::gles2::GLES2Interface* gl = context_provider->ContextGL(); GLuint texture_id = resource_lock->ConsumeTexture(gl); - auto setup_list = base::MakeRefCounted<DisplayItemList>( - DisplayItemList::kTopLevelDisplayItemList); - setup_list->StartPaint(); - setup_list->push<DrawRecordOp>(SetupForRaster(raster_source, raster_full_rect, - playback_rect, transform)); - setup_list->EndPaintOfUnpaired(raster_full_rect); - setup_list->Finalize(); - - // TODO(enne): need to pass color space and transform in the decoder. gl->BeginRasterCHROMIUM(texture_id, raster_source->background_color(), msaa_sample_count, playback_settings.use_lcd_text, use_distance_field_text, resource_lock->PixelConfig()); - gl->RasterCHROMIUM(setup_list.get(), playback_rect.x(), playback_rect.y(), - playback_rect.width(), playback_rect.height()); + // TODO(enne): need to pass color space into this function as well. + float recording_to_raster_scale = + transform.scale() / raster_source->recording_scale_factor(); gl->RasterCHROMIUM(raster_source->GetDisplayItemList().get(), + raster_full_rect.x(), raster_full_rect.y(), playback_rect.x(), playback_rect.y(), - playback_rect.width(), playback_rect.height()); + playback_rect.width(), playback_rect.height(), + transform.translation().x(), transform.translation().y(), + recording_to_raster_scale); gl->EndRasterCHROMIUM(); gl->DeleteTextures(1, &texture_id);
diff --git a/cc/raster/raster_source.h b/cc/raster/raster_source.h index b0626273..8f14c7d5 100644 --- a/cc/raster/raster_source.h +++ b/cc/raster/raster_source.h
@@ -111,6 +111,8 @@ return display_list_; } + float recording_scale_factor() const { return recording_scale_factor_; } + SkColor background_color() const { return background_color_; } base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index cee74b6..f3aa211 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -352,9 +352,18 @@ {% endfor %} {% if enable_vr == "true" %} <activity android:name="org.chromium.chrome.browser.vr.VrMainActivity" + android:theme="@style/VrSupportThemeLauncher" + android:exported="true" + android:enableVrMode="@string/gvr_vr_mode_component" + android:taskAffinity="" + android:relinquishTaskIdentity="true" + android:excludeFromRecents="true" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + {{ self.supports_vr() }} + </activity> + <activity android:name="org.chromium.chrome.browser.vr.CustomTabVrActivity" android:theme="@style/VrSupportTheme" android:screenOrientation="landscape" - android:exported="true" android:enableVrMode="@string/gvr_vr_mode_component" android:taskAffinity="" android:persistableMode="persistNever" @@ -442,19 +451,21 @@ </activity> <activity android:name="org.chromium.chrome.browser.firstrun.LightweightFirstRunActivity" android:theme="@style/SimpleDialog" - android:launchMode="singleInstance" - android:excludeFromRecents="true" - android:autoRemoveFromRecents="true" - android:windowSoftInputMode="stateHidden|adjustPan" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + {{ self.first_run_activity_common() }}> </activity> <activity android:name="org.chromium.chrome.browser.firstrun.FirstRunActivity" - android:theme="@style/DialogWhenLarge" + android:theme="@style/FirstRunTheme" + {% block first_run_activity_common %} android:launchMode="singleInstance" android:excludeFromRecents="true" android:autoRemoveFromRecents="true" android:windowSoftInputMode="stateHidden|adjustPan" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + {% endblock %} + </activity> + <activity android:name="org.chromium.chrome.browser.firstrun.TabbedModeFirstRunActivity" + android:theme="@style/TabbedModeFirstRunTheme" + {{ self.first_run_activity_common() }}> </activity> {% if enable_vr == "true" %} <activity android:name="org.chromium.chrome.browser.vr_shell.VrFirstRunActivity"
diff --git a/chrome/android/java/res/drawable-sw600dp/window_background.xml b/chrome/android/java/res/drawable-sw600dp/window_background.xml index ec92a59..b0a17462 100644 --- a/chrome/android/java/res/drawable-sw600dp/window_background.xml +++ b/chrome/android/java/res/drawable-sw600dp/window_background.xml
@@ -5,9 +5,14 @@ <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + <item> + <shape android:shape="rectangle"> + <solid android:color="@android:color/black" /> + </shape> + </item> <item android:top="25dp" android:bottom="0px"> - <nine-patch android:src="@drawable/toolbar_background" /> - </item> -</layer-list> \ No newline at end of file + <nine-patch android:src="@drawable/toolbar_background" /> + </item> +</layer-list>
diff --git a/chrome/android/java/res/drawable-sw720dp-v19/window_background.xml b/chrome/android/java/res/drawable-sw720dp-v19/window_background.xml index da76c26..527afabec 100644 --- a/chrome/android/java/res/drawable-sw720dp-v19/window_background.xml +++ b/chrome/android/java/res/drawable-sw720dp-v19/window_background.xml
@@ -6,9 +6,14 @@ <!-- Tablets from api 19 and up have the top notification bar --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + <item> + <shape android:shape="rectangle"> + <solid android:color="@android:color/black" /> + </shape> + </item> <item android:top="25dp" android:bottom="0px"> <nine-patch android:src="@drawable/toolbar_background" /> </item> -</layer-list> \ No newline at end of file +</layer-list>
diff --git a/chrome/android/java/res/drawable-sw720dp/window_background.xml b/chrome/android/java/res/drawable-sw720dp/window_background.xml index a0a7841f..d1940b8 100644 --- a/chrome/android/java/res/drawable-sw720dp/window_background.xml +++ b/chrome/android/java/res/drawable-sw720dp/window_background.xml
@@ -9,4 +9,4 @@ <item> <nine-patch android:src="@drawable/toolbar_background" /> </item> -</layer-list> \ No newline at end of file +</layer-list>
diff --git a/chrome/android/java/res/values-large/dimens.xml b/chrome/android/java/res/values-large/dimens.xml index bfa99b4..5c0d5b54 100644 --- a/chrome/android/java/res/values-large/dimens.xml +++ b/chrome/android/java/res/values-large/dimens.xml
@@ -5,4 +5,11 @@ <resources> <dimen name="fre_content_margin">60dp</dimen> + + <!-- Copy of corresponding abc_* values from AppCompat. Used by + TabbedModeFirstRunActivity to simulate DialogWhenLarge layout. --> + <item type="dimen" name="dialog_fixed_width_major">60%</item> + <item type="dimen" name="dialog_fixed_width_minor">90%</item> + <item type="dimen" name="dialog_fixed_height_major">60%</item> + <item type="dimen" name="dialog_fixed_height_minor">90%</item> </resources>
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 3ddf9ba..5619642 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -51,6 +51,12 @@ <item name="android:windowBackground">@android:color/white</item> </style> + <style name="FirstRunTheme" parent="DialogWhenLarge"> + </style> + + <style name="TabbedModeFirstRunTheme" parent="TabbedModeTheme"> + </style> + <!-- The theme to use when starting Chrome in VR mode.--> <style name="VrSupportTheme" parent="MainTheme"> <!-- Android shows a preview window to give the user immediate feedback that the @@ -62,6 +68,10 @@ <item name="android:windowDisablePreview">true</item> <item name="android:windowBackground">@android:color/black</item> </style> + <style name="VrSupportThemeLauncher" parent="@android:style/Theme.NoDisplay"> + <item name="android:windowDisablePreview">true</item> + <item name="android:windowBackground">@android:color/black</item> + </style> <style name="FullscreenWhite" parent="Theme.AppCompat.Light" > <item name="android:windowBackground">@android:color/white</item>
diff --git a/chrome/android/java/res/values-xlarge/dimens.xml b/chrome/android/java/res/values-xlarge/dimens.xml new file mode 100644 index 0000000..2903e47 --- /dev/null +++ b/chrome/android/java/res/values-xlarge/dimens.xml
@@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<resources> + <!-- Copy of corresponding abc_* values from AppCompat. Used by + TabbedModeFirstRunActivity to simulate DialogWhenLarge layout. --> + <item type="dimen" name="dialog_fixed_width_major">50%</item> + <item type="dimen" name="dialog_fixed_width_minor">70%</item> + <item type="dimen" name="dialog_fixed_height_major">60%</item> + <item type="dimen" name="dialog_fixed_height_minor">90%</item> +</resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index a440cf1..c422e4e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -137,6 +137,7 @@ import org.chromium.chrome.browser.util.ChromeFileProvider; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.FeatureUtilities; +import org.chromium.chrome.browser.vr_shell.VrIntentUtils; import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.chrome.browser.webapps.AddToHomescreenManager; import org.chromium.chrome.browser.widget.ControlContainer; @@ -308,6 +309,12 @@ public void preInflationStartup() { super.preInflationStartup(); + // We need to explicitly enable VR mode here so that the system doesn't kick us out of VR + // mode while we prepare for VR rendering. + if (VrIntentUtils.isVrIntent(getIntent())) { + VrShellDelegate.setVrModeEnabled(this); + } + // Force a partner customizations refresh if it has yet to be initialized. This can happen // if Chrome is killed and you refocus a previous activity from Android recents, which does // not go through ChromeLauncherActivity that would have normally triggered this. @@ -925,8 +932,10 @@ @Override protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); + // This should be called before the call to super so that the needed VR flags are set as + // soon as the VR intent is received. VrShellDelegate.maybeHandleVrIntentPreNative(this, intent); + super.onNewIntent(intent); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index ce2699c..102969d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -223,6 +223,7 @@ public static final String VIDEO_PERSISTENCE = "VideoPersistence"; public static final String VR_BROWSING_FEEDBACK = "VrBrowsingFeedback"; public static final String VR_CUSTOM_TAB_BROWSING = "VrCustomTabBrowsing"; + public static final String VR_LAUNCH_INTENT = "VrLaunchIntent"; public static final String VR_SHELL = "VrShell"; public static final String WEB_PAYMENTS = "WebPayments"; public static final String WEB_PAYMENTS_METHOD_SECTION_ORDER_V2 =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java index 341ff4940..c7c38d6c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java
@@ -126,20 +126,6 @@ public static final String ENABLE_HUNG_RENDERER_INFOBAR = "enable-hung-renderer-infobar"; /** - * Enables Web Notification custom layouts. - * Native switch - switches::kEnableWebNotificationCustomLayouts - */ - public static final String ENABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS = - "enable-web-notification-custom-layouts"; - - /** - * Disables Web Notification custom layouts. - * Native switch - switches::kDisableWebNotificationCustomLayouts - */ - public static final String DISABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS = - "disable-web-notification-custom-layouts"; - - /** * Determines which of the Herb prototypes is being tested. * See about:flags for descriptions. */ @@ -183,8 +169,11 @@ /** Switch for enabling "restricted area" swipe logic for Chrome Home. */ public static final String CHROME_HOME_SWIPE_LOGIC_RESTRICT_AREA = "restrict-area"; - /** Switch for enabling "button only" swipe logic for Chrome Home. */ - public static final String CHROME_HOME_SWIPE_LOGIC_BUTTON_ONLY = "button-only"; + /** + * Switch for enabling "velocity" swipe logic for Chrome Home. This means the flings will not + * open the sheet; the user must slide up the sheet relatively slowly. + */ + public static final String CHROME_HOME_SWIPE_LOGIC_VELOCITY = "velocity"; /** Switch for enabling the Chrome Home Survey. */ public static final String CHROME_HOME_FORCE_ENABLE_SURVEY = "force-enable-chrome-home-survey";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java index fdc78d3..bab06395 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -15,6 +15,7 @@ import android.os.Bundle; import android.os.StrictMode; import android.support.annotation.IntDef; +import android.support.annotation.Nullable; import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; @@ -40,7 +41,7 @@ import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.UrlUtilities; -import org.chromium.chrome.browser.vr.VrMainActivity; +import org.chromium.chrome.browser.vr.CustomTabVrActivity; import org.chromium.chrome.browser.vr_shell.VrIntentUtils; import org.chromium.chrome.browser.webapps.ActivityAssigner; import org.chromium.chrome.browser.webapps.WebappLauncherActivity; @@ -83,6 +84,7 @@ private final Intent mIntent; private final boolean mIsCustomTabIntent; private final boolean mIsHerbIntent; + private final boolean mIsVrIntent; @IntDef({Action.CONTINUE, Action.FINISH_ACTIVITY, Action.FINISH_ACTIVITY_REMOVE_TASK}) @Retention(RetentionPolicy.SOURCE) @@ -144,11 +146,13 @@ recordIntentMetrics(); - boolean isCustomTabIntent = isCustomTabIntent(mIntent); + mIsVrIntent = VrIntentUtils.isVrIntent(mIntent); + boolean isCustomTabIntent = (!mIsVrIntent && isCustomTabIntent(mIntent)) + || (mIsVrIntent && VrIntentUtils.isCustomTabVrIntent(mIntent)); boolean isHerbIntent = false; // If the intent was created by Reader Mode, ignore herb and custom tab information. if (!isCustomTabIntent && !ReaderModeManager.isReaderModeCreatedIntent(mIntent) - && !VrIntentUtils.isVrIntent(mIntent)) { + && !mIsVrIntent) { isHerbIntent = isHerbIntent(mIntent); isCustomTabIntent = isHerbIntent; } @@ -157,6 +161,19 @@ } /** + * Returns the options that should be used to start an activity. + */ + @Nullable + private Bundle getStartActivityIntentOptions() { + Bundle options = null; + if (mIsVrIntent) { + // These options hide the 2D screenshot while we prepare for VR rendering. + options = VrIntentUtils.getVrIntentOptions(mActivity); + } + return options; + } + + /** * Figure out how to route the Intent. Because this is on the critical path to startup, please * avoid making the pathway any more complicated than it already is. Make sure that anything * you add _absolutely has_ to be here. @@ -332,9 +349,8 @@ */ public static boolean isCustomTabIntent(Intent intent) { if (intent == null) return false; - if ((CustomTabsIntent.shouldAlwaysUseBrowserUI(intent) - || !intent.hasExtra(CustomTabsIntent.EXTRA_SESSION)) - && !VrIntentUtils.isCustomTabVrIntent(intent)) { + if (CustomTabsIntent.shouldAlwaysUseBrowserUI(intent) + || !intent.hasExtra(CustomTabsIntent.EXTRA_SESSION)) { return false; } return IntentHandler.getUrlFromIntent(intent) != null; @@ -365,7 +381,7 @@ // Force a new document L+ to ensure the proper task/stack creation. newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); if (VrIntentUtils.isVrIntent(intent)) { - newIntent.setClassName(context, VrMainActivity.class.getName()); + newIntent.setClassName(context, CustomTabVrActivity.class.getName()); } else { newIntent.setClassName(context, SeparateTaskCustomTabActivity.class.getName()); } @@ -413,17 +429,9 @@ maybePrefetchDnsInBackground(); // Create and fire a launch intent. - Bundle options = null; - if (VrIntentUtils.isVrIntent(mIntent)) { - // VR intents will open a VR-specific CCT {@link VrMainActivity} which - // starts with a theme that disables the system preview window. As a side effect, you - // see a flash of the previous app exiting before Chrome is started. These options - // prevent that flash as it can look jarring while the user is in their headset. - options = VrIntentUtils.getVrIntentOptions(mActivity); - } mActivity.startActivity(createCustomTabActivityIntent(mActivity, mIntent, !isCustomTabIntent(mIntent) && mIsHerbIntent), - options); + getStartActivityIntentOptions()); if (mIsHerbIntent) { mActivity.overridePendingTransition(R.anim.activity_open_enter, R.anim.no_anim); } @@ -463,7 +471,7 @@ // This system call is often modified by OEMs and not actionable. http://crbug.com/619646. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); try { - mActivity.startActivity(newIntent); + mActivity.startActivity(newIntent, getStartActivityIntentOptions()); } catch (SecurityException ex) { if (isContentScheme) { Toast.makeText(mActivity,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/OWNERS index b6fc493..311827f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/OWNERS
@@ -4,3 +4,4 @@ # This is For simple changes of adding/removing features. For more structural # changes, use the normal OWNERS rules. per-file ChromeFeatureList.java=* +per-file ChromeSwitches.java=*
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index 81fea9a7..5acd1554 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.ComponentName; import android.graphics.Bitmap; +import android.os.Build; import android.util.Pair; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -23,6 +24,7 @@ import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.share.ShareParams; import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.base.MenuSourceType; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid.OnCloseContextMenuListener; @@ -120,7 +122,8 @@ } }; - if (ChromeFeatureList.isEnabled(ChromeFeatureList.CUSTOM_CONTEXT_MENU)) { + if (ChromeFeatureList.isEnabled(ChromeFeatureList.CUSTOM_CONTEXT_MENU) + && params.getSourceType() != MenuSourceType.MENU_SOURCE_MOUSE) { List<Pair<Integer, List<ContextMenuItem>>> items = mPopulator.buildContextMenu(null, mActivity, mCurrentContextMenuParams); if (items.isEmpty()) { @@ -160,7 +163,18 @@ // The Platform Context Menu requires the listener within this helper since this helper and // provides context menu for us to show. view.setOnCreateContextMenuListener(this); - if (view.showContextMenu()) { + boolean wasContextMenuShown = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + && params.getSourceType() == MenuSourceType.MENU_SOURCE_MOUSE) { + final float density = view.getResources().getDisplayMetrics().density; + final float touchPointXPx = params.getTriggeringTouchXDp() * density; + final float touchPointYPx = + (params.getTriggeringTouchYDp() * density) + topContentOffsetPx; + wasContextMenuShown = view.showContextMenu(touchPointXPx, touchPointYPx); + } else { + wasContextMenuShown = view.showContextMenu(); + } + if (wasContextMenuShown) { mOnMenuShown.run(); windowAndroid.addContextMenuCloseListener(new OnCloseContextMenuListener() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index adcaf27..bddad7d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -874,7 +874,11 @@ public void notifyDownloadCanceled(ContentId id) { DownloadSharedPreferenceEntry entry = mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(id); - if (entry == null) return; + if (entry == null) { + // In case notifyDownloadCanceled was called after the entry has already been removed. + stopTrackingInProgressDownload(id, hasDownloadNotificationsInternal(-1)); + return; + } cancelNotification(entry.notificationId, id); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index ccc851733..27fb508 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -7,8 +7,10 @@ import android.app.Activity; import android.app.Fragment; import android.os.Bundle; +import android.support.annotation.CallSuper; import android.support.annotation.StringRes; import android.text.TextUtils; +import android.view.View; import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; @@ -179,16 +181,26 @@ return null; } + /** + * Creates the content view for this activity. + * The only thing subclasses can do is wrapping the view returned by super implementation + * in some extra layout. + */ + @CallSuper + protected View createContentView() { + mPager = new FirstRunViewPager(this); + mPager.setId(R.id.fre_pager); + mPager.setOffscreenPageLimit(3); + return mPager; + } + @Override public void setContentView() { initializeStateFromLaunchData(); setFinishOnTouchOutside(true); - mPager = new FirstRunViewPager(this); - mPager.setId(R.id.fre_pager); - mPager.setOffscreenPageLimit(3); - setContentView(mPager); + setContentView(createContentView()); mFirstRunFlowSequencer = new FirstRunFlowSequencer(this) { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index 2674352..17b8111 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -9,6 +9,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.res.TypedArray; import android.os.Bundle; import android.support.annotation.Nullable; import android.text.TextUtils; @@ -18,6 +19,7 @@ import org.chromium.base.CommandLine; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; @@ -366,6 +368,14 @@ freCallerIntent = new Intent(intent); VrIntentUtils.updateFreCallerIntent(caller, intent); } + + if (maybeSwitchToTabbedMode(caller, freIntent)) { + // We switched to TabbedModeFRE. We need to disable animation on the original + // intent, to make transition seamless. + intent = new Intent(intent); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + } + // Add a PendingIntent so that the intent used to launch Chrome will be resent when // First Run is completed or canceled. addPendingIntent(caller, freIntent, intent, requiresBroadcast); @@ -384,4 +394,39 @@ } return true; } + + /** + * On tablets, where FRE activity is a dialog, transitions from fillscreen activities + * (the ones that use TabbedModeTheme, e.g. ChromeTabbedActivity) look ugly, because + * when FRE is started from CTA.onCreate(), currently running animation for CTA window + * is aborted. This is perceived as a flash of white and doesn't look good. + * + * To solve this, we added TabbedMode FRE activity, which has the same window background + * as TabbedModeTheme activities, but shows content in a FRE-like dialog. + * + * This function attempts to switch FRE to TabbedModeFRE if certain conditions are met. + */ + private static boolean maybeSwitchToTabbedMode(Context caller, Intent freIntent) { + // Caller must be an activity. + if (!(caller instanceof Activity)) return false; + + // We must be on a tablet (where FRE is a dialog). + boolean isTablet = caller.getResources().getBoolean(R.bool.is_tablet); + if (!isTablet) return false; + + // Caller must use a theme with @drawable/window_background (the same background + // used by TabbedModeFRE). + TypedArray a = caller.obtainStyledAttributes(new int[] {android.R.attr.windowBackground}); + int backgroundResourceId = a.getResourceId(0 /* index */, 0); + a.recycle(); + if (backgroundResourceId != R.drawable.window_background) return false; + + // Switch FRE -> TabbedModeFRE. + if (FirstRunActivity.class.getName().equals(freIntent.getComponent().getClassName())) { + freIntent.setClass(caller, TabbedModeFirstRunActivity.class); + return true; + } + + return false; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java new file mode 100644 index 0000000..08258096 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java
@@ -0,0 +1,122 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.firstrun; + +import android.content.Context; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import org.chromium.chrome.R; + +/** + * FirstRunActivity variant that fills the whole screen, but displays the content + * in a dialog-like layout. + */ +public class TabbedModeFirstRunActivity extends FirstRunActivity { + @Override + protected View createContentView() { + return wrapInDialogLayout(super.createContentView()); + } + + /** + * Wraps contentView into layout that resembles DialogWhenLarge. The layout centers + * the content and dims the background to simulate a modal dialog. + */ + private View wrapInDialogLayout(View contentView) { + ContentLayout contentLayout = new ContentLayout(this); + contentLayout.addView(contentView); + + contentLayout.setBackgroundResource(R.drawable.bg_white_dialog); + + // We need an outer layout for two things: + // * centering the content + // * dimming the background + FrameLayout outerLayout = new FrameLayout(this); + outerLayout.addView(contentLayout, + new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER)); + outerLayout.setBackgroundResource(R.color.modal_dialog_scrim_color); + return outerLayout; + } + + /** + * Layout that sizes itself according to DialogWhenLarge constraints. + */ + private static class ContentLayout extends FrameLayout { + private TypedValue mFixedWidthMajor = new TypedValue(); + private TypedValue mFixedWidthMinor = new TypedValue(); + private TypedValue mFixedHeightMajor = new TypedValue(); + private TypedValue mFixedHeightMinor = new TypedValue(); + + public ContentLayout(Context context) { + super(context); + fetchConstraints(); + } + + private void fetchConstraints() { + // Fetch size constraints. These are copies of corresponding abc_* AppCompat values, + // because abc_* values are private, and even though corresponding theme attributes + // are public in AppCompat (e.g. windowFixedWidthMinor), there is no guarantee that + // AppCompat.DialogWhenLarge is actually defined by AppCompat and not based on + // system DialogWhenLarge theme. + // Note that we don't care about the return values, because onMeasure() handles null + // constraints (and they will be null when the device is not considered "large"). + getContext().getResources().getValue( + R.dimen.dialog_fixed_width_minor, mFixedWidthMinor, true); + getContext().getResources().getValue( + R.dimen.dialog_fixed_width_major, mFixedWidthMajor, true); + getContext().getResources().getValue( + R.dimen.dialog_fixed_height_minor, mFixedHeightMinor, true); + getContext().getResources().getValue( + R.dimen.dialog_fixed_height_major, mFixedHeightMajor, true); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); + final boolean isPortrait = metrics.widthPixels < metrics.heightPixels; + + // Constraint handling is adapted from + // sdk/sources/android-25/android/support/v7/widget/ContentFrameLayout.java. + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + assert widthMode == MeasureSpec.AT_MOST; + { + final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor; + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + if (tvw.type != TypedValue.TYPE_NULL) { + assert tvw.type == TypedValue.TYPE_FRACTION; + int width = (int) tvw.getFraction(metrics.widthPixels, metrics.widthPixels); + widthSize = Math.min(width, widthSize); + } + // This either sets the width calculated from the constraints, or simply + // takes all of the available space (as if MATCH_PARENT was specified). + // The behavior is similar to how DialogWhenLarge windows are sized - they + // are either sized by the constraints, or are full screen, but are never + // sized based on the content size. + widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); + } + + // This is similar to the above block that calculates width. + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + assert heightMode == MeasureSpec.AT_MOST; + { + final TypedValue tvh = isPortrait ? mFixedHeightMajor : mFixedHeightMinor; + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + if (tvh.type != TypedValue.TYPE_NULL) { + assert tvh.type == TypedValue.TYPE_FRACTION; + int height = (int) tvh.getFraction(metrics.heightPixels, metrics.heightPixels); + heightSize = Math.min(height, heightSize); + } + heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java index 22c1f57e2..d6bf0d5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java
@@ -21,7 +21,6 @@ import android.text.style.StyleSpan; import org.chromium.base.BuildInfo; -import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; @@ -31,7 +30,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; import org.chromium.chrome.browser.notifications.channels.SiteChannelsManager; @@ -701,8 +699,6 @@ * Determines whether to use standard notification layouts, using NotificationCompat.Builder, * or custom layouts using Chrome's own templates. * - * The --{enable,disable}-web-notification-custom-layouts command line flags take precedence. - * * Normally a standard layout is used on Android N+, and a custom layout is used on older * versions of Android. But if the notification has a content image, there isn't enough room for * the Site Settings button to go on its own line when showing an image, nor is there enough @@ -713,20 +709,7 @@ */ @VisibleForTesting static boolean useCustomLayouts(boolean hasImage) { - CommandLine commandLine = CommandLine.getInstance(); - if (commandLine.hasSwitch(ChromeSwitches.ENABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS)) { - return true; - } - if (commandLine.hasSwitch(ChromeSwitches.DISABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS)) { - return false; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return false; - } - if (hasImage) { - return false; - } - return true; + return Build.VERSION.SDK_INT < Build.VERSION_CODES.N && !hasImage; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java index c0093a4..8b68801 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java
@@ -344,7 +344,8 @@ private boolean isKeyboardBlacklisted() { String pkgName = mDelegate.getKeyboardPackageName(); - return pkgName.contains(".iqqi"); // crbug.com/767016 + return pkgName.contains(".iqqi") // crbug.com/767016 + || pkgName.contains("omronsoft") || pkgName.contains(".iwnn"); // crbug.com/758443 } private boolean shouldFinishCompositionOnDeletion() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java index dd84cca..95d25467 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java
@@ -47,6 +47,9 @@ public void updateWith(PaymentDetails details) {} @Override + public void noUpdatedPaymentDetails() {} + + @Override public void abort() {} @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 02bdba54..d86ba347 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -828,6 +828,28 @@ mShippingAddressesSection.setErrorMessage(details.error); } + enableUserInterfaceAfterShippingAddressOrOptionUpdateEvent(); + } + + /** + * Called when the merchant received a new shipping address or shipping option, but did not + * update the payment details in response. + */ + @Override + public void noUpdatedPaymentDetails() { + if (mClient == null) return; + + if (mUI == null) { + mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER); + disconnectFromClientWithDebugMessage( + "PaymentRequestUpdateEvent fired without PaymentRequest.show()"); + return; + } + + enableUserInterfaceAfterShippingAddressOrOptionUpdateEvent(); + } + + private void enableUserInterfaceAfterShippingAddressOrOptionUpdateEvent() { if (mPaymentInformationCallback != null) { providePaymentInformation(); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/MathUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/util/MathUtils.java index 77f90a7b..286e4cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/MathUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/MathUtils.java
@@ -171,4 +171,18 @@ public static boolean areFloatsEqual(float f1, float f2) { return Math.abs(f1 - f2) < MathUtils.EPSILON; } + + /** + * Compute the distance between two points. + * @param x1 X of point 1. + * @param y1 Y of point 1. + * @param x2 X of point 2. + * @param y2 Y of point 2. + * @return The distance between the two points. + */ + public static float distance(float x1, float y1, float x2, float y2) { + float xDist = x2 - x1; + float yDist = y2 - y1; + return (float) Math.sqrt(xDist * xDist + yDist * yDist); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java new file mode 100644 index 0000000..862b042 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java
@@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr; + +import android.content.Intent; +import android.view.WindowManager; + +import org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity; +import org.chromium.chrome.browser.util.IntentUtils; +import org.chromium.chrome.browser.vr_shell.VrIntentUtils; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; + +/** + * A subclass of SeparateTaskCustomTabActivity created when starting Chrome in VR mode. + * + * The main purpose of this activity is to add flexibility to the way Chrome is started when the + * user's phone is already in their VR headset (e.g, we want to hide the System UI). + */ +public class CustomTabVrActivity extends SeparateTaskCustomTabActivity { + @Override + public void preInflationStartup() { + assert VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(getIntent()); + + // Set VR specific window mode. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getWindow().getDecorView().setSystemUiVisibility(VrShellDelegate.VR_SYSTEM_UI_FLAGS); + + super.preInflationStartup(); + } + + @Override + protected boolean isStartedUpCorrectly(Intent intent) { + if (!VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(getIntent())) { + return false; + } + return super.isStartedUpCorrectly(intent); + } + + @Override + protected Intent validateIntent(final Intent intent) { + return IntentUtils.sanitizeIntent(intent); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrMainActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrMainActivity.java index 9f2144d..8b86e85f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrMainActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrMainActivity.java
@@ -4,42 +4,18 @@ package org.chromium.chrome.browser.vr; -import android.content.Intent; -import android.view.WindowManager; - -import org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity; -import org.chromium.chrome.browser.util.IntentUtils; -import org.chromium.chrome.browser.vr_shell.VrIntentUtils; -import org.chromium.chrome.browser.vr_shell.VrShellDelegate; +import org.chromium.chrome.browser.document.ChromeLauncherActivity; /** - * A subclass of SeparateTaskCustomTabActivity created when starting Chrome in VR mode. + * This is the VR equivalent of {@link ChromeLauncherActivity}. It exists only because the Android + * platform doesn't inherently support hybrid VR apps (like Chrome). All VR intents for Chrome + * should eventually be routed through this activity as its manifest entry contains VR specific + * attributes to ensure a smooth transition into Chrome VR. * - * The main purpose of this activity is to add flexibility to the way Chrome is started when the - * user's phone is already in their VR headset (e.g, we want to hide the System UI). + * More specifically, a special VR theme disables the Preview Window feature to prevent the system + * UI from showing up while Chrome prepares to enter VR mode. The android:enabledVrMode attribute + * ensures that the system doesn't kick us out of VR mode during the transition as this as this can + * result in a screen brightness flicker. Both of these sound minor but look jarring from a VR + * headset. */ -public class VrMainActivity extends SeparateTaskCustomTabActivity { - @Override - public void preInflationStartup() { - assert VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(getIntent()); - - // Set VR specific window mode. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - getWindow().getDecorView().setSystemUiVisibility(VrShellDelegate.VR_SYSTEM_UI_FLAGS); - - super.preInflationStartup(); - } - - @Override - protected boolean isStartedUpCorrectly(Intent intent) { - if (!VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(getIntent())) { - return false; - } - return super.isStartedUpCorrectly(intent); - } - - @Override - protected Intent validateIntent(final Intent intent) { - return IntentUtils.sanitizeIntent(intent); - } -} +public class VrMainActivity extends ChromeLauncherActivity {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java index 5ace96cc..1850000 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
@@ -21,8 +21,9 @@ public class VrIntentUtils { private static final String DAYDREAM_HOME_PACKAGE = "com.google.android.vr.home"; // The Daydream Home app adds this extra to auto-present intents. - private static final String AUTOPRESENT_WEVBVR_EXTRA = "browser.vr.AUTOPRESENT_WEBVR"; + public static final String AUTOPRESENT_WEVBVR_EXTRA = "browser.vr.AUTOPRESENT_WEBVR"; public static final String DAYDREAM_VR_EXTRA = "android.intent.extra.VR_LAUNCH"; + public static final String DAYDREAM_CATEGORY = "com.google.intent.category.DAYDREAM"; static final String VR_FRE_INTENT_EXTRA = "org.chromium.chrome.browser.vr_shell.VR_FRE"; static final String VR_FRE_CALLER_INTENT_EXTRA = @@ -91,11 +92,17 @@ * @return Whether or not the given intent is a VR-specific intent. */ public static boolean isVrIntent(Intent intent) { + if (intent == null) return false; // For simplicity, we only return true here if VR is enabled on the platform and this intent // is not fired from a recent apps page. The latter is there so that we don't enter VR mode // when we're being resumed from the recent apps in 2D mode. + // Note that Daydream removes the Daydream category for deep-links (for no real reason). In + // addition to the category, DAYDREAM_VR_EXTRA tells us that this intent is coming directly + // from VR. boolean canHandleIntent = VrShellDelegate.isVrEnabled() && !launchedFromRecentApps(intent); - return IntentUtils.safeGetBooleanExtra(intent, DAYDREAM_VR_EXTRA, false) && canHandleIntent; + return (intent.hasCategory(DAYDREAM_CATEGORY) + || IntentUtils.safeGetBooleanExtra(intent, DAYDREAM_VR_EXTRA, false)) + && canHandleIntent; } /** @@ -104,7 +111,9 @@ public static boolean isCustomTabVrIntent(Intent intent) { // TODO(crbug.com/719661): Currently, only Daydream intents open in a CustomTab. We should // probably change this once we figure out core CCT flows in VR. - return getHandlerInstance().isTrustedDaydreamIntent(intent); + if (intent == null) return false; + return IntentHandler.getUrlFromIntent(intent) != null + && getHandlerInstance().isTrustedDaydreamIntent(intent); } /** @@ -157,4 +166,14 @@ /* package */ static boolean launchedFromRecentApps(Intent intent) { return ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0); } + + /** + * Removes VR specific extras from the given intent to make it a non-VR intent. + */ + /* package */ static void removeVrExtras(Intent intent) { + if (intent == null) return; + intent.removeExtra(DAYDREAM_VR_EXTRA); + intent.removeCategory(DAYDREAM_CATEGORY); + assert !isVrIntent(intent); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index e1e3c8a..7dab064 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -76,6 +76,7 @@ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; private static final String TAG = "VrShellDelegate"; + private static final boolean DEBUG_LOGS = false; // Pseudo-random number to avoid request id collisions. Result codes must fit in lower 16 bits // when used with startActivityForResult... @@ -167,6 +168,8 @@ // party app has asked us to autopresent WebVr content and we're waiting for the WebVr // content to call requestPresent. private boolean mAutopresentWebVr; + // If set to true, we attempt to enter VR mode when the activity is resumed. + private boolean mEnterVrOnStartup; // Set to true if performed VR browsing at least once. That is, this was not simply a WebVr // presentation experience. @@ -197,7 +200,8 @@ sInstance.mProbablyInDon = false; sInstance.mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null); sInstance.mVrClassesWrapper.setVrModeEnabled(sInstance.mActivity, true); - sInstance.setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + if (DEBUG_LOGS) Log.i(TAG, "VrBroadcastReceiver onReceive"); + sInstance.setWindowModeForVr(); if (sInstance.mPaused) { if (sInstance.mInVrAtChromeLaunch == null) sInstance.mInVrAtChromeLaunch = false; // We add a black overlay view so that we can show black while the VR UI is loading. @@ -270,8 +274,6 @@ VrClassesWrapper wrapper = getVrClassesWrapper(); if (wrapper == null) return; nativeOnLibraryAvailable(); - - if (sInstance != null) sInstance.cancelStartupAnimationIfNeeded(); } protected static boolean isDisplayingUrl() { @@ -417,6 +419,7 @@ * unhandled, the Activity should be recreated in order to handle the change. */ public static boolean onDensityChanged(float oldDpi, float newDpi) { + if (DEBUG_LOGS) Log.i(TAG, "onDensityChanged [%.2f]->[%.2f] ", oldDpi, newDpi); if (sInstance == null) return false; // If density changed while in VR, we expect a second density change to restore the density // to what it previously was when we exit VR. We shouldn't have to recreate the activity as @@ -783,9 +786,10 @@ return; } mInVr = true; + mEnterVrOnStartup = false; mVrClassesWrapper.setVrModeEnabled(mActivity, true); - setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + setWindowModeForVr(); boolean donSuceeded = mDonSucceeded; mDonSucceeded = false; if (!createVrShell()) { @@ -851,6 +855,11 @@ sAddedBlackOverlayView = false; } + private void onVrIntent() { + mNeedsAnimationCancel = true; + mEnterVrOnStartup = true; + } + private void onAutopresentIntent() { // Autopresent intents are only expected from trusted first party apps while // we're not in vr. @@ -861,13 +870,23 @@ mInVrAtChromeLaunch = true; } - private void onAutopresentUnsupported() { + private void onEnterVrUnsupported() { // Auto-presentation is unsupported, but we still need to remove the black overlay before we // exit to Daydream so that the user doesn't see black when they come back to Chrome. The // overlay will be removed when we get paused by Daydream. assert !mInVr; mNeedsAnimationCancel = false; + mEnterVrOnStartup = false; + // We remove the VR-specific system UI flags here so that the system UI shows up properly + // when Chrome is resumed in non-VR mode. + mActivity.getWindow().getDecorView().setSystemUiVisibility(0); mVrDaydreamApi.launchVrHomescreen(); + + // Some Samsung devices change the screen density after exiting VR mode which causes + // us to restart Chrome with the VR intent that originally started it. We don't want to + // enable VR mode when the user opens Chrome again in 2D mode, so we remove VR specific + // extras. + VrIntentUtils.removeVrExtras(mActivity.getIntent()); } /** @@ -877,37 +896,75 @@ if (!VrIntentUtils.isVrIntent(intent)) return; VrShellDelegate instance = getInstance(activity); if (instance == null) return; + // TODO(ymalik): We should cache whether or not VR mode is set so we don't set it + // needlessly. + setVrModeEnabled(activity); // TODO(ymalik): This should use isTrustedAutopresentIntent once the Daydream Home change // that adds the autopresent intent extra rolls out on most devices. This will allow us to // differentiate trusted auto-present intents from Chrome VR intents. if (VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(intent)) { + if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: autopresent"); assert activitySupportsAutopresentation(activity); instance.mAutopresentWebVr = true; if (!ChromeFeatureList.isEnabled(ChromeFeatureList.WEBVR_AUTOPRESENT)) { - instance.onAutopresentUnsupported(); + instance.onEnterVrUnsupported(); return; } instance.onAutopresentIntent(); + } else if (ChromeFeatureList.isEnabled(ChromeFeatureList.VR_LAUNCH_INTENT) + && isVrShellEnabled(instance.mVrSupportLevel)) { + if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: vr"); + instance.onVrIntent(); + } else { + if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: unsupported"); + // TODO(ymalik): Currently we always return to Daydream home, this makes less sense if + // a non-VR app sends an intent, perhaps just ignoring the intent is better. + instance.onEnterVrUnsupported(); + return; } + + // Note that cancelling the animation below is what causes us to enter VR mode when Chrome + // is cold-started. We start an intermediate activity to cancel the animation which causes + // onPause and onResume to be called and we enter VR mode in onResume (because we set the + // mEnterVrOnStartup bit above). If Chrome is already running, onResume which will be called + // after VrShellDelegate#onNewIntentWithNative which will cancel the animation and enter VR + // after that. + if (!instance.mPaused) instance.cancelStartupAnimationIfNeeded(); } /** * This is called when ChromeTabbedActivity gets a new intent before native is initialized. */ public static void maybeHandleVrIntentPreNative(ChromeActivity activity, Intent intent) { - if (VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(intent)) { + if (VrIntentUtils.isVrIntent(intent)) { + if (DEBUG_LOGS) Log.i(TAG, "maybeHandleVrIntentPreNative: preparing for transition"); // We add a black overlay view so that we can show black while the VR UI is loading. // Note that this alone isn't sufficient to prevent 2D UI from showing when // auto-presenting WebVR. See comment about the custom animation in {@link // getVrIntentOptions}. + // TODO(crbug.com/775574): This hack doesn't really work to hide the 2D UI on Samsung + // devices since Chrome gets paused and we prematurely remove the overlay. addBlackOverlayViewForActivity(activity); + + // Enable VR mode and hide system UI. We do this here so we don't get kicked out of + // VR mode and to prevent seeing a flash of system UI. + getVrClassesWrapper().setVrModeEnabled(activity, true); + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + activity.getWindow().getDecorView().setSystemUiVisibility(VR_SYSTEM_UI_FLAGS); } } + /** + * Asynchronously enable VR mode. + */ + public static void setVrModeEnabled(Activity activity) { + getVrClassesWrapper().setVrModeEnabled(activity, true); + } + @Override public void onSystemUiVisibilityChange(int visibility) { if (mInVr && !isWindowModeCorrectForVr()) { - setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + setWindowModeForVr(); } } @@ -933,20 +990,43 @@ && orientation == Configuration.ORIENTATION_LANDSCAPE; } - private void setWindowModeForVr(int requestedOrientation) { + private void setWindowModeForVr() { + ScreenOrientationDelegateManager.setOrientationDelegate(this); + mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + // Set correct orientation. if (mRestoreOrientation == null) { mRestoreOrientation = mActivity.getRequestedOrientation(); } - mActivity.setRequestedOrientation(requestedOrientation); - ScreenOrientationDelegateManager.setOrientationDelegate(this); - setupVrModeWindowFlags(); + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + + // Hide system UI. + int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility(); + if (mRestoreSystemUiVisibilityFlag == -1) { + mRestoreSystemUiVisibilityFlag = flags; + // We may have hidden the system UI earlier so that we don't see it when Chrome is + // started in VR mode. So we should not restore to the flags we added after exiting VR + // mode. This has the issue that if we hide it for another reason before entering VR + // mode, we always show it after exiting VR mode, which is probably okay. + if (mEnterVrOnStartup) mRestoreSystemUiVisibilityFlag &= ~VR_SYSTEM_UI_FLAGS; + } + mActivity.getWindow().getDecorView().setSystemUiVisibility(VR_SYSTEM_UI_FLAGS); } private void restoreWindowMode() { - if (mRestoreOrientation != null) mActivity.setRequestedOrientation(mRestoreOrientation); ScreenOrientationDelegateManager.setOrientationDelegate(null); + mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + // Restore orientation. + if (mRestoreOrientation != null) mActivity.setRequestedOrientation(mRestoreOrientation); mRestoreOrientation = null; - clearVrModeWindowFlags(); + + // Restore system UI visibility. + if (mRestoreSystemUiVisibilityFlag != -1) { + mActivity.getWindow().getDecorView().setSystemUiVisibility( + mRestoreSystemUiVisibilityFlag); + } + mRestoreSystemUiVisibilityFlag = -1; } /* package */ boolean canEnterVr(Tab tab, boolean justCompletedDon) { @@ -1054,6 +1134,7 @@ private boolean cancelStartupAnimationIfNeeded() { if (!mNeedsAnimationCancel) return false; + if (DEBUG_LOGS) Log.e(TAG, "canceling startup animation"); mCancellingEntryAnimation = true; Bundle options = ActivityOptions.makeCustomAnimation(mActivity, 0, 0).toBundle(); mActivity.startActivity(new Intent(mActivity, VrCancelAnimationActivity.class), options); @@ -1062,6 +1143,7 @@ } protected void onResume() { + if (DEBUG_LOGS) Log.i(TAG, "onResume"); if (cancelStartupAnimationIfNeeded()) return; mPaused = false; @@ -1086,7 +1168,18 @@ }); } - if (mDonSucceeded) { + if (mEnterVrOnStartup) { + // This means that Chrome was started with a VR intent, so we should enter VR. + // TODO(crbug.com/776235): VR intents are dispatched to ChromeActivity via a launcher + // which should handle the DON flow to simplify the logic in VrShellDelegate. + assert !mProbablyInDon; + if (DEBUG_LOGS) Log.i(TAG, "onResume: entering VR mode for VR intent"); + mCancellingEntryAnimation = false; + if (enterVrInternal() == ENTER_VR_CANCELLED) { + cancelPendingVrEntry(); + mEnterVrOnStartup = false; + } + } else if (mDonSucceeded) { mCancellingEntryAnimation = false; handleDonFlowSuccess(); } else if (mProbablyInDon) { @@ -1145,6 +1238,7 @@ } protected void onPause() { + if (DEBUG_LOGS) Log.i(TAG, "onPause"); mPaused = true; if (mCancellingEntryAnimation) return; mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null); @@ -1174,6 +1268,7 @@ } private void onStop() { + if (DEBUG_LOGS) Log.i(TAG, "onStop"); mStopped = true; if (!mProbablyInDon) cancelPendingVrEntry(); assert !mCancellingEntryAnimation; @@ -1281,6 +1376,11 @@ return; } + // Some Samsung devices change the screen density after exiting VR mode which causes + // us to restart Chrome with the VR intent that originally started it. We don't want to + // enable VR mode again, so we remove VR specific extras. + VrIntentUtils.removeVrExtras(mActivity.getIntent()); + // The user has exited VR. RecordUserAction.record("VR.DOFF"); @@ -1514,24 +1614,6 @@ decor.removeView(mVrShell.getContainer()); } - private void setupVrModeWindowFlags() { - if (mRestoreSystemUiVisibilityFlag == -1) { - mRestoreSystemUiVisibilityFlag = mActivity.getWindow().getDecorView() - .getSystemUiVisibility(); - } - mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - mActivity.getWindow().getDecorView().setSystemUiVisibility(VR_SYSTEM_UI_FLAGS); - } - - private void clearVrModeWindowFlags() { - mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - if (mRestoreSystemUiVisibilityFlag != -1) { - mActivity.getWindow().getDecorView() - .setSystemUiVisibility(mRestoreSystemUiVisibilityFlag); - } - mRestoreSystemUiVisibilityFlag = -1; - } - private void onDensityChangedInternal(float oldDpi, float newDpi) { if (mVrShell != null) mVrShell.onDensityChanged(oldDpi, newDpi); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java index b079a61..d373867 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
@@ -14,7 +14,6 @@ import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.chrome.browser.ChromeVersionInfo; -import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.webapk.lib.client.WebApkIdentityServiceClient; import org.chromium.webapk.lib.client.WebApkValidator; @@ -24,15 +23,9 @@ public class ChromeWebApkHost { private static ApplicationStatus.ApplicationStateListener sListener; - private static class SignatureChecker implements WebApkValidator.ISignatureChecker { - public boolean isGoogleSigned(String packageName) { - return ExternalAuthUtils.getInstance().isGoogleSigned(packageName); - } - } - public static void init() { WebApkValidator.init(ChromeWebApkHostSignature.EXPECTED_SIGNATURE, - ChromeWebApkHostSignature.PUBLIC_KEY, new SignatureChecker()); + ChromeWebApkHostSignature.PUBLIC_KEY); if (ChromeVersionInfo.isLocalBuild() && CommandLine.getInstance().hasSwitch(SKIP_WEBAPK_VERIFICATION)) { // Tell the WebApkValidator to work for all WebAPKs.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 971bab0..6e9f605 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -150,6 +150,12 @@ private static final float SWIPE_ALLOWED_FRACTION = 0.2f; /** + * The maximum swipe velocity (dp/ms) that should be considered as a user opening the bottom + * sheet intentionally. This is specifically for the 'velocity' swipe logic. + */ + private static final float SHEET_SWIPE_MAX_DP_PER_MS = 0.2f; + + /** * Information about the different scroll states of the sheet. Order is important for these, * they go from smallest to largest. */ @@ -274,6 +280,12 @@ /** A help bubble that points to the bottom sheet, helping users find bookmarks, et. al. */ private ViewAnchoredTextBubble mHelpBubble; + /** Conversion ratio of dp to px. */ + private float mDpToPx; + + /** Whether or not scroll events are currently being blocked for the 'velocity' swipe logic. */ + private boolean mVelocityLogicBlockSwipe; + /** * An interface defining content that can be displayed inside of the bottom sheet for Chrome * Home. @@ -346,7 +358,7 @@ private class BottomSheetSwipeDetector extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { - return isTouchInSwipableXRange(e); + return shouldGestureMoveSheet(e, e); } @Override @@ -361,7 +373,7 @@ return false; } - if (!isTouchInSwipableXRange(e2)) return false; + if (!shouldGestureMoveSheet(e1, e2)) return false; // Only start scrolling if the scroll is up or down. If the user is already scrolling, // continue moving the sheet. @@ -406,7 +418,7 @@ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (!isTouchInSwipableXRange(e2) || !mIsScrolling) return false; + if (!shouldGestureMoveSheet(e1, e2) || !mIsScrolling) return false; cancelAnimation(); @@ -444,19 +456,23 @@ } /** - * Check if a touch event is in the swipable x-axis range of the toolbar when in peeking mode. - * If the "chrome-home-swipe-logic" flag is not set to "restrict-area", "button-only" or the - * sheet is open, this function returns true. - * @param e The touch event. - * @return True if the touch is inside the swipable area of the toolbar. + * Check if a particular gesture or touch event should move the bottom sheet when in peeking + * mode. If the "chrome-home-swipe-logic" flag is not set this function returns true. + * @param initialEvent The event that started the scroll. + * @param currentEvent The current motion event. + * @return True if the bottom sheet should move. */ - private boolean isTouchInSwipableXRange(MotionEvent e) { + private boolean shouldGestureMoveSheet(MotionEvent initialEvent, MotionEvent currentEvent) { // If the sheet is already open, the experiment is not enabled, or accessibility is enabled // there is no need to restrict the swipe area. if (mActivity == null || isSheetOpen() || AccessibilityUtil.isAccessibilityEnabled()) { return true; } + if (currentEvent.getActionMasked() == MotionEvent.ACTION_DOWN) { + mVelocityLogicBlockSwipe = false; + } + String logicType = FeatureUtilities.getChromeHomeSwipeLogicType(); // By default, the entire toolbar is swipable. @@ -469,9 +485,26 @@ float allowedSwipeWidth = mContainerWidth * SWIPE_ALLOWED_FRACTION; startX = mVisibleViewportRect.left + (mContainerWidth - allowedSwipeWidth) / 2; endX = startX + allowedSwipeWidth; + } else if (ChromeSwitches.CHROME_HOME_SWIPE_LOGIC_VELOCITY.equals(logicType)) { + if (mVelocityLogicBlockSwipe) return false; + + float scrollDistanceDp = MathUtils.distance(initialEvent.getX(), initialEvent.getY(), + currentEvent.getX(), currentEvent.getY()) + / mDpToPx; + long timeDelta = currentEvent.getEventTime() - initialEvent.getDownTime(); + + double dpPerMs = scrollDistanceDp / (double) timeDelta; + + if (dpPerMs > SHEET_SWIPE_MAX_DP_PER_MS) { + mVelocityLogicBlockSwipe = true; + return false; + } + + return true; } - return e.getRawX() > startX && e.getRawX() < endX || getSheetState() != SHEET_STATE_PEEK; + return currentEvent.getRawX() > startX && currentEvent.getRawX() < endX + || getSheetState() != SHEET_STATE_PEEK; } /** @@ -713,6 +746,8 @@ mBottomSheetContentContainer.setBackgroundColor( ApiCompatibilityUtils.getColor(getResources(), R.color.modern_primary_color)); + mDpToPx = mActivity.getResources().getDisplayMetrics().density; + // Listen to height changes on the root. root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { private int mPreviousKeyboardHeight;
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index dbf7a42e..ca6c1938 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -428,6 +428,7 @@ "java/src/org/chromium/chrome/browser/firstrun/FirstRunView.java", "java/src/org/chromium/chrome/browser/firstrun/FirstRunViewPager.java", "java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java", + "java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java", "java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java", "java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java", "java/src/org/chromium/chrome/browser/fullscreen/BrowserStateBrowserControlsVisibilityDelegate.java", @@ -1211,6 +1212,7 @@ "java/src/org/chromium/chrome/browser/util/PlatformUtil.java", "java/src/org/chromium/chrome/browser/util/UrlUtilities.java", "java/src/org/chromium/chrome/browser/util/ViewUtils.java", + "java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java", "java/src/org/chromium/chrome/browser/vr/VrMainActivity.java", "java/src/org/chromium/chrome/browser/vr_shell/VrCancelAnimationActivity.java", "java/src/org/chromium/chrome/browser/vr_shell/VrClassesWrapper.java", @@ -1659,6 +1661,7 @@ "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java", + "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppCanMakePaymentQueryTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java new file mode 100644 index 0000000..7279b65 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java
@@ -0,0 +1,113 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments; + +import android.content.DialogInterface; +import android.support.test.filters.MediumTest; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.autofill.AutofillTestHelper; +import org.chromium.chrome.browser.autofill.CardType; +import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; +import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; +import org.chromium.chrome.browser.payments.PaymentRequestTestRule.MainActivityStartCallback; +import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +/** + * A payment integration test for a merchant that either does not listen to update callbacks, does + * not call updateWith(), or does not uses promises. These behaviors are all OK and should not cause + * timeouts. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ + ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, + ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG, +}) +public class PaymentRequestNoUpdateWithTest implements MainActivityStartCallback { + @Rule + public PaymentRequestTestRule mRule = + new PaymentRequestTestRule("payment_request_no_update_with_test.html", this); + + @Override + public void onMainActivityStarted() + throws InterruptedException, ExecutionException, TimeoutException { + AutofillTestHelper helper = new AutofillTestHelper(); + helper.setProfile(new AutofillProfile("" /* guid */, "https://www.example.com" /* origin */, + "Lisa Simpson", "Acme Inc.", "123 Main", "California", "Los Angeles", "", "90210", + "", "US", "555 123-4567", "lisa@simpson.com", "")); + String billingAddressId = helper.setProfile( + new AutofillProfile("" /* guid */, "https://www.example.com" /* origin */, + "Maggie Simpson", "Acme Inc.", "123 Main", "California", "Los Angeles", "", + "90210", "", "Uzbekistan", "555 123-4567", "maggie@simpson.com", "")); + helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, + CardType.UNKNOWN, billingAddressId, "" /* serverId */)); + } + + /** + * A merchant that does not listen to shipping address update events will not cause timeouts in + * UI. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNoEventListener() throws Throwable { + mRule.triggerUIAndWait("buyWithoutListeners", mRule.getReadyForInput()); + mRule.clickInShippingAddressAndWait(R.id.payments_section, mRule.getReadyForInput()); + mRule.clickOnShippingAddressSuggestionOptionAndWait(1, mRule.getReadyForInput()); + mRule.clickAndWait(R.id.button_primary, mRule.getReadyForUnmaskInput()); + mRule.setTextInCardUnmaskDialogAndWait( + R.id.card_unmask_input, "123", mRule.getReadyToUnmask()); + mRule.clickCardUnmaskButtonAndWait(DialogInterface.BUTTON_POSITIVE, mRule.getDismissed()); + mRule.expectResultContains(new String[] {"freeShipping"}); + } + + /** + * A merchant that listens to shipping address update events, but does not call updateWith() on + * the event, will not cause timeouts in UI. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNoUpdateWith() throws Throwable { + mRule.triggerUIAndWait("buyWithoutCallingUpdateWith", mRule.getReadyForInput()); + mRule.clickInShippingAddressAndWait(R.id.payments_section, mRule.getReadyForInput()); + mRule.clickOnShippingAddressSuggestionOptionAndWait(1, mRule.getReadyForInput()); + mRule.clickAndWait(R.id.button_primary, mRule.getReadyForUnmaskInput()); + mRule.setTextInCardUnmaskDialogAndWait( + R.id.card_unmask_input, "123", mRule.getReadyToUnmask()); + mRule.clickCardUnmaskButtonAndWait(DialogInterface.BUTTON_POSITIVE, mRule.getDismissed()); + mRule.expectResultContains(new String[] {"freeShipping"}); + } + + /** A merchant that calls updateWith() without using promises will not cause timeouts in UI. */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNoPromises() throws Throwable { + mRule.triggerUIAndWait("buyWithoutPromises", mRule.getReadyForInput()); + Assert.assertEquals("USD $5.00", mRule.getOrderSummaryTotal()); + mRule.clickInShippingAddressAndWait(R.id.payments_section, mRule.getReadyForInput()); + mRule.clickOnShippingAddressSuggestionOptionAndWait(1, mRule.getReadyForInput()); + Assert.assertEquals("USD $10.00", mRule.getOrderSummaryTotal()); + mRule.clickAndWait(R.id.button_primary, mRule.getReadyForUnmaskInput()); + mRule.setTextInCardUnmaskDialogAndWait( + R.id.card_unmask_input, "123", mRule.getReadyToUnmask()); + mRule.clickCardUnmaskButtonAndWait(DialogInterface.BUTTON_POSITIVE, mRule.getDismissed()); + mRule.expectResultContains(new String[] {"updatedShipping"}); + } +} \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java index 16b458c..95120ce9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java
@@ -60,7 +60,7 @@ @Before public void setup() throws InterruptedException { - ChromePreferenceManager.getInstance().setNewTabPageGenericSigninPromoDismissed(true); + ChromePreferenceManager.getInstance().setNewTabPagePersonalizedSigninPromoDismissed(true); mActivityRule.startMainActivityOnBottomSheet(BottomSheet.SHEET_STATE_PEEK); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java index 030aeee..1ec65f75 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java
@@ -52,7 +52,7 @@ @Before public void setup() throws InterruptedException { - ChromePreferenceManager.getInstance().setNewTabPageGenericSigninPromoDismissed(true); + ChromePreferenceManager.getInstance().setNewTabPagePersonalizedSigninPromoDismissed(true); mActivityRule.startMainActivityOnBlankPage(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java index 1b8f6f5a..e19a8bc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
@@ -47,7 +47,7 @@ @Before public void setup() throws InterruptedException { - ChromePreferenceManager.getInstance().setNewTabPageGenericSigninPromoDismissed(true); + ChromePreferenceManager.getInstance().setNewTabPagePersonalizedSigninPromoDismissed(true); mActivityRule.startMainActivityOnBlankPage(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTransitionTest.java index 5a1e5b5ab..4e53bc97 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTransitionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTransitionTest.java
@@ -12,6 +12,7 @@ import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_DEVICE_NON_DAYDREAM; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; +import android.app.Activity; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; @@ -21,10 +22,12 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.ApplicationStatus; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.vr_shell.mock.MockVrDaydreamApi; import org.chromium.chrome.browser.vr_shell.rules.ChromeTabbedActivityVrTestRule; import org.chromium.chrome.browser.vr_shell.util.NfcSimUtils; @@ -36,7 +39,10 @@ import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.DOMUtils; +import java.lang.ref.WeakReference; +import java.util.List; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; /** * End-to-end tests for state transitions in VR, e.g. exiting WebVR presentation @@ -127,6 +133,57 @@ } /** + * Verifies that browser successfully transitions from 2D chrome to the VR + * browser when Chrome gets a VR intent. + * Note that we need to remove the enable-features flag that's set above and reset it with + * VrLaunchIntent above otherwise the one set on the class takes precedence. + */ + @Test + @Restriction(RESTRICTION_TYPE_DEVICE_DAYDREAM) + @MediumTest + @CommandLineFlags.Remove("enable-features=VrShell") + @CommandLineFlags.Add("enable-features=VrShell,VrLaunchIntent") + public void testVrIntentStartsVrShell() { + // Send a VR intent, which will open the link in a CTA. + String url = VrTestFramework.getHtmlTestFile("test_navigation_2d_page"); + VrTransitionUtils.sendVrLaunchIntent( + url, mVrTestRule.getActivity(), false /* autopresent */); + + // Wait until a CTA is opened due to the intent + final AtomicReference<ChromeTabbedActivity> cta = + new AtomicReference<ChromeTabbedActivity>(); + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + List<WeakReference<Activity>> list = ApplicationStatus.getRunningActivities(); + for (WeakReference<Activity> ref : list) { + Activity activity = ref.get(); + if (activity == null) continue; + if (activity instanceof ChromeTabbedActivity) { + cta.set((ChromeTabbedActivity) activity); + return true; + } + } + return false; + } + }, POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS); + + // Wait until the tab is ready + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + if (cta.get().getActivityTab() == null) return false; + return !cta.get().getActivityTab().isLoading(); + } + }, POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS); + + VrTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS); + Assert.assertTrue(VrShellDelegate.isInVr()); + Assert.assertEquals("Url correct", url, + mVrTestRule.getActivity().getActivityTab().getWebContents().getVisibleUrl()); + } + + /** * Verifies that browser does not enter VR mode on Non-Daydream-ready devices. */ @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java index e6acaf2..5d45e24 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java
@@ -158,9 +158,9 @@ true /* useMockImplementation */, true /* treatIntentsAsTrusted */)); // Send an autopresent intent, which will open the link in a CCT - VrTransitionUtils.sendDaydreamAutopresentIntent( + VrTransitionUtils.sendVrLaunchIntent( VrTestFramework.getHtmlTestFile("test_webvr_autopresent"), - mVrTestRule.getActivity()); + mVrTestRule.getActivity(), true /* autopresent */); // Wait until a CCT is opened due to the intent final AtomicReference<CustomTabActivity> cct = new AtomicReference<CustomTabActivity>();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java index 54ede5a..1d73dc79 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java
@@ -17,7 +17,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; -import org.chromium.chrome.browser.document.ChromeLauncherActivity; +import org.chromium.chrome.browser.vr.VrMainActivity; import org.chromium.chrome.browser.vr_shell.TestVrShellDelegate; import org.chromium.chrome.browser.vr_shell.VrClassesWrapperImpl; import org.chromium.chrome.browser.vr_shell.VrIntentUtils; @@ -182,20 +182,27 @@ } /** - * Sends an intent to Chrome telling it to autopresent the given URL. This - * is expected to fail unless the trusted intent check is disabled in VrShellDelegate. + * Sends an intent to Chrome telling it to launch in VR mode. If the given autopresent param is + * true, this is expected to fail unless the trusted intent check is disabled in + * VrShellDelegate. * * @param url String containing the URL to open * @param activity The activity to launch the intent from + * @param autopresent If this intent is expected to auto-present WebVR */ - public static void sendDaydreamAutopresentIntent(String url, final Activity activity) { - // Create an intent that will launch Chrome at the specified URL with autopresent + public static void sendVrLaunchIntent( + String url, final Activity activity, boolean autopresent) { + // Create an intent that will launch Chrome at the specified URL. final Intent intent = - new Intent(ContextUtils.getApplicationContext(), ChromeLauncherActivity.class); + new Intent(ContextUtils.getApplicationContext(), VrMainActivity.class); intent.setData(Uri.parse(url)); intent.putExtra(VrIntentUtils.DAYDREAM_VR_EXTRA, true); DaydreamApi.setupVrIntent(intent); - intent.removeCategory("com.google.intent.category.DAYDREAM"); + if (autopresent) { + // Daydream removes this category for deep-linked URLs for legacy reasons. + intent.removeCategory(VrIntentUtils.DAYDREAM_CATEGORY); + intent.putExtra(VrIntentUtils.AUTOPRESENT_WEVBVR_EXTRA, true); + } final VrClassesWrapperImpl wrapper = new VrClassesWrapperImpl(); ThreadUtils.runOnUiThreadBlocking(new Runnable() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeUnitTest.java index 1b046e0..7b10de79 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeUnitTest.java
@@ -5,21 +5,16 @@ package org.chromium.chrome.browser.notifications; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.app.Notification; -import android.os.Build; -import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; -import org.chromium.base.CommandLine; import org.chromium.base.test.util.Feature; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; import org.chromium.chrome.browser.notifications.channels.SiteChannelsManager; import org.chromium.testing.local.LocalRobolectricTestRunner; @@ -32,52 +27,6 @@ @RunWith(LocalRobolectricTestRunner.class) @Config(manifest = Config.NONE) public class NotificationPlatformBridgeUnitTest { - @After - public void tearDown() { - // Clean up static state for subsequent tests. - CommandLine.reset(); - } - - @Test - @Feature({"Browser", "Notifications"}) - public void testUseCustomLayouts() { - CommandLine.init(null); - CommandLine.getInstance().appendSwitch( - ChromeSwitches.ENABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS); - assertTrue(NotificationPlatformBridge.useCustomLayouts(false /* hasImage */)); - assertTrue(NotificationPlatformBridge.useCustomLayouts(true /* hasImage */)); - CommandLine.reset(); - - CommandLine.init(null); - CommandLine.getInstance().appendSwitch( - ChromeSwitches.DISABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS); - assertFalse(NotificationPlatformBridge.useCustomLayouts(false /* hasImage */)); - assertFalse(NotificationPlatformBridge.useCustomLayouts(true /* hasImage */)); - CommandLine.reset(); - - // Enable flag takes precedence over disable flag (arbitrarily). - CommandLine.init(null); - CommandLine.getInstance().appendSwitch( - ChromeSwitches.ENABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS); - CommandLine.getInstance().appendSwitch( - ChromeSwitches.DISABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS); - assertTrue(NotificationPlatformBridge.useCustomLayouts(false /* hasImage */)); - assertTrue(NotificationPlatformBridge.useCustomLayouts(true /* hasImage */)); - CommandLine.reset(); - - CommandLine.init(null); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Without comand line flags, custom layouts are always disabled on Nougat+. - assertFalse(NotificationPlatformBridge.useCustomLayouts(false /* hasImage */)); - assertFalse(NotificationPlatformBridge.useCustomLayouts(true /* hasImage */)); - } else { - // On older versions of Android, custom layouts are enabled unless an image is provided. - assertTrue(NotificationPlatformBridge.useCustomLayouts(false /* hasImage */)); - assertFalse(NotificationPlatformBridge.useCustomLayouts(true /* hasImage */)); - } - CommandLine.reset(); - } - /** * Verifies that the getOriginFromTag method returns the origin for valid input, and null for * invalid input.
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java index 9c43cb1..480560d6 100644 --- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java +++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java
@@ -72,18 +72,11 @@ private RobolectricPackageManager mPackageManager; - private static boolean sIsGoogleSignedResult = true; - private class FakeIsGoogleValidator implements WebApkValidator.ISignatureChecker { - public boolean isGoogleSigned(String packageName) { - return sIsGoogleSignedResult; - } - } - @Before public void setUp() { mPackageManager = (RobolectricPackageManager) RuntimeEnvironment.application.getPackageManager(); - WebApkValidator.init(EXPECTED_SIGNATURE, PUBLIC_KEY, new FakeIsGoogleValidator()); + WebApkValidator.init(EXPECTED_SIGNATURE, PUBLIC_KEY); } /** @@ -268,15 +261,16 @@ public void testIsValidWebApkForMapsLite() { mPackageManager.addPackage(newPackageInfoWithBrowserSignature( MAPSLITE_PACKAGE_NAME, new Signature(SIGNATURE_1), MAPSLITE_EXAMPLE_STARTURL)); + mPackageManager.addPackage( + newPackageInfoWithBrowserSignature(MAPSLITE_PACKAGE_NAME + ".other", + new Signature(SIGNATURE_1), MAPSLITE_EXAMPLE_STARTURL)); - sIsGoogleSignedResult = true; assertTrue(WebApkValidator.isValidWebApk( RuntimeEnvironment.application, MAPSLITE_PACKAGE_NAME)); assertFalse(WebApkValidator.isValidWebApk( RuntimeEnvironment.application, MAPSLITE_PACKAGE_NAME + ".other")); - sIsGoogleSignedResult = false; assertFalse(WebApkValidator.isValidWebApk( - RuntimeEnvironment.application, MAPSLITE_PACKAGE_NAME)); + RuntimeEnvironment.application, MAPSLITE_PACKAGE_NAME + ".notfound")); } /**
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java index 60380ea3..1431bd8 100644 --- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java
@@ -46,13 +46,9 @@ private static byte[] sExpectedSignature; private static byte[] sCommentSignedPublicKeyBytes; - private static ISignatureChecker sSignatureChecker; private static PublicKey sCommentSignedPublicKey; private static boolean sOverrideValidationForTesting; - /** Interface to support callback to verify if a goole package name is Google signed. */ - public interface ISignatureChecker { public boolean isGoogleSigned(String packageName); } - /** * Queries the PackageManager to determine whether a WebAPK can handle the URL. Ignores whether * the user has selected a default handler for the URL and whether the default handler is the @@ -239,14 +235,6 @@ Log.d(TAG, "mapslite invalid scope prefix"); return false; } - if (sSignatureChecker == null) { - Log.d(TAG, "sSignatureChecker not set"); - return false; - } - if (!sSignatureChecker.isGoogleSigned(webappPackageName)) { - Log.d(TAG, "mapslite not Google signed"); - return false; - } return true; } @@ -319,17 +307,13 @@ * @param v2PublicKeyBytes New comment signed public key bytes as x509 encoded public key. */ @SuppressFBWarnings("EI_EXPOSE_STATIC_REP2") - public static void init(byte[] expectedSignature, byte[] v2PublicKeyBytes, - ISignatureChecker googleSignedCallback) { + public static void init(byte[] expectedSignature, byte[] v2PublicKeyBytes) { if (sExpectedSignature == null) { sExpectedSignature = expectedSignature; } if (sCommentSignedPublicKeyBytes == null) { sCommentSignedPublicKeyBytes = v2PublicKeyBytes; } - if (sSignatureChecker == null) { - sSignatureChecker = googleSignedCallback; - } } /**
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 8896752..0ec8d4d 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -406,6 +406,10 @@ [ "//chrome/browser/chromeos:ash_pref_connector_manifest" ] } +if (is_win) { + chrome_packaged_services += [ "//chrome/services/util_win:manifest" ] +} + if (!is_android) { chrome_packaged_services += [ "//chrome/utility:profile_import_manifest" ] }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 68d80bd..736f8a2 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -2649,74 +2649,6 @@ No networks found. </message> - <!-- SIM unlock --> - <message name="IDS_SIM_UNLOCK_CHANGE_PIN_TITLE" desc="Cellular device change PIN dialog title in chrome:settings/internet."> - Change SIM card PIN - </message> - <message name="IDS_SIM_UNLOCK_CHANGE_PIN_MESSAGE" desc="Cellular device change PIN dialog message in chrome:settings/internet."> - Please enter old and new PIN. - </message> - <message name="IDS_SIM_UNLOCK_CHANGE_PIN_OLD_PIN" desc="Cellular device change PIN dialog old PIN label text in chrome:settings/internet."> - Old PIN: - </message> - <message name="IDS_SIM_UNLOCK_CHANGE_PIN_NEW_PIN" desc="Cellular device change PIN dialog new PIN label text in chrome:settings/internet."> - New PIN: - </message> - <message name="IDS_SIM_UNLOCK_CHANGE_PIN_RETYPE_PIN" desc="Cellular device change PIN dialog re-type new PIN label text in chrome:settings/internet."> - Re-type new PIN: - </message> - <message name="IDS_SIM_UNLOCK_PINS_DONT_MATCH_ERROR" desc="Cellular device change PIN dialog message shown when entered new PINs don't match in chrome:settings/internet."> - PINs don't match! - </message> - <message name="IDS_SIM_UNLOCK_ENTER_PIN_TITLE" desc="Title of the SIM card unlock dialog in chrome:sim-unlock."> - Enter SIM card PIN - </message> - <message name="IDS_SIM_ENTER_PIN_MESSAGE" desc="Message on the the SIM card dialog asking to enter PIN in chrome:sim-unlock."> - Please enter PIN. - </message> - <message name="IDS_SIM_UNLOCK_ENTER_PIN_TRIES_MESSAGE" desc="Message on the the SIM card unlock dialog asking to enter PIN in chrome:sim-unlock."> - SIM card is locked, please enter PIN. Tries left: <ph name="TRIES_COUNT">$1<ex>42</ex></ph> - </message> - <message name="IDS_SIM_UNLOCK_INCORRECT_PIN_TRIES_MESSAGE" desc="Incorrect PIN message with the number of tries left shown on SIM card unlock dialog in chrome:sim-unlock."> - Incorrect PIN, please try again. Tries left: <ph name="TRIES_COUNT">$1<ex>42</ex></ph> - </message> - <message name="IDS_SIM_UNLOCK_INCORRECT_PIN_TITLE" desc="Title of the Incorrect PIN stage (no tries left) shown on SIM card unlock dialog in chrome:sim-unlock."> - Incorrect PIN - </message> - <message name="IDS_SIM_UNLOCK_NO_PIN_TRIES_LEFT_MESSAGE" desc="Message shown when there's no PIN tries left, shown on SIM card unlock dialog in chrome:sim-unlock."> - You have entered the incorrect PIN too many times. Please contact <ph name="CARRIER_ID">$1<ex>your carrier</ex></ph> to obtain a new 8-digit PIN Unlocking Key. - </message> - <message name="IDS_SIM_UNLOCK_DEFAULT_CARRIER" desc="Generic carrier name shown on SIM unlock dialog. Ex.: IDS_SIM_UNLOCK_NO_PIN_TRIES_LEFT_MESSAGE, IDS_SIM_UNLOCK_ENTER_PUK_MESSAGE"> - your carrier - </message> - <message name="IDS_SIM_UNLOCK_ENTER_PUK_BUTTON" desc="Text of the button that will take to Enter PUK dialog, part of SIM card unlock dialog in chrome:sim-unlock."> - Enter PIN Unlocking Key - </message> - <message name="IDS_SIM_UNLOCK_ENTER_PUK_TITLE" desc="Title of the Enter PUK dialog, which is part of SIM card unlock dialog in chrome:sim-unlock."> - Enter PIN Unlocking Key - </message> - <message name="IDS_SIM_UNLOCK_ENTER_PUK_WARNING" desc="Warning on the Enter PUK dialog with the number of tries left, which is part of SIM card unlock dialog in chrome:sim-unlock."> - Your SIM card will be permanently disabled if you cannot enter the correct PIN Unlocking Key. Tries left: <ph name="TRIES_COUNT">$1<ex>42</ex></ph> - </message> - <message name="IDS_SIM_UNLOCK_ENTER_PUK_MESSAGE" desc="Message on the Enter PUK dialog, which is part of SIM card unlock dialog in chrome:sim-unlock."> - Please enter the 8-digit PIN Unlocking Key provided by <ph name="CARRIER_ID">$1<ex>your carrier</ex></ph>. - </message> - <message name="IDS_SIM_UNLOCK_CHOOSE_PIN_TITLE" desc="Title of the Choose new PIN dialog, which is part of SIM card unlock dialog in chrome:sim-unlock."> - Choose New PIN - </message> - <message name="IDS_SIM_UNLOCK_CHOOSE_PIN_MESSAGE" desc="Message on the Choose new PIN dialog, which is part of SIM card unlock dialog in chrome:sim-unlock."> - Please choose a new PIN. - </message> - <message name="IDS_SIM_UNLOCK_NO_PUK_TRIES_LEFT_MESSAGE" desc="Message shown when there're not PUK tries left, right after last try was used and SIM card is now disabled."> - You have entered the incorrect PIN Unlocking Key too many times. Your SIM card is permanently disabled. - </message> - <message name="IDS_SIM_UNLOCK_SIM_DISABLED_TITLE" desc="Title shown when there're not PUK tries left and SIM card is disabled."> - SIM card disabled - </message> - <message name="IDS_SIM_UNLOCK_SIM_DISABLED_MESSAGE" desc="Message shown when there're not PUK tries left and SIM card is disabled."> - This SIM card is disabled and cannot be used. Please contact your service provider for a replacement. - </message> - <!-- Slow UI --> <message name="IDS_SLOW_DISABLE" desc="The text of the button that disables performance collection for feedback reports"> Disable performance data collection
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 59974568..56ade323 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -11068,8 +11068,8 @@ </message> <if expr="is_win"> - <message name="IDS_UTILITY_PROCESS_SHELL_HANDLER_NAME" desc="The name of the utility process used to handle shell operations."> - Shell Handler + <message name="IDS_UTILITY_PROCESS_UTILITY_WIN_NAME" desc="The name of the utility process used to handle Windows utility operations."> + Windows Utilities </message> </if>
diff --git a/chrome/app/resources/manpage.1.in b/chrome/app/resources/manpage.1.in index e0ff60a..1e4fe85 100644 --- a/chrome/app/resources/manpage.1.in +++ b/chrome/app/resources/manpage.1.in
@@ -24,7 +24,7 @@ \fB\-\-user\-data\-dir\fR=\fIDIR\fR Specifies the directory that user data (your "profile") is kept in. Defaults to -.I ~/.config/@@PACKAGE@@ . +.I $HOME/.config/@@PACKAGE@@ . Separate instances of @@MENUNAME@@ must use separate user data directories; repeated invocations of @@PACKAGE@@ will reuse an existing process for a given user data directory. @@ -150,11 +150,11 @@ .SH FILES .TP -.I ~/.config/@@PACKAGE@@ +.I $HOME/.config/@@PACKAGE@@ Default directory for configuration data. .TP -.I ~/.cache/@@PACKAGE@@ +.I $HOME/.cache/@@PACKAGE@@ Default directory for cache data. (Why? See <http://standards.freedesktop.org/basedir-spec/latest/> .)
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 2a917ee..1f5dc0de 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2794,6 +2794,7 @@ "//chrome/common:metrics_constants_util_win", "//chrome/common:version_header", "//chrome/install_static:install_static_util", + "//chrome/services/util_win/public/interfaces", "//chrome_elf:blacklist", "//chrome_elf:constants", "//chrome_elf:dll_hash",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 96753cb7..adc1c11 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -6,6 +6,7 @@ "+chrome/grit", "+chrome/install_static", "+chrome/installer/util", + "+chrome/services/util_win/public/interfaces", "+chrome_elf/blacklist", "+chrome_elf/chrome_elf_constants.h", "+chrome_elf/dll_hash",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index ad7f06f..ac8d365f 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -373,6 +373,8 @@ {flags_ui::kGenericExperimentChoiceDefault, "", ""}, {flag_descriptions::kChromeHomeSwipeLogicRestrictArea, switches::kChromeHomeSwipeLogicType, "restrict-area"}, + {flag_descriptions::kChromeHomeSwipeLogicVelocity, + switches::kChromeHomeSwipeLogicType, "velocity"}, }; #endif // OS_ANDROID @@ -2237,6 +2239,9 @@ flag_descriptions::kVrShellExperimentalRenderingName, flag_descriptions::kVrShellExperimentalRenderingDescription, kOsAndroid, FEATURE_VALUE_TYPE(features::kVrShellExperimentalRendering)}, + {"enable-vr-launch-intent", flag_descriptions::kVrLaunchIntentName, + flag_descriptions::kVrLaunchIntentDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kVrLaunchIntent)}, {"enable-webvr-autopresent", flag_descriptions::kWebVrAutopresentName, flag_descriptions::kWebVrAutopresentDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kWebVrAutopresent)}, @@ -2369,14 +2374,6 @@ flag_descriptions::kCrosRegionsModeDescription, kOsCrOS, MULTI_VALUE_TYPE(kCrosRegionsModeChoices)}, #endif // OS_CHROMEOS -#if defined(OS_ANDROID) - {"enable-web-notification-custom-layouts", - flag_descriptions::kEnableWebNotificationCustomLayoutsName, - flag_descriptions::kEnableWebNotificationCustomLayoutsDescription, - kOsAndroid, - ENABLE_DISABLE_VALUE_TYPE(switches::kEnableWebNotificationCustomLayouts, - switches::kDisableWebNotificationCustomLayouts)}, -#endif // OS_ANDROID #if defined(OS_WIN) {"enable-appcontainer", flag_descriptions::kEnableAppcontainerName, flag_descriptions::kEnableAppcontainerDescription, kOsWin, @@ -3799,8 +3796,7 @@ flags_storage, internal_name, enable); } -void RemoveFlagsSwitches( - std::map<std::string, base::CommandLine::StringType>* switch_list) { +void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list) { FlagsStateSingleton::GetFlagsState()->RemoveFlagsSwitches(switch_list); }
diff --git a/chrome/browser/about_flags.h b/chrome/browser/about_flags.h index 9df7a7e..9714dea8 100644 --- a/chrome/browser/about_flags.h +++ b/chrome/browser/about_flags.h
@@ -74,8 +74,7 @@ // Removes all switches that were added to a command line by a previous call to // |ConvertFlagsToSwitches()|. -void RemoveFlagsSwitches( - std::map<std::string, base::CommandLine::StringType>* switch_list); +void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list); // Reset all flags to the default state by clearing all flags. void ResetAllFlags(flags_ui::FlagsStorage* flags_storage);
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index af65849..504851b 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -105,6 +105,7 @@ &kVideoPersistence, &kVrBrowsingFeedback, &kVrCustomTabBrowsing, + &kVrLaunchIntent, &payments::features::kWebPaymentsMethodSectionOrderV2, &payments::features::kWebPaymentsModifiers, &kWebPaymentsSingleAppUiSkip, @@ -308,6 +309,9 @@ const base::Feature kVrCustomTabBrowsing{"VrCustomTabBrowsing", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kVrLaunchIntent{"VrLaunchIntent", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kWebPaymentsSingleAppUiSkip{ "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index d815383..a6fa6c9 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -68,6 +68,7 @@ extern const base::Feature kVideoPersistence; extern const base::Feature kVrBrowsingFeedback; extern const base::Feature kVrCustomTabBrowsing; +extern const base::Feature kVrLaunchIntent; extern const base::Feature kWebPaymentsSingleAppUiSkip; extern const base::Feature kWebVrAutopresent; extern const base::Feature kWebVRCardboardSupport;
diff --git a/chrome/browser/android/devtools_manager_delegate_android.cc b/chrome/browser/android/devtools_manager_delegate_android.cc index c4f5852..7ab36d0 100644 --- a/chrome/browser/android/devtools_manager_delegate_android.cc +++ b/chrome/browser/android/devtools_manager_delegate_android.cc
@@ -38,8 +38,7 @@ proxy_->DispatchOnClientHost(message); } - void AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override { + void AgentHostClosed(DevToolsAgentHost* agent_host) override { proxy_->ConnectionClosed(); }
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 07fe429..155601d0 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1779,7 +1779,7 @@ // Test makes sure that interstitial pages renders in <webview>. // Flaky on Win dbg: crbug.com/779973 -#if defined(OS_WIN) && !defined(NDEBUG) +#if defined(OS_WIN) && defined(NDEBUG) #define MAYBE_InterstitialPage DISABLED_InterstitialPage #else #define MAYBE_InterstitialPage InterstitialPage @@ -1809,7 +1809,7 @@ // Test makes sure that interstitial pages are registered in the // RenderWidgetHostInputEventRouter when inside a <webview>. // Flaky on Win dbg: crbug.com/779973 -#if defined(OS_WIN) && !defined(NDEBUG) +#if defined(OS_WIN) && defined(NDEBUG) #define MAYBE_InterstitialPageRouteEvents DISABLED_InterstitialPageRouteEvents #else #define MAYBE_InterstitialPageRouteEvents InterstitialPageRouteEvents
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index be35d8d..dc5b962 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -1375,9 +1375,7 @@ base::CommandLine* old_cl = base::CommandLine::ForCurrentProcess(); auto new_cl = base::MakeUnique<base::CommandLine>(old_cl->GetProgram()); - std::map<std::string, base::CommandLine::StringType> switches = - old_cl->GetSwitches(); - + base::CommandLine::SwitchMap switches = old_cl->GetSwitches(); switches::RemoveSwitchesForAutostart(&switches); // Append the rest of the switches (along with their values, if any)
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 0878b6f..43c2999 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -466,7 +466,6 @@ <include name="IDR_BLUETOOTH_PAIR_DEVICE_HTML" file="resources\chromeos\bluetooth_pair_device.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_BLUETOOTH_DIALOG_HOST_HTML" file="resources\chromeos\bluetooth_dialog_host.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> <include name="IDR_BLUETOOTH_DIALOG_HOST_JS" file="resources\chromeos\bluetooth_dialog_host.js" type="chrome_html" /> - <include name="IDR_SIM_UNLOCK_HTML" file="resources\chromeos\sim_unlock.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SLOW_HTML" file="resources\chromeos\slow.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SLOW_JS" file="resources\chromeos\slow.js" type="BINDATA" /> <include name="IDR_HATS_HTML" file="resources\chromeos\hats\hats.html" flattenhtml="false" type="BINDATA" />
diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc index 09d4f91..6dee3f2 100644 --- a/chrome/browser/browser_shutdown.cc +++ b/chrome/browser/browser_shutdown.cc
@@ -239,8 +239,7 @@ base::CommandLine old_cl(*base::CommandLine::ForCurrentProcess()); std::unique_ptr<base::CommandLine> new_cl( new base::CommandLine(old_cl.GetProgram())); - std::map<std::string, base::CommandLine::StringType> switches = - old_cl.GetSwitches(); + base::CommandLine::SwitchMap switches = old_cl.GetSwitches(); // Remove the switches that shouldn't persist across restart. about_flags::RemoveFlagsSwitches(&switches); switches::RemoveSwitchesForAutostart(&switches);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 0d9e6f8..f7b34d2 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -244,6 +244,7 @@ #include "chrome/browser/chrome_browser_main_win.h" #include "chrome/browser/conflicts/module_database_win.h" #include "chrome/browser/conflicts/module_event_sink_impl_win.h" +#include "chrome/services/util_win/public/interfaces/constants.mojom.h" #include "sandbox/win/src/sandbox_policy.h" #elif defined(OS_MACOSX) #include "chrome/browser/chrome_browser_main_mac.h" @@ -3123,6 +3124,11 @@ l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME); #endif +#if defined(OS_WIN) + (*services)[chrome::mojom::kUtilWinServiceName] = + l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_UTILITY_WIN_NAME); +#endif + #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMash)) mash_service_registry::RegisterOutOfProcessServices(services);
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json index df354fff..739eb92 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -52,7 +52,8 @@ "ime_registrar", "input_device_controller", "window_manager" - ] + ], + "util_win" : [ "shell_util_win" ] } }, "navigation:frame": {
diff --git a/chrome/browser/chrome_content_gpu_manifest_overlay.json b/chrome/browser/chrome_content_gpu_manifest_overlay.json index 0d7c7c1..6398526a 100644 --- a/chrome/browser/chrome_content_gpu_manifest_overlay.json +++ b/chrome/browser/chrome_content_gpu_manifest_overlay.json
@@ -4,12 +4,12 @@ "service_manager:connector": { "provides": { "browser": [ - "arc::mojom::ProtectedBufferManager", "arc::mojom::VideoDecodeAccelerator", "arc::mojom::VideoDecodeClient", "arc::mojom::VideoEncodeAccelerator", "arc::mojom::VideoEncodeClient", "chrome::mojom::ResourceUsageReporter", + "media::mojom::ProtectedBufferManager", "profiling::mojom::ProfilingClient" ] }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 5109ae8..8efd1f2 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1455,8 +1455,6 @@ "settings/system_settings_provider.h", "settings/token_encryptor.cc", "settings/token_encryptor.h", - "sim_dialog_delegate.cc", - "sim_dialog_delegate.h", "status/data_promo_notification.cc", "status/data_promo_notification.h", "status/network_menu.cc", @@ -1825,6 +1823,8 @@ "login/users/affiliation_unittest.cc", "login/users/multi_profile_user_controller_unittest.cc", "login/users/user_manager_unittest.cc", + "login/users/wallpaper/wallpaper_manager_test_utils.cc", + "login/users/wallpaper/wallpaper_manager_test_utils.h", "login/users/wallpaper/wallpaper_manager_unittest.cc", "mobile/mobile_activator_unittest.cc", "mobile_config_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index e8a95154..6c8024da 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -9,6 +9,7 @@ #include <memory> #include <utility> +#include <vector> #include "ash/accessibility/accessibility_controller.h" #include "ash/accessibility/accessibility_focus_ring_controller.h" @@ -1117,6 +1118,11 @@ pref_change_registrar_.reset(); local_state_pref_change_registrar_.reset(); + // Cancel pending PostLoadChromeVox, PostSwitchChromeVoxProfile, and other + // in-flight callbacks - otherwise these callbacks would have operated on + // a different |profile_| than the one they were originally meant for. + weak_ptr_factory_.InvalidateWeakPtrs(); + if (profile) { // TODO(yoshiki): Move following code to PrefHandler. pref_change_registrar_.reset(new PrefChangeRegistrar);
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.cc b/chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.cc index e9fd75e2..288169a3 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.cc
@@ -214,8 +214,9 @@ return navigation_handle()->GetStartingSiteInstance()->GetSiteURL(); } -// We received the array of app candidates to handle this URL (even the Chrome -// app is included). +// Receives the array of app candidates to handle this URL and decides whether a +// preferred app should be triggered right away or ask the browser to display +// the intent picker. void ArcNavigationThrottle::OnAppCandidatesReceived( std::vector<mojom::IntentHandlerInfoPtr> handlers) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -223,7 +224,7 @@ const GURL& url = handle->GetURL(); if (!IsAppAvailable(handlers)) { - // This scenario shouldn't be accessed as ArcNavigatinoThrottle is created + // This scenario shouldn't be accessed as ArcNavigationThrottle is created // iff there are ARC apps which can actually handle the given URL. DVLOG(1) << "There are no app candidates for this URL: " << url; ui_displayed_ = false;
diff --git a/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc index 4505e33..030cad8 100644 --- a/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc +++ b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc
@@ -149,7 +149,7 @@ mojom::OemCryptoServiceRequest request) { // Get the Mojo interface from the GPU for dealing with secure buffers and // pass that to the daemon as well in our Connect call. - mojom::ProtectedBufferManagerPtr gpu_buffer_manager; + media::mojom::ProtectedBufferManagerPtr gpu_buffer_manager; content::BindInterfaceInGpuProcess(mojo::MakeRequest(&gpu_buffer_manager)); oemcrypto_host_daemon_ptr_->Connect(std::move(request), std::move(gpu_buffer_manager));
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc index aa52cbe..6555aa33 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
@@ -23,6 +23,7 @@ #include "base/task_scheduler/post_task.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" #include "chrome/browser/chromeos/arc/voice_interaction/highlighter_controller_client.h" +#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" #include "chrome/browser/profiles/profile.h" @@ -82,10 +83,13 @@ LayerSet excluded_layers; // Exclude metalayer-related layers. This will also include other layers // under kShellWindowId_OverlayContainer which is fine. - aura::Window* overlay_container = ash::Shell::GetContainer( - root_window, ash::kShellWindowId_OverlayContainer); - if (overlay_container != nullptr) - excluded_layers.insert(overlay_container->layer()); + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() != ash::Config::MASH) { + aura::Window* overlay_container = ash::Shell::GetContainer( + root_window, ash::kShellWindowId_OverlayContainer); + if (overlay_container != nullptr) + excluded_layers.insert(overlay_container->layer()); + } auto layer_tree_owner = ::wm::RecreateLayersWithClosure( root_window, base::BindRepeating( @@ -249,6 +253,11 @@ // Since ARC currently only runs in primary display, we restrict // the screenshot to it. + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() == ash::Config::MASH) { + std::move(callback).Run(std::vector<uint8_t>{}); + return; + } aura::Window* window = ash::Shell::GetPrimaryRootWindow(); DCHECK(window); @@ -307,6 +316,9 @@ highlighter_client_->Exit(); state_ = state; + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() == ash::Config::MASH) + return; ash::Shell::Get()->NotifyVoiceInteractionStatusChanged(state); } @@ -355,6 +367,8 @@ // TODO(crbug.com/757012): Avoid using ash::Shell here so that it can work in // mash. + if (chromeos::GetAshConfig() == ash::Config::MASH) + return; PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); bool enabled = prefs->GetBoolean(prefs::kVoiceInteractionEnabled); ash::Shell::Get()->NotifyVoiceInteractionEnabled(enabled); @@ -429,7 +443,9 @@ VoiceInteractionSettingCompleteCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - ash::Shell::Get()->NotifyVoiceInteractionEnabled(enable); + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() != ash::Config::MASH) + ash::Shell::Get()->NotifyVoiceInteractionEnabled(enable); PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); @@ -453,7 +469,9 @@ bool enable) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - ash::Shell::Get()->NotifyVoiceInteractionContextEnabled(enable); + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() != ash::Config::MASH) + ash::Shell::Get()->NotifyVoiceInteractionContextEnabled(enable); PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); prefs->SetBoolean(prefs::kVoiceInteractionContextEnabled, enable); @@ -572,8 +590,11 @@ if (state_ == ash::VoiceInteractionState::NOT_READY) { // If the container side is not ready, we will be waiting for a while. - ash::Shell::Get()->NotifyVoiceInteractionStatusChanged( - ash::VoiceInteractionState::NOT_READY); + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() != ash::Config::MASH) { + ash::Shell::Get()->NotifyVoiceInteractionStatusChanged( + ash::VoiceInteractionState::NOT_READY); + } } ArcBootPhaseMonitorBridge::RecordFirstAppLaunchDelayUMA(context_); @@ -595,11 +616,17 @@ PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); prefs->SetBoolean(prefs::kArcVoiceInteractionValuePropAccepted, completed); + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() == ash::Config::MASH) + return; ash::Shell::Get()->NotifyVoiceInteractionSetupCompleted(completed); } bool ArcVoiceInteractionFrameworkService::IsHomescreenActive() { // Homescreen is considered to be active if there are no active windows. + // TODO(crbug.com/757012): Mash support. + if (chromeos::GetAshConfig() == ash::Config::MASH) + return false; return !ash::Shell::Get()->activation_client()->GetActiveWindow(); }
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc index d46a1206..ab60b216a 100644 --- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc +++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
@@ -233,8 +233,8 @@ // ImageDecoder::ImageRequest. decode_request_.reset(); const PrimaryAccount& account = GetPrimaryAccount(); - chromeos::WallpaperManager::Get()->SetDefaultWallpaper(account.id, - account.is_active); + chromeos::WallpaperManager::Get()->SetDefaultWallpaper( + account.id, account.is_active /* update_wallpaper */); } void ArcWallpaperService::GetWallpaper(GetWallpaperCallback callback) {
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc index db0937a..4cdb0802 100644 --- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc +++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" +#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h" #include "chrome/browser/image_decoder.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -131,6 +132,8 @@ TEST_F(ArcWallpaperServiceTest, SetDefaultWallpaper) { service_->SetDefaultWallpaper(); RunAllPendingInMessageLoop(); + // Wait until wallpaper loading is done. + chromeos::wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); ASSERT_EQ(1u, wallpaper_instance_->changed_ids().size()); EXPECT_EQ(-1, wallpaper_instance_->changed_ids()[0]); } @@ -141,7 +144,8 @@ std::vector<uint8_t> bytes; service_->SetWallpaper(bytes, 10 /* ID */); content::RunAllTasksUntilIdle(); - + // Wait until wallpaper loading is done. + chromeos::wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); ASSERT_EQ(1u, wallpaper_instance_->changed_ids().size()); EXPECT_EQ(10, wallpaper_instance_->changed_ids()[0]); @@ -160,6 +164,8 @@ std::vector<uint8_t> bytes; service_->SetWallpaper(bytes, 10 /* ID */); content::RunAllTasksUntilIdle(); + // Wait until wallpaper loading is done. + chromeos::wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); // For failure case, ArcWallpaperService reports that wallpaper is changed to // requested wallpaper (ID=10), then reports that the wallpaper is changed
diff --git a/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc b/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc index 5820b41..73e4c70 100644 --- a/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc +++ b/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
@@ -247,7 +247,8 @@ IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest, OEMWallpaperIsPresent) { CreateCmdlineWallpapers(); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( ash::Shell::Get()->wallpaper_controller()->GetWallpaper(), @@ -276,7 +277,8 @@ IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest, OEMWallpaperRetryFetch) { CreateCmdlineWallpapers(); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( ash::Shell::Get()->wallpaper_controller()->GetWallpaper(),
diff --git a/chrome/browser/chromeos/extensions/extension_system_event_observer.cc b/chrome/browser/chromeos/extensions/extension_system_event_observer.cc index 3938d9c..e37bdb3 100644 --- a/chrome/browser/chromeos/extensions/extension_system_event_observer.cc +++ b/chrome/browser/chromeos/extensions/extension_system_event_observer.cc
@@ -6,17 +6,19 @@ #include "chrome/browser/extensions/api/system_private/system_private_api.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "components/session_manager/core/session_manager.h" namespace chromeos { -ExtensionSystemEventObserver::ExtensionSystemEventObserver() { +ExtensionSystemEventObserver::ExtensionSystemEventObserver() + : screen_locked_(session_manager::SessionManager::Get()->IsScreenLocked()) { DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); - DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); + session_manager::SessionManager::Get()->AddObserver(this); } ExtensionSystemEventObserver::~ExtensionSystemEventObserver() { DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); - DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); + session_manager::SessionManager::Get()->RemoveObserver(this); } void ExtensionSystemEventObserver::BrightnessChanged(int level, @@ -29,8 +31,11 @@ extensions::DispatchWokeUpEvent(); } -void ExtensionSystemEventObserver::ScreenIsUnlocked() { - extensions::DispatchScreenUnlockedEvent(); +void ExtensionSystemEventObserver::OnSessionStateChanged() { + const bool was_locked = screen_locked_; + screen_locked_ = session_manager::SessionManager::Get()->IsScreenLocked(); + if (was_locked && !screen_locked_) + extensions::DispatchScreenUnlockedEvent(); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/extension_system_event_observer.h b/chrome/browser/chromeos/extensions/extension_system_event_observer.h index ab9f4ab1..42a7c8b 100644 --- a/chrome/browser/chromeos/extensions/extension_system_event_observer.h +++ b/chrome/browser/chromeos/extensions/extension_system_event_observer.h
@@ -8,13 +8,14 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "chromeos/dbus/power_manager_client.h" -#include "chromeos/dbus/session_manager_client.h" +#include "components/session_manager/core/session_manager_observer.h" namespace chromeos { // Dispatches extension events in response to system events. -class ExtensionSystemEventObserver : public PowerManagerClient::Observer, - public SessionManagerClient::Observer { +class ExtensionSystemEventObserver + : public PowerManagerClient::Observer, + public session_manager::SessionManagerObserver { public: // This class registers/unregisters itself as an observer in ctor/dtor. ExtensionSystemEventObserver(); @@ -24,10 +25,12 @@ void BrightnessChanged(int level, bool user_initiated) override; void SuspendDone(const base::TimeDelta& sleep_duration) override; - // SessionManagerClient::Observer override. - void ScreenIsUnlocked() override; + // session_manager::SessionManagerObserver override: + void OnSessionStateChanged() override; private: + bool screen_locked_ = false; + DISALLOW_COPY_AND_ASSIGN(ExtensionSystemEventObserver); };
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc index 688258e..d663661 100644 --- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc +++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -479,7 +479,8 @@ if (wallpaper_manager->IsPolicyControlled(account_id)) return false; - wallpaper_manager->SetDefaultWallpaper(account_id, true); + wallpaper_manager->SetDefaultWallpaper(account_id, + true /* update_wallpaper */); Profile* profile = Profile::FromBrowserContext(browser_context()); // This API is only available to the component wallpaper picker. We do not
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc index fae53fb..7465d59 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -188,7 +188,7 @@ lock_screen_utils::SetUserInputMethod(account_id.GetUserEmail(), ime_state_.get()); lock_screen_utils::SetKeyboardSettings(account_id); - WallpaperManager::Get()->SetUserWallpaperDelayed(account_id); + WallpaperManager::Get()->SetUserWallpaper(account_id); bool use_24hour_clock = false; if (user_manager::known_user::GetBooleanPref(
diff --git a/chrome/browser/chromeos/login/ui/user_adding_screen.cc b/chrome/browser/chromeos/login/ui/user_adding_screen.cc index 75a545e..b6f2e89 100644 --- a/chrome/browser/chromeos/login/ui/user_adding_screen.cc +++ b/chrome/browser/chromeos/login/ui/user_adding_screen.cc
@@ -69,7 +69,7 @@ // Reset wallpaper if cancel adding user from multiple user sign in page. if (user_manager::UserManager::Get()->IsUserLoggedIn()) { - WallpaperManager::Get()->SetUserWallpaperDelayed( + WallpaperManager::Get()->SetUserWallpaper( user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()); } }
diff --git a/chrome/browser/chromeos/login/ui/webui_login_display.cc b/chrome/browser/chromeos/login/ui/webui_login_display.cc index 1d24b425..e5afbdf 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_display.cc +++ b/chrome/browser/chromeos/login/ui/webui_login_display.cc
@@ -223,14 +223,14 @@ } void WebUILoginDisplay::LoadWallpaper(const AccountId& account_id) { - WallpaperManager::Get()->SetUserWallpaperDelayed(account_id); + WallpaperManager::Get()->SetUserWallpaper(account_id); } void WebUILoginDisplay::LoadSigninWallpaper() { if (!WallpaperManager::Get()->SetDeviceWallpaperIfApplicable( user_manager::SignInAccountId())) { - WallpaperManager::Get()->SetDefaultWallpaperDelayed( - user_manager::SignInAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper( + user_manager::SignInAccountId(), true /* update_wallpaper */); } }
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index 379d559..8bae38218 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -770,7 +770,7 @@ user_manager::User::USER_IMAGE_INVALID, false); // Initializes wallpaper after active_user_ is set. - WallpaperManager::Get()->SetUserWallpaperNow(user_manager::GuestAccountId()); + WallpaperManager::Get()->SetUserWallpaper(user_manager::GuestAccountId()); } void ChromeUserManagerImpl::RegularUserLoggedIn(const AccountId& account_id) { @@ -785,7 +785,7 @@ } if (IsCurrentUserNew()) - WallpaperManager::Get()->SetUserWallpaperNow(account_id); + WallpaperManager::Get()->SetUserWallpaper(account_id); GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), false); @@ -801,7 +801,7 @@ ChromeUserManager::RegularUserLoggedInAsEphemeral(account_id); GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), false); - WallpaperManager::Get()->SetUserWallpaperNow(account_id); + WallpaperManager::Get()->SetUserWallpaper(account_id); } void ChromeUserManagerImpl::SupervisedUserLoggedIn( @@ -816,11 +816,11 @@ SetIsCurrentUserNew(true); active_user_ = user_manager::User::CreateSupervisedUser(account_id); // Leaving OAuth token status at the default state = unknown. - WallpaperManager::Get()->SetUserWallpaperNow(account_id); + WallpaperManager::Get()->SetUserWallpaper(account_id); } else { if (supervised_user_manager_->CheckForFirstRun(account_id.GetUserEmail())) { SetIsCurrentUserNew(true); - WallpaperManager::Get()->SetUserWallpaperNow(account_id); + WallpaperManager::Get()->SetUserWallpaper(account_id); } else { SetIsCurrentUserNew(false); } @@ -860,7 +860,7 @@ // always fetched/cleared inside a user session), in the case the user-policy // controlled wallpaper was cached/cleared by not updated in the login screen, // so we need to update the wallpaper after the public user logged in. - WallpaperManager::Get()->SetUserWallpaperNow(user->GetAccountId()); + WallpaperManager::Get()->SetUserWallpaper(user->GetAccountId()); WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); SetPublicAccountDelegates(); @@ -877,7 +877,7 @@ user_manager::User::USER_IMAGE_INVALID, false); const AccountId& kiosk_app_account_id = user->GetAccountId(); - WallpaperManager::Get()->SetUserWallpaperNow(kiosk_app_account_id); + WallpaperManager::Get()->SetUserWallpaper(kiosk_app_account_id); // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like // the kiosk_app_id in these objects, removing the need to re-parse the @@ -947,7 +947,7 @@ *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_LOGIN_DEFAULT_USER)), user_manager::User::USER_IMAGE_INVALID, false); - WallpaperManager::Get()->SetUserWallpaperNow(user_manager::DemoAccountId()); + WallpaperManager::Get()->SetUserWallpaper(user_manager::DemoAccountId()); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); command_line->AppendSwitch(::switches::kForceAppMode);
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc index 7f32f5b..1f892fbc 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -361,48 +361,45 @@ // Enqueued but not started request might be updated by subsequent load // request. Therefore it's created empty, and updated being enqueued. // -// PendingWallpaper is owned by WallpaperManager, but reference to this object -// is passed to other threads by PostTask() calls, therefore it is -// RefCountedThreadSafe. -class WallpaperManager::PendingWallpaper - : public base::RefCountedThreadSafe<PendingWallpaper> { +// PendingWallpaper is owned by WallpaperManager. +class WallpaperManager::PendingWallpaper { public: - // Do LoadWallpaper() - image not found in cache. - PendingWallpaper(const base::TimeDelta delay, const AccountId& account_id) - : account_id_(account_id), - default_(false), - on_finish_(new MovableOnDestroyCallback( - base::Bind(&WallpaperManager::PendingWallpaper::OnWallpaperSet, - this))) { - timer.Start( - FROM_HERE, delay, - base::Bind(&WallpaperManager::PendingWallpaper::ProcessRequest, this)); + PendingWallpaper(const base::TimeDelta delay) : weak_factory_(this) { + on_finish_ = std::make_unique<MovableOnDestroyCallback>( + base::Bind(&WallpaperManager::PendingWallpaper::OnWallpaperSet, + weak_factory_.GetWeakPtr())); + timer.Start(FROM_HERE, delay, + base::Bind(&WallpaperManager::PendingWallpaper::ProcessRequest, + weak_factory_.GetWeakPtr())); } - // There are 4 cases in SetUserWallpaper: + ~PendingWallpaper() { weak_factory_.InvalidateWeakPtrs(); } + + // There are four cases: // 1) gfx::ImageSkia is found in cache. - // - Schedule task to (probably) resize it and install: - // call SetWallpaper(user_wallpaper, layout); - // 2) WallpaperInfo is found in cache - // - need to LoadWallpaper(), resize and install. - // 3) wallpaper path is not NULL, load image URL, then resize, etc... - // 4) SetDefaultWallpaper (either on some error, or when user is new). - void ResetSetWallpaperImage(const gfx::ImageSkia& image, - const wallpaper::WallpaperInfo& info) { - SetMode(image, info, base::FilePath(), false); + void SetWallpaperFromImage(const AccountId& account_id, + const gfx::ImageSkia& image, + const wallpaper::WallpaperInfo& info) { + SetMode(account_id, image, info, base::FilePath(), false); } - void ResetLoadWallpaper(const wallpaper::WallpaperInfo& info) { - SetMode(gfx::ImageSkia(), info, base::FilePath(), false); + // 2) WallpaperInfo is found in cache. + void SetWallpaperFromInfo(const AccountId& account_id, + const wallpaper::WallpaperInfo& info) { + SetMode(account_id, gfx::ImageSkia(), info, base::FilePath(), false); } - void ResetSetCustomWallpaper(const wallpaper::WallpaperInfo& info, - const base::FilePath& wallpaper_path) { - SetMode(gfx::ImageSkia(), info, wallpaper_path, false); + // 3) Wallpaper path is not null. + void SetWallpaperFromPath(const AccountId& account_id, + const wallpaper::WallpaperInfo& info, + const base::FilePath& wallpaper_path) { + SetMode(account_id, gfx::ImageSkia(), info, wallpaper_path, false); } - void ResetSetDefaultWallpaper() { - SetMode(gfx::ImageSkia(), WallpaperInfo(), base::FilePath(), true); + // 4) Set default wallpaper (either on some error, or when user is new). + void SetDefaultWallpaper(const AccountId& account_id) { + SetMode(account_id, gfx::ImageSkia(), WallpaperInfo(), base::FilePath(), + true); } uint32_t GetImageId() const { @@ -410,15 +407,13 @@ } private: - friend class base::RefCountedThreadSafe<PendingWallpaper>; - - ~PendingWallpaper() {} - - // All Reset*() methods use SetMode() to set object to new state. - void SetMode(const gfx::ImageSkia& image, + // All methods use SetMode() to set object to new state. + void SetMode(const AccountId& account_id, + const gfx::ImageSkia& image, const wallpaper::WallpaperInfo& info, const base::FilePath& wallpaper_path, const bool is_default) { + account_id_ = account_id; user_wallpaper_ = image; info_ = info; wallpaper_path_ = wallpaper_path; @@ -427,9 +422,13 @@ // This method is usually triggered by timer to actually load request. void ProcessRequest() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); + // The only known case for this check to fail is global destruction during + // wallpaper load. It should never happen. + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) + return; - timer.Stop(); // Erase reference to self. + // Erase reference to self. + timer.Stop(); WallpaperManager* manager = WallpaperManager::Get(); if (manager->pending_inactive_ == this) @@ -438,11 +437,14 @@ started_load_at_ = base::Time::Now(); if (default_) { + // The most recent request is |SetDefaultWallpaper|. manager->DoSetDefaultWallpaper(account_id_, true /* update_wallpaper */, std::move(on_finish_)); } else if (!user_wallpaper_.isNull()) { + // The most recent request is |SetWallpaperFromImage|. SetWallpaper(user_wallpaper_, info_); } else if (!wallpaper_path_.empty()) { + // The most recent request is |SetWallpaperFromPath|. manager->task_runner_->PostTask( FROM_HERE, base::BindOnce(&WallpaperManager::GetCustomWallpaperInternal, @@ -452,12 +454,13 @@ base::Passed(std::move(on_finish_)), manager->weak_factory_.GetWeakPtr())); } else if (!info_.location.empty()) { + // The most recent request is |SetWallpaperFromInfo|. manager->LoadWallpaper(account_id_, info_, true /* update_wallpaper */, std::move(on_finish_)); } else { - // PendingWallpaper was created and never initialized? + // PendingWallpaper was created but none of the four methods was called. + // This should never happen. Do not record time in this case. NOTREACHED(); - // Error. Do not record time. started_load_at_ = base::Time(); } on_finish_.reset(); @@ -465,14 +468,13 @@ // This method is called by callback, when load request is finished. void OnWallpaperSet() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - // The only known case for this check to fail is global destruction during // wallpaper load. It should never happen. if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) - return; // We are in a process of global destruction. + return; - timer.Stop(); // Erase reference to self. + // Erase reference to self. + timer.Stop(); WallpaperManager* manager = WallpaperManager::Get(); if (!started_load_at_.is_null()) { @@ -504,6 +506,8 @@ // Load start time to calculate duration. base::Time started_load_at_; + base::WeakPtrFactory<PendingWallpaper> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(PendingWallpaper); }; @@ -614,6 +618,9 @@ device_wallpaper_image_subscription_.reset(); user_manager::UserManager::Get()->RemoveObserver(this); weak_factory_.InvalidateWeakPtrs(); + // In case there's wallpaper load request being processed. + for (size_t i = 0; i < loading_.size(); ++i) + delete loading_[i]; } // static @@ -765,7 +772,7 @@ // If decoded wallpaper is empty, we have probably failed to decode the file. // Use default wallpaper in this case. if (image.isNull()) { - SetDefaultWallpaperDelayed(account_id); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); return; } @@ -811,7 +818,7 @@ base::Time::Now().LocalMidnight()}; SetUserWallpaperInfo(account_id, info, is_persistent); if (update_wallpaper) { - GetPendingWallpaper(account_id, false)->ResetSetWallpaperImage(image, info); + GetPendingWallpaper()->SetWallpaperFromImage(account_id, image, info); } wallpaper_cache_[account_id] = CustomWallpaperElement(wallpaper_path, image); @@ -820,7 +827,6 @@ void WallpaperManager::SetDefaultWallpaper(const AccountId& account_id, bool update_wallpaper) { RemoveUserWallpaperInfo(account_id); - const wallpaper::WallpaperInfo info = { std::string(), wallpaper::WALLPAPER_LAYOUT_CENTER, wallpaper::DEFAULT, base::Time::Now().LocalMidnight()}; @@ -830,23 +836,7 @@ SetUserWallpaperInfo(account_id, info, is_persistent); if (update_wallpaper) - SetDefaultWallpaperNow(account_id); -} - -void WallpaperManager::SetDefaultWallpaperNow(const AccountId& account_id) { - GetPendingWallpaper(account_id, false)->ResetSetDefaultWallpaper(); -} - -void WallpaperManager::SetDefaultWallpaperDelayed(const AccountId& account_id) { - GetPendingWallpaper(account_id, true)->ResetSetDefaultWallpaper(); -} - -void WallpaperManager::SetUserWallpaperNow(const AccountId& account_id) { - ScheduleSetUserWallpaper(account_id, false); -} - -void WallpaperManager::SetUserWallpaperDelayed(const AccountId& account_id) { - ScheduleSetUserWallpaper(account_id, true); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); } void WallpaperManager::SetUserWallpaperInfo(const AccountId& account_id, @@ -897,10 +887,8 @@ wallpaper_cache_[account_id] = CustomWallpaperElement(base::FilePath(), image); - if (update_wallpaper) { - GetPendingWallpaper(last_selected_user_, false /* Not delayed */) - ->ResetSetWallpaperImage(image, info); - } + if (update_wallpaper) + GetPendingWallpaper()->SetWallpaperFromImage(account_id, image, info); } void WallpaperManager::InitializeWallpaper() { @@ -936,12 +924,13 @@ if (!user_manager->IsUserLoggedIn()) { if (!StartupUtils::IsDeviceRegistered()) - SetDefaultWallpaperDelayed(user_manager::SignInAccountId()); + GetPendingWallpaper()->SetDefaultWallpaper( + user_manager::SignInAccountId()); else InitializeRegisteredDeviceWallpaper(); return; } - SetUserWallpaperDelayed(user_manager->GetActiveUser()->GetAccountId()); + SetUserWallpaper(user_manager->GetActiveUser()->GetAccountId()); } void WallpaperManager::UpdateWallpaper(bool clear_cache) { @@ -950,13 +939,13 @@ // be set. It could result a black screen on external monitors. // See http://crbug.com/265689 for detail. if (last_selected_user_.empty()) - SetDefaultWallpaperNow(user_manager::SignInAccountId()); + GetPendingWallpaper()->SetDefaultWallpaper(user_manager::SignInAccountId()); for (auto& observer : observers_) observer.OnUpdateWallpaperForTesting(); if (clear_cache) wallpaper_cache_.clear(); - SetUserWallpaperNow(last_selected_user_); + SetUserWallpaper(last_selected_user_); } bool WallpaperManager::IsPendingWallpaper(uint32_t image_id) { @@ -1023,7 +1012,7 @@ if (info == current_user_wallpaper_info_) return; } - SetUserWallpaperNow( + SetUserWallpaper( user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()); } @@ -1119,7 +1108,7 @@ // If we're at the login screen, do not change the wallpaper but defer it // until the user logs in to the system. if (user_manager::UserManager::Get()->IsUserLoggedIn()) - SetDefaultWallpaperNow(account_id); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); } void WallpaperManager::SetCustomizedDefaultWallpaper( @@ -1220,7 +1209,7 @@ } void WallpaperManager::OnChildStatusChanged(const user_manager::User& user) { - SetUserWallpaperNow(user.GetAccountId()); + SetUserWallpaper(user.GetAccountId()); } void WallpaperManager::OnWindowActivated(ActivationReason reason, @@ -1582,7 +1571,8 @@ !HasNonDeviceLocalAccounts(users)) { // Boot into sign in form, preload default wallpaper. if (!SetDeviceWallpaperIfApplicable(user_manager::SignInAccountId())) - SetDefaultWallpaperDelayed(user_manager::SignInAccountId()); + GetPendingWallpaper()->SetDefaultWallpaper( + user_manager::SignInAccountId()); return; } @@ -1591,7 +1581,7 @@ // Normal boot, load user wallpaper. // If normal boot animation is disabled wallpaper would be set // asynchronously once user pods are loaded. - SetUserWallpaperDelayed(users[index]->GetAccountId()); + SetUserWallpaper(users[index]->GetAccountId()); } } @@ -1808,8 +1798,7 @@ SetWallpaper(user_image->image(), info); } -void WallpaperManager::ScheduleSetUserWallpaper(const AccountId& account_id, - bool delayed) { +void WallpaperManager::SetUserWallpaper(const AccountId& account_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Some unit tests come here without a UserManager or without a pref system. if (!user_manager::UserManager::IsInitialized() || @@ -1838,7 +1827,7 @@ user->HasGaiaAccount()) || user->GetType() == user_manager::USER_TYPE_GUEST) { InitInitialUserWallpaper(account_id, false); - GetPendingWallpaper(account_id, delayed)->ResetSetDefaultWallpaper(); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); if (base::SysInfo::IsRunningOnChromeOS()) { LOG(ERROR) << "User is ephemeral or guest! Fallback to default wallpaper."; @@ -1858,13 +1847,13 @@ gfx::ImageSkia user_wallpaper; current_user_wallpaper_info_ = info; if (GetWallpaperFromCache(account_id, &user_wallpaper)) { - GetPendingWallpaper(account_id, delayed) - ->ResetSetWallpaperImage(user_wallpaper, info); + GetPendingWallpaper()->SetWallpaperFromImage(account_id, user_wallpaper, + info); } else { if (info.location.empty()) { // Uses default built-in wallpaper when file is empty. Eventually, we // will only ship one built-in wallpaper in ChromeOS image. - GetPendingWallpaper(account_id, delayed)->ResetSetDefaultWallpaper(); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); return; } @@ -1897,13 +1886,14 @@ CustomWallpaperElement(wallpaper_path, gfx::ImageSkia()); loaded_wallpapers_for_test_++; - GetPendingWallpaper(account_id, delayed) - ->ResetSetCustomWallpaper(info, wallpaper_path); + GetPendingWallpaper()->SetWallpaperFromPath(account_id, info, + wallpaper_path); return; } - // Load downloaded ONLINE or converted DEFAULT wallpapers. - GetPendingWallpaper(account_id, delayed)->ResetLoadWallpaper(info); + // Load downloaded online or converted default wallpapers according to the + // WallpaperInfo. + GetPendingWallpaper()->SetWallpaperFromInfo(account_id, info); } } @@ -2007,22 +1997,22 @@ if (last_load_times_.size() == 0) { delay = base::TimeDelta::FromMilliseconds(kLoadDefaultDelayMs); } else { + // Calculate the average loading time. delay = std::accumulate(last_load_times_.begin(), last_load_times_.end(), base::TimeDelta(), std::plus<base::TimeDelta>()) / last_load_times_.size(); - } - if (delay < base::TimeDelta::FromMilliseconds(kLoadMinDelayMs)) - delay = base::TimeDelta::FromMilliseconds(kLoadMinDelayMs); - else if (delay > base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs)) - delay = base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs); + if (delay < base::TimeDelta::FromMilliseconds(kLoadMinDelayMs)) + delay = base::TimeDelta::FromMilliseconds(kLoadMinDelayMs); + else if (delay > base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs)) + delay = base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs); - // If we had ever loaded wallpaper, adjust wait delay by time since last load. - if (!last_load_finished_at_.is_null()) { + // Reduce the delay by the time passed after the last wallpaper load. + DCHECK(!last_load_finished_at_.is_null()); const base::TimeDelta interval = base::Time::Now() - last_load_finished_at_; if (interval > delay) delay = base::TimeDelta::FromMilliseconds(0); - else if (interval > base::TimeDelta::FromMilliseconds(0)) + else delay -= interval; } return delay; @@ -2222,26 +2212,25 @@ DoSetDefaultWallpaper(account_id, update_wallpaper, std::move(on_finish)); } -WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper( - const AccountId& account_id, - bool delayed) { +WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper() { + // If |pending_inactive_| already exists, return it directly. This allows the + // pending request (whose timer is still running) to be overriden by a + // subsequent request. if (!pending_inactive_) { - loading_.push_back(new WallpaperManager::PendingWallpaper( - (delayed ? GetWallpaperLoadDelay() - : base::TimeDelta::FromMilliseconds(0)), - account_id)); - pending_inactive_ = loading_.back().get(); + loading_.push_back( + new WallpaperManager::PendingWallpaper(GetWallpaperLoadDelay())); + pending_inactive_ = loading_.back(); } return pending_inactive_; } void WallpaperManager::RemovePendingWallpaperFromList( - PendingWallpaper* pending) { + PendingWallpaper* finished_loading_request) { DCHECK(loading_.size() > 0); - for (WallpaperManager::PendingList::iterator i = loading_.begin(); - i != loading_.end(); ++i) { - if (i->get() == pending) { - loading_.erase(i); + for (size_t i = 0; i < loading_.size(); ++i) { + if (loading_[i] == finished_loading_request) { + loading_.erase(loading_.begin() + i); + delete loading_[i]; break; } } @@ -2314,7 +2303,7 @@ if (!success) { LOG(ERROR) << "Failed to download the device wallpaper. Fallback to " "default wallpaper."; - SetDefaultWallpaperDelayed(account_id); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); return; } @@ -2346,7 +2335,7 @@ } else { LOG(ERROR) << "The device wallpaper hash doesn't match with provided " "hash value. Fallback to default wallpaper! "; - SetDefaultWallpaperDelayed(account_id); + GetPendingWallpaper()->SetDefaultWallpaper(account_id); // Reset the boolean variable so that it can retry to download when the // next device wallpaper request comes in. @@ -2373,8 +2362,8 @@ wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED, wallpaper::DEVICE, base::Time::Now().LocalMidnight()}; - GetPendingWallpaper(user_manager::SignInAccountId(), false) - ->ResetSetWallpaperImage(user_image->image(), wallpaper_info); + GetPendingWallpaper()->SetWallpaperFromImage( + account_id, user_image->image(), wallpaper_info); } }
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h index fd3d2b4..bf1dabc3 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h
@@ -257,30 +257,21 @@ const gfx::ImageSkia& image, bool update_wallpaper); - // Updates wallpaper info for |account_id| to default. If |update_wallpaper| - // is false, don't change wallpaper but only update cache. + // Sets default wallpaper. |update_wallpaper| indicates whether to actually + // change the wallpaper, or only update cache. void SetDefaultWallpaper(const AccountId& account_id, bool update_wallpaper); - // Sets wallpaper to default wallpaper (asynchronously with zero delay). - void SetDefaultWallpaperNow(const AccountId& account_id); + // Sets |account_id|'s wallpaper. + void SetUserWallpaper(const AccountId& account_id); - // Sets wallpaper to default wallpaper (asynchronously with default delay). - void SetDefaultWallpaperDelayed(const AccountId& account_id); - - // Sets |account_id|'s wallpaper (asynchronously with zero delay). - void SetUserWallpaperNow(const AccountId& account_id); - - // Sets |account_id|'s wallpaper (asynchronously with default delay). - void SetUserWallpaperDelayed(const AccountId& account_id); - - // Sets selected wallpaper information for |account_id| and saves it to Local - // State if |is_persistent| is true. + // Sets wallpaper info for |account_id| and saves it to local state if + // |is_persistent| is true. void SetUserWallpaperInfo(const AccountId& account_id, const wallpaper::WallpaperInfo& info, bool is_persistent); - // Sets wallpaper to |image| (asynchronously with zero delay). If - // |update_wallpaper| is false, skip change wallpaper but only update cache. + // Sets wallpaper to |image|. If |update_wallpaper| is false, skip change + // wallpaper but only update cache. void SetWallpaperFromImageSkia(const AccountId& account_id, const gfx::ImageSkia& image, wallpaper::WallpaperLayout layout, @@ -292,7 +283,7 @@ void InitializeWallpaper(); // Updates current wallpaper. It may switch the size of wallpaper based on the - // current display's resolution. (asynchronously with zero delay) + // current display's resolution. void UpdateWallpaper(bool clear_cache); // Returns if the image is in the pending list. |image_id| can be obtained @@ -515,9 +506,6 @@ MovableOnDestroyCallbackHolder on_finish, std::unique_ptr<user_manager::UserImage> user_image); - // Creates new PendingWallpaper request (or updates currently pending). - void ScheduleSetUserWallpaper(const AccountId& account_id, bool delayed); - // Sets wallpaper to default if |update_wallpaper| is true. Otherwise just // load defaut wallpaper to cache. void DoSetDefaultWallpaper(const AccountId& account_id, @@ -538,11 +526,9 @@ // Notify all registered observers. void NotifyAnimationFinished(); - // Calculate delay for next wallpaper load. - // It is usually average wallpaper load time. - // If last wallpaper load happened long ago, timeout should be reduced by - // the time passed after last wallpaper load. So usual user experience results - // in zero delay. + // Calculates delay for the next wallpaper load. In most cases it is zero. It + // starts with the average wallpaper load time, and is reduced by the time + // passed after the last wallpaper load. base::TimeDelta GetWallpaperLoadDelay() const; // This is called after we check that supplied default wallpaper files exist. @@ -606,13 +592,13 @@ bool update_wallpaper, MovableOnDestroyCallbackHolder on_finish); - // Returns modifiable PendingWallpaper. - // Returns pending_inactive_ or creates new PendingWallpaper if necessary. - PendingWallpaper* GetPendingWallpaper(const AccountId& account_id, - bool delayed); + // Returns modifiable PendingWallpaper. (Either |pending_inactive_| or a new + // |PendingWallpaper| object.) + PendingWallpaper* GetPendingWallpaper(); // This is called by PendingWallpaper when load is finished. - void RemovePendingWallpaperFromList(PendingWallpaper* pending); + void RemovePendingWallpaperFromList( + PendingWallpaper* finished_loading_request); // Set wallpaper to |user_image| controlled by policy. (Takes a UserImage // because that's the callback interface provided by UserImageLoader.) @@ -718,7 +704,7 @@ // Owns PendingWallpaper. // PendingWallpaper deletes itself from here on load complete. // All pending will be finally deleted on destroy. - typedef std::vector<scoped_refptr<PendingWallpaper>> PendingList; + typedef std::vector<PendingWallpaper*> PendingList; PendingList loading_; content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc index 5be5c10c..e91ef1c 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
@@ -236,7 +236,7 @@ wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true); // Set the wallpaper for |test_account_id1_|. - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); gfx::ImageSkia wallpaper = controller_->GetWallpaper(); @@ -285,15 +285,16 @@ WallpaperManager* wallpaper_manager = WallpaperManager::Get(); // New user log in, a default wallpaper is loaded. LogIn(test_account_id1_, kTestUser1Hash); + wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_EQ(1, LoadedWallpapers()); // Loads the same wallpaper before the initial one finished. It should be // prevented. - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_EQ(1, LoadedWallpapers()); // Loads the same wallpaper after the initial one finished. It should be // prevented. - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_EQ(1, LoadedWallpapers()); ClearDisposableWallpaperCache(); @@ -314,15 +315,15 @@ base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true); - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); WaitAsyncWallpaperLoadStarted(); EXPECT_EQ(2, LoadedWallpapers()); // Loads the same wallpaper before the initial one finished. It should be // prevented. - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); WaitAsyncWallpaperLoadStarted(); EXPECT_EQ(2, LoadedWallpapers()); - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_EQ(2, LoadedWallpapers()); } @@ -383,8 +384,8 @@ HotPlugInScreenAtGAIALoginScreen) { UpdateDisplay("800x600"); // Set initial wallpaper to the default wallpaper. - WallpaperManager::Get()->SetDefaultWallpaperNow( - user_manager::StubAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); // Hook up a 2000x2000 display. The large resolution custom wallpaper should @@ -482,6 +483,7 @@ #endif IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore, MAYBE_RestoreWallpaper) { + wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_EQ(1, LoadedWallpapers()); } @@ -524,11 +526,11 @@ wallpaper::CUSTOMIZED, base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true); - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); std::unique_ptr<WallpaperManager::TestApi> test_api; test_api.reset(new WallpaperManager::TestApi(wallpaper_manager)); - // Verify SetUserWallpaperNow updates wallpaper cache. + // Verify SetUserWallpaper updates wallpaper cache. gfx::ImageSkia cached_wallpaper; EXPECT_TRUE( test_api->GetWallpaperFromCache(test_account_id1_, &cached_wallpaper)); @@ -601,7 +603,8 @@ EXPECT_TRUE(test_api->GetPathFromCache(test_account_id1_, &path)); EXPECT_NE(original_path, path); - wallpaper_manager->SetDefaultWallpaperNow(test_account_id1_); + wallpaper_manager->SetDefaultWallpaper(test_account_id1_, + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); // SetDefaultWallpaper should invalidate the user's wallpaper cache. EXPECT_FALSE( @@ -731,7 +734,8 @@ // At 800x600, the small wallpaper should be loaded. UpdateDisplay("800x600"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -741,7 +745,8 @@ IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, LargeDefaultWallpaper) { CreateCmdlineWallpapers(); UpdateDisplay("1600x1200"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -753,7 +758,8 @@ CreateCmdlineWallpapers(); UpdateDisplay("1200x800/r"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -765,7 +771,8 @@ SessionManager::Get()->CreateSession(user_manager::GuestAccountId(), user_manager::kGuestUserName); UpdateDisplay("800x600"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(user_manager::GuestAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -777,7 +784,8 @@ SessionManager::Get()->CreateSession(user_manager::GuestAccountId(), user_manager::kGuestUserName); UpdateDisplay("1600x1200"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(user_manager::GuestAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -788,7 +796,8 @@ CreateCmdlineWallpapers(); LogInAsChild(test_account_id1_, kTestUser1Hash); UpdateDisplay("800x600"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(test_account_id1_, + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -799,7 +808,8 @@ CreateCmdlineWallpapers(); LogInAsChild(test_account_id1_, kTestUser1Hash); UpdateDisplay("1600x1200"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(test_account_id1_, + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -814,7 +824,8 @@ SessionManager::Get()->CreateSession(user_manager::StubAccountId(), "test_hash"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(), + true /* update_wallpaper */); // Custom wallpaper should be applied immediately, canceling the default // wallpaper load task. @@ -830,7 +841,8 @@ controller_->GetWallpaper(), wallpaper_manager_test_utils::kCustomWallpaperColor)); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(), + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( @@ -845,7 +857,8 @@ SessionManager::Get()->CreateSession(user_manager::StubAccountId(), "test_hash"); - WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId()); + WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(), + true /* update_wallpaper */); gfx::ImageSkia image = wallpaper_manager_test_utils::CreateTestImage( 640, 480, wallpaper_manager_test_utils::kCustomWallpaperColor); @@ -893,7 +906,7 @@ wallpaper::CUSTOMIZED, base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id2_, info2, true); - wallpaper_manager->SetUserWallpaperNow(test_account_id2_); + wallpaper_manager->SetUserWallpaper(test_account_id2_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor( controller_->GetWallpaper(), @@ -947,7 +960,7 @@ wallpaper::CUSTOMIZED, base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true); - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(base::PathExists(small_wallpaper_path)); @@ -967,7 +980,7 @@ wallpaper::CUSTOMIZED, base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id2_, info2, true); - wallpaper_manager->SetUserWallpaperNow(test_account_id2_); + wallpaper_manager->SetUserWallpaper(test_account_id2_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(base::PathExists(small_wallpaper_path2)); @@ -1008,7 +1021,7 @@ wallpaper::CUSTOMIZED, base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true); - wallpaper_manager->SetUserWallpaperNow(test_account_id1_); + wallpaper_manager->SetUserWallpaper(test_account_id1_); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); EXPECT_TRUE(base::PathExists(small_wallpaper_path)); @@ -1019,7 +1032,8 @@ WallpaperInfo info2 = {"", WALLPAPER_LAYOUT_CENTER_CROPPED, wallpaper::DEFAULT, base::Time::Now().LocalMidnight()}; wallpaper_manager->SetUserWallpaperInfo(test_account_id2_, info2, true); - WallpaperManager::Get()->SetDefaultWallpaperNow(test_account_id2_); + WallpaperManager::Get()->SetDefaultWallpaper(test_account_id2_, + true /* update_wallpaper */); wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished(); // Simulate the removal of |test_account_id2_|.
diff --git a/chrome/browser/chromeos/net/network_connect_delegate_chromeos.cc b/chrome/browser/chromeos/net/network_connect_delegate_chromeos.cc index 6bef5c7..3ed8b7a7 100644 --- a/chrome/browser/chromeos/net/network_connect_delegate_chromeos.cc +++ b/chrome/browser/chromeos/net/network_connect_delegate_chromeos.cc
@@ -7,7 +7,6 @@ #include "chrome/browser/chromeos/enrollment_dialog_view.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/net/network_state_notifier.h" -#include "chrome/browser/chromeos/sim_dialog_delegate.h" #include "chrome/browser/ui/ash/system_tray_client.h" #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h" @@ -50,13 +49,6 @@ nullptr /* owning_window */); } -void NetworkConnectDelegateChromeOS::ShowMobileSimDialog() { - if (!IsUIAvailable()) - return; - SimDialogDelegate::ShowDialog(nullptr /* owning_window */, - SimDialogDelegate::SIM_DIALOG_UNLOCK); -} - void NetworkConnectDelegateChromeOS::ShowMobileSetupDialog( const std::string& network_id) { if (!IsUIAvailable())
diff --git a/chrome/browser/chromeos/net/network_connect_delegate_chromeos.h b/chrome/browser/chromeos/net/network_connect_delegate_chromeos.h index 8e3713a26..f49008fd 100644 --- a/chrome/browser/chromeos/net/network_connect_delegate_chromeos.h +++ b/chrome/browser/chromeos/net/network_connect_delegate_chromeos.h
@@ -23,7 +23,6 @@ void ShowNetworkConfigure(const std::string& network_id) override; void ShowNetworkSettings(const std::string& network_id) override; bool ShowEnrollNetwork(const std::string& network_id) override; - void ShowMobileSimDialog() override; void ShowMobileSetupDialog(const std::string& service_path) override; void ShowNetworkConnectError(const std::string& error_name, const std::string& network_id) override;
diff --git a/chrome/browser/chromeos/net/network_state_notifier_unittest.cc b/chrome/browser/chromeos/net/network_state_notifier_unittest.cc index c6dc5bc..586f96e5 100644 --- a/chrome/browser/chromeos/net/network_state_notifier_unittest.cc +++ b/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
@@ -42,7 +42,6 @@ bool ShowEnrollNetwork(const std::string& network_id) override { return false; } - void ShowMobileSimDialog() override {} void ShowMobileSetupDialog(const std::string& service_path) override {} void ShowNetworkConnectError(const std::string& error_name, const std::string& network_id) override {
diff --git a/chrome/browser/chromeos/printing/printers_sync_bridge.cc b/chrome/browser/chromeos/printing/printers_sync_bridge.cc index 2d64860..3bd85b4 100644 --- a/chrome/browser/chromeos/printing/printers_sync_bridge.cc +++ b/chrome/browser/chromeos/printing/printers_sync_bridge.cc
@@ -53,8 +53,8 @@ StoreProxy(PrintersSyncBridge* owner, const syncer::ModelTypeStoreFactory& callback) : owner_(owner), weak_ptr_factory_(this) { - callback.Run(base::Bind(&StoreProxy::OnStoreCreated, - weak_ptr_factory_.GetWeakPtr())); + callback.Run(syncer::PRINTERS, base::Bind(&StoreProxy::OnStoreCreated, + weak_ptr_factory_.GetWeakPtr())); } // Returns true if the store has been initialized.
diff --git a/chrome/browser/chromeos/printing/synced_printers_manager_factory.cc b/chrome/browser/chromeos/printing/synced_printers_manager_factory.cc index 9b6be7749..21a21ed 100644 --- a/chrome/browser/chromeos/printing/synced_printers_manager_factory.cc +++ b/chrome/browser/chromeos/printing/synced_printers_manager_factory.cc
@@ -57,7 +57,7 @@ const syncer::ModelTypeStoreFactory& store_factory = browser_sync::ProfileSyncService::GetModelTypeStoreFactory( - syncer::PRINTERS, profile->GetPath()); + profile->GetPath()); std::unique_ptr<PrintersSyncBridge> sync_bridge = base::MakeUnique<PrintersSyncBridge>(
diff --git a/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc index cc14059..25a5dcd 100644 --- a/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc +++ b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc
@@ -96,8 +96,7 @@ : manager_(SyncedPrintersManager::Create( &profile_, base::MakeUnique<PrintersSyncBridge>( - base::Bind(&syncer::ModelTypeStore::CreateInMemoryStoreForTest, - syncer::PRINTERS), + base::Bind(&syncer::ModelTypeStore::CreateInMemoryStoreForTest), base::BindRepeating( base::IgnoreResult(&base::debug::DumpWithoutCrashing))))) { base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/chromeos/sim_dialog_delegate.cc b/chrome/browser/chromeos/sim_dialog_delegate.cc deleted file mode 100644 index 4bf1c480..0000000 --- a/chrome/browser/chromeos/sim_dialog_delegate.cc +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/sim_dialog_delegate.h" - -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/system_tray_client.h" -#include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/common/url_constants.h" -#include "ui/gfx/geometry/size.h" - -using content::WebContents; -using content::WebUIMessageHandler; - -namespace { - -// Default width/height of the dialog. -const int kDefaultWidth = 350; -const int kDefaultHeight = 225; - -// Width/height for the change PIN dialog mode. -const int kChangePinWidth = 350; -const int kChangePinHeight = 245; - -// Dialog mode constants. -const char kSimDialogChangePinMode[] = "change-pin"; -const char kSimDialogSetLockOnMode[] = "set-lock-on"; -const char kSimDialogSetLockOffMode[] = "set-lock-off"; - -} // namespace - -namespace chromeos { - -// static -void SimDialogDelegate::ShowDialog(gfx::NativeWindow owning_window, - SimDialogMode mode) { - Profile* profile = ProfileManager::GetActiveUserProfile(); - if (owning_window) { - chrome::ShowWebDialog(owning_window, profile, new SimDialogDelegate(mode)); - } else { - chrome::ShowWebDialogInContainer( - SystemTrayClient::GetDialogParentContainerId(), profile, - new SimDialogDelegate(mode)); - } -} - -SimDialogDelegate::SimDialogDelegate(SimDialogMode dialog_mode) - : dialog_mode_(dialog_mode) { -} - -SimDialogDelegate::~SimDialogDelegate() { -} - -ui::ModalType SimDialogDelegate::GetDialogModalType() const { - return ui::MODAL_TYPE_SYSTEM; -} - -base::string16 SimDialogDelegate::GetDialogTitle() const { - return base::string16(); -} - -GURL SimDialogDelegate::GetDialogContentURL() const { - if (dialog_mode_ == SIM_DIALOG_UNLOCK) { - std::string url_string(chrome::kChromeUISimUnlockURL); - return GURL(url_string); - } else { - std::string mode_value; - if (dialog_mode_ == SIM_DIALOG_CHANGE_PIN) - mode_value = kSimDialogChangePinMode; - else if (dialog_mode_ == SIM_DIALOG_SET_LOCK_ON) - mode_value = kSimDialogSetLockOnMode; - else - mode_value = kSimDialogSetLockOffMode; - - // Create a URL that includes an additional mode (other than Unlock flow). - // Possible values for mode are: - // change-pin - use dialog to change PIN, ask for old & new PIN. - // set-lock-on - enable RequirePin restriction. - // set-lock-off - disable RequirePin restriction. - std::string url_string = - std::string(chrome::kChromeUISimUnlockURL) + "?mode=" + mode_value; - return GURL(url_string); - } -} - -void SimDialogDelegate::GetWebUIMessageHandlers( - std::vector<WebUIMessageHandler*>* handlers) const { -} - -void SimDialogDelegate::GetDialogSize(gfx::Size* size) const { - // TODO(nkostylev): Set custom size based on locale settings. - if (dialog_mode_ == SIM_DIALOG_CHANGE_PIN) - size->SetSize(kChangePinWidth , kChangePinHeight); - else - size->SetSize(kDefaultWidth, kDefaultHeight); -} - -std::string SimDialogDelegate::GetDialogArgs() const { - return "[]"; -} - -void SimDialogDelegate::OnDialogClosed(const std::string& json_retval) { - delete this; -} - -void SimDialogDelegate::OnCloseContents(WebContents* source, - bool* out_close_dialog) { - *out_close_dialog = true; -} - -bool SimDialogDelegate::ShouldShowDialogTitle() const { - return false; -} - -bool SimDialogDelegate::HandleContextMenu( - const content::ContextMenuParams& params) { - // Disable context menu. - return true; -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/sim_dialog_delegate.h b/chrome/browser/chromeos/sim_dialog_delegate.h deleted file mode 100644 index d92df156..0000000 --- a/chrome/browser/chromeos/sim_dialog_delegate.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_SIM_DIALOG_DELEGATE_H_ -#define CHROME_BROWSER_CHROMEOS_SIM_DIALOG_DELEGATE_H_ - -#include "base/macros.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/web_dialogs/web_dialog_delegate.h" - -namespace chromeos { - -// SIM unlock dialog displayed in cases when SIM card has to be unlocked. -class SimDialogDelegate : public ui::WebDialogDelegate { - public: - // Type of the SIM dialog that is launched. - typedef enum SimDialogMode { - SIM_DIALOG_UNLOCK = 0, // General unlock flow dialog (PIN/PUK). - SIM_DIALOG_CHANGE_PIN = 1, // Change PIN dialog. - SIM_DIALOG_SET_LOCK_ON = 2, // Enable RequirePin restriction. - SIM_DIALOG_SET_LOCK_OFF = 3, // Disable RequirePin restriction. - } SimDialogMode; - - explicit SimDialogDelegate(SimDialogMode dialog_mode); - - // Shows the SIM unlock dialog box with one of the specified modes. If the - // |owning_window| is null the dialog is placed in the appropriate modal - // dialog container on the primary display. - static void ShowDialog(gfx::NativeWindow owning_window, SimDialogMode mode); - - private: - ~SimDialogDelegate() override; - - // Overridden from ui::WebDialogDelegate: - ui::ModalType GetDialogModalType() const override; - base::string16 GetDialogTitle() const override; - GURL GetDialogContentURL() const override; - void GetWebUIMessageHandlers( - std::vector<content::WebUIMessageHandler*>* handlers) const override; - void GetDialogSize(gfx::Size* size) const override; - std::string GetDialogArgs() const override; - void OnDialogClosed(const std::string& json_retval) override; - void OnCloseContents(content::WebContents* source, - bool* out_close_dialog) override; - bool ShouldShowDialogTitle() const override; - bool HandleContextMenu(const content::ContextMenuParams& params) override; - - SimDialogMode dialog_mode_; - - DISALLOW_COPY_AND_ASSIGN(SimDialogDelegate); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_SIM_DIALOG_DELEGATE_H_
diff --git a/chrome/browser/chromeos/status/data_promo_notification_unittest.cc b/chrome/browser/chromeos/status/data_promo_notification_unittest.cc index b1d903b..c1fbaf5 100644 --- a/chrome/browser/chromeos/status/data_promo_notification_unittest.cc +++ b/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
@@ -42,7 +42,6 @@ bool ShowEnrollNetwork(const std::string& network_id) override { return false; } - void ShowMobileSimDialog() override {} void ShowMobileSetupDialog(const std::string& network_id) override {} void ShowNetworkConnectError(const std::string& error_name, const std::string& network_id) override {}
diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc index f1b5e11..12a78dd 100644 --- a/chrome/browser/chromeos/status/network_menu.cc +++ b/chrome/browser/chromeos/status/network_menu.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/chromeos/mobile_config.h" #include "chrome/browser/chromeos/options/network_config_view.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/sim_dialog_delegate.h" #include "chrome/browser/defaults.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
diff --git a/chrome/browser/conflicts/proto/module_list.proto b/chrome/browser/conflicts/proto/module_list.proto index 8063627..9d95830 100644 --- a/chrome/browser/conflicts/proto/module_list.proto +++ b/chrome/browser/conflicts/proto/module_list.proto
@@ -8,30 +8,17 @@ package chrome.conflicts; -// Describes a version tuple. Versions are matched exactly, so missing fields -// will not match zero value fields. For example, "4" will not match "4.0" or -// "4.0.0.0". -// Next id: 5 -message ModuleVersion { - required uint32 major_version = 1; - optional uint32 minor_version = 2; - // Can only be specified if |minor| is specified. - optional uint32 patch_version = 3; - // Can only be specified if |patch| is specified. - optional uint32 revision_version = 4; -} - // Describes a module. A module is valid only if at least one of |basename| or // |code_id| is specified, although both may be specified. A module must exactly // match all specified fields in order to be considered a match. -// Next id: 7 +// Next id: 5 message Module { // The basename of the module. This is case insensitive. If this is not // specified then |code_id| must be specified. On the client this actually // corresponds to the SHA1 hash of the basename, which has been first made // lowercase. optional string basename = 1; - optional bytes basename_hash = 5; + optional bytes basename_hash = 3; // Code ID. This is equivalent to the string generated by formatting // the FileHeader.TimeDateStamp and OptionalHeader.SizeOfImage with the @@ -40,12 +27,7 @@ // corresponds to the SHA1 hash of the code id, which has first been made // lowercase. optional string code_id = 2; - optional bytes code_id_hash = 6; - - // Version matching. Specifying both a minimum and a maximum provides an - // exact matching mechanism. Both versions are inclusive. - optional ModuleVersion version_min = 3; - optional ModuleVersion version_max = 4; + optional bytes code_id_hash = 4; } // A module group is a collection of one or more modules with shared publisher
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index d63c74c..0e76506 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -650,8 +650,7 @@ } void DevToolsUIBindings::AgentHostClosed( - content::DevToolsAgentHost* agent_host, - bool replaced_with_another_client) { + content::DevToolsAgentHost* agent_host) { DCHECK(agent_host == agent_host_.get()); agent_host_ = NULL; delegate_->InspectedContentsClosing();
diff --git a/chrome/browser/devtools/devtools_ui_bindings.h b/chrome/browser/devtools/devtools_ui_bindings.h index b7c74e1..cfd8d086 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.h +++ b/chrome/browser/devtools/devtools_ui_bindings.h
@@ -92,8 +92,7 @@ // content::DevToolsAgentHostClient implementation. void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, const std::string& message) override; - void AgentHostClosed(content::DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override; + void AgentHostClosed(content::DevToolsAgentHost* agent_host) override; // DevToolsEmbedderMessageDispatcher::Delegate implementation. void ActivateWindow() override;
diff --git a/chrome/browser/extensions/DEPS b/chrome/browser/extensions/DEPS index 09e7040..175ae864 100644 --- a/chrome/browser/extensions/DEPS +++ b/chrome/browser/extensions/DEPS
@@ -1,7 +1,6 @@ include_rules = [ - # TODO(mash): Remove. http://crbug.com/678705 - "+ash", - + # Only public interfaces allowed. See //ash/README.md + "+ash/public/cpp", "+components/chrome_apps", "+components/crx_file", "+components/strings/grit/components_strings.h", @@ -14,3 +13,21 @@ # For access to testing command line switches. "+ppapi/shared_impl", ] +specific_include_rules = { + "bookmark_app_helper\.cc": [ + # TODO(mash): Remove. http://crbug.com/678705 + "+ash/shell.h", + ], + "display_info_provider_chromeos(|_unittest)\.cc": [ + # TODO(mash): Remove. http://crbug.com/678705 + "+ash/display", + "+ash/shell.h", + "+ash/test", + "+ash/touch", + "+ash/wm/tablet_mode/tablet_mode_controller.h", + ], + "launch_util\.cc": [ + # TODO(mash): Remove. http://crbug.com/678705 + "+ash/shell.h", + ], +}
diff --git a/chrome/browser/extensions/api/automation/DEPS b/chrome/browser/extensions/api/automation/DEPS new file mode 100644 index 0000000..ce18564b --- /dev/null +++ b/chrome/browser/extensions/api/automation/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + # TODO(mash): Remove. http://crbug.com/678705 + "+ash/accelerators/accelerator_controller.h", + "+ash/shell.h", +]
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_api.cc b/chrome/browser/extensions/api/content_settings/content_settings_api.cc index f4e45f5..244d6f4 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_api.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_api.cc
@@ -32,6 +32,7 @@ #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/plugin_service.h" +#include "content/public/common/webplugininfo.h" #include "extensions/browser/extension_prefs_scope.h" #include "extensions/common/error_utils.h"
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc index e25573d..5b5ee80 100644 --- a/chrome/browser/extensions/api/debugger/debugger_api.cc +++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -269,8 +269,7 @@ void InfoBarDismissed(); // DevToolsAgentHostClient interface. - void AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override; + void AgentHostClosed(DevToolsAgentHost* agent_host) override; void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override; @@ -366,10 +365,8 @@ // DevToolsAgentHostClient implementation. void ExtensionDevToolsClientHost::AgentHostClosed( - DevToolsAgentHost* agent_host, bool replaced_with_another_client) { + DevToolsAgentHost* agent_host) { DCHECK(agent_host == agent_host_.get()); - if (replaced_with_another_client) - detach_reason_ = api::debugger::DETACH_REASON_REPLACED_WITH_DEVTOOLS; SendDetachedEvent(); delete this; }
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc index ab1b5fb..eb9cb6e 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
@@ -85,7 +85,14 @@ } }; -IN_PROC_BROWSER_TEST_F(FeedbackTest, ShowFeedback) { +// Disabled for ASan due to flakiness on Mac ASan 64 Tests (1). +// See crbug.com/757243. +#if defined(ADDRESS_SANITIZER) +#define MAYBE_ShowFeedback DISABLED_ShowFeedback +#else +#define MAYBE_ShowFeedback ShowFeedback +#endif +IN_PROC_BROWSER_TEST_F(FeedbackTest, MAYBE_ShowFeedback) { WaitForExtensionViewsToLoad(); ASSERT_TRUE(IsFeedbackAppAvailable());
diff --git a/chrome/browser/extensions/api/notifications/extension_notification_handler.cc b/chrome/browser/extensions/api/notifications/extension_notification_handler.cc index 987c932..442b08c 100644 --- a/chrome/browser/extensions/api/notifications/extension_notification_handler.cc +++ b/chrome/browser/extensions/api/notifications/extension_notification_handler.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/notifications/notification_common.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/notifications.h" -#include "chrome/common/features.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/native_app_window.h" @@ -25,9 +24,6 @@ namespace notifications = api::notifications; -const base::Feature kAllowFullscreenAppNotificationsFeature{ - "FSNotificationsApp", base::FEATURE_ENABLED_BY_DEFAULT}; - namespace { std::string GetExtensionId(const std::string& extension_url) { @@ -123,20 +119,8 @@ GetExtensionId(origin)); for (auto* window : windows) { // Window must be fullscreen and visible - if (window->IsFullscreen() && window->GetBaseWindow()->IsActive()) { - bool enabled = - base::FeatureList::IsEnabled(kAllowFullscreenAppNotificationsFeature); - if (enabled) { - UMA_HISTOGRAM_ENUMERATION("Notifications.Display_Fullscreen.Shown", - message_center::NotifierId::APPLICATION, - message_center::NotifierId::SIZE); - } else { - UMA_HISTOGRAM_ENUMERATION("Notifications.Display_Fullscreen.Suppressed", - message_center::NotifierId::APPLICATION, - message_center::NotifierId::SIZE); - } - return enabled; - } + if (window->IsFullscreen() && window->GetBaseWindow()->IsActive()) + return true; } return false;
diff --git a/chrome/browser/extensions/api/notifications/extension_notification_handler.h b/chrome/browser/extensions/api/notifications/extension_notification_handler.h index cbdc6677..5cd13fd7 100644 --- a/chrome/browser/extensions/api/notifications/extension_notification_handler.h +++ b/chrome/browser/extensions/api/notifications/extension_notification_handler.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_NOTIFICATIONS_EXTENSION_NOTIFICATION_HANDLER_H_ #define CHROME_BROWSER_EXTENSIONS_API_NOTIFICATIONS_EXTENSION_NOTIFICATION_HANDLER_H_ -#include "base/feature_list.h" #include "base/macros.h" #include "chrome/browser/notifications/notification_handler.h" #include "extensions/browser/event_router.h" @@ -14,10 +13,6 @@ namespace extensions { -// Exposed publicly for tests. -// TODO(miguelg) we can probably get rid of this now. -extern const base::Feature kAllowFullscreenAppNotificationsFeature; - // Handler for notifications shown by extensions. Will be created and owned by // the NativeNotificationDisplayService. class ExtensionNotificationHandler : public NotificationHandler {
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc index 05f2f61b..500f7ecc 100644 --- a/chrome/browser/extensions/api/notifications/notifications_api.cc +++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/callback.h" -#include "base/feature_list.h" #include "base/guid.h" #include "base/macros.h" #include "base/memory/ptr_util.h"
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.h b/chrome/browser/extensions/api/notifications/notifications_api.h index 0608613..74278ac 100644 --- a/chrome/browser/extensions/api/notifications/notifications_api.h +++ b/chrome/browser/extensions/api/notifications/notifications_api.h
@@ -7,7 +7,6 @@ #include <string> -#include "base/feature_list.h" #include "base/memory/ref_counted.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/common/extensions/api/notifications.h"
diff --git a/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chrome/browser/extensions/api/notifications/notifications_apitest.cc index fee9a1e2..a7a97f6 100644 --- a/chrome/browser/extensions/api/notifications/notifications_apitest.cc +++ b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
@@ -8,7 +8,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/extensions/api/notifications/extension_notification_display_helper.h" @@ -210,20 +209,7 @@ WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST)); } - void EnableFullscreenNotifications() { - feature_list_.InitAndEnableFeature( - extensions::kAllowFullscreenAppNotificationsFeature); - } - - void DisableFullscreenNotifications() { - feature_list_.InitAndDisableFeature( - extensions::kAllowFullscreenAppNotificationsFeature); - } - std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; - - private: - base::test::ScopedFeatureList feature_list_; }; } // namespace @@ -423,7 +409,6 @@ } IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayNormal) { - EnableFullscreenNotifications(); ExtensionTestMessageListener notification_created_listener("created", false); const Extension* extension = LoadAppWithWindowState( "notifications/api/basic_app", WindowState::NORMAL); @@ -447,7 +432,6 @@ // screen decisions are done by the OS directly. #if !defined(OS_MACOSX) IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayFullscreen) { - EnableFullscreenNotifications(); ExtensionTestMessageListener notification_created_listener("created", false); const Extension* extension = LoadAppWithWindowState( "notifications/api/basic_app", WindowState::FULLSCREEN); @@ -472,39 +456,12 @@ ASSERT_TRUE(notification->delegate()->ShouldDisplayOverFullscreen()); } -IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayFullscreenOff) { - DisableFullscreenNotifications(); - ExtensionTestMessageListener notification_created_listener("created", false); - const Extension* extension = LoadAppWithWindowState( - "notifications/api/basic_app", WindowState::FULLSCREEN); - ASSERT_TRUE(extension) << message_; - ASSERT_TRUE(notification_created_listener.WaitUntilSatisfied()); - - // We start by making sure the window is actually focused. - ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( - GetFirstAppWindow(extension->id())->GetNativeWindow())); - - ASSERT_TRUE(GetFirstAppWindow(extension->id())->IsFullscreen()) - << "Not Fullscreen"; - ASSERT_TRUE(GetFirstAppWindow(extension->id())->GetBaseWindow()->IsActive()) - << "Not Active"; - - message_center::Notification* notification = - GetNotificationForExtension(extension); - ASSERT_TRUE(notification); - - // When the experiment flag is off, then ShouldDisplayOverFullscreen should - // return false. - ASSERT_FALSE(notification->delegate()->ShouldDisplayOverFullscreen()); -} - // The Fake OSX fullscreen window doesn't like drawing a second fullscreen // window when another is visible. IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayMultiFullscreen) { // Start a fullscreen app, and then start another fullscreen app on top of the // first. Notifications from the first should not be displayed because it is // not the app actually displaying on the screen. - EnableFullscreenNotifications(); ExtensionTestMessageListener notification_created_listener("created", false); const Extension* extension1 = LoadAppWithWindowState( "notifications/api/basic_app", WindowState::FULLSCREEN); @@ -535,7 +492,6 @@ // creates it is fullscreen with the fullscreen notification flag turned on. IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayPopupNotification) { - EnableFullscreenNotifications(); ExtensionTestMessageListener notification_created_listener("created", false); const Extension* extension = LoadAppWithWindowState( "notifications/api/basic_app", WindowState::FULLSCREEN);
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/DEPS b/chrome/browser/extensions/api/virtual_keyboard_private/DEPS index 67c01d06..fee9b101 100644 --- a/chrome/browser/extensions/api/virtual_keyboard_private/DEPS +++ b/chrome/browser/extensions/api/virtual_keyboard_private/DEPS
@@ -1,3 +1,5 @@ include_rules = [ + # TODO(mash): Remove. http://crbug.com/678705 + "+ash/shell.h", "+media/audio" ]
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index ed2907c..8ecacc3 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -6,7 +6,10 @@ #include <stddef.h> +#include <memory> #include <set> +#include <string> +#include <vector> #include "base/command_line.h" #include "base/debug/alias.h" @@ -41,6 +44,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/vpn_service_proxy.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "extensions/browser/api/web_request/web_request_api.h" @@ -373,25 +377,39 @@ content::RenderProcessHost* process_host, const GURL& url) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // We need to let most extension URLs commit in any process, since this can - // be allowed due to web_accessible_resources. Most hosted app URLs may also - // load in any process (e.g., in an iframe). However, the Chrome Web Store - // cannot be loaded in iframes and should never be requested outside its - // process. ExtensionRegistry* registry = ExtensionRegistry::Get(process_host->GetBrowserContext()); if (!registry) return true; + // Using url::Origin is important to properly handle blob: and filesystem: + // URLs. + GURL resolved_url = url::Origin::Create(url).GetURL(); + const Extension* new_extension = - registry->enabled_extensions().GetExtensionOrAppByURL(url); - if (new_extension && new_extension->is_hosted_app() && - new_extension->id() == kWebStoreAppId && - !ProcessMap::Get(process_host->GetBrowserContext()) - ->Contains(new_extension->id(), process_host->GetID())) { - return false; + registry->enabled_extensions().GetExtensionOrAppByURL(resolved_url); + if (!new_extension) + return true; + + // The Chrome Web Store should never be requested outside of its process. + // Therefore - only consider the explicitly relaxed cases below if the + // |new_extension| is not the Chrome Web Store extension. + if (new_extension->id() != kWebStoreAppId) { + // Hosted app URLs may load in any process (e.g., in an iframe). + if (new_extension->is_hosted_app()) + return true; + + // TODO(lukasza): Remove the if statement below after PlzNavigate ships. + // Without PlzNavigate we sometimes commit in an unexpected process + // (e.g. in case of error pages for failed navigation). + if (!content::IsBrowserSideNavigationEnabled()) + return true; } - return true; + + // Do not allow committing the |url|, unless an earlier SiteInstanceGotProcess + // notification told us that the |process_host| can host the |new_extension|. + return ProcessMap::Get(process_host->GetBrowserContext()) + ->Contains(new_extension->id(), process_host->GetID()); } // static
diff --git a/chrome/browser/extensions/display_info_provider_chromeos.cc b/chrome/browser/extensions/display_info_provider_chromeos.cc index 65a500d8..ea90644f 100644 --- a/chrome/browser/extensions/display_info_provider_chromeos.cc +++ b/chrome/browser/extensions/display_info_provider_chromeos.cc
@@ -610,7 +610,7 @@ unit->name = display_manager->GetDisplayNameForId(display.id()); if (display_manager->IsInMirrorMode()) { unit->mirroring_source_id = - base::Int64ToString(display_manager->mirroring_display_id()); + base::Int64ToString(display_manager->mirroring_source_id()); } const display::ManagedDisplayInfo& display_info =
diff --git a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc index edcc868..4ea53ee 100644 --- a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc +++ b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
@@ -531,7 +531,7 @@ ASSERT_EQ(1u, result.size()); EXPECT_EQ(base::Int64ToString(display_id_primary), result[0].id); - EXPECT_EQ(base::Int64ToString(display_id_secondary), + EXPECT_EQ(base::Int64ToString(display_id_primary), result[0].mirroring_source_id); GetDisplayManager()->SetMirrorMode(false);
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc index ce1bb07..6cfc225 100644 --- a/chrome/browser/extensions/process_manager_browsertest.cc +++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/extensions/browser_action_test_util.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/test_extension_dir.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -319,6 +320,127 @@ EXPECT_EQ(0u, pm->background_hosts().size()); } +// Test that extension URLs can be opened in main profile and in incognito +// profile without hitting the tightened CanCommitURL checks in +// ChromeContentBrowserClientExtensionsPart. This test is mostly based +// on the manual repro steps for https://crbug.com/691145. +IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, + ExtensionSpanningIncognitoProfile_ChildFrame) { + // Setup the embedded test server. + ASSERT_TRUE(embedded_test_server()->Start()); + + // Create a test extension in incognito spanning mode (see also + // https://developer.chrome.com/extensions/manifest/incognito). + TestExtensionDir test_dir; + test_dir.WriteManifest(R"( { "manifest_version": 2, + "browser_action": {}, + "permissions": ["activeTab"], + "name": "spanning", + "incognito": "spanning", + "web_accessible_resources": ["foo.html"], + "version": "0.1" + } )"); + test_dir.WriteFile(FILE_PATH_LITERAL("foo.html"), + "<!DOCTYPE HTML>\n<html><body>Hello world!</body></html>"); + const Extension* extension = LoadExtension(test_dir.UnpackedPath()); + ASSERT_TRUE(extension); + extensions::util::SetIsIncognitoEnabled(extension->id(), browser()->profile(), + true); + + // Grab the 2 URLs that we will test with. + GURL page_url(embedded_test_server()->GetURL("/title1.html")); + GURL extension_url = extension->GetResourceURL("foo.html"); + std::string script = base::StringPrintf(R"( + var i = document.createElement("iframe"); + i.src = "%s"; + document.body.appendChild(i); + )", extension_url.spec().c_str()); + + // Navigate a subframe to an extension URL in the main profile. + ui_test_utils::NavigateToURL(browser(), page_url); + content::WebContents* user_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::TestNavigationObserver user_nav_observer(user_contents); + EXPECT_TRUE(content::ExecuteScript(user_contents, script)); + user_nav_observer.WaitForNavigationFinished(); + ASSERT_EQ(2u, user_contents->GetAllFrames().size()); + content::RenderFrameHost* user_frame = user_contents->GetAllFrames()[1]; + + // Navigate a subframe to an extension URL in the incognito profile. + Browser* browser_incognito = + OpenURLOffTheRecord(browser()->profile(), GURL("about:blank")); + ui_test_utils::NavigateToURL(browser_incognito, page_url); + content::WebContents* incognito_contents = + browser_incognito->tab_strip_model()->GetActiveWebContents(); + content::TestNavigationObserver incognito_nav_observer(incognito_contents); + EXPECT_TRUE(content::ExecuteScript(incognito_contents, script)); + incognito_nav_observer.WaitForNavigationFinished(); + ASSERT_EQ(2u, incognito_contents->GetAllFrames().size()); + content::RenderFrameHost* incognito_frame = + incognito_contents->GetAllFrames()[1]; + + // The main test verification is that nothing crashad / no renderer got killed + // (and that both tabs show the expected contents). + EXPECT_EQ(extension_url, incognito_frame->GetLastCommittedURL()); + EXPECT_EQ(extension_url, user_frame->GetLastCommittedURL()); + EXPECT_TRUE(user_frame->IsRenderFrameLive()); + EXPECT_TRUE(incognito_frame->IsRenderFrameLive()); + + // Verify that the incognito frame is in a separate process from the main + // profile frame. Other process relationships are not well defined until + // we resolve https://crbug.com/691145. + EXPECT_NE(incognito_frame->GetProcess()->GetID(), + user_frame->GetProcess()->GetID()); +} + +// Test that extension URLs can be opened in main profile and in incognito +// profile without hitting the tightened CanCommitURL checks in +// ChromeContentBrowserClientExtensionsPart. +IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, + ExtensionSpanningIncognitoProfile_MainFrame) { + // Create a test extension in incognito spanning mode (see also + // https://developer.chrome.com/extensions/manifest/incognito). + TestExtensionDir test_dir; + test_dir.WriteManifest(R"( { "manifest_version": 2, + "name": "spanning", + "incognito": "spanning", + "version": "0.1" + } )"); + test_dir.WriteFile(FILE_PATH_LITERAL("foo.html"), + "<!DOCTYPE HTML>\n<html><body>Hello world!</body></html>"); + const Extension* extension = LoadExtension(test_dir.UnpackedPath()); + ASSERT_TRUE(extension); + GURL extension_url = extension->GetResourceURL("foo.html"); + + // Navigate in the main profile to an extension URL. + ui_test_utils::NavigateToURL(browser(), extension_url); + content::WebContents* user_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::RenderFrameHost* user_frame = user_contents->GetMainFrame(); + + // Navigate in the incognito profile to an extension URL. + Browser* browser_incognito = + OpenURLOffTheRecord(browser()->profile(), GURL("about:blank")); + ui_test_utils::NavigateToURL(browser_incognito, extension_url); + content::WebContents* incognito_contents = + browser_incognito->tab_strip_model()->GetActiveWebContents(); + content::RenderFrameHost* incognito_frame = + incognito_contents->GetMainFrame(); + + // The main test verification is that nothing crashad / no renderer got killed + // (and that both tabs show the expected contents). + EXPECT_EQ(extension_url, incognito_frame->GetLastCommittedURL()); + EXPECT_EQ(extension_url, user_frame->GetLastCommittedURL()); + EXPECT_TRUE(user_frame->IsRenderFrameLive()); + EXPECT_TRUE(incognito_frame->IsRenderFrameLive()); + + // Verify that the incognito frame is in a separate process from the main + // profile frame. Other process relationships are not well defined until + // we resolve https://crbug.com/691145. + EXPECT_NE(incognito_frame->GetProcess()->GetID(), + user_frame->GetProcess()->GetID()); +} + // Test that basic extension loading creates the appropriate ExtensionHosts // and background pages. IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 6e465535..d9112d1f 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -523,12 +523,6 @@ const char kEnableWasmStreamingDescription[] = "WebAssembly.{compile|instantiate} taking a Response as parameter."; -const char kEnableWebNotificationCustomLayoutsName[] = - "Enable custom layouts for Web Notifications."; -const char kEnableWebNotificationCustomLayoutsDescription[] = - "Enable custom layouts for Web Notifications. They will have subtle layout " - "improvements that are otherwise not possible."; - const char kExpensiveBackgroundTimerThrottlingName[] = "Throttle expensive background timers"; const char kExpensiveBackgroundTimerThrottlingDescription[] = @@ -1666,6 +1660,7 @@ const char kChromeHomeSwipeLogicDescription[] = "Various swipe logic options for Chrome Home for sheet expansion."; const char kChromeHomeSwipeLogicRestrictArea[] = "Restrict swipable area"; +const char kChromeHomeSwipeLogicVelocity[] = "Velocity suppression model"; const char kChromeHomeBottomNavLabelsName[] = "Chrome Home bottom navigation menu item labels."; @@ -2737,6 +2732,10 @@ "Turns on experimental rendering features for Chrome VR, like power saving " "rendering modes."; +const char kVrLaunchIntentName[] = "Enable VR intents"; +const char kVrLaunchIntentDescription[] = + "Allow intents to launch Chrome in VR mode."; + const char kWebVrAutopresentName[] = "Enable WebVr auto presentation"; const char kWebVrAutopresentDescription[] = "Allows auto presentation of WebVr content from trusted first-party apps";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 43fa941..80a08f6 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -336,9 +336,6 @@ extern const char kEnableWasmStreamingName[]; extern const char kEnableWasmStreamingDescription[]; -extern const char kEnableWebNotificationCustomLayoutsName[]; -extern const char kEnableWebNotificationCustomLayoutsDescription[]; - extern const char kExpensiveBackgroundTimerThrottlingName[]; extern const char kExpensiveBackgroundTimerThrottlingDescription[]; @@ -1029,6 +1026,7 @@ extern const char kChromeHomeSwipeLogicName[]; extern const char kChromeHomeSwipeLogicDescription[]; extern const char kChromeHomeSwipeLogicRestrictArea[]; +extern const char kChromeHomeSwipeLogicVelocity[]; extern const char kChromeHomeName[]; extern const char kChromeHomeDescription[]; @@ -1684,6 +1682,9 @@ extern const char kVrShellExperimentalRenderingName[]; extern const char kVrShellExperimentalRenderingDescription[]; +extern const char kVrLaunchIntentName[]; +extern const char kVrLaunchIntentDescription[]; + extern const char kWebVrAutopresentName[]; extern const char kWebVrAutopresentDescription[];
diff --git a/chrome/browser/media/webrtc/webrtc_audio_quality_browsertest.cc b/chrome/browser/media/webrtc/webrtc_audio_quality_browsertest.cc index 81ba621..c4db725 100644 --- a/chrome/browser/media/webrtc/webrtc_audio_quality_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_audio_quality_browsertest.cc
@@ -411,8 +411,15 @@ "score", true); } - DeleteFileUnlessTestFailed(trimmed_reference, false); - DeleteFileUnlessTestFailed(trimmed_recording, false); + if (CanParseAsFloat(mos_lqo) && atof(mos_lqo.c_str()) < 3.0f) { + // If we keep the recordings, it's possible for the WebRTC bot recipes to + // upload them and make them available on the build. + printf("Suspiciously low MOS-LQO score: keeping recordings...\n"); + return; + } else { + DeleteFileUnlessTestFailed(trimmed_reference, false); + DeleteFileUnlessTestFailed(trimmed_recording, false); + } } bool CanParseAsFloat(const std::string& value) { @@ -464,7 +471,7 @@ if (anchor_pos == std::string::npos) { LOG(ERROR) << "PESQ was not able to compute a score; we probably recorded " - << "only silence. Please check the output/input volume levels."; + << "only silence."; return false; }
diff --git a/chrome/browser/metrics/antivirus_metrics_provider_win.cc b/chrome/browser/metrics/antivirus_metrics_provider_win.cc index 2e6f90d..4dab7abb 100644 --- a/chrome/browser/metrics/antivirus_metrics_provider_win.cc +++ b/chrome/browser/metrics/antivirus_metrics_provider_win.cc
@@ -27,9 +27,11 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" +#include "base/task_runner_util.h" #include "base/task_scheduler/post_task.h" #include "base/threading/thread_restrictions.h" #include "base/version.h" +#include "base/win/com_init_util.h" #include "base/win/scoped_bstr.h" #include "base/win/scoped_com_initializer.h" #include "base/win/scoped_variant.h" @@ -161,18 +163,26 @@ } void AntiVirusMetricsProvider::AsyncInit(const base::Closure& done_callback) { - base::PostTaskWithTraitsAndReplyWithResult( + // __uuidof(WSCProductList) expects to be run in an STA and CLSID_WbemLocator + // is fine with an STA or MTA. The COM STA task runner accomodates both of + // these requirements. + base::PostTaskAndReplyWithResult( + base::CreateCOMSTATaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}) + .get(), FROM_HERE, - {base::MayBlock(), base::TaskPriority::BACKGROUND, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::Bind(&AntiVirusMetricsProvider::GetAntiVirusProductsOnFileThread), - base::Bind(&AntiVirusMetricsProvider::GotAntiVirusProducts, - weak_ptr_factory_.GetWeakPtr(), done_callback)); + base::BindOnce( + &AntiVirusMetricsProvider::GetAntiVirusProductsOnCOMSTAThread), + base::BindOnce(&AntiVirusMetricsProvider::GotAntiVirusProducts, + weak_ptr_factory_.GetWeakPtr(), done_callback)); } // static std::vector<AntiVirusMetricsProvider::AvProduct> -AntiVirusMetricsProvider::GetAntiVirusProductsOnFileThread() { +AntiVirusMetricsProvider::GetAntiVirusProductsOnCOMSTAThread() { + base::win::AssertComApartmentType(base::win::ComApartmentType::STA); + std::vector<AvProduct> av_products; ResultCode result = RESULT_GENERIC_FAILURE; @@ -232,10 +242,6 @@ std::vector<AvProduct>* products) { std::vector<AvProduct> result_list; base::AssertBlockingAllowed(); - base::win::ScopedCOMInitializer com_initializer; - - if (!com_initializer.Succeeded()) - return RESULT_FAILED_TO_INITIALIZE_COM; Microsoft::WRL::ComPtr<IWSCProductList> product_list; HRESULT result = @@ -333,10 +339,6 @@ std::vector<AvProduct>* products) { std::vector<AvProduct> result_list; base::AssertBlockingAllowed(); - base::win::ScopedCOMInitializer com_initializer; - - if (!com_initializer.Succeeded()) - return RESULT_FAILED_TO_INITIALIZE_COM; Microsoft::WRL::ComPtr<IWbemLocator> wmi_locator; HRESULT hr =
diff --git a/chrome/browser/metrics/antivirus_metrics_provider_win.h b/chrome/browser/metrics/antivirus_metrics_provider_win.h index 547e878..5395716 100644 --- a/chrome/browser/metrics/antivirus_metrics_provider_win.h +++ b/chrome/browser/metrics/antivirus_metrics_provider_win.h
@@ -77,7 +77,7 @@ static void MaybeAddUnregisteredAntiVirusProducts( std::vector<AvProduct>* products); - static std::vector<AvProduct> GetAntiVirusProductsOnFileThread(); + static std::vector<AvProduct> GetAntiVirusProductsOnCOMSTAThread(); // Removes anything extraneous from the end of the product name such as // versions, years, or anything containing numbers to make it more constant.
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc index edf9308..78880e15 100644 --- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc +++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -25,6 +25,8 @@ #include "chrome/browser/shell_integration.h" #include "components/flags_ui/pref_service_flags_storage.h" #include "content/public/common/content_switches.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" #include "ui/base/touch/touch_device.h" #include "ui/base/ui_base_switches.h" #include "ui/display/screen.h" @@ -463,9 +465,10 @@ // Records the pinned state of the current executable into a histogram. Should // be called on a background thread, with low priority, to avoid slowing down // startup. -void RecordIsPinnedToTaskbarHistogram() { +void RecordIsPinnedToTaskbarHistogram( + std::unique_ptr<service_manager::Connector> connector) { shell_integration::win::GetIsPinnedToTaskbarState( - base::Bind(&OnShellHandlerConnectionError), + std::move(connector), base::Bind(&OnShellHandlerConnectionError), base::Bind(&OnIsPinnedToTaskbarResult)); } #endif // defined(OS_WIN) @@ -548,10 +551,14 @@ // TODO(isherman): The delay below is currently needed to avoid (flakily) // breaking some tests, including all of the ProcessMemoryMetricsEmitterTest // tests. Figure out why there is a dependency and fix the tests. + service_manager::Connector* connector = + content::ServiceManagerConnection::GetForProcess()->GetConnector(); + base::CreateSequencedTaskRunnerWithTraits(background_task_traits) - ->PostDelayedTask(FROM_HERE, - base::BindOnce(&RecordIsPinnedToTaskbarHistogram), - base::TimeDelta::FromSeconds(45)); + ->PostDelayedTask( + FROM_HERE, + base::BindOnce(&RecordIsPinnedToTaskbarHistogram, connector->Clone()), + base::TimeDelta::FromSeconds(45)); #endif // defined(OS_WIN) display_count_ = display::Screen::GetScreen()->GetNumDisplays();
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc index 5508b99..d286ec7 100644 --- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc +++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
@@ -9,7 +9,8 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/test/histogram_tester.h" -#include "base/test/scoped_task_environment.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_service_manager_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/screen.h" #include "ui/display/test/test_screen.h" @@ -34,7 +35,8 @@ private: // Provides a message loop and allows the use of the task scheduler - base::test::ScopedTaskEnvironment scoped_task_environment_; + content::TestBrowserThreadBundle thread_bundle_; + content::TestServiceManagerContext service_manager_context_; // Dummy screen required by a ChromeBrowserMainExtraPartsMetrics test target. display::test::TestScreen test_screen_; @@ -42,8 +44,8 @@ DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsMetricsTest); }; -ChromeBrowserMainExtraPartsMetricsTest::ChromeBrowserMainExtraPartsMetricsTest() - : device_data_manager_test_api_() { +ChromeBrowserMainExtraPartsMetricsTest:: + ChromeBrowserMainExtraPartsMetricsTest() { display::Screen::SetScreenInstance(&test_screen_); }
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index 17b13f10..fce991e 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc
@@ -466,11 +466,13 @@ crash_on_hang_thread_names = command_line.GetSwitchValueASCII(switches::kCrashOnHangThreads); } else if (channel != version_info::Channel::STABLE) { - // Default to crashing the browser if UI or IO threads are not responsive - // except in stable channel. - crash_on_hang_thread_names = - base::StringPrintf("UI:%d:%d,IO:%d:%d", kLiveThreadsThreshold, - crash_seconds, kLiveThreadsThreshold, crash_seconds); + // Default to crashing the browser if UI or IO or FILE threads are not + // responsive except in stable channel. + crash_on_hang_thread_names = base::StringPrintf( + "UI:%d:%d,IO:%d:%d,FILE:%d:%d", + kLiveThreadsThreshold, crash_seconds, + kLiveThreadsThreshold, crash_seconds, + kLiveThreadsThreshold, crash_seconds * 5); } ParseCommandLineCrashOnHangThreads(crash_on_hang_thread_names, @@ -550,6 +552,12 @@ unresponsive_threshold, crash_on_hang_threads); StartWatching(BrowserThread::IO, "IO", kSleepTime, kUnresponsiveTime, unresponsive_threshold, crash_on_hang_threads); + StartWatching(BrowserThread::DB, "DB", kSleepTime, kUnresponsiveTime, + unresponsive_threshold, crash_on_hang_threads); + StartWatching(BrowserThread::FILE, "FILE", kSleepTime, kUnresponsiveTime, + unresponsive_threshold, crash_on_hang_threads); + StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, kUnresponsiveTime, + unresponsive_threshold, crash_on_hang_threads); } // static
diff --git a/chrome/browser/metrics/thread_watcher_report_hang.cc b/chrome/browser/metrics/thread_watcher_report_hang.cc index 7bae67a..93fd6c6 100644 --- a/chrome/browser/metrics/thread_watcher_report_hang.cc +++ b/chrome/browser/metrics/thread_watcher_report_hang.cc
@@ -50,12 +50,36 @@ ReportThreadHang(); } +NOINLINE void ThreadUnresponsive_DB() { + volatile int inhibit_comdat = __LINE__; + ALLOW_UNUSED_LOCAL(inhibit_comdat); + ReportThreadHang(); +} + +NOINLINE void ThreadUnresponsive_FILE() { + volatile int inhibit_comdat = __LINE__; + ALLOW_UNUSED_LOCAL(inhibit_comdat); + ReportThreadHang(); +} + +NOINLINE void ThreadUnresponsive_FILE_USER_BLOCKING() { + volatile int inhibit_comdat = __LINE__; + ALLOW_UNUSED_LOCAL(inhibit_comdat); + ReportThreadHang(); +} + NOINLINE void ThreadUnresponsive_PROCESS_LAUNCHER() { volatile int inhibit_comdat = __LINE__; ALLOW_UNUSED_LOCAL(inhibit_comdat); ReportThreadHang(); } +NOINLINE void ThreadUnresponsive_CACHE() { + volatile int inhibit_comdat = __LINE__; + ALLOW_UNUSED_LOCAL(inhibit_comdat); + ReportThreadHang(); +} + NOINLINE void ThreadUnresponsive_IO() { volatile int inhibit_comdat = __LINE__; ALLOW_UNUSED_LOCAL(inhibit_comdat); @@ -67,16 +91,19 @@ switch (thread_id) { case content::BrowserThread::UI: return ThreadUnresponsive_UI(); + case content::BrowserThread::DB: + return ThreadUnresponsive_DB(); + case content::BrowserThread::FILE: + return ThreadUnresponsive_FILE(); + case content::BrowserThread::FILE_USER_BLOCKING: + return ThreadUnresponsive_FILE_USER_BLOCKING(); case content::BrowserThread::PROCESS_LAUNCHER: return ThreadUnresponsive_PROCESS_LAUNCHER(); + case content::BrowserThread::CACHE: + return ThreadUnresponsive_CACHE(); case content::BrowserThread::IO: return ThreadUnresponsive_IO(); case content::BrowserThread::ID_COUNT: - // TODO(gab): Get rid of deprecated BrowserThread IDs. - case content::BrowserThread::DB: - case content::BrowserThread::FILE: - case content::BrowserThread::FILE_USER_BLOCKING: - case content::BrowserThread::CACHE: NOTREACHED(); break; }
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index b71e2731..590efe8 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -91,7 +91,7 @@ SystemNetworkContextManager::GetURLLoaderFactory() { if (!url_loader_factory_) { GetContext()->CreateURLLoaderFactory( - mojo::MakeRequest(&url_loader_factory_), base::GetUniqueIdForProcess()); + mojo::MakeRequest(&url_loader_factory_), 0); } return url_loader_factory_.get(); }
diff --git a/chrome/browser/notifications/notification_common.cc b/chrome/browser/notifications/notification_common.cc index 15a4c8b9..529d4bb 100644 --- a/chrome/browser/notifications/notification_common.cc +++ b/chrome/browser/notifications/notification_common.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/notifications/notification_common.h" -#include "base/metrics/histogram_macros.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -17,13 +16,6 @@ #include "content/public/browser/browser_context.h" #include "ui/message_center/notifier_settings.h" -namespace features { - -const base::Feature kAllowFullscreenWebNotificationsFeature{ - "FSNotificationsWeb", base::FEATURE_ENABLED_BY_DEFAULT}; - -} // namespace features - NotificationCommon::Metadata::~Metadata() = default; PersistentNotificationMetadata::PersistentNotificationMetadata() { @@ -87,19 +79,9 @@ if (active_contents->GetURL().GetOrigin() == origin && browser->exclusive_access_manager()->context()->IsFullscreen() && browser->window()->IsActive()) { - bool enabled = base::FeatureList::IsEnabled( - features::kAllowFullscreenWebNotificationsFeature); - if (enabled) { - UMA_HISTOGRAM_ENUMERATION("Notifications.Display_Fullscreen.Shown", - message_center::NotifierId::WEB_PAGE, - message_center::NotifierId::SIZE); - } else { - UMA_HISTOGRAM_ENUMERATION("Notifications.Display_Fullscreen.Suppressed", - message_center::NotifierId::WEB_PAGE, - message_center::NotifierId::SIZE); - } - return enabled; + return true; } } + return false; }
diff --git a/chrome/browser/notifications/notification_common.h b/chrome/browser/notifications/notification_common.h index ec4dc5d..01b2ae9 100644 --- a/chrome/browser/notifications/notification_common.h +++ b/chrome/browser/notifications/notification_common.h
@@ -8,13 +8,6 @@ #include "base/feature_list.h" #include "url/gurl.h" -namespace features { - -// TODO(miguelg) We can probably get rid of this altogether. -extern const base::Feature kAllowFullscreenWebNotificationsFeature; - -} // namespace features - namespace content { class BrowserContext; } // namespace content
diff --git a/chrome/browser/notifications/notification_interactive_uitest.cc b/chrome/browser/notifications/notification_interactive_uitest.cc index d5ccaee..5774a61 100644 --- a/chrome/browser/notifications/notification_interactive_uitest.cc +++ b/chrome/browser/notifications/notification_interactive_uitest.cc
@@ -575,8 +575,6 @@ } IN_PROC_BROWSER_TEST_F(NotificationsTest, TestShouldDisplayNormal) { - base::test::ScopedFeatureList scoped_feature_list; - EnableFullscreenNotifications(&scoped_feature_list); ASSERT_TRUE(embedded_test_server()->Start()); // Creates a simple notification. @@ -600,8 +598,6 @@ #if defined(OS_MACOSX) ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen; #endif - base::test::ScopedFeatureList scoped_feature_list; - EnableFullscreenNotifications(&scoped_feature_list); ASSERT_TRUE(embedded_test_server()->Start()); // Creates a simple notification. @@ -634,51 +630,10 @@ (*notifications.rbegin())->delegate()->ShouldDisplayOverFullscreen()); } -IN_PROC_BROWSER_TEST_F(NotificationsTest, TestShouldDisplayFullscreenOff) { -#if defined(OS_MACOSX) - ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen; -#endif - base::test::ScopedFeatureList scoped_feature_list; - DisableFullscreenNotifications(&scoped_feature_list); - ASSERT_TRUE(embedded_test_server()->Start()); - - // Creates a simple notification. - AllowAllOrigins(); - ui_test_utils::NavigateToURL(browser(), GetTestPageURL()); - - std::string result = CreateSimpleNotification(browser(), true); - EXPECT_NE("-1", result); - - // Set the page fullscreen - browser()->exclusive_access_manager()->fullscreen_controller()-> - ToggleBrowserFullscreenMode(); - - { - FullscreenStateWaiter fs_state(browser(), true); - fs_state.Wait(); - } - - ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( - browser()->window()->GetNativeWindow())); - - ASSERT_TRUE(browser()->window()->IsActive()); - - ASSERT_EQ(1, GetNotificationCount()); - message_center::NotificationList::Notifications notifications = - message_center::MessageCenter::Get()->GetVisibleNotifications(); - - // When the experiment flag is off, then ShouldDisplayOverFullscreen should - // return false. - EXPECT_FALSE( - (*notifications.rbegin())->delegate()->ShouldDisplayOverFullscreen()); -} - // The Fake OSX fullscreen window doesn't like drawing a second fullscreen // window when another is visible. #if !defined(OS_MACOSX) IN_PROC_BROWSER_TEST_F(NotificationsTest, TestShouldDisplayMultiFullscreen) { - base::test::ScopedFeatureList scoped_feature_list; - EnableFullscreenNotifications(&scoped_feature_list); ASSERT_TRUE(embedded_test_server()->Start()); AllowAllOrigins(); @@ -729,8 +684,6 @@ #if defined(OS_MACOSX) ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen; #endif - base::test::ScopedFeatureList scoped_feature_list; - EnableFullscreenNotifications(&scoped_feature_list); ASSERT_TRUE(embedded_test_server()->Start()); // Creates a simple notification.
diff --git a/chrome/browser/notifications/notification_interactive_uitest_support.cc b/chrome/browser/notifications/notification_interactive_uitest_support.cc index 9b50e1ab..97f44bb 100644 --- a/chrome/browser/notifications/notification_interactive_uitest_support.cc +++ b/chrome/browser/notifications/notification_interactive_uitest_support.cc
@@ -318,30 +318,6 @@ #endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) } -void NotificationsTest::EnableFullscreenNotifications( - base::test::ScopedFeatureList* scoped_feature_list) { -#if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) - scoped_feature_list->InitWithFeatures( - {features::kAllowFullscreenWebNotificationsFeature}, - {features::kNativeNotifications}); -#else - scoped_feature_list->InitAndEnableFeature( - features::kAllowFullscreenWebNotificationsFeature); -#endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) -} - -void NotificationsTest::DisableFullscreenNotifications( - base::test::ScopedFeatureList* scoped_feature_list) { -#if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) - scoped_feature_list->InitWithFeatures( - {}, {features::kAllowFullscreenWebNotificationsFeature, - features::kNativeNotifications}); -#else - scoped_feature_list->InitAndDisableFeature( - features::kAllowFullscreenWebNotificationsFeature); -#endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) -} - void NotificationsTest::DropOriginPreference(const GURL& origin) { DesktopNotificationProfileUtil::ClearSetting(browser()->profile(), origin); }
diff --git a/chrome/browser/notifications/notification_interactive_uitest_support.h b/chrome/browser/notifications/notification_interactive_uitest_support.h index b169bde..0fadada 100644 --- a/chrome/browser/notifications/notification_interactive_uitest_support.h +++ b/chrome/browser/notifications/notification_interactive_uitest_support.h
@@ -72,10 +72,6 @@ protected: void EnablePermissionsEmbargo( base::test::ScopedFeatureList* scoped_feature_list); - void EnableFullscreenNotifications( - base::test::ScopedFeatureList* scoped_feature_list); - void DisableFullscreenNotifications( - base::test::ScopedFeatureList* scoped_feature_list); private: std::string RequestAndRespondToPermission(
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index 5ccc799..ab83f56 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -141,16 +141,6 @@ RequestAndRespondToPermission(PermissionRequestManager::DENY_ALL); } - void EnableFullscreenNotifications() { - feature_list_.InitAndEnableFeature( - features::kAllowFullscreenWebNotificationsFeature); - } - - void DisableFullscreenNotifications() { - feature_list_.InitAndDisableFeature( - features::kAllowFullscreenWebNotificationsFeature); - } - double GetEngagementScore(const GURL& origin) const { return SiteEngagementService::Get(browser()->profile())->GetScore(origin); } @@ -198,7 +188,6 @@ private: std::unique_ptr<net::EmbeddedTestServer> https_server_; - base::test::ScopedFeatureList feature_list_; }; PlatformNotificationServiceBrowserTest::PlatformNotificationServiceBrowserTest() @@ -702,7 +691,6 @@ IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest, TestShouldDisplayFullscreen) { ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest()); - EnableFullscreenNotifications(); std::string script_result; ASSERT_TRUE(RunScript( @@ -732,43 +720,8 @@ } IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest, - TestShouldDisplayFullscreenOff) { - ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest()); - DisableFullscreenNotifications(); - - std::string script_result; - ASSERT_TRUE(RunScript( - "DisplayPersistentNotification('display_normal')", &script_result)); - EXPECT_EQ("ok", script_result); - - // Set the page fullscreen - browser()->exclusive_access_manager()->fullscreen_controller()-> - ToggleBrowserFullscreenMode(); - - { - FullscreenStateWaiter fs_state(browser(), true); - fs_state.Wait(); - } - - ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( - browser()->window()->GetNativeWindow())); - - ASSERT_TRUE(browser()->window()->IsActive()) - << "Browser is active after going fullscreen"; - - std::vector<message_center::Notification> notifications = - GetDisplayedNotifications(true /* is_persistent */); - ASSERT_EQ(1u, notifications.size()); - - // When the experiment flag is off, then ShouldDisplayOverFullscreen should - // return false. - EXPECT_FALSE(notifications[0].delegate()->ShouldDisplayOverFullscreen()); -} - -IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest, TestShouldDisplayMultiFullscreen) { ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest()); - EnableFullscreenNotifications(); Browser* other_browser = CreateBrowser(browser()->profile()); ui_test_utils::NavigateToURL(other_browser, GURL("about:blank"));
diff --git a/chrome/browser/plugins/plugin_finder.cc b/chrome/browser/plugins/plugin_finder.cc index 55af7c81..474179b 100644 --- a/chrome/browser/plugins/plugin_finder.cc +++ b/chrome/browser/plugins/plugin_finder.cc
@@ -11,6 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/string16.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -22,13 +23,11 @@ #include "chrome/grit/browser_resources.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/plugin_service.h" +#include "content/public/common/webplugininfo.h" #include "ui/base/resource/resource_bundle.h" #include "url/gurl.h" using base::DictionaryValue; -using content::PluginService; namespace { @@ -154,17 +153,16 @@ // static PluginFinder* PluginFinder::GetInstance() { - // PluginFinder::GetInstance() is the only method that's allowed to call - // base::Singleton<PluginFinder>::get(). - return base::Singleton<PluginFinder>::get(); + static PluginFinder* instance = new PluginFinder(); + return instance; } PluginFinder::PluginFinder() : version_(-1) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } void PluginFinder::Init() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Load the built-in plugin list first. If we have a newer version stored // locally or download one, we will replace this one with it. std::unique_ptr<base::DictionaryValue> plugin_list(LoadBuiltInPluginList()); @@ -179,7 +177,7 @@ } // static -base::DictionaryValue* PluginFinder::LoadBuiltInPluginList() { +std::unique_ptr<base::DictionaryValue> PluginFinder::LoadBuiltInPluginList() { base::StringPiece json_resource( ui::ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_PLUGIN_DB_JSON)); @@ -234,36 +232,12 @@ DCHECK_EQ(base::JSONReader::JSON_NO_ERROR, error_code); RecordBuiltInPluginListError(PluginListError::PLUGIN_LIST_NO_ERROR); - return static_cast<base::DictionaryValue*>(value.release()); + return base::DictionaryValue::From(std::move(value)); } PluginFinder::~PluginFinder() { } -bool PluginFinder::FindPlugin( - const std::string& mime_type, - const std::string& language, - PluginInstaller** installer, - std::unique_ptr<PluginMetadata>* plugin_metadata) { - if (g_browser_process->local_state()->GetBoolean(prefs::kDisablePluginFinder)) - return false; - - base::AutoLock lock(mutex_); - auto metadata_it = identifier_plugin_.begin(); - for (; metadata_it != identifier_plugin_.end(); ++metadata_it) { - if (language == metadata_it->second->language() && - metadata_it->second->HasMimeType(mime_type)) { - *plugin_metadata = metadata_it->second->Clone(); - - auto installer_it = installers_.find(metadata_it->second->identifier()); - DCHECK(installer_it != installers_.end()); - *installer = installer_it->second.get(); - return true; - } - } - return false; -} - bool PluginFinder::FindPluginWithIdentifier( const std::string& identifier, PluginInstaller** installer, @@ -293,10 +267,11 @@ return; version_ = version; + identifier_plugin_.clear(); for (base::DictionaryValue::Iterator plugin_it(*plugin_list); !plugin_it.IsAtEnd(); plugin_it.Advance()) { - const base::DictionaryValue* plugin = NULL; + const base::DictionaryValue* plugin = nullptr; const std::string& identifier = plugin_it.key(); if (plugin_list->GetDictionaryWithoutPathExpansion(identifier, &plugin)) { DCHECK(identifier_plugin_.find(identifier) == identifier_plugin_.end());
diff --git a/chrome/browser/plugins/plugin_finder.h b/chrome/browser/plugins/plugin_finder.h index 217e06c..b4636df 100644 --- a/chrome/browser/plugins/plugin_finder.h +++ b/chrome/browser/plugins/plugin_finder.h
@@ -12,16 +12,17 @@ #include "base/callback.h" #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/singleton.h" -#include "base/strings/string16.h" +#include "base/sequence_checker.h" #include "base/synchronization/lock.h" -#include "chrome/common/features.h" -#include "content/public/common/webplugininfo.h" namespace base { class DictionaryValue; } +namespace content { +struct WebPluginInfo; +} + class PluginInstaller; class PluginMetadata; class PrefRegistrySimple; @@ -40,15 +41,6 @@ void ReinitializePlugins(const base::DictionaryValue* json_metadata); - // Finds a plugin for the given MIME type and language (specified as an IETF - // language tag, i.e. en-US). If found, sets |installer| to the - // corresponding PluginInstaller and |plugin_metadata| to a copy of the - // corresponding PluginMetadata. - bool FindPlugin(const std::string& mime_type, - const std::string& language, - PluginInstaller** installer, - std::unique_ptr<PluginMetadata>* plugin_metadata); - // Finds the plugin with the given identifier. If found, sets |installer| // to the corresponding PluginInstaller and |plugin_metadata| to a copy // of the corresponding PluginMetadata. |installer| may be null. @@ -62,16 +54,17 @@ const content::WebPluginInfo& plugin); private: - friend struct base::DefaultSingletonTraits<PluginFinder>; FRIEND_TEST_ALL_PREFIXES(PluginFinderTest, JsonSyntax); - FRIEND_TEST_ALL_PREFIXES(PluginFinderTest, PluginGroups); + FRIEND_TEST_ALL_PREFIXES(PluginFinderTest, ReinitializePlugins); PluginFinder(); ~PluginFinder(); // Loads the plugin information from the browser resources and parses it. // Returns null if the plugin list couldn't be parsed. - static base::DictionaryValue* LoadBuiltInPluginList(); + static std::unique_ptr<base::DictionaryValue> LoadBuiltInPluginList(); + + SEQUENCE_CHECKER(sequence_checker_); std::map<std::string, std::unique_ptr<PluginInstaller>> installers_;
diff --git a/chrome/browser/plugins/plugin_finder_unittest.cc b/chrome/browser/plugins/plugin_finder_unittest.cc index 6030171..fc3a4db 100644 --- a/chrome/browser/plugins/plugin_finder_unittest.cc +++ b/chrome/browser/plugins/plugin_finder_unittest.cc
@@ -12,9 +12,9 @@ using base::ListValue; TEST(PluginFinderTest, JsonSyntax) { - std::unique_ptr<base::DictionaryValue> plugin_list( - PluginFinder::LoadBuiltInPluginList()); - ASSERT_TRUE(plugin_list.get()); + std::unique_ptr<base::DictionaryValue> plugin_list = + PluginFinder::LoadBuiltInPluginList(); + ASSERT_TRUE(plugin_list); std::unique_ptr<base::Value> version; ASSERT_TRUE(plugin_list->Remove("x-version", &version)); EXPECT_EQ(base::Value::Type::INTEGER, version->type()); @@ -73,3 +73,21 @@ } } } + +TEST(PluginFinderTest, ReinitializePlugins) { + PluginFinder* plugin_finder = PluginFinder::GetInstance(); + + plugin_finder->Init(); + + std::unique_ptr<base::DictionaryValue> plugin_list = + PluginFinder::LoadBuiltInPluginList(); + + // Increment the version number by one. + const base::Value* version_value = plugin_list->FindKey("x-version"); + ASSERT_TRUE(version_value); + int version = 0; + ASSERT_TRUE(version_value->GetAsInteger(&version)); + plugin_list->SetKey("x-version", base::Value(version + 1)); + + plugin_finder->ReinitializePlugins(plugin_list.get()); +}
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 5cef4434..0b70b5da 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -488,7 +488,7 @@ ~FakeDevToolsClient() override {} void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override {} - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {} + void AgentHostClosed(DevToolsAgentHost* agent_host) override {} }; // A ContentBrowserClient that cancels all prerenderers on OpenURL.
diff --git a/chrome/browser/profiling_host/profiling_process_host.h b/chrome/browser/profiling_host/profiling_process_host.h index ecbd5c0..9790694 100644 --- a/chrome/browser/profiling_host/profiling_process_host.h +++ b/chrome/browser/profiling_host/profiling_process_host.h
@@ -92,7 +92,7 @@ void RequestProcessReport(base::ProcessId pid, std::string trigger_name); // For testing. Only one can be set at a time. Will be called after the - // profiling proecss dumps heaps into the trace log. No guarantees are made + // profiling process dumps heaps into the trace log. No guarantees are made // about the task queue on which the callback will be Run. void SetDumpProcessForTracingCallback(base::OnceClosure callback);
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index a6f3b08..fdcc508 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -962,15 +962,14 @@ if (g_browser_process->IsShuttingDown()) return; + // TODO(crbug.com/762775): Pause or resume background tab opening based on + // memory pressure signal after it becomes more reliable. switch (memory_pressure_level) { case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: - ResumeBackgroundTabOpeningIfNeeded(); break; case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: - PauseBackgroundTabOpeningIfNeeded(); break; case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: - PauseBackgroundTabOpeningIfNeeded(); LogMemoryAndDiscardTab(kUrgentShutdown); break; default:
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc index 1551fb998..d2364c698 100644 --- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -942,10 +942,8 @@ EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); - // Simulate memory pressure getting high. TabManager pause loading pending - // background tabs. - tab_manager->OnMemoryPressure( - base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE); + // TabManager pauses loading pending background tabs. + tab_manager->PauseBackgroundTabOpeningIfNeeded(); EXPECT_EQ(TabManager::BackgroundTabLoadingMode::kPaused, tab_manager->background_tab_loading_mode_); @@ -968,10 +966,8 @@ EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); - // Simulate memory pressure is relieved. TabManager will reset the loading - // mode and try to load the next tab. - tab_manager->OnMemoryPressure( - base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); + // TabManager resumes loading pending background tabs. + tab_manager->ResumeBackgroundTabOpeningIfNeeded(); EXPECT_EQ(TabManager::BackgroundTabLoadingMode::kStaggered, tab_manager->background_tab_loading_mode_); @@ -1059,10 +1055,8 @@ EXPECT_TRUE( tab_manager->stats_collector()->is_in_background_tab_opening_session()); - // Simulate memory pressure getting high. TabManager pause loading pending - // background tabs, and ends the background tab opening session. - tab_manager->OnMemoryPressure( - base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE); + // TabManager pauses loading pending background tabs. + tab_manager->PauseBackgroundTabOpeningIfNeeded(); EXPECT_EQ(TabManager::BackgroundTabLoadingMode::kPaused, tab_manager->background_tab_loading_mode_); EXPECT_FALSE(tab_manager->IsInBackgroundTabOpeningSession()); @@ -1082,11 +1076,8 @@ EXPECT_FALSE( tab_manager->stats_collector()->is_in_background_tab_opening_session()); - // Simulate memory pressure is relieved. TabManager will reset the loading - // mode and try to load the next tab. If there is pending tab, TabManager - // starts a new BackgroundTabOpening session. - tab_manager->OnMemoryPressure( - base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); + // TabManager resumes loading pending background tabs. + tab_manager->ResumeBackgroundTabOpeningIfNeeded(); EXPECT_EQ(TabManager::BackgroundTabLoadingMode::kStaggered, tab_manager->background_tab_loading_mode_); EXPECT_TRUE(tab_manager->IsInBackgroundTabOpeningSession());
diff --git a/chrome/browser/resources/chromeos/sim_unlock.css b/chrome/browser/resources/chromeos/sim_unlock.css deleted file mode 100644 index 99c9036..0000000 --- a/chrome/browser/resources/chromeos/sim_unlock.css +++ /dev/null
@@ -1,99 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -.error { - color: red; -} - -#pin-error-msg { - height: 25px; - margin: 5px auto 5px auto; -} - -.content-area { - max-height: 125px; - overflow: auto; -} - -.change-pin-content-area { - height: 156px; - overflow: auto; - padding: 10px 15px 5px 15px; - width: 320px; -} - -.choose-pin-content-area { - max-height: 125px; - min-height: 120px; - overflow: auto; - padding: 10px 15px 5px 15px; - width: 320px; -} - -.input-area { - margin: 10px auto 25px auto; - width: 125px; -} - -#pin-input-area { - margin-top: 30px; -} - -#puk-input-area { - margin-bottom: 0; -} - -#puk-content-area { - max-height: 163px; -} - -.code-input { - border: 1px solid #aaa; - border-radius: 2px; - font-size: inherit; - padding: 3px; -} - -#locked-puk-action-area { - -webkit-box-pack: center; -} - -#disabled-sim-action-area { - -webkit-box-pack: center; -} - -#puk-warning-msg { - padding-bottom: 6px; -} - -#puk-enter-msg { - padding-top: 6px; -} - -#choose-pin-msg { - padding-bottom: 6px; -} - -#choose-pin-error { - padding-top: 6px; -} - -.label { - margin: 5px 5px 5px 0; - padding: 5px 5px 5px 0; - width: 150px; -} - -.input-with-label { - display: -webkit-box; -} - -.choose-pin-input-area { - margin: 5px 5px 5px 5px; - width: 125px; -} - -#choose-pin-action-area { - padding: 6px; -}
diff --git a/chrome/browser/resources/chromeos/sim_unlock.html b/chrome/browser/resources/chromeos/sim_unlock.html deleted file mode 100644 index c6c2d36..0000000 --- a/chrome/browser/resources/chromeos/sim_unlock.html +++ /dev/null
@@ -1,143 +0,0 @@ -<!doctype html> -<html i18n-values="dir:textdirection;lang:language"> -<head> -<meta charset="utf-8"> -<title i18n-content="title"></title> -<link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> -<link rel="stylesheet" href="chrome://resources/css/widgets.css"> -<link rel="stylesheet" href="mobile_dialogs.css"> -<link rel="stylesheet" href="sim_unlock.css"> -<script src="chrome://resources/js/cr.js"></script> -<script src="chrome://resources/js/cr/event_target.js"></script> -<script src="chrome://resources/js/util.js"></script> -<script src="sim_unlock.js"></script> -<script> -var SimUnlock = mobile.SimUnlock; - -function load() { - SimUnlock.initialize(); -} - -document.addEventListener('DOMContentLoaded', load); -</script> -</head> -<body> - <div id="container" class="container"> - <div id="locked-pin-overlay" class="dialog" hidden> - <h1 i18n-content="enterPinTitle"></h1> - <div id="pin-content-area" class="content-area"> - <div id="pin-error-msg"></div> - <div id="pin-input-area" class="input-area"> - <input id="pin-input" class="code-input" type="password" - maxlength="8" size="14"> - </div> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="enter-pin-confirm" i18n-content="ok"></button> - <button id="enter-pin-dismiss" i18n-content="cancel"></button> - </div> - </div> - </div> - </div> - <div id="locked-pin-no-tries-overlay" class="dialog" hidden> - <h1 i18n-content="incorrectPinTitle"></h1> - <div id="pin-no-tries-content-area" class="content-area"> - <!-- TODO(nkostylev): Add warning icon. --> - <div id="pin-no-tries-error-msg" i18n-content="noPinTriesLeft"></div> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="pin-no-tries-proceed" i18n-content="enterPukButton"> - </button> - <button id="pin-no-tries-dismiss" i18n-content="cancel"></button> - </div> - </div> - </div> - </div> - <div id="locked-puk-overlay" class="dialog" hidden> - <h1 i18n-content="enterPukTitle"></h1> - <div id="puk-content-area" class="content-area"> - <div id="puk-warning-msg" i18n-content="enterPukWarning" class="error"> - </div> - <div id="puk-enter-msg" i18n-content="enterPukMessage"></div> - <div id="puk-input-area" class="input-area"> - <input id="puk-input" class="code-input" type="password" - maxlength="8" size="14"> - </div> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="enter-puk-confirm" i18n-content="ok"></button> - <button id="enter-puk-dismiss" i18n-content="cancel"></button> - </div> - </div> - </div> - </div> - <div id="choose-pin-overlay" class="dialog" hidden> - <h1 id="choose-pin-title" i18n-content="choosePinTitle"></h1> - <div id="choose-pin-content-area" class="choose-pin-content-area"> - <div id="choose-pin-msg" i18n-content="choosePinMessage"></div> - <div class="input-with-label"> - <div id="old-pin-label" i18n-content="oldPin" class="label" hidden> - </div> - <div id="old-pin-input-area" class="choose-pin-input-area" hidden> - <input id="old-pin-input" class="code-input" type="password" - maxlength="8" size="14"> - </div> - </div> - <div class="input-with-label"> - <div id="new-pin-label" i18n-content="newPin" class="label"></div> - <div id="new-pin-input-area" class="choose-pin-input-area"> - <input id="new-pin-input" class="code-input" type="password" - maxlength="8" size="14"> - </div> - </div> - <div class="input-with-label"> - <div id="retype-new-pin-label" i18n-content="retypeNewPin" - class="label"></div> - <div id="retype-new-pin-input-area" class="choose-pin-input-area"> - <input id="retype-new-pin-input" class="code-input" type="password" - maxlength="8" size="14"> - </div> - </div> - <div id="choose-pin-error" class="error" - i18n-content="pinsDontMatchMessage" hidden></div> - </div> - <div id="choose-pin-action-area" class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="choose-pin-confirm" i18n-content="ok"></button> - <button id="choose-pin-dismiss" i18n-content="cancel"></button> - </div> - </div> - </div> - </div> - <div id="locked-puk-no-tries-overlay" class="dialog" hidden> - <h1 i18n-content="enterPukTitle"></h1> - <div id="puk-no-tries-content-area" class="content-area"> - <div id="puk-no-tries-msg" i18n-content="noPukTriesLeft"></div> - </div> - <div id="locked-puk-action-area" class="action-area"> - <div class="button-strip"> - <button id="puk-no-tries-confirm" i18n-content="ok"></button> - </div> - </div> - </div> - <div id="sim-disabled-overlay" class="dialog" hidden> - <h1 i18n-content="simDisabledTitle"></h1> - <div id="sim-disabled-content-area" class="content-area"> - <div id="sim-disabled-msg" i18n-content="simDisabledMessage"></div> - </div> - <div id="disabled-sim-action-area" class="action-area"> - <div class="button-strip"> - <button id="sim-disabled-confirm" i18n-content="ok"></button> - </div> - </div> - </div> - </div> -</body> -</html>
diff --git a/chrome/browser/resources/chromeos/sim_unlock.js b/chrome/browser/resources/chromeos/sim_unlock.js deleted file mode 100644 index 0d20e88..0000000 --- a/chrome/browser/resources/chromeos/sim_unlock.js +++ /dev/null
@@ -1,419 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('mobile', function() { - - function SimUnlock() {} - - cr.addSingletonGetter(SimUnlock); - - // State of the dialog. - SimUnlock.SIM_UNLOCK_LOADING = -1; - SimUnlock.SIM_ABSENT_NOT_LOCKED = 0, SimUnlock.SIM_NOT_LOCKED_ASK_PIN = 1; - SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN = 2; - SimUnlock.SIM_LOCKED_PIN = 3; - SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT = 4; - SimUnlock.SIM_LOCKED_PUK = 5; - SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT = 6; - SimUnlock.SIM_DISABLED = 7; - - // Mode of the dialog. - SimUnlock.SIM_DIALOG_UNLOCK = 0; - SimUnlock.SIM_DIALOG_CHANGE_PIN = 1; - SimUnlock.SIM_DIALOG_SET_LOCK_ON = 2; - SimUnlock.SIM_DIALOG_SET_LOCK_OFF = 3; - - // Error codes. - SimUnlock.ERROR_PIN = 'incorrectPin'; - SimUnlock.ERROR_PUK = 'incorrectPuk'; - SimUnlock.ERROR_OK = 'ok'; - - // Misc constants. - SimUnlock.PIN_MIN_LENGTH = 4; - SimUnlock.PUK_LENGTH = 8; - - SimUnlock.prototype = { - initialized_: false, - mode_: SimUnlock.SIM_DIALOG_UNLOCK, - pukValue_: '', - defaultDialogSize_: - {'width': window.innerWidth, 'height': window.innerHeight}, - state_: SimUnlock.SIM_UNLOCK_LOADING, - - changeState_: function(simInfo) { - var newState = simInfo.state; - var error = simInfo.error; - var tries = simInfo.tries; - var pinMessage; - this.hideAll_(); - switch (newState) { - case SimUnlock.SIM_UNLOCK_LOADING: - break; - case SimUnlock.SIM_ABSENT_NOT_LOCKED: - SimUnlock.close(); - break; - case SimUnlock.SIM_LOCKED_PIN: - if (error == SimUnlock.ERROR_OK) { - pinMessage = loadTimeData.getStringF('enterPinTriesMessage', tries); - $('pin-error-msg').classList.remove('error'); - } else if (error == SimUnlock.ERROR_PIN) { - pinMessage = - loadTimeData.getStringF('incorrectPinTriesMessage', tries); - $('pin-error-msg').classList.add('error'); - } - $('pin-error-msg').textContent = pinMessage; - $('pin-input').value = ''; - SimUnlock.enablePinDialog(true); - $('locked-pin-overlay').hidden = false; - $('pin-input').focus(); - break; - case SimUnlock.SIM_NOT_LOCKED_ASK_PIN: - if (error == SimUnlock.ERROR_OK) { - pinMessage = loadTimeData.getString('enterPinMessage'); - $('pin-error-msg').classList.remove('error'); - } else if (error == SimUnlock.ERROR_PIN) { - pinMessage = - loadTimeData.getStringF('incorrectPinTriesMessage', tries); - $('pin-error-msg').classList.add('error'); - } - $('pin-error-msg').textContent = pinMessage; - $('pin-input').value = ''; - SimUnlock.enablePinDialog(true); - $('locked-pin-overlay').hidden = false; - $('pin-input').focus(); - break; - case SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN: - SimUnlock.prepareChoosePinDialog(true); - if (error == SimUnlock.ERROR_OK) { - pinMessage = loadTimeData.getString('changePinMessage'); - $('choose-pin-msg').classList.remove('error'); - } else if (error == SimUnlock.ERROR_PIN) { - pinMessage = - loadTimeData.getStringF('incorrectPinTriesMessage', tries); - $('choose-pin-msg').classList.add('error'); - } - $('choose-pin-msg').textContent = pinMessage; - $('old-pin-input').value = ''; - $('new-pin-input').value = ''; - $('retype-new-pin-input').value = ''; - $('choose-pin-overlay').hidden = false; - SimUnlock.enableChoosePinDialog(true); - $('old-pin-input').focus(); - break; - case SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT: - $('locked-pin-no-tries-overlay').hidden = false; - break; - case SimUnlock.SIM_LOCKED_PUK: - $('puk-input').value = ''; - if (tries && tries >= 0) { - var pukMessage = loadTimeData.getStringF('enterPukWarning', tries); - $('puk-warning-msg').textContent = pukMessage; - } - $('enter-puk-confirm').disabled = true; - $('locked-puk-overlay').hidden = false; - $('puk-input').focus(); - - // Resize the dialog to accomodate the PUK contents. - this.updateDialogSize_(0, 45); - break; - case SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT: - $('locked-puk-no-tries-overlay').hidden = false; - break; - case SimUnlock.SIM_DISABLED: - $('sim-disabled-overlay').hidden = false; - break; - } - this.state_ = newState; - }, - - /** - * Returns current state of the dialog. - * @type {number} value of the state. - */ - get state() { - return this.state_; - }, - - updateDialogSize_: function(deltaX, deltaY) { - window.resizeTo( - this.defaultDialogSize_.width + deltaX, - this.defaultDialogSize_.height + deltaY); - }, - - hideAll_: function() { - $('locked-pin-overlay').hidden = true; - $('locked-pin-no-tries-overlay').hidden = true; - $('locked-puk-overlay').hidden = true; - $('choose-pin-overlay').hidden = true; - $('locked-puk-no-tries-overlay').hidden = true; - $('sim-disabled-overlay').hidden = true; - }, - - newPinEntered_: function(newPin, newPin2) { - var changePinMode = this.state_ == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN; - if (newPin.length < SimUnlock.PIN_MIN_LENGTH || - newPin2.length < SimUnlock.PIN_MIN_LENGTH || - (changePinMode && - $('old-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH)) { - return; - } - if (newPin != newPin2) { - $('choose-pin-error').hidden = false; - $('old-pin-input').value = ''; - $('new-pin-input').value = ''; - $('retype-new-pin-input').value = ''; - if (changePinMode) - $('old-pin-input').focus(); - else - $('new-pin-input').focus(); - } else { - $('choose-pin-error').hidden = true; - SimUnlock.enableChoosePinDialog(false); - if (changePinMode) { - var oldPin = $('old-pin-input').value; - chrome.send('changePinCode', [oldPin, newPin]); - } else { - chrome.send('enterPukCode', [this.pukValue_, newPin]); - this.pukValue_ = ''; - } - } - }, - - pukEntered_: function(pukValue) { - if (pukValue.length < SimUnlock.PUK_LENGTH) - return; - this.pukValue_ = pukValue; - this.hideAll_(); - SimUnlock.prepareChoosePinDialog(false); - SimUnlock.enableChoosePinDialog(true); - $('new-pin-input').value = ''; - $('retype-new-pin-input').value = ''; - $('choose-pin-overlay').hidden = false; - $('new-pin-input').focus(); - this.updateDialogSize_(0, 18); - }, - - updateSimStatus_: function(simInfo) { - this.changeState_(simInfo); - }, - }; - - SimUnlock.cancel = function() { - SimUnlock.close(); - }; - - SimUnlock.close = function() { - window.close(); - }; - - SimUnlock.initialize = function() { - this.initialized_ = true; - - var modePattern = /(^\?|&)mode=([^&#]*)/; - var results = modePattern.exec(window.location.search); - if (results == null) { - this.mode_ = SimUnlock.SIM_DIALOG_UNLOCK; - } else { - var mode = results[2]; - if (mode == 'change-pin') - this.mode_ = SimUnlock.SIM_DIALOG_CHANGE_PIN; - else if (mode == 'set-lock-on') - this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_ON; - else if (mode == 'set-lock-off') - this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_OFF; - } - - // PIN input screen. - $('pin-input').addEventListener('keydown', function(event) { - if (event.key == 'Enter') { - SimUnlock.submitPin(); - return; - } - }); - $('pin-input').addEventListener('keyup', function(event) { - $('enter-pin-confirm').disabled = $('enter-pin-dismiss').disabled || - this.value.length < SimUnlock.PIN_MIN_LENGTH; - }); - $('pin-input') - .addEventListener('textInput', SimUnlock.processInput.bind(this)); - $('enter-pin-confirm').addEventListener('click', function(event) { - SimUnlock.submitPin(); - }); - $('enter-pin-dismiss').addEventListener('click', function(event) { - SimUnlock.cancel(); - }); - - // No PIN retries left screen. - $('pin-no-tries-proceed').addEventListener('click', function(event) { - chrome.send('proceedToPukInput'); - }); - $('pin-no-tries-dismiss').addEventListener('click', function(event) { - SimUnlock.cancel(); - }); - - // PUK input screen. - $('puk-input').addEventListener('keydown', function(event) { - if (event.key == 'Enter') { - SimUnlock.pukEntered($('puk-input').value); - return; - } - }); - $('puk-input').addEventListener('keyup', function(event) { - $('enter-puk-confirm').disabled = $('enter-puk-dismiss').disabled || - this.value.length < SimUnlock.PUK_LENGTH; - }); - $('puk-input') - .addEventListener('textInput', SimUnlock.processInput.bind(this)); - $('enter-puk-confirm').addEventListener('click', function(event) { - SimUnlock.pukEntered($('puk-input').value); - }); - $('enter-puk-dismiss').addEventListener('click', function(event) { - SimUnlock.cancel(); - }); - - // Change PIN / new PIN screen. - $('old-pin-input').addEventListener('keydown', function(event) { - if (event.key == 'Enter') { - if (this.value.length >= SimUnlock.PIN_MIN_LENGTH) - $('new-pin-input').focus(); - return; - } - }); - $('old-pin-input').addEventListener('keyup', function(event) { - $('choose-pin-confirm').disabled = $('choose-pin-dismiss').disabled || - this.value.length < SimUnlock.PIN_MIN_LENGTH || - $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH || - $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH; - }); - $('old-pin-input') - .addEventListener('textInput', SimUnlock.processInput.bind(this)); - $('new-pin-input').addEventListener('keydown', function(event) { - if (event.key == 'Enter') { - if (this.value.length >= SimUnlock.PIN_MIN_LENGTH) - $('retype-new-pin-input').focus(); - return; - } - }); - $('new-pin-input').addEventListener('keyup', function(event) { - var changePinMode = - SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN; - var oldPinLengthOk = - $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH; - var oldPinOk = !changePinMode || oldPinLengthOk; - $('choose-pin-confirm').disabled = $('choose-pin-dismiss').disabled || - this.value.length < SimUnlock.PIN_MIN_LENGTH || - $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH || - !oldPinOk; - }); - $('new-pin-input') - .addEventListener('textInput', SimUnlock.processInput.bind(this)); - $('retype-new-pin-input').addEventListener('keyup', function(event) { - var changePinMode = - SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN; - var oldPinLengthOk = - $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH; - var oldPinOk = !changePinMode || oldPinLengthOk; - $('choose-pin-confirm').disabled = $('choose-pin-dismiss').disabled || - this.value.length < SimUnlock.PIN_MIN_LENGTH || - $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH || - !oldPinOk; - }); - $('retype-new-pin-input').addEventListener('keydown', function(event) { - if (event.key == 'Enter') { - SimUnlock.newPinEntered( - $('new-pin-input').value, $('retype-new-pin-input').value); - return; - } - }); - $('retype-new-pin-input') - .addEventListener('textInput', SimUnlock.processInput.bind(this)); - $('choose-pin-confirm').addEventListener('click', function(event) { - SimUnlock.newPinEntered( - $('new-pin-input').value, $('retype-new-pin-input').value); - }); - $('choose-pin-dismiss').addEventListener('click', function(event) { - SimUnlock.cancel(); - }); - - // SIM blocked screens. - $('puk-no-tries-confirm').addEventListener('click', function(event) { - SimUnlock.close(); - }); - $('sim-disabled-confirm').addEventListener('click', function(event) { - SimUnlock.close(); - }); - chrome.send('simStatusInitialize', [this.mode_]); - }; - - SimUnlock.enablePinDialog = function(enabled) { - $('pin-input').disabled = !enabled; - // Ok button is initially disabled. - $('enter-pin-confirm').disabled = true; - $('enter-pin-dismiss').disabled = !enabled; - }; - - SimUnlock.enableChoosePinDialog = function(enabled) { - $('old-pin-input').disabled = !enabled; - $('new-pin-input').disabled = !enabled; - $('retype-new-pin-input').disabled = !enabled; - // Ok button is initially disabled. - $('choose-pin-confirm').disabled = true; - $('choose-pin-dismiss').disabled = !enabled; - }; - - SimUnlock.submitPin = function() { - var pin = $('pin-input').value; - if (pin.length < SimUnlock.PIN_MIN_LENGTH) - return; - SimUnlock.enablePinDialog(false); - chrome.send('enterPinCode', [pin]); - }; - - SimUnlock.prepareChoosePinDialog = function(changePin) { - // Our dialog has different height than choose-pin step of the - // unlock process which we're reusing. - if (changePin) { - $('choose-pin-content-area').classList.remove('choose-pin-content-area'); - $('choose-pin-content-area').classList.add('change-pin-content-area'); - var title = loadTimeData.getString('changePinTitle'); - $('choose-pin-title').textContent = title; - } else { - $('choose-pin-content-area').classList.remove('change-pin-content-area'); - $('choose-pin-content-area').classList.add('choose-pin-content-area'); - var pinMessage = loadTimeData.getString('choosePinMessage'); - $('choose-pin-msg').classList.remove('error'); - $('choose-pin-msg').textContent = pinMessage; - var title = loadTimeData.getString('choosePinTitle'); - $('choose-pin-title').textContent = title; - } - $('old-pin-label').hidden = !changePin; - $('old-pin-input-area').hidden = !changePin; - }; - - SimUnlock.newPinEntered = function(newPin, newPin2) { - SimUnlock.getInstance().newPinEntered_(newPin, newPin2); - }; - - SimUnlock.pukEntered = function(pukValue) { - SimUnlock.getInstance().pukEntered_(pukValue); - }; - - /** - * Processes PIN/PUK fields input, restricting it to 0..9. - */ - SimUnlock.processInput = function(event) { - if (/[^0-9]+/gi.test(event.data)) - event.preventDefault(); - }; - - SimUnlock.simStateChanged = function(simInfo) { - SimUnlock.getInstance().updateSimStatus_(simInfo); - }; - - // Export - return {SimUnlock: SimUnlock}; - -}); - -disableTextSelectAndDrag();
diff --git a/chrome/browser/resources/md_extensions/error_page.html b/chrome/browser/resources/md_extensions/error_page.html index afba3393..571f4c3 100644 --- a/chrome/browser/resources/md_extensions/error_page.html +++ b/chrome/browser/resources/md_extensions/error_page.html
@@ -8,7 +8,6 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> @@ -206,7 +205,7 @@ </template> </div> </template> - </iron-list> + </div> </div> </div> </div>
diff --git a/chrome/browser/resources/md_user_manager/user_manager.html b/chrome/browser/resources/md_user_manager/user_manager.html index 95537c92..072ba3cc 100644 --- a/chrome/browser/resources/md_user_manager/user_manager.html +++ b/chrome/browser/resources/md_user_manager/user_manager.html
@@ -72,6 +72,17 @@ opacity: 0; } + /* The name-container font-sizes is to counteract the countainer's + * scale(0.8), so that the text still stays legible. */ + podrow[ncolumns='6'] .pod .name-container { + font-size: 1.25em; + transition: font-size 180ms; + } + + podrow[ncolumns='6'] .pod.focused .name-container { + font-size: 1em; + } + .pod { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .24), 0 0 2px 0 rgba(0, 0, 0, .12);
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc index 2edc7dc..5cdb6b2 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h" +#include <sstream> #include <string> #include <tuple> #include <utility> @@ -223,14 +224,14 @@ kUwsFoundNoRebootRequired, }; +typedef std:: + tuple<CleanerProcessStatus, CrashPoint, UwsFoundStatus, UserResponse> + ChromeCleanerControllerTestParams; + // Test fixture that runs a mock Chrome Cleaner process in various // configurations and mocks the user's response. class ChromeCleanerControllerTest - : public testing::TestWithParam< - std::tuple<CleanerProcessStatus, - MockChromeCleanerProcess::CrashPoint, - UwsFoundStatus, - ChromeCleanerController::UserResponse>>, + : public testing::TestWithParam<ChromeCleanerControllerTestParams>, public ChromeCleanerRunnerTestDelegate, public ChromeCleanerControllerDelegate { public: @@ -492,6 +493,8 @@ EXPECT_CALL(mock_observer_, OnIdle(ExpectedIdleReason())) .WillOnce( InvokeWithoutArgs([&run_loop]() { run_loop.QuitWhenIdle(); })); + } else { + EXPECT_CALL(mock_observer_, OnIdle(_)).Times(0); } if (ExpectedOnInfectedCalled()) { @@ -505,17 +508,23 @@ // called only if the user response is kAcceptedWithoutLogs. if (user_response_ == UserResponse::kAcceptedWithoutLogs) EXPECT_CALL(mock_observer_, OnLogsEnabledChanged(false)); + } else { + EXPECT_CALL(mock_observer_, OnInfected(_)).Times(0); } if (ExpectedOnCleaningCalled()) { EXPECT_CALL(mock_observer_, OnCleaning(_)) .WillOnce(SaveArg<0>(&files_to_delete_on_cleaning)); + } else { + EXPECT_CALL(mock_observer_, OnCleaning(_)).Times(0); } if (ExpectedOnRebootRequiredCalled()) { EXPECT_CALL(mock_observer_, OnRebootRequired()) .WillOnce( InvokeWithoutArgs([&run_loop]() { run_loop.QuitWhenIdle(); })); + } else { + EXPECT_CALL(mock_observer_, OnRebootRequired()).Times(0); } // Assert here that we expect at least one of OnIdle or OnRebootRequired to be @@ -556,6 +565,86 @@ controller_->RemoveObserver(&mock_observer_); } +// Make all the test parameter types printable. + +std::ostream& operator<<(std::ostream& out, CleanerProcessStatus status) { + switch (status) { + case CleanerProcessStatus::kFetchFailure: + return out << "FetchFailure"; + case CleanerProcessStatus::kFetchSuccessInvalidProcess: + return out << "FetchSuccessInvalidProcess"; + case CleanerProcessStatus::kFetchSuccessValidProcess: + return out << "FetchSuccessValidProcess"; + default: + NOTREACHED(); + return out << "UnknownProcessStatus" << status; + } +} + +std::ostream& operator<<(std::ostream& out, CrashPoint crash_point) { + switch (crash_point) { + case CrashPoint::kNone: + return out << "NoCrash"; + case CrashPoint::kOnStartup: + return out << "CrashOnStartup"; + case CrashPoint::kAfterConnection: + return out << "CrashAfterConnection"; + case CrashPoint::kAfterRequestSent: + return out << "CrashAfterRequestSent"; + case CrashPoint::kAfterResponseReceived: + return out << "CrashAfterResponseReceived"; + default: + NOTREACHED(); + return out << "UnknownCrashPoint" << crash_point; + } +} + +std::ostream& operator<<(std::ostream& out, UwsFoundStatus status) { + switch (status) { + case UwsFoundStatus::kNoUwsFound: + return out << "NoUwsFound"; + case UwsFoundStatus::kUwsFoundRebootRequired: + return out << "UwsFoundRebootRequired"; + case UwsFoundStatus::kUwsFoundNoRebootRequired: + return out << "UwsFoundNoRebootRequired"; + default: + NOTREACHED(); + return out << "UnknownFoundStatus" << status; + } +} + +std::ostream& operator<<(std::ostream& out, UserResponse response) { + switch (response) { + case UserResponse::kAcceptedWithLogs: + return out << "UserAcceptedWithLogs"; + case UserResponse::kAcceptedWithoutLogs: + return out << "UserAcceptedWithoutLogs"; + case UserResponse::kDenied: + return out << "UserDenied"; + case UserResponse::kDismissed: + return out << "UserDismissed"; + default: + NOTREACHED(); + return out << "UnknownUserResponse" << response; + } +} + +// ::testing::PrintToStringParamName does not format tuples as a valid test +// name, so this functor can be used to get each element in the tuple +// explicitly and format them using the above operator<< overrides. +struct ChromeCleanerControllerTestParamsToString { + std::string operator()( + const ::testing::TestParamInfo<ChromeCleanerControllerTestParams>& info) + const { + std::ostringstream param_name; + param_name << std::get<0>(info.param) << "_"; + param_name << std::get<1>(info.param) << "_"; + param_name << std::get<2>(info.param) << "_"; + param_name << std::get<3>(info.param); + return param_name.str(); + } +}; + INSTANTIATE_TEST_CASE_P( All, ChromeCleanerControllerTest, @@ -575,7 +664,8 @@ Values(UserResponse::kAcceptedWithLogs, UserResponse::kAcceptedWithoutLogs, UserResponse::kDenied, - UserResponse::kDismissed))); + UserResponse::kDismissed)), + ChromeCleanerControllerTestParamsToString()); } // namespace } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 49a70fc..fd74d42 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -248,10 +248,11 @@ const security_interstitials::UnsafeResource& unsafe_resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags) override { + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback) override { details_ = new ThreatDetails(delegate, web_contents, unsafe_resource, request_context_getter, history_service, - trim_to_ad_tags); + trim_to_ad_tags, done_callback); return details_; }
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index 3298ced..0ff90ce0f 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -154,10 +154,8 @@ FillCacheBase(context_getter, /*use_https_threat_url=*/true); } -// Lets us provide a MockURLRequestContext with an HTTP Cache we pre-populate. +// Lets us control synchronization of the done callback for ThreatDetails. // Also exposes the constructor. -// TODO(lpz): is this class still needed? ThreatDetails seems to handle the -// MockURLRequestContext case just fine on its own. class ThreatDetailsWrap : public ThreatDetails { public: ThreatDetailsWrap( @@ -171,7 +169,11 @@ unsafe_resource, request_context_getter, history_service, - /*trim_to_ad_tags=*/false) {} + /*trim_to_ad_tags=*/false, + base::Bind(&ThreatDetailsWrap::ThreatDetailsDone, + base::Unretained(this))), + run_loop_(nullptr), + done_callback_count_(0) {} ThreatDetailsWrap( SafeBrowsingUIManager* ui_manager, @@ -185,35 +187,45 @@ unsafe_resource, request_context_getter, history_service, - trim_to_ad_tags) {} + trim_to_ad_tags, + base::Bind(&ThreatDetailsWrap::ThreatDetailsDone, + base::Unretained(this))), + run_loop_(nullptr), + done_callback_count_(0) {} + + void ThreatDetailsDone(content::WebContents* web_contents) { + ++done_callback_count_; + run_loop_->Quit(); + run_loop_ = NULL; + } + + // Used to synchronize ThreatDetailsDone() with WaitForThreatDetailsDone(). + // RunLoop::RunUntilIdle() is not sufficient because the MessageLoop task + // queue completely drains at some point between the send and the wait. + void SetRunLoopToQuit(base::RunLoop* run_loop) { + DCHECK(run_loop_ == NULL); + run_loop_ = run_loop; + } + + size_t done_callback_count() { return done_callback_count_; } private: ~ThreatDetailsWrap() override {} + + base::RunLoop* run_loop_; + size_t done_callback_count_; }; class MockSafeBrowsingUIManager : public SafeBrowsingUIManager { public: - base::RunLoop* run_loop_; // The safe browsing UI manager does not need a service for this test. - MockSafeBrowsingUIManager() : SafeBrowsingUIManager(NULL), run_loop_(NULL) {} + MockSafeBrowsingUIManager() : SafeBrowsingUIManager(NULL) {} - // When the ThreatDetails is done, this is called. + // When the serialized report is sent, this is called. void SendSerializedThreatDetails(const std::string& serialized) override { - DVLOG(1) << "SendSerializedThreatDetails"; - run_loop_->Quit(); - run_loop_ = NULL; serialized_ = serialized; } - // Used to synchronize SendSerializedThreatDetails() with - // WaitForSerializedReport(). RunLoop::RunUntilIdle() is not sufficient - // because the MessageLoop task queue completely drains at some point - // between the send and the wait. - void SetRunLoopToQuit(base::RunLoop* run_loop) { - DCHECK(run_loop_ == NULL); - run_loop_ = run_loop; - } - const std::string& GetSerialized() { return serialized_; } private: @@ -237,17 +249,18 @@ false /* no_db */)); } - std::string WaitForSerializedReport(ThreatDetails* report, - bool did_proceed, - int num_visit) { + std::string WaitForThreatDetailsDone(ThreatDetailsWrap* report, + bool did_proceed, + int num_visit) { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::BindOnce(&ThreatDetails::FinishCollection, report, did_proceed, num_visit)); - // Wait for the callback (SendSerializedThreatDetails). - DVLOG(1) << "Waiting for SendSerializedThreatDetails"; + // Wait for the callback (ThreatDetailsDone). base::RunLoop run_loop; - ui_manager_->SetRunLoopToQuit(&run_loop); + report->SetRunLoopToQuit(&run_loop); run_loop.Run(); + // Make sure the done callback was run exactly once. + EXPECT_EQ(1u, report->done_callback_count()); return ui_manager_->GetSerialized(); } @@ -412,7 +425,7 @@ scoped_refptr<ThreatDetailsWrap> report = new ThreatDetailsWrap( ui_manager_.get(), web_contents(), resource, NULL, history_service()); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, 1 /* num_visit */); ClientSafeBrowsingReportRequest actual; @@ -456,7 +469,7 @@ scoped_refptr<ThreatDetailsWrap> report = new ThreatDetailsWrap( ui_manager_.get(), web_contents(), resource, NULL, history_service()); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 1 /* num_visit */); ClientSafeBrowsingReportRequest actual; @@ -517,7 +530,7 @@ params.push_back(parent_node); report->OnReceivedThreatDOMDetails(main_rfh(), params); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -713,7 +726,7 @@ report->OnReceivedThreatDOMDetails(main_rfh(), outer_params); report->OnReceivedThreatDOMDetails(child_rfh, inner_params); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -757,7 +770,7 @@ report->OnReceivedThreatDOMDetails(child_rfh, inner_params); report->OnReceivedThreatDOMDetails(main_rfh(), outer_params); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -876,7 +889,7 @@ report->OnReceivedThreatDOMDetails(main_rfh(), outer_params); report->OnReceivedThreatDOMDetails(child_rfh, inner_params); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -1098,7 +1111,7 @@ trimmed_report->OnReceivedThreatDOMDetails(child_rfh, inner_params); trimmed_report->OnReceivedThreatDOMDetails(main_rfh(), outer_params); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( trimmed_report.get(), false /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -1124,7 +1137,7 @@ scoped_refptr<ThreatDetailsWrap> report = new ThreatDetailsWrap( ui_manager_.get(), web_contents(), resource, NULL, history_service()); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -1199,7 +1212,7 @@ controller().DiscardNonCommittedEntries(); // Finish ThreatDetails collection. - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 1 /* num_visit */); ClientSafeBrowsingReportRequest actual; @@ -1253,7 +1266,7 @@ // Do ThreatDetails collection. scoped_refptr<ThreatDetailsWrap> report = new ThreatDetailsWrap( ui_manager_.get(), web_contents(), resource, NULL, history_service()); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, 1 /* num_visit */); ClientSafeBrowsingReportRequest actual; @@ -1300,7 +1313,7 @@ // Do ThreatDetails collection. scoped_refptr<ThreatDetailsWrap> report = new ThreatDetailsWrap( ui_manager_.get(), web_contents(), resource, NULL, history_service()); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, 1 /* num_visit */); ClientSafeBrowsingReportRequest actual; @@ -1347,7 +1360,7 @@ base::RunLoop().RunUntilIdle(); DVLOG(1) << "Getting serialized report"; - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, -1 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -1431,7 +1444,7 @@ base::RunLoop().RunUntilIdle(); DVLOG(1) << "Getting serialized report"; - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, -1 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -1509,7 +1522,7 @@ base::RunLoop().RunUntilIdle(); DVLOG(1) << "Getting serialized report"; - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, -1 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized); @@ -1564,7 +1577,7 @@ // Let the redirects callbacks complete. base::RunLoop().RunUntilIdle(); - std::string serialized = WaitForSerializedReport( + std::string serialized = WaitForThreatDetailsDone( report.get(), true /* did_proceed*/, 1 /* num_visit */); ClientSafeBrowsingReportRequest actual; actual.ParseFromString(serialized);
diff --git a/chrome/browser/safe_browsing/trigger_creator.cc b/chrome/browser/safe_browsing/trigger_creator.cc index b595d295..6ccd0cc 100644 --- a/chrome/browser/safe_browsing/trigger_creator.cc +++ b/chrome/browser/safe_browsing/trigger_creator.cc
@@ -30,13 +30,19 @@ return; } + TriggerManager* trigger_manager = + g_browser_process->safe_browsing_service()->trigger_manager(); + + // Create the helper for listening to events for this webcontents, created for + // all tabs since reports could be triggered from other places besides here. + safe_browsing::TriggerManagerWebContentsHelper::CreateForWebContents( + web_contents, trigger_manager); + // We only start triggers for this tab if they are eligible to collect data // (eg: because of opt-ins, available quota, etc). If we skip a trigger but // later opt-in changes or quota becomes available, the trigger won't be // running on old tabs, but that's acceptable. The trigger will be started for // new tabs. - TriggerManager* trigger_manager = - g_browser_process->safe_browsing_service()->trigger_manager(); SBErrorOptions options = TriggerManager::GetSBErrorDisplayOptions( *profile->GetPrefs(), *web_contents); if (trigger_manager->CanStartDataCollection(options,
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc index 9615c149..db8b6bd 100644 --- a/chrome/browser/shell_integration_win.cc +++ b/chrome/browser/shell_integration_win.cc
@@ -47,15 +47,17 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/shell_handler_win.mojom.h" #include "chrome/grit/generated_resources.h" #include "chrome/install_static/install_util.h" #include "chrome/installer/util/browser_distribution.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/scoped_user_protocol_entry.h" #include "chrome/installer/util/shell_util.h" +#include "chrome/services/util_win/public/interfaces/constants.mojom.h" +#include "chrome/services/util_win/public/interfaces/shell_util_win.mojom.h" #include "components/variations/variations_associated_data.h" -#include "content/public/browser/utility_process_mojo_client.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" #include "ui/base/l10n/l10n_util.h" namespace shell_integration { @@ -451,22 +453,29 @@ OpenSystemSettingsHelper* OpenSystemSettingsHelper::instance_ = nullptr; // Helper class to determine if Chrome is pinned to the taskbar. Hides the -// complexity of managing the lifetime of a UtilityProcessMojoClient. +// complexity of managing the lifetime of the connection to the ChromeWinUtil +// service. class IsPinnedToTaskbarHelper { public: using ResultCallback = win::IsPinnedToTaskbarCallback; using ErrorCallback = win::ConnectionErrorCallback; - static void GetState(const ErrorCallback& error_callback, + static void GetState(std::unique_ptr<service_manager::Connector> connector, + const ErrorCallback& error_callback, const ResultCallback& result_callback); private: - IsPinnedToTaskbarHelper(const ErrorCallback& error_callback, + IsPinnedToTaskbarHelper(std::unique_ptr<service_manager::Connector> connector, + const ErrorCallback& error_callback, const ResultCallback& result_callback); void OnConnectionError(); void OnIsPinnedToTaskbarResult(bool succeeded, bool is_pinned_to_taskbar); - content::UtilityProcessMojoClient<chrome::mojom::ShellHandler> shell_handler_; + chrome::mojom::ShellUtilWinPtr shell_util_win_ptr_; + // The connector used to retrieve the Patch service. We can't simply use + // content::ServiceManagerConnection::GetForProcess()->GetConnector() as this + // is called on a background thread. + std::unique_ptr<service_manager::Connector> connector_; ErrorCallback error_callback_; ResultCallback result_callback_; @@ -477,37 +486,38 @@ }; // static -void IsPinnedToTaskbarHelper::GetState(const ErrorCallback& error_callback, - const ResultCallback& result_callback) { +void IsPinnedToTaskbarHelper::GetState( + std::unique_ptr<service_manager::Connector> connector, + const ErrorCallback& error_callback, + const ResultCallback& result_callback) { // Self-deleting when the ShellHandler completes. - new IsPinnedToTaskbarHelper(error_callback, result_callback); + new IsPinnedToTaskbarHelper(std::move(connector), error_callback, + result_callback); } IsPinnedToTaskbarHelper::IsPinnedToTaskbarHelper( + std::unique_ptr<service_manager::Connector> connector, const ErrorCallback& error_callback, const ResultCallback& result_callback) - : shell_handler_( - l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_SHELL_HANDLER_NAME)), + : connector_(std::move(connector)), error_callback_(error_callback), result_callback_(result_callback) { DCHECK(error_callback_); DCHECK(result_callback_); - // |shell_handler_| owns the callbacks and is guaranteed to be destroyed + connector_->BindInterface(chrome::mojom::kUtilWinServiceName, + &shell_util_win_ptr_); + // |shell_util_win_ptr_| owns the callbacks and is guaranteed to be destroyed // before |this|, therefore making base::Unretained() safe to use. - shell_handler_.set_error_callback(base::Bind( + shell_util_win_ptr_.set_connection_error_handler(base::Bind( &IsPinnedToTaskbarHelper::OnConnectionError, base::Unretained(this))); - shell_handler_.set_disable_sandbox(); - shell_handler_.Start(); - - shell_handler_.service()->IsPinnedToTaskbar( + shell_util_win_ptr_->IsPinnedToTaskbar( base::Bind(&IsPinnedToTaskbarHelper::OnIsPinnedToTaskbarResult, base::Unretained(this))); } void IsPinnedToTaskbarHelper::OnConnectionError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - error_callback_.Run(); delete this; } @@ -744,9 +754,11 @@ } void GetIsPinnedToTaskbarState( + std::unique_ptr<service_manager::Connector> connector, const ConnectionErrorCallback& on_error_callback, const IsPinnedToTaskbarCallback& result_callback) { - IsPinnedToTaskbarHelper::GetState(on_error_callback, result_callback); + IsPinnedToTaskbarHelper::GetState(std::move(connector), on_error_callback, + result_callback); } int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe,
diff --git a/chrome/browser/shell_integration_win.h b/chrome/browser/shell_integration_win.h index 5be0e0d..f3e168a 100644 --- a/chrome/browser/shell_integration_win.h +++ b/chrome/browser/shell_integration_win.h
@@ -5,12 +5,17 @@ #ifndef CHROME_BROWSER_SHELL_INTEGRATION_WIN_H_ #define CHROME_BROWSER_SHELL_INTEGRATION_WIN_H_ +#include <memory> #include <string> #include "base/callback_forward.h" #include "base/files/file_path.h" #include "base/strings/string16.h" +namespace service_manager { +class Connector; +} + namespace shell_integration { namespace win { @@ -62,9 +67,11 @@ // is true if Chrome is pinned to the taskbar. // The ConnectionErrorCallback is called instead if something wrong happened // with the connection to the remote process. +// |connector| should be a fresh connector unbound to any thread. using ConnectionErrorCallback = base::Closure; using IsPinnedToTaskbarCallback = base::Callback<void(bool, bool)>; void GetIsPinnedToTaskbarState( + std::unique_ptr<service_manager::Connector> connector, const ConnectionErrorCallback& on_error_callback, const IsPinnedToTaskbarCallback& result_callback);
diff --git a/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc index c9401b6d..baac035 100644 --- a/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc
@@ -28,8 +28,7 @@ ~TestClient() override {} void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, const std::string& message) override {} - void AgentHostClosed(content::DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override {} + void AgentHostClosed(content::DevToolsAgentHost* agent_host) override {} }; class ScopedDevtoolsOpener {
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc index 493ec16ed..d84f94dd 100644 --- a/chrome/browser/sync/profile_sync_test_util.cc +++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -21,6 +21,7 @@ #include "components/sync/driver/signin_manager_wrapper.h" #include "components/sync/driver/startup_controller.h" #include "components/sync/driver/sync_api_component_factory_mock.h" +#include "components/sync/model/model_type_store_test_util.h" using browser_sync::ProfileSyncService; @@ -54,6 +55,8 @@ init_params.url_request_context = profile->GetRequestContext(); init_params.debug_identifier = profile->GetDebugName(); init_params.channel = chrome::GetChannel(); + init_params.model_type_store_factory = + syncer::ModelTypeStoreTestUtil::FactoryForInMemoryStoreForTest(); return init_params; }
diff --git a/chrome/browser/sync/user_event_service_factory.cc b/chrome/browser/sync/user_event_service_factory.cc index 87c9b6f5..5aa7c525 100644 --- a/chrome/browser/sync/user_event_service_factory.cc +++ b/chrome/browser/sync/user_event_service_factory.cc
@@ -52,7 +52,7 @@ syncer::ModelTypeStoreFactory store_factory = browser_sync::ProfileSyncService::GetModelTypeStoreFactory( - syncer::USER_EVENTS, profile->GetPath()); + profile->GetPath()); syncer::ModelTypeSyncBridge::ChangeProcessorFactory processor_factory = base::BindRepeating(&syncer::ModelTypeChangeProcessor::Create, base::BindRepeating(&syncer::ReportUnrecoverableError,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 02ef4b6..d42b724fa 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1436,8 +1436,6 @@ "webui/chromeos/power_ui.h", "webui/chromeos/set_time_ui.cc", "webui/chromeos/set_time_ui.h", - "webui/chromeos/sim_unlock_ui.cc", - "webui/chromeos/sim_unlock_ui.h", "webui/chromeos/slow_trace_ui.cc", "webui/chromeos/slow_trace_ui.h", "webui/chromeos/slow_ui.cc",
diff --git a/chrome/browser/ui/ash/lock_screen_client.cc b/chrome/browser/ui/ash/lock_screen_client.cc index 2c68835..7985267 100644 --- a/chrome/browser/ui/ash/lock_screen_client.cc +++ b/chrome/browser/ui/ash/lock_screen_client.cc
@@ -92,7 +92,7 @@ } void LockScreenClient::LoadWallpaper(const AccountId& account_id) { - chromeos::WallpaperManager::Get()->SetUserWallpaperDelayed(account_id); + chromeos::WallpaperManager::Get()->SetUserWallpaper(account_id); } void LockScreenClient::SignOutUser() {
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc index 0348314..c49054d 100644 --- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc +++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
@@ -189,7 +189,7 @@ wallpaper_delegate->SetAnimationDurationOverride( std::max(duration, kMinimalAnimationTimeMS)); if (screen_cover_ != NEW_USER_COVERS_SCREEN) { - chromeos::WallpaperManager::Get()->SetUserWallpaperNow(new_account_id_); + chromeos::WallpaperManager::Get()->SetUserWallpaper(new_account_id_); wallpaper_user_id_for_test_ = (NO_USER_COVERS_SCREEN == screen_cover_ ? "->" : "") + new_account_id_.Serialize(); @@ -198,7 +198,7 @@ // Revert the wallpaper cross dissolve animation duration back to the // default. if (screen_cover_ == NEW_USER_COVERS_SCREEN) - chromeos::WallpaperManager::Get()->SetUserWallpaperNow(new_account_id_); + chromeos::WallpaperManager::Get()->SetUserWallpaper(new_account_id_); // Coming here the wallpaper user id is the final result. No matter how we // got here.
diff --git a/chrome/browser/ui/cocoa/content_settings/blocked_plugin_bubble_controller.mm b/chrome/browser/ui/cocoa/content_settings/blocked_plugin_bubble_controller.mm index c6074a2..0a06bed 100644 --- a/chrome/browser/ui/cocoa/content_settings/blocked_plugin_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/content_settings/blocked_plugin_bubble_controller.mm
@@ -45,7 +45,7 @@ // The size of this bubble, and the other layout constants elsewhere in this // file, were lifted from ContentBlockedPlugins.xib base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] - initWithContentRect:NSMakeRect(0, 0, 314, 179) + initWithContentRect:NSMakeRect(0, 0, 314, 145) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm index 4a06c42..0d71af5 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
@@ -141,6 +141,8 @@ NSImage* infoIcon = rb.GetNativeImageNamed(IDR_INFO).ToNSImage(); [infoBarIcon_ setImage:infoIcon]; + [self.window setBackgroundColor:[NSColor windowBackgroundColor]]; + // Initialize the banner gradient and stroke color. NSColor* bannerStartingColor = [NSColor colorWithCalibratedRed:kBannerGradientColorTop[0]
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc index fbf7002..889f987a 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -17,7 +17,7 @@ #include "base/run_loop.h" #include "components/ui_devtools/devtools_server.h" #include "components/ui_devtools/views/css_agent.h" -#include "components/ui_devtools/views/ui_devtools_dom_agent.h" +#include "components/ui_devtools/views/dom_agent.h" #include "components/ui_devtools/views/ui_devtools_overlay_agent.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/service_manager_connection.h" @@ -113,7 +113,7 @@ // Start devtools server devtools_server_ = ui_devtools::UiDevToolsServer::Create(nullptr); if (devtools_server_) { - auto dom_backend = base::MakeUnique<ui_devtools::UIDevToolsDOMAgent>(); + auto dom_backend = base::MakeUnique<ui_devtools::DOMAgent>(); auto overlay_backend = base::MakeUnique<ui_devtools::UIDevToolsOverlayAgent>( dom_backend.get());
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index 7d0430c..baac28e7 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/collected_cookies_infobar_delegate.h" #include "chrome/browser/ui/views/cookie_info_view.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" @@ -408,8 +409,9 @@ TabSpecificContentSettings::FromWebContents(web_contents_); // Create the controls that go into the pane. - allowed_label_ = new views::Label(l10n_util::GetStringUTF16( - IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL)); + allowed_label_ = new views::Label( + l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL), + CONTEXT_BODY_TEXT_LARGE); allowed_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); allowed_cookies_tree_model_ = @@ -479,9 +481,10 @@ // Create the controls that go into the pane. blocked_label_ = new views::Label( l10n_util::GetStringUTF16( - prefs->GetBoolean(prefs::kBlockThirdPartyCookies) ? - IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED : - IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL)); + prefs->GetBoolean(prefs::kBlockThirdPartyCookies) + ? IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED + : IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL), + CONTEXT_BODY_TEXT_LARGE); blocked_label_->SetMultiLine(true); blocked_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); blocked_label_->SizeToFit(kTreeViewWidth);
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 09d7f6f..eb7c6da 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -357,7 +357,7 @@ } bool ContentSettingBubbleContents::ShouldShowCloseButton() const { - return false; + return ChromeLayoutProvider::Get()->IsHarmonyMode(); } void ContentSettingBubbleContents::Init() {
diff --git a/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc new file mode 100644 index 0000000..3eece01 --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc
@@ -0,0 +1,136 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h" +#include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "content/public/test/browser_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace payments { + +class PaymentRequestNoUpdateWithTest : public PaymentRequestBrowserTestBase { + protected: + PaymentRequestNoUpdateWithTest() + : PaymentRequestBrowserTestBase( + "/payment_request_no_update_with_test.html") {} + + void RunJavaScriptFunctionToOpenPaymentRequestUI( + const std::string& function_name) { + ResetEventObserver(DialogEvent::DIALOG_OPENED); + + content::WebContents* web_contents = GetActiveWebContents(); + ASSERT_TRUE(content::ExecuteScript(web_contents, function_name + "();")); + + WaitForObservedEvent(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(PaymentRequestNoUpdateWithTest); +}; + +// A merchant that does not listen to shipping address update events will not +// cause timeouts in UI. +IN_PROC_BROWSER_TEST_F(PaymentRequestNoUpdateWithTest, BuyWithoutListeners) { + autofill::AutofillProfile billing_address = autofill::test::GetFullProfile(); + AddAutofillProfile(billing_address); + AddAutofillProfile(autofill::test::GetFullProfile2()); + autofill::CreditCard card = autofill::test::GetCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); + + RunJavaScriptFunctionToOpenPaymentRequestUI("buyWithoutListeners"); + + OpenShippingAddressSectionScreen(); + ResetEventObserverForSequence(std::list<DialogEvent>{ + DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION}); + ClickOnChildInListViewAndWait( + /* child_index=*/1, /*total_num_children=*/2, + DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW, + /*wait_for_animation=*/false); + // Wait for the animation here explicitly, otherwise + // ClickOnChildInListViewAndWait tries to install an AnimationDelegate before + // the animation is kicked off (since that's triggered off of the spec being + // updated) and this hits a DCHECK. + WaitForAnimation(); + + PayWithCreditCardAndWait(base::ASCIIToUTF16("123")); + + ExpectBodyContains({"freeShipping"}); +} + +// A merchant that listens to shipping address update events, but does not call +// updateWith() on the event, will not cause timeouts in UI. +IN_PROC_BROWSER_TEST_F(PaymentRequestNoUpdateWithTest, + BuyWithoutCallingUpdateWith) { + autofill::AutofillProfile billing_address = autofill::test::GetFullProfile(); + AddAutofillProfile(billing_address); + AddAutofillProfile(autofill::test::GetFullProfile2()); + autofill::CreditCard card = autofill::test::GetCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); + + RunJavaScriptFunctionToOpenPaymentRequestUI("buyWithoutCallingUpdateWith"); + + OpenShippingAddressSectionScreen(); + ResetEventObserverForSequence(std::list<DialogEvent>{ + DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION}); + ClickOnChildInListViewAndWait( + /* child_index=*/1, /*total_num_children=*/2, + DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW, + /*wait_for_animation=*/false); + // Wait for the animation here explicitly, otherwise + // ClickOnChildInListViewAndWait tries to install an AnimationDelegate before + // the animation is kicked off (since that's triggered off of the spec being + // updated) and this hits a DCHECK. + WaitForAnimation(); + + PayWithCreditCardAndWait(base::ASCIIToUTF16("123")); + + ExpectBodyContains({"freeShipping"}); +} + +// A merchant that invokes updateWith() directly without using a promise will +// not cause timeouts in UI. +IN_PROC_BROWSER_TEST_F(PaymentRequestNoUpdateWithTest, BuyWithoutPromises) { + autofill::AutofillProfile billing_address = autofill::test::GetFullProfile(); + AddAutofillProfile(billing_address); + AddAutofillProfile(autofill::test::GetFullProfile2()); + autofill::CreditCard card = autofill::test::GetCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); + + RunJavaScriptFunctionToOpenPaymentRequestUI("buyWithoutPromises"); + + OpenOrderSummaryScreen(); + EXPECT_EQ(base::ASCIIToUTF16("$5.00"), + GetLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL)); + ClickOnBackArrow(); + + OpenShippingAddressSectionScreen(); + ResetEventObserverForSequence(std::list<DialogEvent>{ + DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION}); + ClickOnChildInListViewAndWait( + /* child_index=*/1, /*total_num_children=*/2, + DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW, + /*wait_for_animation=*/false); + // Wait for the animation here explicitly, otherwise + // ClickOnChildInListViewAndWait tries to install an AnimationDelegate before + // the animation is kicked off (since that's triggered off of the spec being + // updated) and this hits a DCHECK. + WaitForAnimation(); + + OpenOrderSummaryScreen(); + EXPECT_EQ(base::ASCIIToUTF16("$10.00"), + GetLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL)); + ClickOnBackArrow(); + + PayWithCreditCardAndWait(base::ASCIIToUTF16("123")); + + ExpectBodyContains({"updatedShipping"}); +} + +} // namespace payments
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 2953c4a4..d82b63c 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -146,7 +146,6 @@ #include "chrome/browser/ui/webui/chromeos/network_ui.h" #include "chrome/browser/ui/webui/chromeos/power_ui.h" #include "chrome/browser/ui/webui/chromeos/set_time_ui.h" -#include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h" #include "chrome/browser/ui/webui/chromeos/slow_trace_ui.h" #include "chrome/browser/ui/webui/chromeos/slow_ui.h" #include "chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.h" @@ -464,8 +463,6 @@ return &NewWebUI<chromeos::InternetDetailDialogUI>; if (url.host_piece() == chrome::kChromeUISetTimeHost) return &NewWebUI<chromeos::SetTimeUI>; - if (url.host_piece() == chrome::kChromeUISimUnlockHost) - return &NewWebUI<chromeos::SimUnlockUI>; if (url.host_piece() == chrome::kChromeUISlowHost) return &NewWebUI<chromeos::SlowUI>; if (url.host_piece() == chrome::kChromeUISlowTraceHost)
diff --git a/chrome/browser/ui/webui/chromeos/OWNERS b/chrome/browser/ui/webui/chromeos/OWNERS index b55e3b7..7de2d5d 100644 --- a/chrome/browser/ui/webui/chromeos/OWNERS +++ b/chrome/browser/ui/webui/chromeos/OWNERS
@@ -6,7 +6,5 @@ zelidrag@chromium.org per-file network*=stevenjb@chromium.org -per-file sim_unlock_ui.*=armansito@chromium.org -per-file sim_unlock_ui.*=stevenjb@chromium.org per-file drive_internals_ui.*=hashimoto@chromium.org per-file drive_internals_ui.*=kinaba@chromium.org
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc index a6db11fe..92543e0 100644 --- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
@@ -300,7 +300,7 @@ const AccountId& manager_id) { if (!delegate_) return; - WallpaperManager::Get()->SetUserWallpaperNow(manager_id); + WallpaperManager::Get()->SetUserWallpaper(manager_id); } void SupervisedUserCreationScreenHandler::HandleImportUserSelected(
diff --git a/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc b/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc deleted file mode 100644 index 023317e..0000000 --- a/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc +++ /dev/null
@@ -1,780 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h" - -#include <stddef.h> -#include <stdint.h> - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted_memory.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/string_piece.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/sim_dialog_delegate.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/network/device_state.h" -#include "chromeos/network/network_device_handler.h" -#include "chromeos/network/network_event_log.h" -#include "chromeos/network/network_state_handler.h" -#include "chromeos/network/network_state_handler_observer.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/url_data_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_message_handler.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/webui/jstemplate_builder.h" -#include "ui/base/webui/web_ui_util.h" - -using content::BrowserThread; -using content::WebContents; -using content::WebUIMessageHandler; - -namespace { - -// JS API callbacks names. -const char kJsApiChangePinCode[] = "changePinCode"; -const char kJsApiEnterPinCode[] = "enterPinCode"; -const char kJsApiEnterPukCode[] = "enterPukCode"; -const char kJsApiProceedToPukInput[] = "proceedToPukInput"; -const char kJsApiSimStatusInitialize[] = "simStatusInitialize"; - -// Page JS API function names. -const char kJsApiSimStatusChanged[] = "mobile.SimUnlock.simStateChanged"; - -// SIM state variables which are passed to the page. -const char kState[] = "state"; -const char kError[] = "error"; -const char kTriesLeft[] = "tries"; - -// Error constants, passed to the page. -const char kErrorPin[] = "incorrectPin"; -const char kErrorOk[] = "ok"; - -chromeos::NetworkDeviceHandler* GetNetworkDeviceHandler() { - return chromeos::NetworkHandler::Get()->network_device_handler(); -} - -chromeos::NetworkStateHandler* GetNetworkStateHandler() { - return chromeos::NetworkHandler::Get()->network_state_handler(); -} - -} // namespace - -namespace chromeos { - -class SimUnlockUIHTMLSource : public content::URLDataSource { - public: - SimUnlockUIHTMLSource(); - - // content::URLDataSource implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) override; - std::string GetMimeType(const std::string&) const override { - return "text/html"; - } - bool ShouldAddContentSecurityPolicy() const override { return false; } - bool AllowCaching() const override { - // Should not be cached to reflect dynamically-generated contents that may - // depend on current settings. - return false; - } - - private: - ~SimUnlockUIHTMLSource() override {} - - std::string service_path_; - DISALLOW_COPY_AND_ASSIGN(SimUnlockUIHTMLSource); -}; - -// The handler for Javascript messages related to the "sim-unlock" view. -class SimUnlockHandler : public WebUIMessageHandler, - public base::SupportsWeakPtr<SimUnlockHandler>, - public NetworkStateHandlerObserver { - public: - SimUnlockHandler(); - ~SimUnlockHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // NetworkStateHandlerObserver implementation. - void DeviceListChanged() override; - - private: - // Should keep this state enum in sync with similar one in JS code. - // SIM_NOT_LOCKED_ASK_PIN - SIM card is not locked but we ask user - // for PIN input because PinRequired preference change was requested. - // SIM_NOT_LOCKED_CHANGE_PIN - SIM card is not locked, ask user for old PIN - // and new PIN to change it. - typedef enum SimUnlockState { - SIM_UNLOCK_LOADING = -1, - SIM_ABSENT_NOT_LOCKED = 0, - SIM_NOT_LOCKED_ASK_PIN = 1, - SIM_NOT_LOCKED_CHANGE_PIN = 2, - SIM_LOCKED_PIN = 3, - SIM_LOCKED_NO_PIN_TRIES_LEFT = 4, - SIM_LOCKED_PUK = 5, - SIM_LOCKED_NO_PUK_TRIES_LEFT = 6, - SIM_DISABLED = 7, - } SimUnlockState; - - // Type of the SIM unlock code. - enum SimUnlockCode { - CODE_PIN, - CODE_PUK - }; - - enum PinOperationError { - PIN_ERROR_NONE = 0, - PIN_ERROR_UNKNOWN = 1, - PIN_ERROR_INCORRECT_CODE = 2, - PIN_ERROR_BLOCKED = 3 - }; - - class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { - public: - explicit TaskProxy(const base::WeakPtr<SimUnlockHandler>& handler) - : handler_(handler), - code_type_() { - } - - TaskProxy(const base::WeakPtr<SimUnlockHandler>& handler, - const std::string& code, - SimUnlockCode code_type) - : handler_(handler), - code_(code), - code_type_(code_type) { - } - - void HandleEnterCode() { - if (handler_) - handler_->EnterCode(code_, code_type_); - } - - void HandleInitialize() { - if (handler_) - handler_->InitializeSimStatus(); - } - - void HandleProceedToPukInput() { - if (handler_) - handler_->ProceedToPukInput(); - } - - private: - friend class base::RefCountedThreadSafe<TaskProxy>; - - ~TaskProxy() {} - - base::WeakPtr<SimUnlockHandler> handler_; - - // Pending code input (PIN/PUK). - std::string code_; - - // Pending code type. - SimUnlockCode code_type_; - - DISALLOW_COPY_AND_ASSIGN(TaskProxy); - }; - - // Returns the cellular device that this dialog currently corresponds to. - const DeviceState* GetCellularDevice(); - - // Pass PIN/PUK code to shill and check status. - void EnterCode(const std::string& code, SimUnlockCode code_type); - - // Methods to invoke shill PIN/PUK D-Bus operations. - void ChangeRequirePin(bool require_pin, const std::string& pin); - void EnterPin(const std::string& pin); - void ChangePin(const std::string& old_pin, const std::string& new_pin); - void UnblockPin(const std::string& puk, const std::string& new_pin); - void PinOperationSuccessCallback(const std::string& operation_name); - void PinOperationErrorCallback( - const std::string& operation_name, - const std::string& error_name, - std::unique_ptr<base::DictionaryValue> error_data); - - // Called when an asynchronous PIN operation has completed. - void OnPinOperationCompleted(PinOperationError error); - - // Single handler for PIN/PUK code operations. - void HandleEnterCode(SimUnlockCode code_type, const std::string& code); - - // Handlers for JS WebUI messages. - void HandleChangePinCode(const base::ListValue* args); - void HandleEnterPinCode(const base::ListValue* args); - void HandleEnterPukCode(const base::ListValue* args); - void HandleProceedToPukInput(const base::ListValue* args); - void HandleSimStatusInitialize(const base::ListValue* args); - - // Initialize current SIM card status, passes that to page. - void InitializeSimStatus(); - - // Checks whether SIM card is in PUK locked state and proceeds to PUK input. - void ProceedToPukInput(); - - // Processes current SIM card state and update internal state/page. - void ProcessSimCardState(const DeviceState* cellular); - - // Updates page with the current state/SIM card info/error. - void UpdatePage(const DeviceState* cellular, const std::string& error_msg); - - // Dialog internal state. - SimUnlockState state_; - - // Path of the Cellular device that we monitor property updates from. - std::string cellular_device_path_; - - // Type of the dialog: generic unlock/change pin/change PinRequire. - SimDialogDelegate::SimDialogMode dialog_mode_; - - // New PIN value for the case when we unblock SIM card or change PIN. - std::string new_pin_; - - // The initial lock type value, used to observe changes to lock status; - std::string sim_lock_type_; - - // True if there's a pending PIN operation. - // That means that SIM lock state change will be received 2 times: - // OnNetworkDeviceSimLockChanged and OnPinOperationCompleted. - // First one should be ignored. - bool pending_pin_operation_; - - base::WeakPtrFactory<SimUnlockHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(SimUnlockHandler); -}; - -// SimUnlockUIHTMLSource ------------------------------------------------------- - -SimUnlockUIHTMLSource::SimUnlockUIHTMLSource() { -} - -std::string SimUnlockUIHTMLSource::GetSource() const { - return chrome::kChromeUISimUnlockHost; -} - -void SimUnlockUIHTMLSource::StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) { - base::DictionaryValue strings; - strings.SetString("title", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_ENTER_PIN_TITLE)); - strings.SetString("ok", l10n_util::GetStringUTF16(IDS_OK)); - strings.SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL)); - strings.SetString("enterPinTitle", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_ENTER_PIN_TITLE)); - strings.SetString("enterPinMessage", - l10n_util::GetStringUTF16(IDS_SIM_ENTER_PIN_MESSAGE)); - strings.SetString("enterPinTriesMessage", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_ENTER_PIN_TRIES_MESSAGE)); - strings.SetString("incorrectPinTriesMessage", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_INCORRECT_PIN_TRIES_MESSAGE)); - strings.SetString("incorrectPinTitle", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_INCORRECT_PIN_TITLE)); - // TODO(nkostylev): Pass carrier name if we know that. - strings.SetString("noPinTriesLeft", l10n_util::GetStringFUTF16( - IDS_SIM_UNLOCK_NO_PIN_TRIES_LEFT_MESSAGE, - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_DEFAULT_CARRIER))); - strings.SetString("enterPukButton", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_ENTER_PUK_BUTTON)); - strings.SetString("enterPukTitle", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_ENTER_PUK_TITLE)); - strings.SetString("enterPukWarning", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_ENTER_PUK_WARNING)); - // TODO(nkostylev): Pass carrier name if we know that. - strings.SetString("enterPukMessage", l10n_util::GetStringFUTF16( - IDS_SIM_UNLOCK_ENTER_PUK_MESSAGE, - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_DEFAULT_CARRIER))); - strings.SetString("choosePinTitle", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_CHOOSE_PIN_TITLE)); - strings.SetString("choosePinMessage", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_CHOOSE_PIN_MESSAGE)); - strings.SetString( - "newPin", l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_CHANGE_PIN_NEW_PIN)); - strings.SetString("retypeNewPin", l10n_util::GetStringUTF16( - IDS_SIM_UNLOCK_CHANGE_PIN_RETYPE_PIN)); - strings.SetString( - "pinsDontMatchMessage", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_PINS_DONT_MATCH_ERROR)); - strings.SetString("noPukTriesLeft", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_NO_PUK_TRIES_LEFT_MESSAGE)); - strings.SetString("simDisabledTitle", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_SIM_DISABLED_TITLE)); - strings.SetString("simDisabledMessage", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_SIM_DISABLED_MESSAGE)); - - strings.SetString("changePinTitle", - l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_CHANGE_PIN_TITLE)); - strings.SetString("changePinMessage", l10n_util::GetStringUTF16( - IDS_SIM_UNLOCK_CHANGE_PIN_MESSAGE)); - strings.SetString( - "oldPin", l10n_util::GetStringUTF16(IDS_SIM_UNLOCK_CHANGE_PIN_OLD_PIN)); - - const std::string& app_locale = g_browser_process->GetApplicationLocale(); - webui::SetLoadTimeDataDefaults(app_locale, &strings); - - static const base::StringPiece html( - ui::ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_SIM_UNLOCK_HTML)); - - std::string full_html = webui::GetI18nTemplateHtml(html, &strings); - callback.Run(base::RefCountedString::TakeString(&full_html)); -} - -// SimUnlockHandler ------------------------------------------------------------ - -SimUnlockHandler::SimUnlockHandler() - : state_(SIM_UNLOCK_LOADING), - dialog_mode_(SimDialogDelegate::SIM_DIALOG_UNLOCK), - pending_pin_operation_(false), - weak_ptr_factory_(this) { - if (GetNetworkStateHandler() - ->GetTechnologyState(NetworkTypePattern::Cellular()) != - NetworkStateHandler::TECHNOLOGY_UNAVAILABLE) - GetNetworkStateHandler()->AddObserver(this, FROM_HERE); -} - -SimUnlockHandler::~SimUnlockHandler() { - GetNetworkStateHandler()->RemoveObserver(this, FROM_HERE); -} - -void SimUnlockHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback(kJsApiChangePinCode, - base::Bind(&SimUnlockHandler::HandleChangePinCode, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kJsApiEnterPinCode, - base::Bind(&SimUnlockHandler::HandleEnterPinCode, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kJsApiEnterPukCode, - base::Bind(&SimUnlockHandler::HandleEnterPukCode, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kJsApiProceedToPukInput, - base::Bind(&SimUnlockHandler::HandleProceedToPukInput, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kJsApiSimStatusInitialize, - base::Bind(&SimUnlockHandler::HandleSimStatusInitialize, - base::Unretained(this))); -} - -void SimUnlockHandler::DeviceListChanged() { - const DeviceState* cellular_device = GetCellularDevice(); - if (!cellular_device) { - LOG(WARNING) << "Cellular device with path '" << cellular_device_path_ - << "' disappeared."; - ProcessSimCardState(NULL); - return; - } - - // Process the SIM card state only if the lock state changed. - if (cellular_device->sim_lock_type() == sim_lock_type_) - return; - - sim_lock_type_ = cellular_device->sim_lock_type(); - uint32_t retries_left = cellular_device->sim_retries_left(); - VLOG(1) << "OnNetworkDeviceSimLockChanged, lock: " << sim_lock_type_ - << ", retries: " << retries_left; - // There's a pending PIN operation. - // Wait for it to finish and refresh state then. - if (!pending_pin_operation_) - ProcessSimCardState(cellular_device); -} - -void SimUnlockHandler::OnPinOperationCompleted(PinOperationError error) { - pending_pin_operation_ = false; - VLOG(1) << "OnPinOperationCompleted, error: " << error; - const DeviceState* cellular = GetCellularDevice(); - if (!cellular) { - VLOG(1) << "Cellular device disappeared. Dismissing dialog."; - ProcessSimCardState(NULL); - return; - } - if (state_ == SIM_NOT_LOCKED_ASK_PIN && error == PIN_ERROR_NONE) { - CHECK(dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON || - dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF); - // Dialog will close itself. - state_ = SIM_ABSENT_NOT_LOCKED; - } else if (state_ == SIM_NOT_LOCKED_CHANGE_PIN && error == PIN_ERROR_NONE) { - CHECK(dialog_mode_ == SimDialogDelegate::SIM_DIALOG_CHANGE_PIN); - // Dialog will close itself. - state_ = SIM_ABSENT_NOT_LOCKED; - } - // If previous EnterPIN was last PIN attempt and SIMLock state was already - // processed by OnNetworkDeviceChanged, let dialog stay on - // NO_PIN_RETRIES_LEFT step. - if (!(state_ == SIM_LOCKED_NO_PIN_TRIES_LEFT && error == PIN_ERROR_BLOCKED)) - ProcessSimCardState(cellular); -} - -const DeviceState* SimUnlockHandler::GetCellularDevice() { - return GetNetworkStateHandler()->GetDeviceState(cellular_device_path_); -} - -void SimUnlockHandler::EnterCode(const std::string& code, - SimUnlockCode code_type) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - pending_pin_operation_ = true; - - switch (code_type) { - case CODE_PIN: - if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON || - dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF) { - if (!sim_lock_type_.empty()) { - // If SIM is locked/absent, change RequirePin UI is not accessible. - NOTREACHED() << - "Changing RequirePin pref on locked / uninitialized SIM."; - } - ChangeRequirePin( - dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON, - code); - } else if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_CHANGE_PIN) { - if (!sim_lock_type_.empty()) { - // If SIM is locked/absent, changing PIN UI is not accessible. - NOTREACHED() << "Changing PIN on locked / uninitialized SIM."; - } - ChangePin(code, new_pin_); - } else { - EnterPin(code); - } - break; - case CODE_PUK: - DCHECK(!new_pin_.empty()); - UnblockPin(code, new_pin_); - break; - } -} - -void SimUnlockHandler::ChangeRequirePin(bool require_pin, - const std::string& pin) { - const DeviceState* cellular = GetCellularDevice(); - if (!cellular) { - NOTREACHED() << "Calling RequirePin method w/o cellular device."; - return; - } - std::string operation_name = "ChangeRequirePin"; - NET_LOG_USER(operation_name, cellular->path()); - GetNetworkDeviceHandler()->RequirePin( - cellular->path(), - require_pin, - pin, - base::Bind(&SimUnlockHandler::PinOperationSuccessCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name), - base::Bind(&SimUnlockHandler::PinOperationErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name)); -} - -void SimUnlockHandler::EnterPin(const std::string& pin) { - const DeviceState* cellular = GetCellularDevice(); - if (!cellular) { - NOTREACHED() << "Calling RequirePin method w/o cellular device."; - return; - } - std::string operation_name = "EnterPin"; - NET_LOG_USER(operation_name, cellular->path()); - GetNetworkDeviceHandler()->EnterPin( - cellular->path(), - pin, - base::Bind(&SimUnlockHandler::PinOperationSuccessCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name), - base::Bind(&SimUnlockHandler::PinOperationErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name)); -} - -void SimUnlockHandler::ChangePin(const std::string& old_pin, - const std::string& new_pin) { - const DeviceState* cellular = GetCellularDevice(); - if (!cellular) { - NOTREACHED() << "Calling RequirePin method w/o cellular device."; - return; - } - std::string operation_name = "ChangePin"; - NET_LOG_USER(operation_name, cellular->path()); - GetNetworkDeviceHandler()->ChangePin( - cellular->path(), - old_pin, - new_pin, - base::Bind(&SimUnlockHandler::PinOperationSuccessCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name), - base::Bind(&SimUnlockHandler::PinOperationErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name)); -} - -void SimUnlockHandler::UnblockPin(const std::string& puk, - const std::string& new_pin) { - const DeviceState* cellular = GetCellularDevice(); - if (!cellular) { - NOTREACHED() << "Calling RequirePin method w/o cellular device."; - return; - } - std::string operation_name = "UnblockPin"; - NET_LOG_USER(operation_name, cellular->path()); - GetNetworkDeviceHandler()->UnblockPin( - cellular->path(), - puk, - new_pin, - base::Bind(&SimUnlockHandler::PinOperationSuccessCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name), - base::Bind(&SimUnlockHandler::PinOperationErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - operation_name)); -} - -void SimUnlockHandler::PinOperationSuccessCallback( - const std::string& operation_name) { - NET_LOG_DEBUG("Pin operation successful.", operation_name); - OnPinOperationCompleted(PIN_ERROR_NONE); -} - -void SimUnlockHandler::PinOperationErrorCallback( - const std::string& operation_name, - const std::string& error_name, - std::unique_ptr<base::DictionaryValue> error_data) { - NET_LOG_ERROR("Pin operation failed: " + error_name, operation_name); - PinOperationError pin_error; - if (error_name == NetworkDeviceHandler::kErrorIncorrectPin || - error_name == NetworkDeviceHandler::kErrorPinRequired) - pin_error = PIN_ERROR_INCORRECT_CODE; - else if (error_name == NetworkDeviceHandler::kErrorPinBlocked) - pin_error = PIN_ERROR_BLOCKED; - else - pin_error = PIN_ERROR_UNKNOWN; - OnPinOperationCompleted(pin_error); -} - -void SimUnlockHandler::HandleChangePinCode(const base::ListValue* args) { - const size_t kChangePinParamCount = 2; - std::string pin; - std::string new_pin; - if (args->GetSize() != kChangePinParamCount || - !args->GetString(0, &pin) || - !args->GetString(1, &new_pin)) { - NOTREACHED(); - return; - } - new_pin_ = new_pin; - HandleEnterCode(CODE_PIN, pin); -} - -void SimUnlockHandler::HandleEnterCode(SimUnlockCode code_type, - const std::string& code) { - scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), code, code_type); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&TaskProxy::HandleEnterCode, task.get())); -} - -void SimUnlockHandler::HandleEnterPinCode(const base::ListValue* args) { - const size_t kEnterPinParamCount = 1; - std::string pin; - if (args->GetSize() != kEnterPinParamCount || !args->GetString(0, &pin)) { - NOTREACHED(); - return; - } - HandleEnterCode(CODE_PIN, pin); -} - -void SimUnlockHandler::HandleEnterPukCode(const base::ListValue* args) { - const size_t kEnterPukParamCount = 2; - std::string puk; - std::string new_pin; - if (args->GetSize() != kEnterPukParamCount || - !args->GetString(0, &puk) || - !args->GetString(1, &new_pin)) { - NOTREACHED(); - return; - } - new_pin_ = new_pin; - HandleEnterCode(CODE_PUK, puk); -} - -void SimUnlockHandler::HandleProceedToPukInput(const base::ListValue* args) { - const size_t kProceedToPukInputParamCount = 0; - if (args->GetSize() != kProceedToPukInputParamCount) { - NOTREACHED(); - return; - } - scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr()); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&TaskProxy::HandleProceedToPukInput, task.get())); -} - -void SimUnlockHandler::HandleSimStatusInitialize(const base::ListValue* args) { - const size_t kSimStatusInitializeParamCount = 1; - double mode; - if (args->GetSize() != kSimStatusInitializeParamCount || - !args->GetDouble(0, &mode)) { - NOTREACHED(); - return; - } - dialog_mode_ = static_cast<SimDialogDelegate::SimDialogMode>(mode); - VLOG(1) << "Initializing SIM dialog in mode: " << dialog_mode_; - scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr()); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&TaskProxy::HandleInitialize, task.get())); -} - -void SimUnlockHandler::InitializeSimStatus() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - // TODO(armansito): For now, we're initializing the device path to the first - // available cellular device. We should try to obtain a specific device here, - // as there can be multiple cellular devices present. - const DeviceState* cellular_device = - GetNetworkStateHandler() - ->GetDeviceStateByType(NetworkTypePattern::Cellular()); - if (cellular_device) { - cellular_device_path_ = cellular_device->path(); - sim_lock_type_ = cellular_device->sim_lock_type(); - } - ProcessSimCardState(cellular_device); -} - -void SimUnlockHandler::ProceedToPukInput() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - ProcessSimCardState(GetCellularDevice()); -} - -void SimUnlockHandler::ProcessSimCardState( - const DeviceState* cellular) { - std::string error_msg; - if (cellular) { - uint32_t retries_left = cellular->sim_retries_left(); - VLOG(1) << "Current state: " << state_ << " lock_type: " << sim_lock_type_ - << " retries: " << retries_left; - switch (state_) { - case SIM_UNLOCK_LOADING: - if (sim_lock_type_ == shill::kSIMLockPin) { - state_ = SIM_LOCKED_PIN; - } else if (sim_lock_type_ == shill::kSIMLockPuk) { - if (retries_left > 0) - state_ = SIM_LOCKED_PUK; - else - state_ = SIM_DISABLED; - } else if (sim_lock_type_.empty()) { - if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON || - dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF) { - state_ = SIM_NOT_LOCKED_ASK_PIN; - } else if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_CHANGE_PIN) { - state_ = SIM_NOT_LOCKED_CHANGE_PIN; - } else { - state_ = SIM_ABSENT_NOT_LOCKED; - } - } else { - // SIM_UNKNOWN: when SIM status is not initialized (should not happen, - // since this UI is accessible when SIM is initialized) - // or SIM card is absent. In latter case just close dialog. - state_ = SIM_ABSENT_NOT_LOCKED; - } - break; - case SIM_ABSENT_NOT_LOCKED: - // Dialog will close itself in this case. - break; - case SIM_NOT_LOCKED_ASK_PIN: - case SIM_NOT_LOCKED_CHANGE_PIN: - // We always start in these states when SIM is unlocked. - // So if we get here while still being UNLOCKED, - // that means entered PIN was incorrect. - if (sim_lock_type_.empty()) { - error_msg = kErrorPin; - } else if (sim_lock_type_ == shill::kSIMLockPuk) { - state_ = SIM_LOCKED_NO_PIN_TRIES_LEFT; - } else { - NOTREACHED() - << "Change PIN / Set lock mode with unexpected SIM lock state"; - state_ = SIM_ABSENT_NOT_LOCKED; - } - break; - case SIM_LOCKED_PIN: - if (sim_lock_type_ == shill::kSIMLockPuk) { - state_ = SIM_LOCKED_NO_PIN_TRIES_LEFT; - } else if (sim_lock_type_ == shill::kSIMLockPin) { - // Still locked with PIN. - error_msg = kErrorPin; - } else { - state_ = SIM_ABSENT_NOT_LOCKED; - } - break; - case SIM_LOCKED_NO_PIN_TRIES_LEFT: - // Proceed user to PUK input. - state_ = SIM_LOCKED_PUK; - break; - case SIM_LOCKED_PUK: - if (sim_lock_type_ != shill::kSIMLockPin && - sim_lock_type_ != shill::kSIMLockPuk) { - state_ = SIM_ABSENT_NOT_LOCKED; - } else if (retries_left == 0) { - state_ = SIM_LOCKED_NO_PUK_TRIES_LEFT; - } - // Otherwise SIM card is still locked with PUK code. - // Dialog will display enter PUK screen with an updated retries count. - break; - case SIM_LOCKED_NO_PUK_TRIES_LEFT: - case SIM_DISABLED: - // User will close dialog manually. - break; - } - } else { - VLOG(1) << "Cellular device is absent."; - // No cellular device, should close dialog. - state_ = SIM_ABSENT_NOT_LOCKED; - } - VLOG(1) << "New state: " << state_; - UpdatePage(cellular, error_msg); -} - -void SimUnlockHandler::UpdatePage(const DeviceState* cellular, - const std::string& error_msg) { - base::DictionaryValue sim_dict; - if (cellular) - sim_dict.SetInteger(kTriesLeft, cellular->sim_retries_left()); - sim_dict.SetInteger(kState, state_); - if (!error_msg.empty()) - sim_dict.SetString(kError, error_msg); - else - sim_dict.SetString(kError, kErrorOk); - web_ui()->CallJavascriptFunctionUnsafe(kJsApiSimStatusChanged, sim_dict); -} - -// SimUnlockUI ----------------------------------------------------------------- - -SimUnlockUI::SimUnlockUI(content::WebUI* web_ui) : WebUIController(web_ui) { - web_ui->AddMessageHandler(base::MakeUnique<SimUnlockHandler>()); - SimUnlockUIHTMLSource* html_source = new SimUnlockUIHTMLSource(); - - // Set up the chrome://sim-unlock/ source. - Profile* profile = Profile::FromWebUI(web_ui); - content::URLDataSource::Add(profile, html_source); -} - -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/sim_unlock_ui.h b/chrome/browser/ui/webui/chromeos/sim_unlock_ui.h deleted file mode 100644 index f7b03d8..0000000 --- a/chrome/browser/ui/webui/chromeos/sim_unlock_ui.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_SIM_UNLOCK_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_SIM_UNLOCK_UI_H_ - -#include "base/macros.h" -#include "content/public/browser/web_ui_controller.h" - -namespace chromeos { - -// A custom WebUI that defines datasource for SIM unlock dialog that is used -// in Chrome OS for specific tasks: -// - Unlock SIM card (enter PIN/PUK codes). -// - Display "SIM card is blocked" message when there're no PUK tries left. -class SimUnlockUI : public content::WebUIController { - public: - explicit SimUnlockUI(content::WebUI* web_ui); - - private: - DISALLOW_COPY_AND_ASSIGN(SimUnlockUI); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_SIM_UNLOCK_UI_H_
diff --git a/chrome/browser/ui/webui/welcome_win10_handler.cc b/chrome/browser/ui/webui/welcome_win10_handler.cc index bb74e7d..6c28c935 100644 --- a/chrome/browser/ui/webui/welcome_win10_handler.cc +++ b/chrome/browser/ui/webui/welcome_win10_handler.cc
@@ -15,6 +15,8 @@ #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" #include "url/gurl.h" namespace { @@ -43,6 +45,13 @@ is_pinned); } +// Returns a new Connector that can be used on a different thread. +std::unique_ptr<service_manager::Connector> GetClonedConnector() { + return content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->Clone(); +} + } // namespace WelcomeWin10Handler::WelcomeWin10Handler(bool inline_style_variant) @@ -72,7 +81,8 @@ base::Closure error_callback = base::Bind(&RecordPinnedResult, histogram_suffix, false, false); shell_integration::win::GetIsPinnedToTaskbarState( - error_callback, base::Bind(&RecordPinnedResult, histogram_suffix)); + GetClonedConnector(), error_callback, + base::Bind(&RecordPinnedResult, histogram_suffix)); } } @@ -139,7 +149,7 @@ weak_ptr_factory_.GetWeakPtr(), false, true); shell_integration::win::GetIsPinnedToTaskbarState( - error_callback, + GetClonedConnector(), error_callback, base::Bind(&WelcomeWin10Handler::OnIsPinnedToTaskbarResult, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index 872978e..e51b53e 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -102,7 +102,10 @@ "gltf_asset.h", "gltf_parser.cc", "gltf_parser.h", + "model/model.cc", "model/model.h", + "model/omnibox_suggestions.cc", + "model/omnibox_suggestions.h", "service/vr_device_manager.cc", "service/vr_device_manager.h", "service/vr_display_host.cc", @@ -151,6 +154,7 @@ "//chrome/browser/resources:vr_shell_resources", "//chrome/browser/vr/vector_icons", "//chrome/common:constants", + "//components/omnibox/browser", "//components/security_state/core", "//components/strings", "//components/toolbar",
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h index d3796b0f..70488676 100644 --- a/chrome/browser/vr/elements/ui_element_name.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -68,6 +68,7 @@ kSpeechRecognitionPromptInnerCircle, kSpeechRecognitionPromptMicrophoneIcon, kSpeechRecognitionPromptBackplane, + kSuggestionLayout, }; } // namespace vr
diff --git a/chrome/browser/vr/model/model.cc b/chrome/browser/vr/model/model.cc new file mode 100644 index 0000000..994ec49 --- /dev/null +++ b/chrome/browser/vr/model/model.cc
@@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/model/model.h" + +namespace vr { + +Model::Model() {} + +Model::~Model() {} + +} // namespace vr
diff --git a/chrome/browser/vr/model/model.h b/chrome/browser/vr/model/model.h index 6908f15e..5260d17 100644 --- a/chrome/browser/vr/model/model.h +++ b/chrome/browser/vr/model/model.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_VR_MODEL_MODEL_H_ #define CHROME_BROWSER_VR_MODEL_MODEL_H_ +#include "chrome/browser/vr/model/omnibox_suggestions.h" + namespace vr { // As we wait for WebVR frames, we may pass through the following states. @@ -24,6 +26,9 @@ }; struct Model { + Model(); + ~Model(); + bool loading = false; float load_progress = 0.0f; @@ -32,6 +37,8 @@ bool recognizing_speech = false; int speech_recognition_state = 0; + + std::vector<OmniboxSuggestion> omnibox_suggestions; }; } // namespace vr
diff --git a/chrome/browser/vr/model/omnibox_suggestions.cc b/chrome/browser/vr/model/omnibox_suggestions.cc new file mode 100644 index 0000000..c73ab97 --- /dev/null +++ b/chrome/browser/vr/model/omnibox_suggestions.cc
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/model/omnibox_suggestions.h" + +namespace vr { + +OmniboxSuggestion::OmniboxSuggestion(const base::string16& new_content, + const base::string16& new_description, + AutocompleteMatch::Type new_type) + : content(new_content), description(new_description), type(new_type) {} + +OmniboxSuggestions::OmniboxSuggestions() {} + +OmniboxSuggestions::~OmniboxSuggestions() {} + +} // namespace vr
diff --git a/chrome/browser/vr/model/omnibox_suggestions.h b/chrome/browser/vr/model/omnibox_suggestions.h new file mode 100644 index 0000000..6dedff0e --- /dev/null +++ b/chrome/browser/vr/model/omnibox_suggestions.h
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VR_MODEL_OMNIBOX_SUGGESTIONS_H_ +#define CHROME_BROWSER_VR_MODEL_OMNIBOX_SUGGESTIONS_H_ + +#include "base/strings/string16.h" +#include "components/omnibox/browser/autocomplete_match.h" + +namespace vr { + +struct OmniboxSuggestion { + OmniboxSuggestion(const base::string16& new_content, + const base::string16& new_description, + AutocompleteMatch::Type new_type); + + base::string16 content; + base::string16 description; + AutocompleteMatch::Type type; +}; + +struct OmniboxSuggestions { + OmniboxSuggestions(); + ~OmniboxSuggestions(); + + std::vector<OmniboxSuggestion> suggestions; +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_MODEL_OMNIBOX_SUGGESTIONS_H_
diff --git a/chrome/browser/vr/test/ui_scene_manager_test.cc b/chrome/browser/vr/test/ui_scene_manager_test.cc index c36fec5..c8a341a9 100644 --- a/chrome/browser/vr/test/ui_scene_manager_test.cc +++ b/chrome/browser/vr/test/ui_scene_manager_test.cc
@@ -120,6 +120,21 @@ return true; } +int UiSceneManagerTest::NumVisibleChildren(UiElementName name) const { + auto* root = scene_->GetUiElementByName(name); + EXPECT_NE(root, nullptr); + if (!root) { + return 0; + } + int visible = 0; + for (const auto& element : *root) { + if (element.IsVisible()) { + visible++; + } + } + return visible; +} + bool UiSceneManagerTest::VerifyRequiresLayout( const std::set<UiElementName>& names, bool requires_layout) const {
diff --git a/chrome/browser/vr/test/ui_scene_manager_test.h b/chrome/browser/vr/test/ui_scene_manager_test.h index b86fd9b..b368b17b 100644 --- a/chrome/browser/vr/test/ui_scene_manager_test.h +++ b/chrome/browser/vr/test/ui_scene_manager_test.h
@@ -59,6 +59,9 @@ bool VerifyVisibility(const std::set<UiElementName>& names, bool visible) const; + // Count the number of elements in the named element's subtree. + int NumVisibleChildren(UiElementName name) const; + // Return false if not all elements in the set match the specified requires // layout state. Other elements are ignored. bool VerifyRequiresLayout(const std::set<UiElementName>& names,
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 6ea2547..3cd5fdc 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -8,7 +8,10 @@ #include "base/memory/ptr_util.h" #include "base/numerics/ranges.h" #include "base/path_service.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/vr/model/model.h" +#include "chrome/browser/vr/model/omnibox_suggestions.h" #include "chrome/browser/vr/test/constants.h" #include "chrome/browser/vr/toolbar_state.h" #include "chrome/browser/vr/ui.h" @@ -18,6 +21,7 @@ #include "chrome/browser/vr/ui_scene.h" #include "chrome/browser/vr/ui_scene_manager.h" #include "chrome/browser/vr/vr_shell_renderer.h" +#include "components/omnibox/browser/vector_icons.h" #include "components/security_state/core/security_state.h" #include "components/toolbar/vector_icons.h" #include "third_party/WebKit/public/platform/WebGestureEvent.h" @@ -118,6 +122,10 @@ incognito_ = !incognito_; ui_->SetIncognito(incognito_); break; + case ui::DomCode::US_S: { + CreateFakeOmniboxSuggestions(); + break; + } default: break; } @@ -211,6 +219,21 @@ return texture_id; } +void VrTestContext::CreateFakeOmniboxSuggestions() { + // Every time this method is called, change the number of suggestions shown. + static int num_suggestions = 0; + num_suggestions = (num_suggestions + 1) % 4; + + auto result = base::MakeUnique<OmniboxSuggestions>(); + for (int i = 0; i < num_suggestions; i++) { + result->suggestions.emplace_back(OmniboxSuggestion( + base::UTF8ToUTF16("Suggestion ") + base::IntToString16(i + 1), + base::UTF8ToUTF16("Description text"), + AutocompleteMatch::Type::VOICE_SUGGEST)); + } + ui_->SetOmniboxSuggestions(std::move(result)); +} + void VrTestContext::OnContentEnter(const gfx::PointF& normalized_hit_point) {} void VrTestContext::OnContentLeave() {}
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h index 4da6f471..5b311b4 100644 --- a/chrome/browser/vr/testapp/vr_test_context.h +++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -64,6 +64,7 @@ private: unsigned int CreateFakeContentTexture(); + void CreateFakeOmniboxSuggestions(); std::unique_ptr<Ui> ui_; gfx::Size window_size_;
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index 4d075fc..c930f86e 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -7,6 +7,7 @@ #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/vr/model/model.h" +#include "chrome/browser/vr/model/omnibox_suggestions.h" #include "chrome/browser/vr/speech_recognizer.h" #include "chrome/browser/vr/ui_input_manager.h" #include "chrome/browser/vr/ui_interface.h" @@ -106,6 +107,11 @@ model_->speech_recognition_state = new_state; } +void Ui::SetOmniboxSuggestions( + std::unique_ptr<OmniboxSuggestions> suggestions) { + model_->omnibox_suggestions = suggestions->suggestions; +} + bool Ui::ShouldRenderWebVr() { return scene_manager_->ShouldRenderWebVr(); }
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h index bdabdecf..e38d9f4 100644 --- a/chrome/browser/vr/ui.h +++ b/chrome/browser/vr/ui.h
@@ -26,6 +26,8 @@ namespace vr { +struct OmniboxSuggestions; + struct UiInitialState { bool in_cct = false; bool in_web_vr = false; @@ -80,6 +82,8 @@ void OnWebVrTimedOut() override; void OnWebVrTimeoutImminent() override; + void SetOmniboxSuggestions(std::unique_ptr<OmniboxSuggestions> suggestions); + private: // This state may be further abstracted into a SkiaUi object. std::unique_ptr<vr::UiScene> scene_;
diff --git a/chrome/browser/vr/ui_scene.cc b/chrome/browser/vr/ui_scene.cc index 674768d..9baa2db5 100644 --- a/chrome/browser/vr/ui_scene.cc +++ b/chrome/browser/vr/ui_scene.cc
@@ -38,8 +38,11 @@ CHECK_GE(element->id(), 0); CHECK_EQ(GetUiElementById(element->id()), nullptr); CHECK_GE(element->draw_phase(), 0); - if (gl_initialized_) - element->Initialize(); + if (gl_initialized_) { + for (auto& child : *element) { + child.Initialize(); + } + } GetUiElementByName(parent)->AddChild(std::move(element)); is_dirty_ = true; }
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index ef72d99..f239889 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -167,6 +167,14 @@ static constexpr float kVoiceSearchButtonXOffset = 0.25f; +static constexpr float kSuggestionGap = 0.01f; +static constexpr float kSuggestionLineGap = 0.01f; +static constexpr float kSuggestionIconGap = 0.01f; +static constexpr float kSuggestionIconSize = 0.1f; +static constexpr float kSuggestionTextFieldWidth = 0.3f; +static constexpr float kSuggestionContentTextHeight = 0.02f; +static constexpr float kSuggestionDescriptionTextHeight = 0.015f; + } // namespace vr #endif // CHROME_BROWSER_VR_UI_SCENE_CONSTANTS_H_
diff --git a/chrome/browser/vr/ui_scene_manager.cc b/chrome/browser/vr/ui_scene_manager.cc index ec4e622d..86303633 100644 --- a/chrome/browser/vr/ui_scene_manager.cc +++ b/chrome/browser/vr/ui_scene_manager.cc
@@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "base/numerics/math_constants.h" #include "chrome/browser/vr/databinding/binding.h" +#include "chrome/browser/vr/databinding/vector_binding.h" #include "chrome/browser/vr/elements/button.h" #include "chrome/browser/vr/elements/content_element.h" #include "chrome/browser/vr/elements/draw_phase.h" @@ -72,6 +73,66 @@ base::Unretained(text)))); } +typedef LinearLayout SuggestionItem; +typedef VectorBinding<OmniboxSuggestion, SuggestionItem> SuggestionSetBinding; +typedef typename SuggestionSetBinding::ElementBinding SuggestionBinding; + +void OnSuggestionModelAdded(UiScene* scene, + SuggestionBinding* element_binding) { + auto icon = base::MakeUnique<VectorIcon>(100); + icon->SetVisible(true); + icon->SetSize(kSuggestionIconSize, kSuggestionIconSize); + icon->set_draw_phase(kPhaseForeground); + VectorIcon* p_icon = icon.get(); + + auto content_text = base::MakeUnique<Text>(512, kSuggestionContentTextHeight, + kSuggestionTextFieldWidth); + content_text->set_draw_phase(kPhaseForeground); + content_text->SetVisible(true); + content_text->SetTextAlignment(UiTexture::kTextAlignmentLeft); + Text* p_content_text = content_text.get(); + + auto description_text = base::MakeUnique<Text>( + 512, kSuggestionDescriptionTextHeight, kSuggestionTextFieldWidth); + description_text->set_draw_phase(kPhaseForeground); + description_text->SetVisible(true); + description_text->SetTextAlignment(UiTexture::kTextAlignmentLeft); + Text* p_description_text = description_text.get(); + + auto text_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown); + text_layout->set_hit_testable(false); + text_layout->set_margin(kSuggestionLineGap); + text_layout->AddChild(std::move(content_text)); + text_layout->AddChild(std::move(description_text)); + text_layout->SetVisible(true); + + auto suggestion_layout = base::MakeUnique<LinearLayout>(LinearLayout::kRight); + suggestion_layout->set_hit_testable(false); + suggestion_layout->set_margin(kSuggestionIconGap); + suggestion_layout->SetVisible(true); + suggestion_layout->AddChild(std::move(icon)); + suggestion_layout->AddChild(std::move(text_layout)); + + element_binding->set_view(suggestion_layout.get()); + + element_binding->bindings().push_back( + VR_BIND_FUNC(base::string16, SuggestionBinding, element_binding, + model()->content, Text, p_content_text, SetText)); + element_binding->bindings().push_back( + VR_BIND_FUNC(base::string16, SuggestionBinding, element_binding, + model()->description, Text, p_description_text, SetText)); + element_binding->bindings().push_back( + VR_BIND(AutocompleteMatch::Type, SuggestionBinding, element_binding, + model()->type, VectorIcon, p_icon, + SetIcon(AutocompleteMatch::TypeToVectorIcon(value)))); + + scene->AddUiElement(kSuggestionLayout, std::move(suggestion_layout)); +} + +void OnSuggestionModelRemoved(UiScene* scene, SuggestionBinding* binding) { + scene->RemoveUiElement(binding->view()->id()); +} + } // namespace UiSceneManager::UiSceneManager(UiBrowserInterface* browser, @@ -96,6 +157,7 @@ CreateWebVRExitWarning(); CreateSystemIndicators(); CreateUrlBar(model); + CreateSuggestionList(model); CreateWebVrUrlToast(); CreateCloseButton(); CreateScreenDimmer(); @@ -614,6 +676,27 @@ scene_->AddUiElement(kLoadingIndicator, std::move(indicator_fg)); } +void UiSceneManager::CreateSuggestionList(Model* model) { + auto layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown); + + layout->set_name(kSuggestionLayout); + layout->set_hit_testable(false); + layout->set_y_anchoring(YAnchoring::YTOP); + layout->SetTranslate(0, 0.5, 0.2); + layout->set_margin(kSuggestionGap); + layout->SetVisible(true); + + SuggestionSetBinding::ModelAddedCallback added_callback = + base::Bind(&OnSuggestionModelAdded, base::Unretained(scene_)); + SuggestionSetBinding::ModelRemovedCallback removed_callback = + base::Bind(&OnSuggestionModelRemoved, base::Unretained(scene_)); + + auto binding = base::MakeUnique<SuggestionSetBinding>( + &model->omnibox_suggestions, added_callback, removed_callback); + layout->AddBinding(std::move(binding)); + scene_->AddUiElement(kUrlBar, std::move(layout)); +} + TransientElement* UiSceneManager::AddTransientParent(UiElementName name, UiElementName parent_name, int timeout_seconds,
diff --git a/chrome/browser/vr/ui_scene_manager.h b/chrome/browser/vr/ui_scene_manager.h index ad7801d..fd6ba133 100644 --- a/chrome/browser/vr/ui_scene_manager.h +++ b/chrome/browser/vr/ui_scene_manager.h
@@ -63,6 +63,8 @@ // kExitButton // kUnderDevelopmentNotice // kVoiceSearchButton +// kSuggestionLayout +// (variable number of suggestions) // kScreenDimmer // k2dBrowsingViewportAwareRoot // kExitWarning @@ -148,6 +150,7 @@ void CreateBackground(); void CreateViewportAwareRoot(); void CreateUrlBar(Model* model); + void CreateSuggestionList(Model* model); void CreateWebVrUrlToast(); void CreateCloseButton(); void CreateExitPrompt();
diff --git a/chrome/browser/vr/ui_scene_manager_unittest.cc b/chrome/browser/vr/ui_scene_manager_unittest.cc index 554bd38..269821d9 100644 --- a/chrome/browser/vr/ui_scene_manager_unittest.cc +++ b/chrome/browser/vr/ui_scene_manager_unittest.cc
@@ -686,4 +686,26 @@ EXPECT_TRUE(IsVisible(k2dBrowsingForeground)); } +TEST_F(UiSceneManagerTest, OmniboxSuggestionBindings) { + MakeManager(kNotInCct, kNotInWebVr); + UiElement* container = scene_->GetUiElementByName(kSuggestionLayout); + ASSERT_NE(container, nullptr); + + OnBeginFrame(); + EXPECT_EQ(container->children().size(), 0u); + int initially_visible = NumVisibleChildren(kSuggestionLayout); + + model_->omnibox_suggestions.emplace_back( + OmniboxSuggestion(base::string16(), base::string16(), + AutocompleteMatch::Type::VOICE_SUGGEST)); + OnBeginFrame(); + EXPECT_EQ(container->children().size(), 1u); + EXPECT_GT(NumVisibleChildren(kSuggestionLayout), initially_visible); + + model_->omnibox_suggestions.clear(); + OnBeginFrame(); + EXPECT_EQ(container->children().size(), 0u); + EXPECT_EQ(NumVisibleChildren(kSuggestionLayout), initially_visible); +} + } // namespace vr
diff --git a/chrome/browser/win/chrome_select_file_dialog_factory.cc b/chrome/browser/win/chrome_select_file_dialog_factory.cc index 66f7e35..76c666e 100644 --- a/chrome/browser/win/chrome_select_file_dialog_factory.cc +++ b/chrome/browser/win/chrome_select_file_dialog_factory.cc
@@ -14,9 +14,11 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/win/win_util.h" -#include "chrome/common/shell_handler_win.mojom.h" #include "chrome/grit/generated_resources.h" -#include "content/public/browser/utility_process_mojo_client.h" +#include "chrome/services/util_win/public/interfaces/constants.mojom.h" +#include "chrome/services/util_win/public/interfaces/shell_util_win.mojom.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/win/open_file_name_win.h" #include "ui/shell_dialogs/select_file_dialog_win.h" @@ -27,23 +29,12 @@ constexpr base::Feature kIsolateShellOperations{ "IsolateShellOperations", base::FEATURE_DISABLED_BY_DEFAULT}; -using UtilityProcessClient = - content::UtilityProcessMojoClient<chrome::mojom::ShellHandler>; - -std::unique_ptr<UtilityProcessClient> StartUtilityProcess() { - auto utility_process_client = base::MakeUnique<UtilityProcessClient>( - l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_FILE_DIALOG_NAME)); - - // TODO(crbug.com/618459): should we change the mojo utility client - // to allow an empty error callback? Currently, the client DCHECKs - // if no error callback is set when Start() is called. - utility_process_client->set_error_callback(base::Bind(&base::DoNothing)); - - utility_process_client->set_disable_sandbox(); - - utility_process_client->Start(); - - return utility_process_client; +chrome::mojom::ShellUtilWinPtr BindShellUtilWin() { + chrome::mojom::ShellUtilWinPtr shell_util_win_ptr; + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(chrome::mojom::kUtilWinServiceName, &shell_util_win_ptr); + return shell_util_win_ptr; } } // namespace @@ -66,13 +57,14 @@ if (!base::FeatureList::IsEnabled(kIsolateShellOperations)) return ::GetOpenFileName(ofn) == TRUE; - auto utility_process_client = StartUtilityProcess(); - mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; std::vector<base::FilePath> files; base::FilePath directory; - utility_process_client->service()->CallGetOpenFileName( + // Sync operation, it's OK for the shell_util_win_ptr to go out of scope right + // after the call. + chrome::mojom::ShellUtilWinPtr shell_util_win_ptr = BindShellUtilWin(); + shell_util_win_ptr->CallGetOpenFileName( base::win::HandleToUint32(ofn->hwndOwner), static_cast<uint32_t>(ofn->Flags & ~OFN_ENABLEHOOK), ui::win::OpenFileName::GetFilters(ofn), @@ -92,13 +84,15 @@ if (!base::FeatureList::IsEnabled(kIsolateShellOperations)) return ::GetSaveFileName(ofn) == TRUE; - auto utility_process_client = StartUtilityProcess(); mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; uint32_t filter_index = 0; base::FilePath path; - utility_process_client->service()->CallGetSaveFileName( + // Sync operation, it's OK for the shell_util_win_ptr to go out of scope right + // after the call. + chrome::mojom::ShellUtilWinPtr shell_util_win_ptr = BindShellUtilWin(); + shell_util_win_ptr->CallGetSaveFileName( base::win::HandleToUint32(ofn->hwndOwner), static_cast<uint32_t>(ofn->Flags & ~OFN_ENABLEHOOK), ui::win::OpenFileName::GetFilters(ofn), ofn->nFilterIndex,
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index cf16d53..eaf3792c 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -681,10 +681,7 @@ ] if (is_win) { - sources += [ - "conflicts/module_event_sink_win.mojom", - "shell_handler_win.mojom", - ] + sources += [ "conflicts/module_event_sink_win.mojom" ] } if (is_chromeos) {
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 498e5cd..4d677aea 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -261,10 +261,6 @@ const char kDisableSearchGeolocationDisclosure[] = "disable-search-geolocation-disclosure"; -// Disables Web Notification custom layouts. -const char kDisableWebNotificationCustomLayouts[] = - "disable-web-notification-custom-layouts"; - // Some tests seem to require the application to close when the last // browser window is closed. Thus, we need a switch to force this behavior // for ChromeOS Aura, disable "zero window mode". @@ -383,10 +379,6 @@ // Enables user control over muting tab audio from the tab strip. const char kEnableTabAudioMuting[] = "enable-tab-audio-muting"; -// Enables Web Notification custom layouts. -const char kEnableWebNotificationCustomLayouts[] = - "enable-web-notification-custom-layouts"; - // If the WebRTC logging private API is active, enables WebRTC event logging. const char kEnableWebRtcEventLoggingFromExtension[] = "enable-webrtc-event-logging-from-extension";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index f14eede9..a2149a4 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -90,7 +90,6 @@ extern const char kDisablePromptOnRepost[]; extern const char kDisablePushApiBackgroundMode[]; extern const char kDisableSearchGeolocationDisclosure[]; -extern const char kDisableWebNotificationCustomLayouts[]; extern const char kDisableZeroBrowsersOpenForTests[]; extern const char kDiskCacheDir[]; extern const char kDiskCacheSize[]; @@ -122,7 +121,6 @@ extern const char kEnablePushApiBackgroundMode[]; extern const char kEnableSiteSettings[]; extern const char kEnableTabAudioMuting[]; -extern const char kEnableWebNotificationCustomLayouts[]; extern const char kEnableWebRtcEventLoggingFromExtension[]; extern const char kExtensionContentVerification[]; extern const char kExtensionContentVerificationBootstrap[];
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index 8cf1aff..1d6563c5 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc
@@ -224,6 +224,9 @@ // Accessibility keys. Temporary for http://crbug.com/765490. {"ax_tree_error", kSmallSize}, {"ax_tree_update", kMediumSize}, + + // Temporary for crbug.com/756624. + {"break_iterator", kSmallSize}, }; // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/chrome/common/extensions/api/debugger.json b/chrome/common/extensions/api/debugger.json index c00c749..e935d61e5 100644 --- a/chrome/common/extensions/api/debugger.json +++ b/chrome/common/extensions/api/debugger.json
@@ -27,7 +27,7 @@ "id": "DetachReason", "type": "string", "description": "Connection termination reason.", - "enum": [ "target_closed", "canceled_by_user", "replaced_with_devtools" ] + "enum": [ "target_closed", "canceled_by_user" ] }, { "id": "TargetInfo",
diff --git a/chrome/common/switch_utils.cc b/chrome/common/switch_utils.cc index 29acd4e..21f9bc7 100644 --- a/chrome/common/switch_utils.cc +++ b/chrome/common/switch_utils.cc
@@ -35,8 +35,7 @@ } // namespace -void RemoveSwitchesForAutostart( - std::map<std::string, base::CommandLine::StringType>* switch_list) { +void RemoveSwitchesForAutostart(base::CommandLine::SwitchMap* switch_list) { for (size_t i = 0; i < arraysize(kSwitchesToRemoveOnAutorestart); ++i) switch_list->erase(kSwitchesToRemoveOnAutorestart[i]);
diff --git a/chrome/common/switch_utils.h b/chrome/common/switch_utils.h index df91b2d5..84ce5e74 100644 --- a/chrome/common/switch_utils.h +++ b/chrome/common/switch_utils.h
@@ -13,8 +13,7 @@ namespace switches { // Remove the keys that we shouldn't pass through during restart. -void RemoveSwitchesForAutostart( - std::map<std::string, base::CommandLine::StringType>* switches); +void RemoveSwitchesForAutostart(base::CommandLine::SwitchMap* switches); } // namespace switches
diff --git a/chrome/common/switch_utils_unittest.cc b/chrome/common/switch_utils_unittest.cc index 0b02bc37..b780702 100644 --- a/chrome/common/switch_utils_unittest.cc +++ b/chrome/common/switch_utils_unittest.cc
@@ -21,8 +21,7 @@ base::CommandLine cmd_line(arraysize(argv), argv); EXPECT_FALSE(cmd_line.GetCommandLineString().empty()); - std::map<std::string, base::CommandLine::StringType> switches = - cmd_line.GetSwitches(); + base::CommandLine::SwitchMap switches = cmd_line.GetSwitches(); EXPECT_EQ(5U, switches.size()); switches::RemoveSwitchesForAutostart(&switches); @@ -44,8 +43,7 @@ L" --bar"); EXPECT_FALSE(cmd_line.GetCommandLineString().empty()); - std::map<std::string, base::CommandLine::StringType> switches = - cmd_line.GetSwitches(); + base::CommandLine::SwitchMap switches = cmd_line.GetSwitches(); EXPECT_EQ(5U, switches.size()); switches::RemoveSwitchesForAutostart(&switches); @@ -63,8 +61,7 @@ base::CommandLine cmd_line(arraysize(argv), argv); EXPECT_FALSE(cmd_line.GetCommandLineString().empty()); - std::map<std::string, base::CommandLine::StringType> switches = - cmd_line.GetSwitches(); + base::CommandLine::SwitchMap switches = cmd_line.GetSwitches(); EXPECT_EQ(3U, switches.size()); switches::RemoveSwitchesForAutostart(&switches); @@ -83,8 +80,7 @@ base::CommandLine cmd_line(arraysize(argv), argv); EXPECT_FALSE(cmd_line.GetCommandLineString().empty()); - std::map<std::string, base::CommandLine::StringType> switches = - cmd_line.GetSwitches(); + base::CommandLine::SwitchMap switches = cmd_line.GetSwitches(); EXPECT_EQ(4U, switches.size()); switches::RemoveSwitchesForAutostart(&switches);
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 213270ba..fef1e17 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -209,8 +209,6 @@ const char kChromeUIScreenlockIconURL[] = "chrome://screenlock-icon/"; const char kChromeUISetTimeHost[] = "set-time"; const char kChromeUISetTimeURL[] = "chrome://set-time/"; -const char kChromeUISimUnlockHost[] = "sim-unlock"; -const char kChromeUISimUnlockURL[] = "chrome://sim-unlock/"; const char kChromeUISlowHost[] = "slow"; const char kChromeUISlowTraceHost[] = "slow_trace"; const char kChromeUISlowURL[] = "chrome://slow/";
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index 0248c0b..54b7983 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -206,8 +206,6 @@ extern const char kChromeUIScreenlockIconURL[]; extern const char kChromeUISetTimeHost[]; extern const char kChromeUISetTimeURL[]; -extern const char kChromeUISimUnlockHost[]; -extern const char kChromeUISimUnlockURL[]; extern const char kChromeUISlowHost[]; extern const char kChromeUISlowTraceHost[]; extern const char kChromeUISlowURL[];
diff --git a/chrome/gpu/BUILD.gn b/chrome/gpu/BUILD.gn index 4581690..93bdd8a 100644 --- a/chrome/gpu/BUILD.gn +++ b/chrome/gpu/BUILD.gn
@@ -27,10 +27,6 @@ "gpu_arc_video_decode_accelerator.h", "gpu_arc_video_encode_accelerator.cc", "gpu_arc_video_encode_accelerator.h", - "protected_buffer_manager.cc", - "protected_buffer_manager.h", - "protected_buffer_manager_proxy.cc", - "protected_buffer_manager_proxy.h", ] } }
diff --git a/chrome/gpu/arc_video_decode_accelerator.h b/chrome/gpu/arc_video_decode_accelerator.h index bd1104e..c56d5df 100644 --- a/chrome/gpu/arc_video_decode_accelerator.h +++ b/chrome/gpu/arc_video_decode_accelerator.h
@@ -72,8 +72,6 @@ struct Config { size_t num_input_buffers = 0; uint32_t input_pixel_format = 0; - // If true, only buffers created via AllocateProtectedBuffer() may be used. - bool secure_mode = false; // TODO(owenlin): Add output_pixel_format. For now only the native pixel // format of each VDA on Chromium is supported. }; @@ -113,27 +111,10 @@ // returns SUCCESS iff initialization is successful. virtual Result Initialize(const Config& config, Client* client) = 0; - // Allocates a new protected buffer on accelerator side for the given |port| - // and |index|, the contents of which will be inaccessible to the client. - // The protected buffer will remain valid for at least as long as the resource - // backing the passed |handle_fd| is not released (i.e. there is at least one - // reference on the file backing |handle_fd|. - // - // Usable only if the accelerator has been initialized to run in secure mode. - // Allocation for input will create a protected buffer of at least |size|; - // for output, |size| is ignored, and the currently configured output format - // is used instead to determine the required buffer size and format. - virtual bool AllocateProtectedBuffer(PortType port, - uint32_t index, - base::ScopedFD handle_fd, - size_t size) = 0; - // Assigns a shared memory to be used for the accelerator at the specified // port and index. A buffer must be successfully bound before it can be passed // to the accelerator via UseBuffer(). Already bound buffers may be reused // multiple times without additional bindings. - // Not allowed in secure_mode, where protected buffers have to be allocated - // instead. virtual void BindSharedMemory(PortType port, uint32_t index, base::ScopedFD ashmem_fd, @@ -144,8 +125,6 @@ // port and index. A buffer must be successfully bound before it can be // passed to the accelerator via UseBuffer(). Already bound buffers may be // reused multiple times without additional bindings. - // Not allowed in secure_mode, where protected buffers have to be allocated - // instead. virtual void BindDmabuf( PortType port, uint32_t index, @@ -155,8 +134,6 @@ // Passes a buffer to the accelerator. For input buffer, the accelerator // will process it. For output buffer, the accelerator will output content // to it. - // In secure mode, |port| and |index| must correspond to a protected buffer - // allocated using AllocateProtectedBuffer(). virtual void UseBuffer(PortType port, uint32_t index, const BufferMetadata& metadata) = 0;
diff --git a/chrome/gpu/chrome_arc_video_decode_accelerator.cc b/chrome/gpu/chrome_arc_video_decode_accelerator.cc index 59617a5..16715b663 100644 --- a/chrome/gpu/chrome_arc_video_decode_accelerator.cc +++ b/chrome/gpu/chrome_arc_video_decode_accelerator.cc
@@ -10,9 +10,7 @@ #include "base/numerics/safe_math.h" #include "base/run_loop.h" #include "base/unguessable_token.h" -#include "chrome/gpu/protected_buffer_manager.h" #include "media/base/video_frame.h" -#include "media/gpu/format_utils.h" #include "media/gpu/gpu_video_decode_accelerator_factory.h" namespace chromeos { @@ -43,33 +41,27 @@ ChromeArcVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() = default; -ChromeArcVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() { - if (shm_handle.OwnershipPassesToIPC()) - shm_handle.Close(); -} +ChromeArcVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo( + InputBufferInfo&& other) = default; + +ChromeArcVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() = default; ChromeArcVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo() = default; -ChromeArcVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() { - if (!gpu_memory_buffer_handle.is_null()) { - for (const auto& fd : gpu_memory_buffer_handle.native_pixmap_handle.fds) { - // Close the fd by wrapping it in a ScopedFD and letting - // it fall out of scope. - base::ScopedFD scoped_fd(fd.fd); - } - } -} +ChromeArcVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo( + OutputBufferInfo&& other) = default; + +ChromeArcVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() = + default; ChromeArcVideoDecodeAccelerator::ChromeArcVideoDecodeAccelerator( - const gpu::GpuPreferences& gpu_preferences, - ProtectedBufferManager* protected_buffer_manager) + const gpu::GpuPreferences& gpu_preferences) : arc_client_(nullptr), next_bitstream_buffer_id_(0), output_pixel_format_(media::PIXEL_FORMAT_UNKNOWN), output_buffer_size_(0), requested_num_of_output_buffers_(0), - gpu_preferences_(gpu_preferences), - protected_buffer_manager_(protected_buffer_manager) {} + gpu_preferences_(gpu_preferences) {} ChromeArcVideoDecodeAccelerator::~ChromeArcVideoDecodeAccelerator() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -103,20 +95,13 @@ return ILLEGAL_STATE; } - arc_client_ = client; - if (client_count_ >= kMaxConcurrentClients) { LOG(WARNING) << "Reject to Initialize() due to too many clients: " << client_count_; return INSUFFICIENT_RESOURCES; } - if (config.secure_mode && !protected_buffer_manager_) { - DLOG(ERROR) << "Secure mode unsupported"; - return PLATFORM_FAILURE; - } - - secure_mode_ = config.secure_mode; + arc_client_ = client; if (config.num_input_buffers > kMaxBufferCount) { DLOG(ERROR) << "Request too many buffers: " << config.num_input_buffers; @@ -183,60 +168,6 @@ buffers_pending_import_.resize(number); } -bool ChromeArcVideoDecodeAccelerator::AllocateProtectedBuffer( - PortType port, - uint32_t index, - base::ScopedFD handle_fd, - size_t size) { - DVLOG(5) << "port=" << port << " index=" << index - << " handle=" << handle_fd.get() << " size=" << size; - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - if (!secure_mode_) { - DLOG(ERROR) << "Not in secure mode"; - arc_client_->OnError(INVALID_ARGUMENT); - return false; - } - - if (!ValidatePortAndIndex(port, index)) { - arc_client_->OnError(INVALID_ARGUMENT); - return false; - } - - if (port == PORT_INPUT) { - auto protected_shmem = - protected_buffer_manager_->AllocateProtectedSharedMemory( - std::move(handle_fd), size); - if (!protected_shmem) { - DLOG(ERROR) << "Failed allocating protected shared memory"; - return false; - } - - auto input_info = std::make_unique<InputBufferInfo>(); - input_info->shm_handle = protected_shmem->shm_handle(); - input_info->protected_buffer_handle = std::move(protected_shmem); - input_buffer_info_[index] = std::move(input_info); - } else if (port == PORT_OUTPUT) { - auto protected_pixmap = - protected_buffer_manager_->AllocateProtectedNativePixmap( - std::move(handle_fd), - media::VideoPixelFormatToGfxBufferFormat(output_pixel_format_), - coded_size_); - if (!protected_pixmap) { - DLOG(ERROR) << "Failed allocating a protected pixmap"; - return false; - } - auto output_info = std::make_unique<OutputBufferInfo>(); - output_info->gpu_memory_buffer_handle.type = gfx::NATIVE_PIXMAP; - output_info->gpu_memory_buffer_handle.native_pixmap_handle = - CloneHandleForIPC(protected_pixmap->native_pixmap_handle()); - output_info->protected_buffer_handle = std::move(protected_pixmap); - buffers_pending_import_[index] = std::move(output_info); - } - - return true; -} - void ChromeArcVideoDecodeAccelerator::BindSharedMemory(PortType port, uint32_t index, base::ScopedFD ashmem_fd, @@ -245,13 +176,6 @@ DVLOG(5) << "ArcGVDA::BindSharedMemory, offset: " << offset << ", length: " << length; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - if (secure_mode_) { - DLOG(ERROR) << "not allowed in secure mode"; - arc_client_->OnError(INVALID_ARGUMENT); - return; - } - if (!vda_) { DLOG(ERROR) << "VDA not initialized"; return; @@ -266,14 +190,10 @@ arc_client_->OnError(INVALID_ARGUMENT); return; } - - auto input_info = std::make_unique<InputBufferInfo>(); - input_info->shm_handle = - base::SharedMemoryHandle(base::FileDescriptor(ashmem_fd.release(), true), - length, base::UnguessableToken::Create()); - DCHECK(input_info->shm_handle.OwnershipPassesToIPC()); + InputBufferInfo* input_info = &input_buffer_info_[index]; + input_info->handle = std::move(ashmem_fd); input_info->offset = offset; - input_buffer_info_[index] = std::move(input_info); + input_info->length = length; } bool ChromeArcVideoDecodeAccelerator::VerifyDmabuf( @@ -321,12 +241,6 @@ const std::vector<::arc::VideoFramePlane>& planes) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (secure_mode_) { - DLOG(ERROR) << "not allowed in secure mode"; - arc_client_->OnError(INVALID_ARGUMENT); - return; - } - if (!vda_) { DLOG(ERROR) << "VDA not initialized"; return; @@ -346,19 +260,9 @@ return; } -#if defined(USE_OZONE) - auto output_info = std::make_unique<OutputBufferInfo>(); - output_info->gpu_memory_buffer_handle.type = gfx::NATIVE_PIXMAP; - output_info->gpu_memory_buffer_handle.native_pixmap_handle.fds.emplace_back( - base::FileDescriptor(dmabuf_fd.release(), true)); - for (const auto& plane : planes) { - output_info->gpu_memory_buffer_handle.native_pixmap_handle.planes - .emplace_back(plane.stride, plane.offset, 0, 0); - } - buffers_pending_import_[index] = std::move(output_info); -#else - arc_client_->OnError(PLATFORM_FAILURE); -#endif + OutputBufferInfo& info = buffers_pending_import_[index]; + info.handle = std::move(dmabuf_fd); + info.planes = planes; } void ChromeArcVideoDecodeAccelerator::UseBuffer( @@ -379,44 +283,41 @@ } switch (port) { case PORT_INPUT: { - auto& input_info = input_buffer_info_[index]; - if (!input_info) { - DLOG(ERROR) << "Buffer not initialized"; - arc_client_->OnError(INVALID_ARGUMENT); - return; - } - + InputBufferInfo* input_info = &input_buffer_info_[index]; int32_t bitstream_buffer_id = next_bitstream_buffer_id_; // Mask against 30 bits, to avoid (undefined) wraparound on signed // integer. next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; - - auto duplicated_handle = input_info->shm_handle.Duplicate(); - if (!duplicated_handle.IsValid()) { + int dup_fd = HANDLE_EINTR(dup(input_info->handle.get())); + if (dup_fd < 0) { + DLOG(ERROR) << "dup() failed."; arc_client_->OnError(PLATFORM_FAILURE); return; } - CreateInputRecord(bitstream_buffer_id, index, metadata.timestamp); - vda_->Decode( - media::BitstreamBuffer(bitstream_buffer_id, duplicated_handle, - metadata.bytes_used, input_info->offset)); + base::UnguessableToken guid = base::UnguessableToken::Create(); + vda_->Decode(media::BitstreamBuffer( + bitstream_buffer_id, + base::SharedMemoryHandle(base::FileDescriptor(dup_fd, true), 0u, + guid), + metadata.bytes_used, input_info->offset)); break; } case PORT_OUTPUT: { - auto& output_info = buffers_pending_import_[index]; - if (!output_info) { - DLOG(ERROR) << "Buffer not initialized"; - arc_client_->OnError(INVALID_ARGUMENT); - return; - } - // is_null() is false the first time the buffer is passed to the VDA. + // is_valid() is true for the first time the buffer is passed to the VDA. // In that case, VDA needs to import the buffer first. - if (!output_info->gpu_memory_buffer_handle.is_null()) { - vda_->ImportBufferForPicture(index, - output_info->gpu_memory_buffer_handle); - // VDA takes ownership, so just clear out, don't close the handle. - output_info->gpu_memory_buffer_handle = gfx::GpuMemoryBufferHandle(); + OutputBufferInfo& info = buffers_pending_import_[index]; + if (info.handle.is_valid()) { + gfx::GpuMemoryBufferHandle handle; +#if defined(USE_OZONE) + handle.native_pixmap_handle.fds.emplace_back( + base::FileDescriptor(info.handle.release(), true)); + for (const auto& plane : info.planes) { + handle.native_pixmap_handle.planes.emplace_back(plane.stride, + plane.offset, 0, 0); + } +#endif + vda_->ImportBufferForPicture(index, handle); } else { vda_->ReusePictureBuffer(index); }
diff --git a/chrome/gpu/chrome_arc_video_decode_accelerator.h b/chrome/gpu/chrome_arc_video_decode_accelerator.h index 2da28c2..a520398 100644 --- a/chrome/gpu/chrome_arc_video_decode_accelerator.h +++ b/chrome/gpu/chrome_arc_video_decode_accelerator.h
@@ -19,9 +19,6 @@ namespace chromeos { namespace arc { -class ProtectedBufferManager; -class ProtectedBufferHandle; - // This class is executed in the GPU process. It takes decoding requests from // ARC via IPC channels and translates and sends those requests to an // implementation of media::VideoDecodeAccelerator. It also returns the decoded @@ -31,9 +28,8 @@ public media::VideoDecodeAccelerator::Client, public base::SupportsWeakPtr<ChromeArcVideoDecodeAccelerator> { public: - ChromeArcVideoDecodeAccelerator( - const gpu::GpuPreferences& gpu_preferences, - ProtectedBufferManager* protected_buffer_manager); + explicit ChromeArcVideoDecodeAccelerator( + const gpu::GpuPreferences& gpu_preferences); ~ChromeArcVideoDecodeAccelerator() override; // Implementation of the ArcVideoDecodeAccelerator interface. @@ -41,10 +37,6 @@ const Config& config, ArcVideoDecodeAccelerator::Client* client) override; void SetNumberOfOutputBuffers(size_t number) override; - bool AllocateProtectedBuffer(PortType port, - uint32_t index, - base::ScopedFD handle_fd, - size_t size) override; void BindSharedMemory(PortType port, uint32_t index, base::ScopedFD ashmem_fd, @@ -88,34 +80,28 @@ // The information about the shared memory used as an input buffer. struct InputBufferInfo { - // SharedMemoryHandle for this buffer to be passed to accelerator. - // In non-secure mode, received via BindSharedMemory from the client, - // in secure mode, a handle for the SharedMemory in protected_shmem. - base::SharedMemoryHandle shm_handle; + // The file handle to access the buffer. It is owned by this class and + // should be closed after use. + base::ScopedFD handle; - // Used only in secure mode; handle to the protected buffer backing - // this input buffer. - std::unique_ptr<ProtectedBufferHandle> protected_buffer_handle; - - // Offset to the payload from the beginning of the shared memory buffer. + // The offset of the payload to the beginning of the shared memory. off_t offset = 0; + // The size of the payload in bytes. + size_t length = 0; + InputBufferInfo(); + InputBufferInfo(InputBufferInfo&& other); ~InputBufferInfo(); }; - // The information about the native pixmap used as an output buffer. + // The information about the dmabuf used as an output buffer. struct OutputBufferInfo { - // GpuMemoryBufferHandle for this buffer to be passed to accelerator. - // In non-secure mode, received via BindDmabuf from the client, - // in secure mode, a handle to the NativePixmap in protected_pixmap. - gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle; - - // Used only in secure mode; handle to the protected buffer backing - // this output buffer. - std::unique_ptr<ProtectedBufferHandle> protected_buffer_handle; + base::ScopedFD handle; + std::vector<::arc::VideoFramePlane> planes; OutputBufferInfo(); + OutputBufferInfo(OutputBufferInfo&& other); ~OutputBufferInfo(); }; @@ -169,12 +155,12 @@ std::list<InputRecord> input_records_; // The details of the shared memory of each input buffers. - std::vector<std::unique_ptr<InputBufferInfo>> input_buffer_info_; + std::vector<InputBufferInfo> input_buffer_info_; // To keep those output buffers which have been bound by bindDmabuf() but // haven't been passed to VDA yet. Will call VDA::ImportBufferForPicture() // when those buffers are used for the first time. - std::vector<std::unique_ptr<OutputBufferInfo>> buffers_pending_import_; + std::vector<OutputBufferInfo> buffers_pending_import_; THREAD_CHECKER(thread_checker_); size_t output_buffer_size_; @@ -182,10 +168,7 @@ // The minimal number of requested output buffers. uint32_t requested_num_of_output_buffers_; - bool secure_mode_ = false; - gpu::GpuPreferences gpu_preferences_; - ProtectedBufferManager* protected_buffer_manager_; DISALLOW_COPY_AND_ASSIGN(ChromeArcVideoDecodeAccelerator); };
diff --git a/chrome/gpu/chrome_content_gpu_client.cc b/chrome/gpu/chrome_content_gpu_client.cc index ae7e058c..bcd0060 100644 --- a/chrome/gpu/chrome_content_gpu_client.cc +++ b/chrome/gpu/chrome_content_gpu_client.cc
@@ -22,14 +22,8 @@ #if defined(OS_CHROMEOS) #include "chrome/gpu/gpu_arc_video_decode_accelerator.h" #include "chrome/gpu/gpu_arc_video_encode_accelerator.h" -#include "chrome/gpu/protected_buffer_manager.h" -#include "chrome/gpu/protected_buffer_manager_proxy.h" #include "content/public/common/service_manager_connection.h" #include "services/service_manager/public/cpp/binder_registry.h" -#if defined(USE_OZONE) -#include "ui/ozone/public/ozone_platform.h" -#include "ui/ozone/public/surface_factory_ozone.h" -#endif #endif namespace { @@ -52,10 +46,6 @@ metrics::CallStackProfileParams::MAY_SHUFFLE))) { if (StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) stack_sampling_profiler_.Start(); - -#if defined(OS_CHROMEOS) - protected_buffer_manager_.reset(new chromeos::arc::ProtectedBufferManager()); -#endif } ChromeContentGpuClient::~ChromeContentGpuClient() {} @@ -71,10 +61,6 @@ base::Bind(&ChromeContentGpuClient::CreateArcVideoEncodeAccelerator, base::Unretained(this)), base::ThreadTaskRunnerHandle::Get()); - registry->AddInterface( - base::Bind(&ChromeContentGpuClient::CreateProtectedBufferManager, - base::Unretained(this)), - base::ThreadTaskRunnerHandle::Get()); #endif } @@ -82,13 +68,6 @@ const gpu::GpuPreferences& gpu_preferences) { #if defined(OS_CHROMEOS) gpu_preferences_ = gpu_preferences; -#if defined(USE_OZONE) - ui::OzonePlatform::GetInstance() - ->GetSurfaceFactoryOzone() - ->SetGetProtectedNativePixmapDelegate(base::Bind( - &chromeos::arc::ProtectedBufferManager::GetProtectedNativePixmapFor, - base::Unretained(protected_buffer_manager_.get()))); -#endif #endif metrics::mojom::CallStackProfileCollectorPtr browser_interface; @@ -99,11 +78,12 @@ } #if defined(OS_CHROMEOS) + void ChromeContentGpuClient::CreateArcVideoDecodeAccelerator( ::arc::mojom::VideoDecodeAcceleratorRequest request) { mojo::MakeStrongBinding( base::MakeUnique<chromeos::arc::GpuArcVideoDecodeAccelerator>( - gpu_preferences_, protected_buffer_manager_.get()), + gpu_preferences_), std::move(request)); } @@ -114,12 +94,4 @@ gpu_preferences_), std::move(request)); } - -void ChromeContentGpuClient::CreateProtectedBufferManager( - ::arc::mojom::ProtectedBufferManagerRequest request) { - mojo::MakeStrongBinding( - base::MakeUnique<chromeos::arc::GpuArcProtectedBufferManagerProxy>( - protected_buffer_manager_.get()), - std::move(request)); -} #endif
diff --git a/chrome/gpu/chrome_content_gpu_client.h b/chrome/gpu/chrome_content_gpu_client.h index bbc731f..78abc0e 100644 --- a/chrome/gpu/chrome_content_gpu_client.h +++ b/chrome/gpu/chrome_content_gpu_client.h
@@ -12,16 +12,10 @@ #include "content/public/gpu/content_gpu_client.h" #if defined(OS_CHROMEOS) -#include "components/arc/common/protected_buffer_manager.mojom.h" #include "components/arc/common/video_decode_accelerator.mojom.h" #include "components/arc/common/video_encode_accelerator.mojom.h" #include "gpu/command_buffer/service/gpu_preferences.h" -namespace chromeos { -namespace arc { -class ProtectedBufferManager; -} // namespace arc -} // namespace chromeos #endif class ChromeContentGpuClient : public content::ContentGpuClient { @@ -41,9 +35,6 @@ void CreateArcVideoEncodeAccelerator( ::arc::mojom::VideoEncodeAcceleratorRequest request); - - void CreateProtectedBufferManager( - ::arc::mojom::ProtectedBufferManagerRequest request); #endif // Used to profile process startup. @@ -51,8 +42,6 @@ #if defined(OS_CHROMEOS) gpu::GpuPreferences gpu_preferences_; - std::unique_ptr<chromeos::arc::ProtectedBufferManager> - protected_buffer_manager_; #endif DISALLOW_COPY_AND_ASSIGN(ChromeContentGpuClient);
diff --git a/chrome/gpu/gpu_arc_video_decode_accelerator.cc b/chrome/gpu/gpu_arc_video_decode_accelerator.cc index b94aa8f..d53c3c0 100644 --- a/chrome/gpu/gpu_arc_video_decode_accelerator.cc +++ b/chrome/gpu/gpu_arc_video_decode_accelerator.cc
@@ -98,7 +98,6 @@ chromeos::arc::ArcVideoDecodeAccelerator::Config result; result.num_input_buffers = input->num_input_buffers; result.input_pixel_format = input->input_pixel_format; - result.secure_mode = input->secure_mode; return result; } }; @@ -109,12 +108,9 @@ namespace arc { GpuArcVideoDecodeAccelerator::GpuArcVideoDecodeAccelerator( - const gpu::GpuPreferences& gpu_preferences, - ProtectedBufferManager* protected_buffer_manager) + const gpu::GpuPreferences& gpu_preferences) : gpu_preferences_(gpu_preferences), - accelerator_(std::make_unique<ChromeArcVideoDecodeAccelerator>( - gpu_preferences_, - protected_buffer_manager)) {} + accelerator_(new ChromeArcVideoDecodeAccelerator(gpu_preferences_)) {} GpuArcVideoDecodeAccelerator::~GpuArcVideoDecodeAccelerator() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -170,9 +166,7 @@ LOG(ERROR) << "only decoder is supported"; std::move(callback).Run( ::arc::mojom::VideoDecodeAccelerator::Result::INVALID_ARGUMENT); - return; } - client_ = std::move(client); ArcVideoDecodeAccelerator::Result result = accelerator_->Initialize( config.To<ArcVideoDecodeAccelerator::Config>(), this); @@ -203,26 +197,6 @@ return base::ScopedFD(platform_file); } -void GpuArcVideoDecodeAccelerator::AllocateProtectedBuffer( - ::arc::mojom::PortType port, - uint32_t index, - mojo::ScopedHandle handle, - uint64_t size, - AllocateProtectedBufferCallback callback) { - DVLOG(2) << "port=" << port << ", index=" << index << ", size=" << size; - - base::ScopedFD fd = UnwrapFdFromMojoHandle(std::move(handle)); - if (!fd.is_valid()) { - std::move(callback).Run(false); - return; - } - - bool result = accelerator_->AllocateProtectedBuffer( - static_cast<PortType>(port), index, std::move(fd), size); - - std::move(callback).Run(result); -} - void GpuArcVideoDecodeAccelerator::BindSharedMemory( ::arc::mojom::PortType port, uint32_t index,
diff --git a/chrome/gpu/gpu_arc_video_decode_accelerator.h b/chrome/gpu/gpu_arc_video_decode_accelerator.h index daf6088..078c17d1 100644 --- a/chrome/gpu/gpu_arc_video_decode_accelerator.h +++ b/chrome/gpu/gpu_arc_video_decode_accelerator.h
@@ -19,8 +19,6 @@ namespace chromeos { namespace arc { -class ProtectedBufferManager; - // GpuArcVideoDecodeAccelerator manages life-cycle and IPC message translation // for ArcVideoDecodeAccelerator. // @@ -30,9 +28,8 @@ : public ::arc::mojom::VideoDecodeAccelerator, public ArcVideoDecodeAccelerator::Client { public: - GpuArcVideoDecodeAccelerator( - const gpu::GpuPreferences& gpu_preferences, - ProtectedBufferManager* protected_buffer_manager); + explicit GpuArcVideoDecodeAccelerator( + const gpu::GpuPreferences& gpu_preferences); ~GpuArcVideoDecodeAccelerator() override; private: @@ -49,14 +46,6 @@ void Initialize(::arc::mojom::VideoDecodeAcceleratorConfigPtr config, ::arc::mojom::VideoDecodeClientPtr client, InitializeCallback callback) override; - - void AllocateProtectedBuffer( - ::arc::mojom::PortType port, - uint32_t index, - mojo::ScopedHandle handle, - uint64_t size, - AllocateProtectedBufferCallback callback) override; - void BindSharedMemory(::arc::mojom::PortType port, uint32_t index, mojo::ScopedHandle ashmem_handle,
diff --git a/chrome/gpu/protected_buffer_manager.cc b/chrome/gpu/protected_buffer_manager.cc deleted file mode 100644 index 47bcdaf..0000000 --- a/chrome/gpu/protected_buffer_manager.cc +++ /dev/null
@@ -1,411 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/gpu/protected_buffer_manager.h" - -#include "base/bits.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/memory/shared_memory.h" -#include "base/sys_info.h" -#include "mojo/public/cpp/system/buffer.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "ui/gfx/geometry/size.h" -#include "ui/ozone/public/ozone_platform.h" -#include "ui/ozone/public/surface_factory_ozone.h" - -#define VLOGF(level) VLOG(level) << __func__ << "(): " - -namespace chromeos { -namespace arc { - -namespace { -// Size of the pixmap to be used as the dummy handle for protected buffers. -constexpr gfx::Size kDummyBufferSize(32, 32); -} // namespace - -ProtectedBufferHandle::ProtectedBufferHandle( - base::OnceClosure destruction_cb, - const base::SharedMemoryHandle& shm_handle) - : shm_handle_(shm_handle), destruction_cb_(std::move(destruction_cb)) { - DCHECK(shm_handle_.IsValid()); - DCHECK(shm_handle.OwnershipPassesToIPC()); -} - -ProtectedBufferHandle::ProtectedBufferHandle( - base::OnceClosure destruction_cb, - const gfx::NativePixmapHandle& native_pixmap_handle) - : native_pixmap_handle_(native_pixmap_handle), - destruction_cb_(std::move(destruction_cb)) { - DCHECK(!native_pixmap_handle_.fds.empty()); - for (const auto& fd : native_pixmap_handle_.fds) - DCHECK(fd.auto_close); -} - -ProtectedBufferHandle::~ProtectedBufferHandle() { - if (shm_handle_.OwnershipPassesToIPC()) - shm_handle_.Close(); - - for (const auto& fd : native_pixmap_handle_.fds) { - // Close the fd by wrapping it in a ScopedFD and letting - // it fall out of scope. - base::ScopedFD scoped_fd(fd.fd); - } - - std::move(destruction_cb_).Run(); -} - -base::SharedMemoryHandle ProtectedBufferHandle::shm_handle() const { - base::SharedMemoryHandle handle = shm_handle_; - handle.SetOwnershipPassesToIPC(false); - return handle; -} - -gfx::NativePixmapHandle ProtectedBufferHandle::native_pixmap_handle() const { - return native_pixmap_handle_; -} - -class ProtectedBufferManager::ProtectedBuffer { - public: - virtual ~ProtectedBuffer() {} - - // Downcasting methods to return duplicated handles to the underlying - // protected buffers for each buffer type, or empty/null handles if not - // applicable. - virtual base::SharedMemoryHandle DuplicateSharedMemoryHandle() const { - return base::SharedMemoryHandle(); - } - virtual gfx::NativePixmapHandle DuplicateNativePixmapHandle() const { - return gfx::NativePixmapHandle(); - } - - // Downcasting method to return a scoped_refptr to the underlying - // NativePixmap, or null if not applicable. - virtual scoped_refptr<gfx::NativePixmap> GetNativePixmap() const { - return nullptr; - } - - protected: - explicit ProtectedBuffer(scoped_refptr<gfx::NativePixmap> dummy_handle) - : dummy_handle_(std::move(dummy_handle)) {} - - private: - scoped_refptr<gfx::NativePixmap> dummy_handle_; - - DISALLOW_COPY_AND_ASSIGN(ProtectedBuffer); -}; - -class ProtectedBufferManager::ProtectedSharedMemory - : public ProtectedBufferManager::ProtectedBuffer { - public: - ~ProtectedSharedMemory() override; - - // Allocate a ProtectedSharedMemory buffer of |size| bytes. - static std::unique_ptr<ProtectedSharedMemory> Create( - scoped_refptr<gfx::NativePixmap> dummy_handle, - size_t size); - - base::SharedMemoryHandle DuplicateSharedMemoryHandle() const override { - return base::SharedMemory::DuplicateHandle(shmem_->handle()); - } - - private: - explicit ProtectedSharedMemory(scoped_refptr<gfx::NativePixmap> dummy_handle); - - std::unique_ptr<base::SharedMemory> shmem_; -}; - -ProtectedBufferManager::ProtectedSharedMemory::ProtectedSharedMemory( - scoped_refptr<gfx::NativePixmap> dummy_handle) - : ProtectedBuffer(std::move(dummy_handle)) {} - -ProtectedBufferManager::ProtectedSharedMemory::~ProtectedSharedMemory() {} - -// static -std::unique_ptr<ProtectedBufferManager::ProtectedSharedMemory> -ProtectedBufferManager::ProtectedSharedMemory::Create( - scoped_refptr<gfx::NativePixmap> dummy_handle, - size_t size) { - std::unique_ptr<ProtectedSharedMemory> protected_shmem( - new ProtectedSharedMemory(std::move(dummy_handle))); - - size_t aligned_size = - base::bits::Align(size, base::SysInfo::VMAllocationGranularity()); - - mojo::ScopedSharedBufferHandle mojo_shared_buffer = - mojo::SharedBufferHandle::Create(aligned_size); - if (!mojo_shared_buffer->is_valid()) { - VLOGF(1) << "Failed to allocate shared memory"; - return nullptr; - } - - base::SharedMemoryHandle shm_handle; - MojoResult mojo_result = mojo::UnwrapSharedMemoryHandle( - std::move(mojo_shared_buffer), &shm_handle, nullptr, nullptr); - if (mojo_result != MOJO_RESULT_OK) { - VLOGF(1) << "Failed to unwrap a mojo shared memory handle"; - return nullptr; - } - - protected_shmem->shmem_ = - std::make_unique<base::SharedMemory>(shm_handle, false); - return protected_shmem; -} - -class ProtectedBufferManager::ProtectedNativePixmap - : public ProtectedBufferManager::ProtectedBuffer { - public: - ~ProtectedNativePixmap() override; - - // Allocate a ProtectedNativePixmap of |format| and |size|. - static std::unique_ptr<ProtectedNativePixmap> Create( - scoped_refptr<gfx::NativePixmap> dummy_handle, - gfx::BufferFormat format, - const gfx::Size& size); - - gfx::NativePixmapHandle DuplicateNativePixmapHandle() const override { - return native_pixmap_->ExportHandle(); - } - - scoped_refptr<gfx::NativePixmap> GetNativePixmap() const override { - return native_pixmap_; - } - - private: - explicit ProtectedNativePixmap(scoped_refptr<gfx::NativePixmap> dummy_handle); - - scoped_refptr<gfx::NativePixmap> native_pixmap_; -}; - -ProtectedBufferManager::ProtectedNativePixmap::ProtectedNativePixmap( - scoped_refptr<gfx::NativePixmap> dummy_handle) - : ProtectedBuffer(std::move(dummy_handle)) {} - -ProtectedBufferManager::ProtectedNativePixmap::~ProtectedNativePixmap() {} - -// static -std::unique_ptr<ProtectedBufferManager::ProtectedNativePixmap> -ProtectedBufferManager::ProtectedNativePixmap::Create( - scoped_refptr<gfx::NativePixmap> dummy_handle, - gfx::BufferFormat format, - const gfx::Size& size) { - std::unique_ptr<ProtectedNativePixmap> protected_pixmap( - new ProtectedNativePixmap(std::move(dummy_handle))); - - ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); - ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); - protected_pixmap->native_pixmap_ = - factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size, format, - gfx::BufferUsage::SCANOUT_VDA_WRITE); - - if (!protected_pixmap->native_pixmap_) { - VLOGF(1) << "Failed allocating a native pixmap"; - return nullptr; - } - - return protected_pixmap; -} - -ProtectedBufferManager::ProtectedBufferManager() : weak_factory_(this) { - VLOGF(2); - weak_this_ = weak_factory_.GetWeakPtr(); -} - -ProtectedBufferManager::~ProtectedBufferManager() { - VLOGF(2); -} - -std::unique_ptr<ProtectedBufferHandle> -ProtectedBufferManager::AllocateProtectedSharedMemory(base::ScopedFD dummy_fd, - size_t size) { - VLOGF(2) << "dummy_fd: " << dummy_fd.get() << ", size: " << size; - - // Import the |dummy_fd| to produce a unique id for it. - uint32_t id; - auto pixmap = ImportDummyFd(std::move(dummy_fd), &id); - if (!pixmap) - return nullptr; - - base::AutoLock lock(buffer_map_lock_); - - if (buffer_map_.find(id) != buffer_map_.end()) { - VLOGF(1) << "A protected buffer for this handle already exists"; - return nullptr; - } - - // Allocate a protected buffer and associate it with the dummy pixmap. - // The pixmap needs to be stored to ensure the id remains the same for - // the entire lifetime of the dummy pixmap. - auto protected_shmem = ProtectedSharedMemory::Create(pixmap, size); - if (!protected_shmem) { - VLOGF(1) << "Failed allocating a protected shared memory buffer"; - return nullptr; - } - - auto shm_handle = protected_shmem->DuplicateSharedMemoryHandle(); - if (!shm_handle.IsValid()) { - VLOGF(1) << "Failed duplicating SharedMemoryHandle"; - return nullptr; - } - - // Store the buffer in the buffer_map_, and return a handle to it to the - // client. The buffer will be permanently removed from the map when the - // handle is destroyed. - VLOGF(2) << "New protected shared memory buffer, handle id: " << id; - auto protected_buffer_handle = base::MakeUnique<ProtectedBufferHandle>( - base::BindOnce(&ProtectedBufferManager::RemoveEntry, weak_this_, id), - shm_handle); - - // This will always succeed as we find() first above. - buffer_map_.emplace(id, std::move(protected_shmem)); - - return protected_buffer_handle; -} - -std::unique_ptr<ProtectedBufferHandle> -ProtectedBufferManager::AllocateProtectedNativePixmap(base::ScopedFD dummy_fd, - gfx::BufferFormat format, - const gfx::Size& size) { - VLOGF(2) << "dummy_fd: " << dummy_fd.get() << ", format: " << (int)format - << ", size: " << size.ToString(); - - // Import the |dummy_fd| to produce a unique id for it. - uint32_t id = 0; - auto pixmap = ImportDummyFd(std::move(dummy_fd), &id); - if (!pixmap) - return nullptr; - - base::AutoLock lock(buffer_map_lock_); - - if (buffer_map_.find(id) != buffer_map_.end()) { - VLOGF(1) << "A protected buffer for this handle already exists"; - return nullptr; - } - - // Allocate a protected buffer and associate it with the dummy pixmap. - // The pixmap needs to be stored to ensure the id remains the same for - // the entire lifetime of the dummy pixmap. - auto protected_pixmap = ProtectedNativePixmap::Create(pixmap, format, size); - if (!protected_pixmap) { - VLOGF(1) << "Failed allocating a protected native pixmap"; - return nullptr; - } - - auto native_pixmap_handle = protected_pixmap->DuplicateNativePixmapHandle(); - if (native_pixmap_handle.planes.empty()) { - VLOGF(1) << "Failed duplicating NativePixmapHandle"; - return nullptr; - } - - // Store the buffer in the buffer_map_, and return a handle to it to the - // client. The buffer will be permanently removed from the map when the - // handle is destroyed. - VLOGF(2) << "New protected native pixmap, handle id: " << id; - auto protected_buffer_handle = base::MakeUnique<ProtectedBufferHandle>( - base::BindOnce(&ProtectedBufferManager::RemoveEntry, weak_this_, id), - native_pixmap_handle); - - // This will always succeed as we find() first above. - buffer_map_.emplace(id, std::move(protected_pixmap)); - - return protected_buffer_handle; -} - -base::SharedMemoryHandle -ProtectedBufferManager::GetProtectedSharedMemoryHandleFor( - base::ScopedFD dummy_fd) { - uint32_t id = 0; - auto pixmap = ImportDummyFd(std::move(dummy_fd), &id); - - base::AutoLock lock(buffer_map_lock_); - const auto& iter = buffer_map_.find(id); - if (iter == buffer_map_.end()) - return base::SharedMemoryHandle(); - - return iter->second->DuplicateSharedMemoryHandle(); -} - -gfx::NativePixmapHandle -ProtectedBufferManager::GetProtectedNativePixmapHandleFor( - base::ScopedFD dummy_fd) { - uint32_t id = 0; - auto pixmap = ImportDummyFd(std::move(dummy_fd), &id); - - base::AutoLock lock(buffer_map_lock_); - const auto& iter = buffer_map_.find(id); - if (iter == buffer_map_.end()) - return gfx::NativePixmapHandle(); - - return iter->second->DuplicateNativePixmapHandle(); -} - -scoped_refptr<gfx::NativePixmap> -ProtectedBufferManager::GetProtectedNativePixmapFor( - const gfx::NativePixmapHandle& handle) { - // Only the first fd is used for lookup. - if (handle.fds.empty()) - return nullptr; - - base::ScopedFD dummy_fd(HANDLE_EINTR(dup(handle.fds[0].fd))); - uint32_t id = 0; - auto pixmap = ImportDummyFd(std::move(dummy_fd), &id); - - base::AutoLock lock(buffer_map_lock_); - const auto& iter = buffer_map_.find(id); - if (iter == buffer_map_.end()) - return nullptr; - - auto native_pixmap = iter->second->GetNativePixmap(); - if (native_pixmap) { - for (const auto& fd : handle.fds) - base::ScopedFD scoped_fd(fd.fd); - } - - return native_pixmap; -} - -scoped_refptr<gfx::NativePixmap> ProtectedBufferManager::ImportDummyFd( - base::ScopedFD dummy_fd, - uint32_t* id) const { - // 0 is an invalid handle id. - *id = 0; - - // Import dummy_fd to acquire its unique id. - // CreateNativePixmapFromHandle() takes ownership and will close the handle - // also on failure. - gfx::NativePixmapHandle pixmap_handle; - pixmap_handle.fds.emplace_back( - base::FileDescriptor(dummy_fd.release(), true)); - pixmap_handle.planes.emplace_back(gfx::NativePixmapPlane()); - ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); - ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); - scoped_refptr<gfx::NativePixmap> pixmap = - factory->CreateNativePixmapForProtectedBufferHandle( - gfx::kNullAcceleratedWidget, kDummyBufferSize, gfx::BufferFormat::R_8, - pixmap_handle); - if (!pixmap) { - VLOGF(1) << "Failed importing dummy handle"; - return nullptr; - } - - *id = pixmap->GetUniqueId(); - if (*id == 0) { - VLOGF(1) << "Failed acquiring unique id for handle"; - return nullptr; - } - - return pixmap; -} - -void ProtectedBufferManager::RemoveEntry(uint32_t id) { - VLOGF(2) << "id: " << id; - - base::AutoLock lock(buffer_map_lock_); - auto num_erased = buffer_map_.erase(id); - if (num_erased != 1) - VLOGF(1) << "No buffer id " << id << " to destroy"; -} - -} // namespace arc -} // namespace chromeos
diff --git a/chrome/gpu/protected_buffer_manager.h b/chrome/gpu/protected_buffer_manager.h deleted file mode 100644 index 40a5e01..0000000 --- a/chrome/gpu/protected_buffer_manager.h +++ /dev/null
@@ -1,145 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_GPU_PROTECTED_BUFFER_MANAGER_H_ -#define CHROME_GPU_PROTECTED_BUFFER_MANAGER_H_ - -#include <map> - -#include "base/memory/ref_counted.h" -#include "base/memory/shared_memory.h" -#include "base/memory/weak_ptr.h" -#include "base/synchronization/lock.h" -#include "ui/gfx/gpu_memory_buffer.h" -#include "ui/gfx/native_pixmap.h" - -namespace chromeos { -namespace arc { - -// A ProtectedBufferHandle is returned to the owning client that requested -// the underlying ProtectedBuffer to be allocated. -// -// A ProtectedBuffer is a buffer that can be referred to via a handle (a dummy -// handle), which does not provide access to the actual contents of the buffer. -// -// The client should release this handle once the buffer is no longer needed. -// Releasing triggers destruction of the ProtectedBuffer instance stored in -// the ProtectedBufferManager, via the destruction callback passed to the -// ProtectedBufferHandle's constructor. -class ProtectedBufferHandle { - public: - // ProtectedBufferHandle takes ownership of the passed |shm_handle|. - ProtectedBufferHandle(base::OnceClosure destruction_cb, - const base::SharedMemoryHandle& shm_handle); - - // ProtectedBufferHandle takes ownership of the passed |native_pixmap_handle|. - ProtectedBufferHandle(base::OnceClosure destruction_cb, - const gfx::NativePixmapHandle& native_pixmap_handle); - - // Closes the underlying handle. - ~ProtectedBufferHandle(); - - // Return a non-owned SharedMemoryHandle or NativePixmapHandle for this - // ProtectedBufferHandle, or an invalid/null handle if not applicable for the - // underlying type. - base::SharedMemoryHandle shm_handle() const; - gfx::NativePixmapHandle native_pixmap_handle() const; - - private: - // The underlying, owning handles to the protected buffer. - // Only one of the handles is valid for each instance of this class. - // Closed on destruction of this ProtectedBufferHandle. - base::SharedMemoryHandle shm_handle_; - gfx::NativePixmapHandle native_pixmap_handle_; - - base::OnceClosure destruction_cb_; -}; - -class ProtectedBufferManager { - public: - ProtectedBufferManager(); - ~ProtectedBufferManager(); - - // Allocate a ProtectedSharedMemory buffer of |size| bytes, to be referred to - // via |dummy_fd| as the dummy handle, returning a ProtectedBufferHandle to - // it. - // Destroying the ProtectedBufferHandle will result in permanently - // disassociating the |dummy_fd| with the underlying ProtectedBuffer, but may - // not free the underlying protected memory, which will remain valid as long - // as any SharedMemoryHandles to it are still in use. - // Return nullptr on failure. - std::unique_ptr<ProtectedBufferHandle> AllocateProtectedSharedMemory( - base::ScopedFD dummy_fd, - size_t size); - - // Allocate a ProtectedNativePixmap of |format| and |size|, to be referred to - // via |dummy_fd| as the dummy handle, returning a ProtectedBufferHandle to - // it. - // Destroying the ProtectedBufferHandle will result in permanently - // disassociating the |dummy_fd| with the underlying ProtectedBuffer, but may - // not free the underlying protected memory, which will remain valid as long - // as any NativePixmapHandles to it are still in use. - // Return nullptr on failure. - std::unique_ptr<ProtectedBufferHandle> AllocateProtectedNativePixmap( - base::ScopedFD dummy_fd, - gfx::BufferFormat format, - const gfx::Size& size); - - // Return a duplicated SharedMemoryHandle associated with the |dummy_fd|, - // if one exists, or an invalid handle otherwise. - // The client is responsible for closing the handle after use. - base::SharedMemoryHandle GetProtectedSharedMemoryHandleFor( - base::ScopedFD dummy_fd); - - // Return a duplicated NativePixmapHandle associated with the |dummy_fd|, - // if one exists, or an empty handle otherwise. - // The client is responsible for closing the handle after use. - gfx::NativePixmapHandle GetProtectedNativePixmapHandleFor( - base::ScopedFD dummy_fd); - - // Return a protected NativePixmap for a dummy |handle|, if one exists, or - // nullptr otherwise. On success, the |handle| is closed. - scoped_refptr<gfx::NativePixmap> GetProtectedNativePixmapFor( - const gfx::NativePixmapHandle& handle); - - private: - // Used internally to maintain the association between the dummy handle and - // the underlying buffer. - class ProtectedBuffer; - class ProtectedSharedMemory; - class ProtectedNativePixmap; - - // Imports the |dummy_fd| as a NativePixmap. This returns a unique |id|, - // which is guaranteed to be the same for all future imports of any fd - // referring to the buffer to which |dummy_fd| refers to, regardless of - // whether it is the same fd as the original one, or not, for the lifetime - // of the buffer. - // - // This allows us to have an unambiguous mapping from any fd referring to - // the same memory buffer to the same unique id. - // - // Returns nullptr on failure, in which case the returned id is not valid. - scoped_refptr<gfx::NativePixmap> ImportDummyFd(base::ScopedFD dummy_fd, - uint32_t* id) const; - - // Removes an entry for given |id| from buffer_map_, to be called when the - // last reference to the buffer is dropped. - void RemoveEntry(uint32_t id); - - // A map of unique ids to the ProtectedBuffers associated with them. - using ProtectedBufferMap = - std::map<uint32_t, std::unique_ptr<ProtectedBuffer>>; - ProtectedBufferMap buffer_map_; - base::Lock buffer_map_lock_; - - base::WeakPtr<ProtectedBufferManager> weak_this_; - base::WeakPtrFactory<ProtectedBufferManager> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ProtectedBufferManager); -}; - -} // namespace arc -} // namespace chromeos - -#endif // CHROME_GPU_PROTECTED_BUFFER_MANAGER_H_
diff --git a/chrome/gpu/protected_buffer_manager_proxy.cc b/chrome/gpu/protected_buffer_manager_proxy.cc deleted file mode 100644 index 8080ed1..0000000 --- a/chrome/gpu/protected_buffer_manager_proxy.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/gpu/protected_buffer_manager_proxy.h" - -#include "chrome/gpu/protected_buffer_manager.h" -#include "mojo/public/cpp/system/platform_handle.h" - -#define VLOGF(level) VLOG(level) << __func__ << "(): " - -namespace chromeos { -namespace arc { - -GpuArcProtectedBufferManagerProxy::GpuArcProtectedBufferManagerProxy( - chromeos::arc::ProtectedBufferManager* protected_buffer_manager) - : protected_buffer_manager_(protected_buffer_manager) { - DCHECK(protected_buffer_manager_); -} - -base::ScopedFD GpuArcProtectedBufferManagerProxy::UnwrapFdFromMojoHandle( - mojo::ScopedHandle handle) { - base::PlatformFile platform_file; - MojoResult mojo_result = - mojo::UnwrapPlatformFile(std::move(handle), &platform_file); - if (mojo_result != MOJO_RESULT_OK) { - VLOGF(1) << "UnwrapPlatformFile failed: " << mojo_result; - return base::ScopedFD(); - } - - return base::ScopedFD(platform_file); -} - -mojo::ScopedHandle GpuArcProtectedBufferManagerProxy::WrapFdInMojoHandle( - base::ScopedFD fd) { - return mojo::WrapPlatformFile(fd.release()); -} - -void GpuArcProtectedBufferManagerProxy::GetProtectedSharedMemoryFromHandle( - mojo::ScopedHandle dummy_handle, - GetProtectedSharedMemoryFromHandleCallback callback) { - base::ScopedFD unwrapped_fd = UnwrapFdFromMojoHandle(std::move(dummy_handle)); - - base::ScopedFD shmem_fd( - protected_buffer_manager_ - ->GetProtectedSharedMemoryHandleFor(std::move(unwrapped_fd)) - .Release()); - - std::move(callback).Run(WrapFdInMojoHandle(std::move(shmem_fd))); -} - -} // namespace arc -} // namespace chromeos
diff --git a/chrome/gpu/protected_buffer_manager_proxy.h b/chrome/gpu/protected_buffer_manager_proxy.h deleted file mode 100644 index 324065c..0000000 --- a/chrome/gpu/protected_buffer_manager_proxy.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_GPU_PROTECTED_BUFFER_MANAGER_PROXY_H_ -#define CHROME_GPU_PROTECTED_BUFFER_MANAGER_PROXY_H_ - -#include "components/arc/common/protected_buffer_manager.mojom.h" - -namespace chromeos { -namespace arc { - -class ProtectedBufferManager; - -// Manages mojo IPC translation for chromeos::arc::ProtectedBufferManager. -class GpuArcProtectedBufferManagerProxy - : public ::arc::mojom::ProtectedBufferManager { - public: - explicit GpuArcProtectedBufferManagerProxy( - chromeos::arc::ProtectedBufferManager* protected_buffer_manager); - - // arc::mojom::ProtectedBufferManager implementation. - void GetProtectedSharedMemoryFromHandle( - mojo::ScopedHandle dummy_handle, - GetProtectedSharedMemoryFromHandleCallback callback) override; - - private: - base::ScopedFD UnwrapFdFromMojoHandle(mojo::ScopedHandle handle); - mojo::ScopedHandle WrapFdInMojoHandle(base::ScopedFD fd); - - chromeos::arc::ProtectedBufferManager* protected_buffer_manager_; - - DISALLOW_COPY_AND_ASSIGN(GpuArcProtectedBufferManagerProxy); -}; - -} // namespace arc -} // namespace chromeos - -#endif // CHROME_GPU_PROTECTED_BUFFER_MANAGER_PROXY_H_
diff --git a/chrome/profiling/json_exporter.cc b/chrome/profiling/json_exporter.cc index 61df4983..96ecb2a 100644 --- a/chrome/profiling/json_exporter.cc +++ b/chrome/profiling/json_exporter.cc
@@ -223,12 +223,10 @@ out << "}"; // heaps_v2 } -void WriteMemoryMaps( - const std::vector<memory_instrumentation::mojom::VmRegionPtr>& maps, - std::ostream& out) { +void WriteMemoryMaps(const ExportParams& params, std::ostream& out) { base::trace_event::TracedValue traced_value; - memory_instrumentation::TracingObserver::MemoryMapsAsValueInto(maps, - &traced_value); + memory_instrumentation::TracingObserver::MemoryMapsAsValueInto( + params.maps, &traced_value, params.is_argument_filtering_enabled); out << "\"process_mmaps\":" << traced_value.ToString(); } @@ -463,7 +461,7 @@ // Start dictionary. out << "{\n"; - WriteMemoryMaps(params.maps, out); + WriteMemoryMaps(params, out); out << ",\n"; // Write level of detail.
diff --git a/chrome/profiling/json_exporter.h b/chrome/profiling/json_exporter.h index a90fe57e..e3fb751 100644 --- a/chrome/profiling/json_exporter.h +++ b/chrome/profiling/json_exporter.h
@@ -38,6 +38,9 @@ // Only allocations exceeding this size or count will be exported. size_t min_size_threshold = 0; size_t min_count_threshold = 0; + + // Whether or not the outputted JSON should filter strings (anonymized trace). + bool is_argument_filtering_enabled = false; }; // Creates a JSON-encoded string that is similar in form to traces created by
diff --git a/chrome/profiling/memlog_connection_manager.cc b/chrome/profiling/memlog_connection_manager.cc index fc9ec98..31a53b4 100644 --- a/chrome/profiling/memlog_connection_manager.cc +++ b/chrome/profiling/memlog_connection_manager.cc
@@ -347,6 +347,7 @@ params.process_type = process_type; params.min_size_threshold = kMinSizeThreshold; params.min_count_threshold = kMinCountThreshold; + params.is_argument_filtering_enabled = true; std::ostringstream oss; ExportMemoryMapsAndV2StackTraceToJSON(params, oss);
diff --git a/chrome/services/DEPS b/chrome/services/DEPS new file mode 100644 index 0000000..ea32aa3 --- /dev/null +++ b/chrome/services/DEPS
@@ -0,0 +1,9 @@ +include_rules = [ + "+mojo", # By definition. + + # Services have to list which other services they depend on. + "-chrome/services", + "-services", + + "+services/service_manager/public", # Every service talks to Service Manager. +]
diff --git a/chrome/services/OWNERS b/chrome/services/OWNERS new file mode 100644 index 0000000..92c84d9e --- /dev/null +++ b/chrome/services/OWNERS
@@ -0,0 +1,2 @@ +jcivelli@chromium.org +rockot@chromium.org
diff --git a/chrome/services/util_win/BUILD.gn b/chrome/services/util_win/BUILD.gn new file mode 100644 index 0000000..0213b4d --- /dev/null +++ b/chrome/services/util_win/BUILD.gn
@@ -0,0 +1,30 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//services/service_manager/public/cpp/service.gni") +import("//services/service_manager/public/service_manifest.gni") + +source_set("lib") { + sources = [ + "shell_util_win_impl.cc", + "shell_util_win_impl.h", + "util_win_service.cc", + "util_win_service.h", + ] + + deps = [ + "//base", + "//mojo/public/cpp/bindings", + ] + + public_deps = [ + "//chrome/services/util_win/public/interfaces", + "//services/service_manager/public/cpp", + ] +} + +service_manifest("manifest") { + name = "util_win" + source = "manifest.json" +}
diff --git a/chrome/services/util_win/DEPS b/chrome/services/util_win/DEPS new file mode 100644 index 0000000..b3447e4 --- /dev/null +++ b/chrome/services/util_win/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+chrome/installer/util/install_util.h", + "+content/public/utility/utility_thread.h", +]
diff --git a/chrome/services/util_win/OWNERS b/chrome/services/util_win/OWNERS new file mode 100644 index 0000000..75ed5350 --- /dev/null +++ b/chrome/services/util_win/OWNERS
@@ -0,0 +1,5 @@ +pmonette@chromium.org +noel@chromium.org + +per-file manifest.json=set noparent +per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chrome/services/util_win/manifest.json b/chrome/services/util_win/manifest.json new file mode 100644 index 0000000..4ecc1edd --- /dev/null +++ b/chrome/services/util_win/manifest.json
@@ -0,0 +1,15 @@ +{ + "name": "util_win", + "display_name": "Windows Utilities", + "sandbox_type": "none", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + "shell_util_win": [ "chrome::mojom::ShellUtilWin" ] + }, + "requires": { + "service_manager": [ "service_manager:all_users" ] + } + } + } +}
diff --git a/chrome/services/util_win/public/interfaces/BUILD.gn b/chrome/services/util_win/public/interfaces/BUILD.gn new file mode 100644 index 0000000..a194859 --- /dev/null +++ b/chrome/services/util_win/public/interfaces/BUILD.gn
@@ -0,0 +1,22 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("interfaces") { + sources = [ + "shell_util_win.mojom", + ] + + public_deps = [ + ":constants", + "//mojo/common:common_custom_types", + ] +} + +mojom("constants") { + sources = [ + "constants.mojom", + ] +}
diff --git a/chrome/services/util_win/public/interfaces/OWNERS b/chrome/services/util_win/public/interfaces/OWNERS new file mode 100644 index 0000000..d28aad2 --- /dev/null +++ b/chrome/services/util_win/public/interfaces/OWNERS
@@ -0,0 +1,5 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS + +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chrome/services/util_win/public/interfaces/constants.mojom b/chrome/services/util_win/public/interfaces/constants.mojom new file mode 100644 index 0000000..0da35f4 --- /dev/null +++ b/chrome/services/util_win/public/interfaces/constants.mojom
@@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module chrome.mojom; + +const string kUtilWinServiceName = "util_win";
diff --git a/chrome/common/shell_handler_win.mojom b/chrome/services/util_win/public/interfaces/shell_util_win.mojom similarity index 98% rename from chrome/common/shell_handler_win.mojom rename to chrome/services/util_win/public/interfaces/shell_util_win.mojom index 099e084..550418f7 100644 --- a/chrome/common/shell_handler_win.mojom +++ b/chrome/services/util_win/public/interfaces/shell_util_win.mojom
@@ -10,7 +10,7 @@ import "mojo/common/file_path.mojom"; import "mojo/common/string16.mojom"; -interface ShellHandler { +interface ShellUtilWin { // Returns the pinned state of the current executable. IsPinnedToTaskbar() => (bool succeeded, bool is_pinned_to_taskbar);
diff --git a/chrome/common/shell_handler_win.typemap b/chrome/services/util_win/public/interfaces/shell_util_win.typemap similarity index 82% rename from chrome/common/shell_handler_win.typemap rename to chrome/services/util_win/public/interfaces/shell_util_win.typemap index 0a596ac..54edafac 100644 --- a/chrome/common/shell_handler_win.typemap +++ b/chrome/services/util_win/public/interfaces/shell_util_win.typemap
@@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//chrome/common/shell_handler_win.mojom" +mojom = "//chrome/services/util_win/public/interfaces/shell_util_win.mojom" public_headers = [ "//base/strings/string16.h" ]
diff --git a/chrome/utility/shell_handler_impl_win.cc b/chrome/services/util_win/shell_util_win_impl.cc similarity index 88% rename from chrome/utility/shell_handler_impl_win.cc rename to chrome/services/util_win/shell_util_win_impl.cc index 4572f94..639f10c 100644 --- a/chrome/utility/shell_handler_impl_win.cc +++ b/chrome/services/util_win/shell_util_win_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/utility/shell_handler_impl_win.h" +#include "chrome/services/util_win/shell_util_win_impl.h" #include <objbase.h> #include <shldisp.h> @@ -20,10 +20,11 @@ #include "base/win/shortcut.h" #include "base/win/win_util.h" #include "chrome/installer/util/install_util.h" -#include "content/public/utility/utility_thread.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "ui/base/win/open_file_name_win.h" +namespace chrome { + namespace { // This class checks if the current executable is pinned to the taskbar. It also @@ -205,6 +206,7 @@ base::FileEnumerator::DIRECTORIES); for (base::FilePath directory = directory_enum.Next(); !directory.empty(); directory = directory_enum.Next()) { + current_exe.value(); if (DirectoryContainsPinnedShortcutForProgram(directory, current_exe_compare)) { return true; @@ -215,31 +217,25 @@ } // namespace -ShellHandlerImpl::ShellHandlerImpl() = default; +ShellUtilWinImpl::ShellUtilWinImpl( + std::unique_ptr<service_manager::ServiceContextRef> service_ref) + : service_ref_(std::move(service_ref)) {} -ShellHandlerImpl::~ShellHandlerImpl() = default; +ShellUtilWinImpl::~ShellUtilWinImpl() = default; -// static -void ShellHandlerImpl::Create( - chrome::mojom::ShellHandlerRequest request) { - mojo::MakeStrongBinding(base::MakeUnique<ShellHandlerImpl>(), - std::move(request)); -} - -void ShellHandlerImpl::IsPinnedToTaskbar( - const IsPinnedToTaskbarCallback& callback) { +void ShellUtilWinImpl::IsPinnedToTaskbar(IsPinnedToTaskbarCallback callback) { IsPinnedToTaskbarHelper helper; bool is_pinned_to_taskbar = helper.GetResult(); - callback.Run(!helper.error_occured(), is_pinned_to_taskbar); + std::move(callback).Run(!helper.error_occured(), is_pinned_to_taskbar); } -void ShellHandlerImpl::CallGetOpenFileName( +void ShellUtilWinImpl::CallGetOpenFileName( uint32_t owner, uint32_t flags, const std::vector<std::tuple<base::string16, base::string16>>& filters, const base::FilePath& initial_directory, const base::FilePath& initial_filename, - const CallGetOpenFileNameCallback& callback) { + CallGetOpenFileNameCallback callback) { ui::win::OpenFileName open_file_name( reinterpret_cast<HWND>(base::win::Uint32ToHandle(owner)), flags); @@ -252,13 +248,13 @@ open_file_name.GetResult(&directory, &files); if (!files.empty()) { - callback.Run(directory, files); + std::move(callback).Run(directory, files); } else { - callback.Run(base::FilePath(), std::vector<base::FilePath>()); + std::move(callback).Run(base::FilePath(), std::vector<base::FilePath>()); } } -void ShellHandlerImpl::CallGetSaveFileName( +void ShellUtilWinImpl::CallGetSaveFileName( uint32_t owner, uint32_t flags, const std::vector<std::tuple<base::string16, base::string16>>& filters, @@ -266,7 +262,7 @@ const base::FilePath& initial_directory, const base::FilePath& suggested_filename, const base::string16& default_extension, - const CallGetSaveFileNameCallback& callback) { + CallGetSaveFileNameCallback callback) { ui::win::OpenFileName open_file_name( reinterpret_cast<HWND>(base::win::Uint32ToHandle(owner)), flags); @@ -276,8 +272,9 @@ open_file_name.GetOPENFILENAME()->lpstrDefExt = default_extension.c_str(); if (::GetSaveFileName(open_file_name.GetOPENFILENAME())) { - callback.Run(base::FilePath(open_file_name.GetOPENFILENAME()->lpstrFile), - open_file_name.GetOPENFILENAME()->nFilterIndex); + std::move(callback).Run( + base::FilePath(open_file_name.GetOPENFILENAME()->lpstrFile), + open_file_name.GetOPENFILENAME()->nFilterIndex); return; } @@ -285,5 +282,7 @@ if (DWORD error_code = ::CommDlgExtendedError()) NOTREACHED() << "::GetSaveFileName() failed: error code " << error_code; - callback.Run(base::FilePath(), 0); + std::move(callback).Run(base::FilePath(), 0); } + +} // namespace chrome
diff --git a/chrome/services/util_win/shell_util_win_impl.h b/chrome/services/util_win/shell_util_win_impl.h new file mode 100644 index 0000000..5aebbb0 --- /dev/null +++ b/chrome/services/util_win/shell_util_win_impl.h
@@ -0,0 +1,49 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_SERVICES_UTIL_WIN_SHELL_UTIL_WIN_IMPL_H_ +#define CHROME_SERVICES_UTIL_WIN_SHELL_UTIL_WIN_IMPL_H_ + +#include "base/macros.h" +#include "chrome/services/util_win/public/interfaces/shell_util_win.mojom.h" +#include "services/service_manager/public/cpp/service_context_ref.h" + +namespace chrome { + +class ShellUtilWinImpl : public chrome::mojom::ShellUtilWin { + public: + explicit ShellUtilWinImpl( + std::unique_ptr<service_manager::ServiceContextRef> service_ref); + ~ShellUtilWinImpl() override; + + private: + // chrome::mojom::ShellUtilWin: + void IsPinnedToTaskbar(IsPinnedToTaskbarCallback callback) override; + + void CallGetOpenFileName( + uint32_t owner, + uint32_t flags, + const std::vector<std::tuple<base::string16, base::string16>>& filters, + const base::FilePath& initial_directory, + const base::FilePath& initial_filename, + CallGetOpenFileNameCallback callback) override; + + void CallGetSaveFileName( + uint32_t owner, + uint32_t flags, + const std::vector<std::tuple<base::string16, base::string16>>& filters, + uint32_t one_based_filter_index, + const base::FilePath& initial_directory, + const base::FilePath& suggested_filename, + const base::string16& default_extension, + CallGetSaveFileNameCallback callback) override; + + const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; + + DISALLOW_COPY_AND_ASSIGN(ShellUtilWinImpl); +}; + +} // namespace chrome + +#endif // CHROME_SERVICES_UTIL_WIN_SHELL_UTIL_WIN_IMPL_H_
diff --git a/chrome/services/util_win/util_win_service.cc b/chrome/services/util_win/util_win_service.cc new file mode 100644 index 0000000..e64feed --- /dev/null +++ b/chrome/services/util_win/util_win_service.cc
@@ -0,0 +1,51 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/services/util_win/util_win_service.h" + +#include <memory> + +#include "build/build_config.h" +#include "chrome/services/util_win/public/interfaces/shell_util_win.mojom.h" +#include "chrome/services/util_win/shell_util_win_impl.h" +#include "mojo/public/cpp/bindings/strong_binding.h" + +namespace chrome { + +namespace { + +void OnShellUtilWinRequest( + service_manager::ServiceContextRefFactory* ref_factory, + chrome::mojom::ShellUtilWinRequest request) { + mojo::MakeStrongBinding( + std::make_unique<ShellUtilWinImpl>(ref_factory->CreateRef()), + std::move(request)); +} + +} // namespace + +UtilWinService::UtilWinService() = default; + +UtilWinService::~UtilWinService() = default; + +std::unique_ptr<service_manager::Service> UtilWinService::CreateService() { + return std::unique_ptr<service_manager::Service>(new UtilWinService()); +} + +void UtilWinService::OnStart() { + ref_factory_ = std::make_unique<service_manager::ServiceContextRefFactory>( + base::Bind(&service_manager::ServiceContext::RequestQuit, + base::Unretained(context()))); + registry_.AddInterface( + base::Bind(&OnShellUtilWinRequest, ref_factory_.get())); +} + +void UtilWinService::OnBindInterface( + const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + registry_.BindInterface(interface_name, std::move(interface_pipe)); +} + +} // namespace chrome
diff --git a/chrome/services/util_win/util_win_service.h b/chrome/services/util_win/util_win_service.h new file mode 100644 index 0000000..3283d8d --- /dev/null +++ b/chrome/services/util_win/util_win_service.h
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_SERVICES_UTIL_WIN_UTIL_WIN_SERVICE_H_ +#define CHROME_SERVICES_UTIL_WIN_UTIL_WIN_SERVICE_H_ + +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/service_context.h" +#include "services/service_manager/public/cpp/service_context_ref.h" + +namespace chrome { + +class UtilWinService : public service_manager::Service { + public: + ~UtilWinService() override; + + // Factory method for creating the service. + static std::unique_ptr<service_manager::Service> CreateService(); + + // Lifescycle events that occur after the service has started to spinup. + void OnStart() override; + void OnBindInterface(const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; + + private: + UtilWinService(); + + // State needed to manage service lifecycle and lifecycle of bound clients. + std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; + service_manager::BinderRegistry registry_; + + DISALLOW_COPY_AND_ASSIGN(UtilWinService); +}; + +} // namespace chrome + +#endif // CHROME_SERVICES_UTIL_WIN_UTIL_WIN_SERVICE_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index d156314..6997770 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2085,6 +2085,7 @@ "../browser/ui/views/payments/payment_request_data_url_browsertest.cc", "../browser/ui/views/payments/payment_request_debit_browsertest.cc", "../browser/ui/views/payments/payment_request_journey_logger_browsertest.cc", + "../browser/ui/views/payments/payment_request_no_update_with_browsertest.cc", "../browser/ui/views/payments/payment_request_payment_app_browsertest.cc", "../browser/ui/views/payments/payment_request_payment_response_browsertest.cc", "../browser/ui/views/payments/payment_request_shipping_address_instance_browsertest.cc",
diff --git a/chrome/typemaps.gni b/chrome/typemaps.gni index 79a9ff1..99bfa2bd 100644 --- a/chrome/typemaps.gni +++ b/chrome/typemaps.gni
@@ -5,5 +5,5 @@ typemaps = [ "//chrome/common/search.typemap", "//chrome/common/safe_browsing/safe_archive_analyzer.typemap", - "//chrome/common/shell_handler_win.typemap", + "//chrome/services/util_win/public/interfaces/shell_util_win.typemap", ]
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 874ac9f2..21da6dd 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -18,8 +18,6 @@ "cloud_print/bitmap_image.h", "cloud_print/pwg_encoder.cc", "cloud_print/pwg_encoder.h", - "shell_handler_impl_win.cc", - "shell_handler_impl_win.h", "utility_message_handler.h", ] @@ -135,6 +133,8 @@ # Add ESE library for Edge Import support. libs = [ "esent.lib" ] ldflags += [ "/DELAYLOAD:esent.dll" ] + + deps += [ "//chrome/services/util_win:lib" ] } if (is_win || is_mac) {
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index c31c46e..a389f51 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -2,6 +2,8 @@ "+chrome/grit", "+chrome/installer/util", "+chrome/profiling", + "+chrome/services/util_win/util_win_service.h", + "+chrome/services/util_win/public/interfaces", "+components/font_service/font_service_app.h", "+components/payments/content/utility", "+components/printing/service/public/cpp",
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 20c22c6..a7697d2 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -50,7 +50,8 @@ #endif #if defined(OS_WIN) -#include "chrome/utility/shell_handler_impl_win.h" +#include "chrome/services/util_win/public/interfaces/constants.mojom.h" +#include "chrome/services/util_win/util_win_service.h" #endif #if BUILDFLAG(ENABLE_EXTENSIONS) @@ -281,6 +282,7 @@ if (!utility_process_running_elevated_) { registry->AddInterface(base::Bind(&FilePatcherImpl::Create), base::ThreadTaskRunnerHandle::Get()); + #if !defined(OS_ANDROID) registry->AddInterface(base::Bind(CreateResourceUsageReporter), base::ThreadTaskRunnerHandle::Get()); @@ -288,10 +290,7 @@ base::Bind(&media_router::DialDeviceDescriptionParserImpl::Create), base::ThreadTaskRunnerHandle::Get()); #endif // !defined(OS_ANDROID) -#if defined(OS_WIN) - registry->AddInterface(base::Bind(&ShellHandlerImpl::Create), - base::ThreadTaskRunnerHandle::Get()); -#endif + #if defined(OS_CHROMEOS) registry->AddInterface(base::Bind(&ZipFileCreatorImpl::Create), base::ThreadTaskRunnerHandle::Get()); @@ -358,6 +357,14 @@ profile_import_info); #endif +#if defined(OS_WIN) + { + service_manager::EmbeddedServiceInfo service_info; + service_info.factory = base::Bind(&chrome::UtilWinService::CreateService); + services->emplace(chrome::mojom::kUtilWinServiceName, service_info); + } +#endif + #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) RegisterMashServices(services); #endif
diff --git a/chrome/utility/shell_handler_impl_win.h b/chrome/utility/shell_handler_impl_win.h deleted file mode 100644 index a8e5170..0000000 --- a/chrome/utility/shell_handler_impl_win.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_UTILITY_SHELL_HANDLER_IMPL_WIN_H_ -#define CHROME_UTILITY_SHELL_HANDLER_IMPL_WIN_H_ - -#include "base/macros.h" -#include "chrome/common/shell_handler_win.mojom.h" - -class ShellHandlerImpl : public chrome::mojom::ShellHandler { - public: - ShellHandlerImpl(); - ~ShellHandlerImpl() override; - - static void Create(chrome::mojom::ShellHandlerRequest request); - - private: - // chrome::mojom::ShellHandler: - void IsPinnedToTaskbar(const IsPinnedToTaskbarCallback& callback) override; - - void CallGetOpenFileName( - uint32_t owner, - uint32_t flags, - const std::vector<std::tuple<base::string16, base::string16>>& filters, - const base::FilePath& initial_directory, - const base::FilePath& initial_filename, - const CallGetOpenFileNameCallback& callback) override; - - void CallGetSaveFileName( - uint32_t owner, - uint32_t flags, - const std::vector<std::tuple<base::string16, base::string16>>& filters, - uint32_t one_based_filter_index, - const base::FilePath& initial_directory, - const base::FilePath& suggested_filename, - const base::string16& default_extension, - const CallGetSaveFileNameCallback& callback) override; - - DISALLOW_COPY_AND_ASSIGN(ShellHandlerImpl); -}; - -#endif // CHROME_UTILITY_SHELL_HANDLER_IMPL_WIN_H_
diff --git a/chromecast/browser/cast_media_blocker_unittest.cc b/chromecast/browser/cast_media_blocker_unittest.cc index 3f9ed13..709e9dd 100644 --- a/chromecast/browser/cast_media_blocker_unittest.cc +++ b/chromecast/browser/cast_media_blocker_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/time/time.h" #include "content/public/browser/media_session.h" #include "content/public/test/test_content_client_initializer.h" #include "content/public/test/test_renderer_host.h" @@ -30,6 +31,8 @@ MOCK_METHOD1(Resume, void(content::MediaSession::SuspendType)); MOCK_METHOD1(Suspend, void(content::MediaSession::SuspendType)); MOCK_METHOD1(Stop, void(content::MediaSession::SuspendType)); + MOCK_METHOD1(SeekForward, void(base::TimeDelta)); + MOCK_METHOD1(SeekBackward, void(base::TimeDelta)); MOCK_CONST_METHOD0(IsControllable, bool()); MOCK_CONST_METHOD0(IsActuallyPaused, bool()); MOCK_METHOD0(StartDucking, void());
diff --git a/chromecast/crash/cast_crash_keys.cc b/chromecast/crash/cast_crash_keys.cc index c0e2467..0ac90cef 100644 --- a/chromecast/crash/cast_crash_keys.cc +++ b/chromecast/crash/cast_crash_keys.cc
@@ -84,6 +84,9 @@ // Accessibility keys. Temporary for http://crbug.com/765490. {"ax_tree_error", ::crash_keys::kSmallSize}, {"ax_tree_update", ::crash_keys::kMediumSize}, + + // Temporary for crbug.com/756624. + {"break_iterator", ::crash_keys::kSmallSize}, }; return base::debug::InitCrashKeys(fixed_keys, arraysize(fixed_keys),
diff --git a/chromeos/dbus/session_manager_client.cc b/chromeos/dbus/session_manager_client.cc index faca3f8..2cdfa58e 100644 --- a/chromeos/dbus/session_manager_client.cc +++ b/chromeos/dbus/session_manager_client.cc
@@ -727,14 +727,10 @@ void ScreenIsLockedReceived(dbus::Signal* signal) { screen_is_locked_ = true; - for (auto& observer : observers_) - observer.ScreenIsLocked(); } void ScreenIsUnlockedReceived(dbus::Signal* signal) { screen_is_locked_ = false; - for (auto& observer : observers_) - observer.ScreenIsUnlocked(); } void ArcInstanceStoppedReceived(dbus::Signal* signal) { @@ -852,7 +848,7 @@ SessionManagerClientStubImpl() = default; ~SessionManagerClientStubImpl() override = default; - // SessionManagerClient overrides + // SessionManagerClient overrides: void Init(dbus::Bus* bus) override {} void SetStubDelegate(StubDelegate* delegate) override { delegate_ = delegate; @@ -881,16 +877,8 @@ if (delegate_) delegate_->LockScreenForStub(); } - void NotifyLockScreenShown() override { - screen_is_locked_ = true; - for (auto& observer : observers_) - observer.ScreenIsLocked(); - } - void NotifyLockScreenDismissed() override { - screen_is_locked_ = false; - for (auto& observer : observers_) - observer.ScreenIsUnlocked(); - } + void NotifyLockScreenShown() override { screen_is_locked_ = true; } + void NotifyLockScreenDismissed() override { screen_is_locked_ = false; } void RetrieveActiveSessions(ActiveSessionsCallback callback) override {} void RetrieveDevicePolicy(RetrievePolicyCallback callback) override { base::FilePath owner_key_path;
diff --git a/chromeos/dbus/session_manager_client.h b/chromeos/dbus/session_manager_client.h index 6fd3662..7e2dc09 100644 --- a/chromeos/dbus/session_manager_client.h +++ b/chromeos/dbus/session_manager_client.h
@@ -58,15 +58,6 @@ // Called when the property change is complete. virtual void PropertyChangeComplete(bool success) {} - // Called when the session manager announces that the screen has been locked - // successfully (i.e. after NotifyLockScreenShown() has been called). - virtual void ScreenIsLocked() {} - - // Called when the session manager announces that the screen has been - // unlocked successfully (i.e. after NotifyLockScreenDismissed() has - // been called). - virtual void ScreenIsUnlocked() {} - // Called after EmitLoginPromptVisible is called. virtual void EmitLoginPromptVisibleCalled() {} @@ -95,14 +86,14 @@ // remains with the caller. virtual void SetStubDelegate(StubDelegate* delegate) = 0; - // Adds and removes the observer. + // Adds or removes an observer. virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; virtual bool HasObserver(const Observer* observer) const = 0; // Returns the most recent screen-lock state received from session_manager. - // This mirrors the last Observer::ScreenIsLocked() or ScreenIsUnlocked() - // call. + // This method should only be called by low-level code that is unable to + // depend on UI code and get the lock state from it instead. virtual bool IsScreenLocked() const = 0; // Kicks off an attempt to emit the "login-prompt-visible" upstart signal. @@ -132,13 +123,14 @@ // Triggers a TPM firmware update. virtual void StartTPMFirmwareUpdate(const std::string& update_mode) = 0; - // Locks the screen. + // Sends a request to lock the screen to session_manager. Locking occurs + // asynchronously. virtual void RequestLockScreen() = 0; - // Notifies that the lock screen is shown. + // Notifies session_manager that Chrome has shown the lock screen. virtual void NotifyLockScreenShown() = 0; - // Notifies that the lock screen is dismissed. + // Notifies session_manager that Chrome has hidden the lock screen. virtual void NotifyLockScreenDismissed() = 0; // Notifies that supervised user creation have started.
diff --git a/chromeos/network/device_state.cc b/chromeos/network/device_state.cc index d33c8ed..60ccefd 100644 --- a/chromeos/network/device_state.cc +++ b/chromeos/network/device_state.cc
@@ -123,16 +123,6 @@ return false; } -bool DeviceState::InitialPropertiesReceived( - const base::DictionaryValue& properties) { - // Update UMA stats. - if (sim_present_) { - bool locked = !sim_lock_type_.empty(); - UMA_HISTOGRAM_BOOLEAN("Cellular.SIMLocked", locked); - } - return false; -} - void DeviceState::IPConfigPropertiesChanged( const std::string& ip_config_path, const base::DictionaryValue& properties) {
diff --git a/chromeos/network/device_state.h b/chromeos/network/device_state.h index 69a6bbf..973cb625 100644 --- a/chromeos/network/device_state.h +++ b/chromeos/network/device_state.h
@@ -26,8 +26,6 @@ // ManagedState overrides bool PropertyChanged(const std::string& key, const base::Value& value) override; - bool InitialPropertiesReceived( - const base::DictionaryValue& properties) override; void IPConfigPropertiesChanged(const std::string& ip_config_path, const base::DictionaryValue& properties);
diff --git a/chromeos/network/network_connect.cc b/chromeos/network/network_connect.cc index f201748..9c9b38d1 100644 --- a/chromeos/network/network_connect.cc +++ b/chromeos/network/network_connect.cc
@@ -454,10 +454,11 @@ NET_LOG_USER("Cannot enable cellular device without SIM.", log_string); return; } - if (!mobile->sim_lock_type().empty()) { + if (!mobile->IsSimLocked()) { // A SIM has been inserted, but it is locked. Let the user unlock it - // via the dialog. - delegate_->ShowMobileSimDialog(); + // via Settings or the details dialog. + const NetworkState* network = handler->FirstNetworkByType(technology); + delegate_->ShowNetworkSettings(network ? network->guid() : ""); return; } }
diff --git a/chromeos/network/network_connect.h b/chromeos/network/network_connect.h index b5fcfbd..c837995 100644 --- a/chromeos/network/network_connect.h +++ b/chromeos/network/network_connect.h
@@ -38,9 +38,6 @@ // and returns true, otherwise returns false. virtual bool ShowEnrollNetwork(const std::string& network_id) = 0; - // Shows UI to unlock a mobile sim. - virtual void ShowMobileSimDialog() = 0; - // Shows UI to setup a mobile network. virtual void ShowMobileSetupDialog(const std::string& network_id) = 0;
diff --git a/chromeos/network/network_connect_unittest.cc b/chromeos/network/network_connect_unittest.cc index c07691ff..d6fb1f9 100644 --- a/chromeos/network/network_connect_unittest.cc +++ b/chromeos/network/network_connect_unittest.cc
@@ -50,7 +50,6 @@ MOCK_METHOD1(ShowNetworkConfigure, void(const std::string& network_id)); MOCK_METHOD1(ShowNetworkSettings, void(const std::string& network_id)); MOCK_METHOD1(ShowEnrollNetwork, bool(const std::string& network_id)); - MOCK_METHOD0(ShowMobileSimDialog, void()); MOCK_METHOD1(ShowMobileSetupDialog, void(const std::string& network_id)); MOCK_METHOD2(ShowNetworkConnectError, void(const std::string& error_name, @@ -350,52 +349,4 @@ NetworkConnect::Get()->ConnectToNetworkId(kCellular1Guid); } -TEST_F(NetworkConnectTest, ShowMobileSimDialog) { - EXPECT_CALL(*mock_delegate_, ShowMobileSimDialog()); - - NetworkConnect::Get()->SetTechnologyEnabled(NetworkTypePattern::Cellular(), - false); - - device_test_->SetDeviceProperty( - kCellular1DevicePath, shill::kSIMPresentProperty, base::Value(true)); - device_test_->SetSimLocked(kCellular1DevicePath, true); - - base::RunLoop().RunUntilIdle(); - - NetworkConnect::Get()->SetTechnologyEnabled(NetworkTypePattern::Cellular(), - true); -} - -TEST_F(NetworkConnectTest, ShowMobileSimDialog_SimAbsent) { - EXPECT_CALL(*mock_delegate_, ShowMobileSimDialog()).Times(0); - - NetworkConnect::Get()->SetTechnologyEnabled(NetworkTypePattern::Cellular(), - false); - - device_test_->SetDeviceProperty( - kCellular1DevicePath, shill::kSIMPresentProperty, base::Value(false)); - device_test_->SetSimLocked(kCellular1DevicePath, true); - - base::RunLoop().RunUntilIdle(); - - NetworkConnect::Get()->SetTechnologyEnabled(NetworkTypePattern::Cellular(), - true); -} - -TEST_F(NetworkConnectTest, ShowMobileSimDialog_SimUnlocked) { - EXPECT_CALL(*mock_delegate_, ShowMobileSimDialog()).Times(0); - - NetworkConnect::Get()->SetTechnologyEnabled(NetworkTypePattern::Cellular(), - false); - - device_test_->SetDeviceProperty( - kCellular1DevicePath, shill::kSIMPresentProperty, base::Value(true)); - device_test_->SetSimLocked(kCellular1DevicePath, false); - - base::RunLoop().RunUntilIdle(); - - NetworkConnect::Get()->SetTechnologyEnabled(NetworkTypePattern::Cellular(), - true); -} - } // namespace chromeos
diff --git a/components/arc/common/oemcrypto_daemon.mojom b/components/arc/common/oemcrypto_daemon.mojom index b75db2d..5b2b782 100644 --- a/components/arc/common/oemcrypto_daemon.mojom +++ b/components/arc/common/oemcrypto_daemon.mojom
@@ -21,5 +21,5 @@ // Next Method ID: 1 interface OemCryptoHostDaemon { Connect@0(arc.mojom.OemCryptoService& oemcryptor, - arc.mojom.ProtectedBufferManager protected_buffer_manager); + media.mojom.ProtectedBufferManager protected_buffer_manager); };
diff --git a/components/arc/common/protected_buffer_manager.mojom b/components/arc/common/protected_buffer_manager.mojom index 298f6d3..b226ea3d 100644 --- a/components/arc/common/protected_buffer_manager.mojom +++ b/components/arc/common/protected_buffer_manager.mojom
@@ -5,7 +5,7 @@ // The original version of this file lives in the Chromium repository at: // src/components/arc/common/protected_buffer_manager.mojom -module arc.mojom; +module media.mojom; // This interface is exposed by the GPU process for translating dummy handles // for secure buffers into a usable shared memory handle. The output of a
diff --git a/components/arc/common/video_decode_accelerator.mojom b/components/arc/common/video_decode_accelerator.mojom index 5307594..bb732f9 100644 --- a/components/arc/common/video_decode_accelerator.mojom +++ b/components/arc/common/video_decode_accelerator.mojom
@@ -40,7 +40,6 @@ uint32 crop_height; }; -// Next MinVersion: 2 struct VideoDecodeAcceleratorConfig { // Deprecated. This config struct is used for decoder only. enum DeviceTypeDeprecated { @@ -52,12 +51,11 @@ DeviceTypeDeprecated device_type_deprecated; uint32 num_input_buffers; uint32 input_pixel_format; - [MinVersion=1] bool secure_mode; }; -// Next MinVersion: 5 +// Next MinVersion: 4 // Deprecated method IDs: 2, 7 -// Next method ID: 11 +// Next method ID: 10 interface VideoDecodeAccelerator { enum Result { SUCCESS = 0, @@ -72,10 +70,6 @@ Initialize@8(VideoDecodeAcceleratorConfig config, VideoDecodeClient client) => (Result result); - [MinVersion=4] - AllocateProtectedBuffer@10(PortType port, uint32 index, handle handle_fd, - uint64 size) => (bool result); - BindSharedMemory@1(PortType port, uint32 index, handle ashmem_fd, uint32 offset, uint32 length);
diff --git a/components/autofill/core/browser/credit_card_save_manager.cc b/components/autofill/core/browser/credit_card_save_manager.cc index 4daa56a9..845f3b4 100644 --- a/components/autofill/core/browser/credit_card_save_manager.cc +++ b/components/autofill/core/browser/credit_card_save_manager.cc
@@ -428,7 +428,8 @@ upload_request_.app_locale = app_locale_; // If the upload request does not have card CVC, populate it with the value // provided by the user: - if (upload_request_.cvc.empty()) { + if (upload_request_.cvc.empty() && + IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled()) { DCHECK(client_->GetSaveCardBubbleController()); upload_request_.cvc = client_->GetSaveCardBubbleController()->GetCvcEnteredByUser();
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc index 87021d55..607d943 100644 --- a/components/autofill/core/browser/payments/payments_client.cc +++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -53,6 +53,9 @@ const char kUploadCardRequestFormat[] = "requestContentType=application/json; charset=utf-8&request=%s" "&s7e_1_pan=%s&s7e_13_cvc=%s"; +const char kUploadCardRequestFormatWithoutCvc[] = + "requestContentType=application/json; charset=utf-8&request=%s" + "&s7e_1_pan=%s"; const char kTokenServiceConsumerId[] = "wallet_client"; const char kPaymentsOAuth2Scope[] = @@ -341,7 +344,8 @@ std::string GetRequestContent() override { base::DictionaryValue request_dict; request_dict.SetString("encrypted_pan", "__param:s7e_1_pan"); - request_dict.SetString("encrypted_cvc", "__param:s7e_13_cvc"); + if (!request_details_.cvc.empty()) + request_dict.SetString("encrypted_cvc", "__param:s7e_13_cvc"); request_dict.SetKey("risk_data_encoded", BuildRiskDictionary(request_details_.risk_data)); @@ -384,13 +388,21 @@ AutofillType(CREDIT_CARD_NUMBER), app_locale); std::string json_request; base::JSONWriter::Write(request_dict, &json_request); - std::string request_content = base::StringPrintf( - kUploadCardRequestFormat, - net::EscapeUrlEncodedData(json_request, true).c_str(), - net::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(), - net::EscapeUrlEncodedData(base::UTF16ToASCII(request_details_.cvc), - true) - .c_str()); + std::string request_content; + if (request_details_.cvc.empty()) { + request_content = base::StringPrintf( + kUploadCardRequestFormatWithoutCvc, + net::EscapeUrlEncodedData(json_request, true).c_str(), + net::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str()); + } else { + request_content = base::StringPrintf( + kUploadCardRequestFormat, + net::EscapeUrlEncodedData(json_request, true).c_str(), + net::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(), + net::EscapeUrlEncodedData(base::UTF16ToASCII(request_details_.cvc), + true) + .c_str()); + } VLOG(3) << "savecard request body: " << request_content; return request_content; }
diff --git a/components/autofill/core/browser/payments/payments_client_unittest.cc b/components/autofill/core/browser/payments/payments_client_unittest.cc index d576d09..0820d33e 100644 --- a/components/autofill/core/browser/payments/payments_client_unittest.cc +++ b/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -103,13 +103,14 @@ "language-LOCALE"); } - void StartUploading() { + void StartUploading(bool include_cvc) { token_service_->AddAccount("example@gmail.com"); identity_provider_->LogIn("example@gmail.com"); PaymentsClient::UploadRequestDetails request_details; request_details.billing_customer_number = 111222333444; request_details.card = test::GetCreditCard(); - request_details.cvc = base::ASCIIToUTF16("123"); + if (include_cvc) + request_details.cvc = base::ASCIIToUTF16("123"); request_details.context_token = base::ASCIIToUTF16("context token"); request_details.risk_data = "some risk data"; request_details.app_locale = "language-LOCALE"; @@ -264,7 +265,7 @@ } TEST_F(PaymentsClientTest, UploadSuccessWithoutServerId) { - StartUploading(); + StartUploading(/*include_cvc=*/true); IssueOAuthToken(); ReturnResponse(net::HTTP_OK, "{}"); EXPECT_EQ(AutofillClient::SUCCESS, result_); @@ -272,7 +273,7 @@ } TEST_F(PaymentsClientTest, UploadSuccessWithServerId) { - StartUploading(); + StartUploading(/*include_cvc=*/true); IssueOAuthToken(); ReturnResponse(net::HTTP_OK, "{ \"credit_card_id\": \"InstrumentData:1\" }"); EXPECT_EQ(AutofillClient::SUCCESS, result_); @@ -280,7 +281,7 @@ } TEST_F(PaymentsClientTest, UploadIncludesNonLocationData) { - StartUploading(); + StartUploading(/*include_cvc=*/true); // Verify that the recipient name field and test names do appear in the upload // data. @@ -304,7 +305,7 @@ TEST_F(PaymentsClientTest, UploadRequestIncludesBillingCustomerNumberInRequestIfExperimentOn) { - StartUploading(); + StartUploading(/*include_cvc=*/true); // Verify that the billing customer number is included in the request. EXPECT_TRUE( @@ -317,13 +318,33 @@ UploadRequestDoesNotIncludeBillingCustomerNumberInRequestIfExperimentOff) { DisableAutofillSendBillingCustomerNumberExperiment(); - StartUploading(); + StartUploading(/*include_cvc=*/true); // Verify that the billing customer number is not included in the request. EXPECT_TRUE(GetUploadData().find("external_customer_id") == std::string::npos); } +TEST_F(PaymentsClientTest, UploadIncludesCvcInRequestIfProvided) { + StartUploading(/*include_cvc=*/true); + + // Verify that the encrypted_cvc and s7e_13_cvc parameters were included in + // the request. + EXPECT_TRUE(GetUploadData().find("encrypted_cvc") != std::string::npos); + EXPECT_TRUE(GetUploadData().find("__param:s7e_13_cvc") != std::string::npos); + EXPECT_TRUE(GetUploadData().find("&s7e_13_cvc=") != std::string::npos); +} + +TEST_F(PaymentsClientTest, UploadDoesNotIncludeCvcInRequestIfNotProvided) { + StartUploading(/*include_cvc=*/false); + + // Verify that the encrypted_cvc and s7e_13_cvc parameters were not included + // in the request. + EXPECT_TRUE(GetUploadData().find("encrypted_cvc") == std::string::npos); + EXPECT_TRUE(GetUploadData().find("__param:s7e_13_cvc") == std::string::npos); + EXPECT_TRUE(GetUploadData().find("&s7e_13_cvc=") == std::string::npos); +} + TEST_F(PaymentsClientTest, GetDetailsFollowedByUploadSuccess) { StartGettingUploadDetails(); ReturnResponse( @@ -333,7 +354,7 @@ result_ = AutofillClient::NONE; - StartUploading(); + StartUploading(/*include_cvc=*/true); IssueOAuthToken(); ReturnResponse(net::HTTP_OK, "{}"); EXPECT_EQ(AutofillClient::SUCCESS, result_);
diff --git a/components/autofill/ios/browser/resources/autofill_controller.js b/components/autofill/ios/browser/resources/autofill_controller.js index fd297d1f..6edf8da 100644 --- a/components/autofill/ios/browser/resources/autofill_controller.js +++ b/components/autofill/ios/browser/resources/autofill_controller.js
@@ -566,7 +566,7 @@ */ __gCrWeb.autofill['fillActiveFormField'] = function(data) { var activeElement = document.activeElement; - if (data['name'] !== __gCrWeb['common'].nameForAutofill(activeElement)) { + if (data['name'] !== __gCrWeb['common'].getFieldIdentifier(activeElement)) { return; } __gCrWeb.autofill.lastAutoFilledElement = activeElement; @@ -610,7 +610,7 @@ if (!__gCrWeb.autofill.isAutofillableElement(element)) { continue; } - var fieldName = __gCrWeb['common'].nameForAutofill(element); + var fieldName = __gCrWeb['common'].getFieldIdentifier(element); // Skip non-empty fields unless this is the forceFillFieldName or it's a // 'select-one' element. 'select-one' elements are always autofilled even @@ -2090,7 +2090,7 @@ // The label is not officially part of a form control element; however, the // labels for all form control elements are scraped from the DOM and set in // form data. - field['name'] = __gCrWeb['common'].nameForAutofill(element); + field['name'] = __gCrWeb['common'].getFieldIdentifier(element); field['form_control_type'] = element.type; var autocomplete_attribute = element.getAttribute('autocomplete'); if (autocomplete_attribute) { @@ -2186,7 +2186,7 @@ if (!__gCrWeb.autofill.isAutofillableElement(element)) { continue; } - var elementName = __gCrWeb['common'].nameForAutofill(element); + var elementName = __gCrWeb['common'].getFieldIdentifier(element); var value = formData[elementName]; if (value) { element.placeholder = value;
diff --git a/components/browser_sync/BUILD.gn b/components/browser_sync/BUILD.gn index f8a153e..1bddf05 100644 --- a/components/browser_sync/BUILD.gn +++ b/components/browser_sync/BUILD.gn
@@ -122,6 +122,7 @@ "//components/sync", "//components/sync:test_support_driver", "//components/sync:test_support_engine", + "//components/sync:test_support_model", "//components/sync_preferences:test_support", "//components/sync_sessions:test_support", "//google_apis",
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index 1f35ed0b..73ab6dce 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -191,6 +191,12 @@ current_version.substr(0, current_version.find('.'))) { passphrase_prompt_triggered_by_version_ = true; } + + if (init_params.model_type_store_factory.is_null()) { + model_type_store_factory_ = GetModelTypeStoreFactory(base_directory_); + } else { + model_type_store_factory_ = init_params.model_type_store_factory; + } } ProfileSyncService::~ProfileSyncService() { @@ -235,10 +241,8 @@ sync_enabled_weak_factory_.GetWeakPtr(), syncer::ModelTypeSet(syncer::SESSIONS))); - const syncer::ModelTypeStoreFactory& store_factory = - GetModelTypeStoreFactory(syncer::DEVICE_INFO, base_directory_); device_info_sync_bridge_ = std::make_unique<DeviceInfoSyncBridge>( - local_device_.get(), store_factory, + local_device_.get(), model_type_store_factory_, base::BindRepeating( &ModelTypeChangeProcessor::Create, base::BindRepeating(&syncer::ReportUnrecoverableError, channel_))); @@ -1622,13 +1626,12 @@ // static syncer::ModelTypeStoreFactory ProfileSyncService::GetModelTypeStoreFactory( - ModelType type, const base::FilePath& base_path) { // TODO(skym): Verify using AsUTF8Unsafe is okay here. Should work as long // as the Local State file is guaranteed to be UTF-8. const std::string path = FormatSharedModelTypeStorePath(base_path).AsUTF8Unsafe(); - return base::Bind(&ModelTypeStore::CreateStore, type, path); + return base::Bind(&ModelTypeStore::CreateStore, path); } void ProfileSyncService::ConfigureDataTypeManager() {
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index 127d0377..84f04cc 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -237,6 +237,7 @@ scoped_refptr<net::URLRequestContextGetter> url_request_context; std::string debug_identifier; version_info::Channel channel = version_info::Channel::UNKNOWN; + syncer::ModelTypeStoreFactory model_type_store_factory; private: DISALLOW_COPY_AND_ASSIGN(InitParams); @@ -553,10 +554,9 @@ void SetPlatformSyncAllowedProvider( const PlatformSyncAllowedProvider& platform_sync_allowed_provider); - // Returns a function for |type| that will create a ModelTypeStore that shares + // Returns a function that will create a ModelTypeStore that shares // the sync LevelDB backend. |base_path| should be set to profile path. static syncer::ModelTypeStoreFactory GetModelTypeStoreFactory( - syncer::ModelType type, const base::FilePath& base_path); // Needed to test whether the directory is deleted properly. @@ -882,6 +882,12 @@ // platform. PlatformSyncAllowedProvider platform_sync_allowed_provider_; + // The factory used to initialize the ModelTypeStore passed to + // sync bridges created by the ProfileSyncService. The default factory + // creates an on disk leveldb-backed ModelTypeStore; one might override this + // default to, e.g., use an in-memory db for unit tests. + syncer::ModelTypeStoreFactory model_type_store_factory_; + // This weak factory invalidates its issued pointers when Sync is disabled. base::WeakPtrFactory<ProfileSyncService> sync_enabled_weak_factory_;
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc index 6966231..fa95486 100644 --- a/components/browser_sync/profile_sync_service_unittest.cc +++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -31,6 +31,7 @@ #include "components/sync/driver/sync_service_observer.h" #include "components/sync/driver/sync_util.h" #include "components/sync/engine/fake_sync_engine.h" +#include "components/sync/model/model_type_store_test_util.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/version_info/version_info_values.h" #include "google_apis/gaia/gaia_constants.h" @@ -202,6 +203,8 @@ ProfileSyncService::InitParams init_params = profile_sync_service_bundle_.CreateBasicInitParams(behavior, builder.Build()); + init_params.model_type_store_factory = + syncer::ModelTypeStoreTestUtil::FactoryForInMemoryStoreForTest(); service_ = std::make_unique<ProfileSyncService>(std::move(init_params)); service_->RegisterDataTypeController(
diff --git a/components/browser_sync/profile_sync_test_util.cc b/components/browser_sync/profile_sync_test_util.cc index 5880546f..fede9aa 100644 --- a/components/browser_sync/profile_sync_test_util.cc +++ b/components/browser_sync/profile_sync_test_util.cc
@@ -19,6 +19,7 @@ #include "components/sync/engine/passive_model_worker.h" #include "components/sync/engine/sequenced_model_worker.h" #include "components/sync/engine/ui_model_worker.h" +#include "components/sync/model/model_type_store_test_util.h" #include "net/url_request/url_request_test_util.h" namespace browser_sync { @@ -264,6 +265,8 @@ init_params.url_request_context = url_request_context(); init_params.debug_identifier = "dummyDebugName"; init_params.channel = version_info::Channel::UNKNOWN; + init_params.model_type_store_factory = + syncer::ModelTypeStoreTestUtil::FactoryForInMemoryStoreForTest(); return init_params; }
diff --git a/components/cronet/ios/test/BUILD.gn b/components/cronet/ios/test/BUILD.gn index 607f355..5ee713b 100644 --- a/components/cronet/ios/test/BUILD.gn +++ b/components/cronet/ios/test/BUILD.gn
@@ -11,6 +11,7 @@ "cronet_acceptlang_test.mm", "cronet_http_test.mm", "cronet_netlog_test.mm", + "cronet_performance_test.mm", "cronet_pkp_test.mm", "cronet_prefs_test.mm", "cronet_quic_test.mm",
diff --git a/components/cronet/ios/test/cronet_http_test.mm b/components/cronet/ios/test/cronet_http_test.mm index 1164970..4e0dcf5b 100644 --- a/components/cronet/ios/test/cronet_http_test.mm +++ b/components/cronet/ios/test/cronet_http_test.mm
@@ -105,38 +105,6 @@ base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); } -TEST_F(HttpTest, NSURLSessionReceivesBigHttpDataLoop) { - int iterations = 50; - long size = 10 * 1024 * 1024; - LOG(INFO) << "Downloading " << size << " bytes " << iterations << " times."; - NSTimeInterval elapsed_avg = 0; - NSTimeInterval elapsed_max = 0; - NSURL* url = net::NSURLWithGURL(GURL(TestServer::PrepareBigDataURL(size))); - for (int i = 0; i < iterations; ++i) { - [delegate_ reset]; - __block BOOL block_used = NO; - NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; - [Cronet setRequestFilterBlock:^(NSURLRequest* request) { - block_used = YES; - EXPECT_EQ([request URL], url); - return YES; - }]; - NSDate* start = [NSDate date]; - StartDataTaskAndWaitForCompletion(task); - NSTimeInterval elapsed = -[start timeIntervalSinceNow]; - elapsed_avg += elapsed; - if (elapsed > elapsed_max) - elapsed_max = elapsed; - EXPECT_TRUE(block_used); - EXPECT_EQ(nil, [delegate_ error]); - EXPECT_EQ(size, [delegate_ totalBytesReceived]); - } - // Release the response buffer. - TestServer::ReleaseBigDataURL(); - LOG(INFO) << "Elapsed Average:" << elapsed_avg * 1000 / iterations - << "ms Max:" << elapsed_max * 1000 << "ms"; -} - TEST_F(HttpTest, GetGlobalMetricsDeltas) { NSData* delta1 = [Cronet getGlobalMetricsDeltas];
diff --git a/components/cronet/ios/test/cronet_performance_test.mm b/components/cronet/ios/test/cronet_performance_test.mm new file mode 100644 index 0000000..6e64a198 --- /dev/null +++ b/components/cronet/ios/test/cronet_performance_test.mm
@@ -0,0 +1,269 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cronet/Cronet.h> +#import <Foundation/Foundation.h> + +#include <stdint.h> + +#include "base/logging.h" +#include "base/mac/scoped_nsobject.h" +#include "base/strings/stringprintf.h" +#include "base/strings/sys_string_conversions.h" +#include "components/cronet/ios/test/cronet_test_base.h" +#include "components/cronet/ios/test/test_server.h" +#include "components/grpc_support/test/quic_test_server.h" +#include "net/base/mac/url_conversions.h" +#include "net/base/net_errors.h" +#include "net/cert/mock_cert_verifier.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gtest_mac.h" +#include "url/gurl.h" + +namespace { + +const int kTestIterations = 10; +const BOOL kUseExternalUrl = NO; +const int kDownloadSize = 19307439; // used for internal server only +const char* kExternalUrl = "https://www.gstatic.com/chat/hangouts/bg/davec.jpg"; + +struct PerfResult { + NSTimeInterval total; + NSTimeInterval mean; + NSTimeInterval max; + int total_bytes_downloaded; + int failed_requests; + int total_requests; +}; + +struct TestConfig { + BOOL quic; + BOOL http2; + BOOL akd4; + BOOL cronet; +}; + +bool operator<(TestConfig a, TestConfig b) { + return std::tie(a.quic, a.http2, a.akd4, a.cronet) < + std::tie(b.quic, b.http2, b.akd4, b.cronet); +} + +const TestConfig test_combinations[] = { + // QUIC HTTP2 AKD4 Cronet + { false, false, false, false, }, + { false, false, false, true, }, + { false, true, false, true, }, + { true, false, false, true, }, + { true, false, true, true, }, +}; + +} // namespace + +namespace cronet { + +class PerfTest : public CronetTestBase, + public ::testing::WithParamInterface<TestConfig> { + public: + static void TearDownTestCase() { + NSMutableString* perf_data_acc = [NSMutableString stringWithCapacity:0]; + + LOG(INFO) << "Performance Data:"; + for (auto const& entry : perf_test_results) { + NSString* formatted_entry = [NSString + stringWithFormat: + @"Quic %i\tHttp2 %i\tAKD4 %i\tCronet %i: Mean: %fs " + @"(%fmbps)\tMax: " + @"%fs with %i fails out of %i total requests.", + entry.first.quic, entry.first.http2, entry.first.akd4, + entry.first.cronet, entry.second.mean, + entry.second.total ? 8 * entry.second.total_bytes_downloaded / + entry.second.total / 10e6 + : 0, + entry.second.max, entry.second.failed_requests, + entry.second.total_requests]; + + [perf_data_acc appendFormat:@"%@\n", formatted_entry]; + + LOG(INFO) << base::SysNSStringToUTF8(formatted_entry); + } + + NSString* filename = [NSString + stringWithFormat:@"performance_metrics-%@.txt", + [[NSDate date] + descriptionWithLocale:[NSLocale currentLocale]]]; + NSString* path = + [[[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory + inDomains:NSUserDomainMask] + lastObject] URLByAppendingPathComponent:filename] path]; + + NSData* filedata = [perf_data_acc dataUsingEncoding:NSUTF8StringEncoding]; + [[NSFileManager defaultManager] createFileAtPath:path + contents:filedata + attributes:nil]; + } + + protected: + static std::map<TestConfig, PerfResult> perf_test_results; + + PerfTest() {} + ~PerfTest() override {} + + void SetUp() override { + CronetTestBase::SetUp(); + TestServer::Start(); + + // These are normally called by StartCronet(), but because of the test + // parameterization we need to call them inline, and not use StartCronet() + [Cronet setUserAgent:@"CronetTest/1.0.0.0" partial:NO]; + [Cronet setQuicEnabled:GetParam().quic]; + [Cronet setHttp2Enabled:GetParam().http2]; + [Cronet setAcceptLanguages:@"en-US,en"]; + if (kUseExternalUrl) { + NSString* external_host = [[NSURL + URLWithString:[NSString stringWithUTF8String:kExternalUrl]] host]; + [Cronet addQuicHint:external_host port:443 altPort:443]; + } else { + [Cronet addQuicHint:@"test.example.com" port:443 altPort:443]; + } + [Cronet enableTestCertVerifierForTesting]; + [Cronet setHttpCacheType:CRNHttpCacheTypeDisabled]; + if (GetParam().akd4) { + [Cronet setExperimentalOptions: + @"{\"QUIC\":{\"connection_options\":\"AKD4\"}}"]; + } + + [Cronet start]; + + NSString* rules = base::SysUTF8ToNSString( + base::StringPrintf("MAP test.example.com 127.0.0.1:%d," + "MAP notfound.example.com ~NOTFOUND", + grpc_support::GetQuicTestServerPort())); + [Cronet setHostResolverRulesForTesting:rules]; + // This is the end of the behavior normally performed by StartCronet() + + NSURLSessionConfiguration* config = + [NSURLSessionConfiguration ephemeralSessionConfiguration]; + config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; + if (GetParam().cronet) { + [Cronet registerHttpProtocolHandler]; + [Cronet installIntoSessionConfiguration:config]; + } else { + [Cronet unregisterHttpProtocolHandler]; + } + session_ = [NSURLSession sessionWithConfiguration:config + delegate:delegate_ + delegateQueue:nil]; + } + + void TearDown() override { + TestServer::Shutdown(); + + [Cronet shutdownForTesting]; + CronetTestBase::TearDown(); + } + + NSURLSession* session_; +}; + +// static +std::map<TestConfig, PerfResult> PerfTest::perf_test_results; + +TEST_P(PerfTest, NSURLSessionReceivesImageLoop) { + int iterations = kTestIterations; + int failed_iterations = 0; + int total_bytes_received = 0; + NSTimeInterval elapsed_total = 0; + NSTimeInterval elapsed_max = 0; + + int first_log = false; + + LOG(INFO) << "Running with parameters: " + << "QUIC: " << GetParam().quic << "\t" + << "HTTP2: " << GetParam().http2 << "\t" + << "AKD4: " << GetParam().akd4 << "\t" + << "Cronet: " << GetParam().cronet << "\t"; + + NSURL* url; + if (kUseExternalUrl) { + url = net::NSURLWithGURL(GURL(kExternalUrl)); + } else { + LOG(INFO) << "Downloading " << kDownloadSize << " bytes per iteration"; + url = + net::NSURLWithGURL(GURL(TestServer::PrepareBigDataURL(kDownloadSize))); + } + + for (int i = 0; i < iterations; ++i) { + __block BOOL block_used = NO; + NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; + [Cronet setRequestFilterBlock:^(NSURLRequest* request) { + block_used = YES; + EXPECT_EQ([request URL], url); + return YES; + }]; + + NSDate* start = [NSDate date]; + BOOL success = StartDataTaskAndWaitForCompletion(task); + + if (!success) { + [task cancel]; + } + + NSTimeInterval elapsed = -[start timeIntervalSinceNow]; + + // Do not tolerate failures on internal server. + if (!kUseExternalUrl) { + CHECK(success && ![delegate_ errorPerTask][task]); + } + + if (kUseExternalUrl && success && !first_log) { + LOG(INFO) << "Downloaded " << [delegate_ totalBytesReceivedPerTask][task] + << " bytes on first iteration."; + first_log = true; + } + + if (!success) { + if ([delegate_ errorPerTask][task]) { + LOG(WARNING) << "Request failed during performance testing: " + << base::SysNSStringToUTF8([[delegate_ errorPerTask][task] + localizedDescription]); + } else { + LOG(WARNING) << "Request timed out during performance testing."; + } + ++failed_iterations; + } else { + // Checking that the correct amount of data was downloaded only makes + // sense if the request succeeded. + EXPECT_EQ([[delegate_ expectedContentLengthPerTask][task] intValue], + [[delegate_ totalBytesReceivedPerTask][task] intValue]); + + elapsed_total += elapsed; + elapsed_max = MAX(elapsed, elapsed_max); + + total_bytes_received += + [[delegate_ totalBytesReceivedPerTask][task] intValue]; + } + + EXPECT_EQ(block_used, GetParam().cronet); + } + + LOG(INFO) << "Elapsed Total:" << elapsed_total * 1000 << "ms"; + + // Reject performance data from too many failures. + if (kUseExternalUrl) { + CHECK(failed_iterations < iterations / 2); + } + + perf_test_results[GetParam()] = { + elapsed_total, elapsed_total / iterations, elapsed_max, + total_bytes_received, failed_iterations, iterations}; + + if (!kUseExternalUrl) { + TestServer::ReleaseBigDataURL(); + } +} + +INSTANTIATE_TEST_CASE_P(Loops, + PerfTest, + ::testing::ValuesIn(test_combinations)); +} // namespace cronet
diff --git a/components/cronet/ios/test/cronet_test_base.h b/components/cronet/ios/test/cronet_test_base.h index 1580e78..63d4556 100644 --- a/components/cronet/ios/test/cronet_test_base.h +++ b/components/cronet/ios/test/cronet_test_base.h
@@ -31,21 +31,33 @@ @interface TestDelegate : NSObject<NSURLSessionDataDelegate> // Error the request this delegate is attached to failed with, if any. -@property(retain, atomic) NSError* error; +@property(retain, atomic) + NSMutableDictionary<NSURLSessionTask*, NSError*>* errorPerTask; // Contains total amount of received data. -@property(readonly) long totalBytesReceived; +@property(readonly) NSMutableDictionary<NSURLSessionDataTask*, NSNumber*>* + totalBytesReceivedPerTask; + +@property(readonly) NSMutableDictionary<NSURLSessionDataTask*, NSNumber*>* + expectedContentLengthPerTask; // Resets the delegate, so it can be used again for another request. - (void)reset; // Contains the response body. -- (NSString*)responseBody; +- (NSString*)responseBody:(NSURLSessionDataTask*)task; -/// Waits for request to complete. +/// Waits for a single request to complete. /// @return |NO| if the request didn't complete and the method timed-out. -- (BOOL)waitForDone; +- (BOOL)waitForDone:(NSURLSessionDataTask*)task + withTimeout:(int64_t)deadline_ns; + +// Convenience functions for single-task delegates +- (NSError*)error; +- (long)totalBytesReceived; +- (long)expectedContentLength; +- (NSString*)responseBody; @end @@ -65,7 +77,9 @@ void SetUp() override; void TearDown() override; - void StartDataTaskAndWaitForCompletion(NSURLSessionDataTask* task); + bool StartDataTaskAndWaitForCompletion(NSURLSessionDataTask* task, + int64_t deadline_ns = 20 * + NSEC_PER_SEC); std::unique_ptr<net::MockCertVerifier> CreateMockCertVerifier( const std::vector<std::string>& certs, bool known_root);
diff --git a/components/cronet/ios/test/cronet_test_base.mm b/components/cronet/ios/test/cronet_test_base.mm index a056ab0b..6eb8acaa 100644 --- a/components/cronet/ios/test/cronet_test_base.mm +++ b/components/cronet/ios/test/cronet_test_base.mm
@@ -15,48 +15,98 @@ #pragma mark @implementation TestDelegate { - // Completion semaphore for this TestDelegate. When the request this delegate - // is attached to finishes (either successfully or with an error), this - // delegate signals this semaphore. - dispatch_semaphore_t _semaphore; + // Dictionary which maps tasks to completion semaphores for this TestDelegate. + // When a request this delegate is attached to finishes (either successfully + // or with an error), this delegate signals that task's semaphore. + NSMutableDictionary<NSURLSessionTask*, dispatch_semaphore_t>* _semaphores; + + NSMutableDictionary<NSURLSessionDataTask*, NSMutableArray<NSData*>*>* + _responseDataPerTask; } -@synthesize error = _error; -@synthesize totalBytesReceived = _totalBytesReceived; - -NSMutableArray<NSData*>* _responseData; +@synthesize errorPerTask = _errorPerTask; +@synthesize totalBytesReceivedPerTask = _totalBytesReceivedPerTask; +@synthesize expectedContentLengthPerTask = _expectedContentLengthPerTask; - (id)init { if (self = [super init]) { - _semaphore = dispatch_semaphore_create(0); + _semaphores = [NSMutableDictionary dictionaryWithCapacity:0]; } return self; } - (void)reset { - _responseData = nil; - _error = nil; - _totalBytesReceived = 0; + _responseDataPerTask = [NSMutableDictionary dictionaryWithCapacity:0]; + _errorPerTask = [NSMutableDictionary dictionaryWithCapacity:0]; + _totalBytesReceivedPerTask = [NSMutableDictionary dictionaryWithCapacity:0]; + _expectedContentLengthPerTask = + [NSMutableDictionary dictionaryWithCapacity:0]; +} + +- (NSError*)error { + if ([_errorPerTask count] == 0) + return nil; + + DCHECK([_errorPerTask count] == 1); + return [[_errorPerTask objectEnumerator] nextObject]; +} + +- (long)totalBytesReceived { + DCHECK([_totalBytesReceivedPerTask count] == 1); + return [[[_totalBytesReceivedPerTask objectEnumerator] nextObject] intValue]; +} + +- (long)expectedContentLength { + DCHECK([_expectedContentLengthPerTask count] == 1); + return + [[[_expectedContentLengthPerTask objectEnumerator] nextObject] intValue]; } - (NSString*)responseBody { - if (_responseData == nil) { + if ([_responseDataPerTask count] == 0) + return nil; + + DCHECK([_responseDataPerTask count] == 1); + NSURLSessionDataTask* task = + [[_responseDataPerTask keyEnumerator] nextObject]; + + return [self responseBody:task]; +} + +- (NSString*)responseBody:(NSURLSessionDataTask*)task { + if (_responseDataPerTask[task] == nil) { return nil; } NSMutableString* body = [NSMutableString string]; - for (NSData* data in _responseData) { + for (NSData* data in _responseDataPerTask[task]) { [body appendString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]]; } VLOG(3) << "responseBody size:" << [body length] - << " chunks:" << [_responseData count]; + << " chunks:" << [_responseDataPerTask[task] count]; return body; } -- (BOOL)waitForDone { - int64_t deadline_ns = 20 * NSEC_PER_SEC; - return dispatch_semaphore_wait( - _semaphore, dispatch_time(DISPATCH_TIME_NOW, deadline_ns)) == 0; +- (dispatch_semaphore_t)getSemaphoreForTask:(NSURLSessionTask*)task { + @synchronized(_semaphores) { + if (!_semaphores[task]) { + _semaphores[task] = dispatch_semaphore_create(0); + } + return _semaphores[task]; + } +} + +// |timeout_ns|, if positive, specifies how long to wait before timing out in +// nanoseconds, a value of 0 or less means do not ever time out. +- (BOOL)waitForDone:(NSURLSessionDataTask*)task + withTimeout:(int64_t)timeout_ns { + dispatch_semaphore_t _semaphore = [self getSemaphoreForTask:task]; + if (timeout_ns > 0) { + return dispatch_semaphore_wait( + _semaphore, dispatch_time(DISPATCH_TIME_NOW, timeout_ns)) == 0; + } else { + return dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER) == 0; + } } - (void)URLSession:(NSURLSession*)session @@ -66,7 +116,10 @@ - (void)URLSession:(NSURLSession*)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError*)error { - [self setError:error]; + if (error) + _errorPerTask[task] = error; + + dispatch_semaphore_t _semaphore = [self getSemaphoreForTask:task]; dispatch_semaphore_signal(_semaphore); } @@ -84,17 +137,27 @@ didReceiveResponse:(NSURLResponse*)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition)) completionHandler { + _expectedContentLengthPerTask[dataTask] = + [NSNumber numberWithInt:[response expectedContentLength]]; completionHandler(NSURLSessionResponseAllow); } - (void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveData:(NSData*)data { - _totalBytesReceived += [data length]; - if (_responseData == nil) { - _responseData = [[NSMutableArray alloc] init]; + if (_totalBytesReceivedPerTask[dataTask]) { + _totalBytesReceivedPerTask[dataTask] = [NSNumber + numberWithInt:[_totalBytesReceivedPerTask[dataTask] intValue] + + [data length]]; + } else { + _totalBytesReceivedPerTask[dataTask] = + [NSNumber numberWithInt:[data length]]; } - [_responseData addObject:data]; + + if (_responseDataPerTask[dataTask] == nil) { + _responseDataPerTask[dataTask] = [[NSMutableArray alloc] init]; + } + [_responseDataPerTask[dataTask] addObject:data]; } - (void)URLSession:(NSURLSession*)session @@ -120,13 +183,15 @@ ::testing::Test::TearDown(); } -// Launches the supplied |task| and blocks until it completes, with a timeout -// of 1 second. -void CronetTestBase::StartDataTaskAndWaitForCompletion( - NSURLSessionDataTask* task) { +// Launches the supplied |task| and blocks until it completes, with a default +// timeout of 20 seconds. |deadline_ns|, if specified, is in nanoseconds. +// If |deadline_ns| is 0 or negative, the request will not time out. +bool CronetTestBase::StartDataTaskAndWaitForCompletion( + NSURLSessionDataTask* task, + int64_t deadline_ns) { [delegate_ reset]; [task resume]; - CHECK([delegate_ waitForDone]); + return [delegate_ waitForDone:task withTimeout:deadline_ns]; } ::testing::AssertionResult CronetTestBase::IsResponseSuccessful() {
diff --git a/components/data_reduction_proxy/OWNERS b/components/data_reduction_proxy/OWNERS index 7d2916a7..b4fc113a 100644 --- a/components/data_reduction_proxy/OWNERS +++ b/components/data_reduction_proxy/OWNERS
@@ -1,4 +1,5 @@ bengr@chromium.org +dougarnett@chromium.org megjablon@chromium.org rajendrant@chromium.org ryansturm@chromium.org @@ -11,4 +12,4 @@ per-file *_messages*.h=set noparent per-file *_messages*.h=file://ipc/SECURITY_OWNERS -# COMPONENT: Internals>Network>DataProxy \ No newline at end of file +# COMPONENT: Internals>Network>DataProxy
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index f54c170b..96e7144 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -291,6 +291,7 @@ DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface)); pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point())); sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point())); + sub_surfaces_changed_ = true; } void Surface::RemoveSubSurface(Surface* sub_surface) { @@ -307,13 +308,10 @@ DCHECK(ListContainsEntry(sub_surfaces_, sub_surface)); auto it = FindListEntry(sub_surfaces_, sub_surface); - pending_damage_.op(SkIRect::MakeXYWH(it->second.x(), it->second.y(), - sub_surface->content_size().width(), - sub_surface->content_size().height()), - SkRegion::kUnion_Op); sub_surfaces_.erase(it); // Force recreating resources when the surface is added to a tree again. sub_surface->SurfaceHierarchyResourcesLost(); + sub_surfaces_changed_ = true; } void Surface::SetSubSurfacePosition(Surface* sub_surface, @@ -439,7 +437,10 @@ if (needs_commit_surface_) { needs_commit_surface_ = false; + // TODO(penghuang): Make the damage more precise for sub surface changes. + // https://crbug.com/779704 bool needs_full_damage = + sub_surfaces_changed_ || pending_state_.opaque_region != state_.opaque_region || pending_state_.buffer_scale != state_.buffer_scale || pending_state_.buffer_transform != state_.buffer_transform || @@ -517,7 +518,7 @@ damage_.setRect(output_rect); } else { // pending_damage_ is in Surface coordinates. - damage_.set(pending_damage_); + damage_.swap(pending_damage_); damage_.intersects(output_rect); } pending_damage_.setEmpty(); @@ -660,8 +661,6 @@ void Surface::SurfaceHierarchyResourcesLost() { // Update resource and full damage are needed for next frame. needs_update_resource_ = true; - damage_.setRect( - SkIRect::MakeWH(content_size_.width(), content_size_.height())); for (const auto& sub_surface : sub_surfaces_) sub_surface.first->SurfaceHierarchyResourcesLost(); }
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc index ab5b6a3..6b6de06 100644 --- a/components/exo/surface_unittest.cc +++ b/components/exo/surface_unittest.cc
@@ -838,9 +838,11 @@ surface->Commit(); RunAllPendingInMessageLoop(); - // Remove the subsurface by destroying it. This should damage |surface|. + // Remove the subsurface by destroying it. This should not damage |surface|. + // TODO(penghuang): Make the damage more precise for sub surface changes. + // https://crbug.com/779704 sub_surface.reset(); - EXPECT_TRUE(surface->HasPendingDamageForTesting(gfx::Rect(20, 10, 64, 128))); + EXPECT_FALSE(surface->HasPendingDamageForTesting(gfx::Rect(20, 10, 64, 128))); } } // namespace
diff --git a/components/flags_ui/flags_state.cc b/components/flags_ui/flags_state.cc index 663d04a..5ee6372 100644 --- a/components/flags_ui/flags_state.cc +++ b/components/flags_ui/flags_state.cc
@@ -374,7 +374,7 @@ } void FlagsState::RemoveFlagsSwitches( - std::map<std::string, base::CommandLine::StringType>* switch_list) { + base::CommandLine::SwitchMap* switch_list) { for (const auto& entry : flags_switches_) switch_list->erase(entry.first);
diff --git a/components/flags_ui/flags_state.h b/components/flags_ui/flags_state.h index b888a0ae..8540ce8 100644 --- a/components/flags_ui/flags_state.h +++ b/components/flags_ui/flags_state.h
@@ -84,8 +84,7 @@ void SetFeatureEntryEnabled(FlagsStorage* flags_storage, const std::string& internal_name, bool enable); - void RemoveFlagsSwitches( - std::map<std::string, base::CommandLine::StringType>* switch_list); + void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list); void ResetAllFlags(FlagsStorage* flags_storage); void Reset();
diff --git a/components/flags_ui/flags_state_unittest.cc b/components/flags_ui/flags_state_unittest.cc index 6b396e11..11bf0ffc 100644 --- a/components/flags_ui/flags_state_unittest.cc +++ b/components/flags_ui/flags_state_unittest.cc
@@ -440,7 +440,7 @@ } TEST_F(FlagsStateTest, RemoveFlagSwitches) { - std::map<std::string, base::CommandLine::StringType> switch_list; + base::CommandLine::SwitchMap switch_list; switch_list[kSwitch1] = base::CommandLine::StringType(); switch_list[switches::kFlagSwitchesBegin] = base::CommandLine::StringType(); switch_list[switches::kFlagSwitchesEnd] = base::CommandLine::StringType();
diff --git a/components/net_log/resources/net_export.html b/components/net_log/resources/net_export.html index 823892b..b6556e8 100644 --- a/components/net_log/resources/net_export.html +++ b/components/net_log/resources/net_export.html
@@ -168,9 +168,14 @@ <div class="section-container"> <!-- TODO(rayraymond): Change link to that of new standalone webapp. See http://crbug.com/472699 --> - The log file can also be loaded using + <if expr="not is_ios"> + The log file can be loaded using <a href="chrome://net-internals#import" target="_blank">net-internals</a>. + </if> + <if expr="is_ios"> + The log file can be loaded using chrome://net-internals/ on desktop. + </if> </div> <div class="section-container">
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 2610f498..01266a6b 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") +import("//device/vr/features/features.gni") import("//third_party/protobuf/proto_library.gni") import("//components/vector_icons/vector_icons.gni") @@ -9,6 +11,11 @@ import("//build/config/android/rules.gni") } +buildflag_header("build_features") { + header = "features.h" + flags = [ "ENABLE_VR=$enable_vr" ] +} + aggregate_vector_icons("omnibox_vector_icons") { icon_directory = "vector_icons" @@ -56,6 +63,7 @@ "clipboard_url_provider.h", "contextual_suggestions_service.cc", "contextual_suggestions_service.h", + "features.h", "history_match.cc", "history_match.h", "history_provider.cc", @@ -140,6 +148,7 @@ "//third_party/metrics_proto", ] deps = [ + ":build_features", ":in_memory_url_index_cache_proto", "//base", "//base:i18n", @@ -173,7 +182,7 @@ "//url", ] - if (!is_android && !is_ios) { + if ((!is_android || enable_vr) && !is_ios) { sources += get_target_outputs(":omnibox_vector_icons") deps += [ ":omnibox_vector_icons",
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 1ddb541..5d59081 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -20,6 +20,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "components/omnibox/browser/autocomplete_provider.h" +#include "components/omnibox/browser/features.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/suggestion_answer.h" #include "components/search_engines/template_url.h" @@ -28,7 +29,7 @@ #include "ui/gfx/vector_icon_types.h" #include "url/third_party/mozilla/url_parse.h" -#if !defined(OS_ANDROID) && !defined(OS_IOS) +#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) #include "components/omnibox/browser/vector_icons.h" // nogncheck #include "components/vector_icons/vector_icons.h" // nogncheck #endif @@ -185,7 +186,7 @@ // static const gfx::VectorIcon& AutocompleteMatch::TypeToVectorIcon(Type type) { -#if !defined(OS_ANDROID) && !defined(OS_IOS) +#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) switch (type) { case Type::URL_WHAT_YOU_TYPED: case Type::HISTORY_URL:
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index 69e5a1b..183cea27 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -350,12 +350,23 @@ You could lose access to your Google Account or experience identity theft. Chromium recommends changing your password now. </message> </if> - <message name="IDS_PAGE_INFO_CHANGE_PASSWORD_BUTTON" desc="The string used in the page info change password button."> - Help me fix this - </message> - <message name="IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON" desc="The string used in the page info ignore password warning button."> - Ignore - </message> + + <if expr="use_titlecase"> + <message name="IDS_PAGE_INFO_CHANGE_PASSWORD_BUTTON" desc="The string used in the page info change password button. Title case format."> + Help Me Fix This + </message> + <message name="IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON" desc="The string used in the page info ignore password warning button. Title case format."> + Ignore + </message> + </if> + <if expr="not use_titlecase"> + <message name="IDS_PAGE_INFO_CHANGE_PASSWORD_BUTTON" desc="The string used in the page info change password button."> + Help me fix this + </message> + <message name="IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON" desc="The string used in the page info ignore password warning button."> + Ignore + </message> + </if> <message name="IDS_PAGE_INFO_WHITELIST_PASSWORD_REUSE_BUTTON" desc="The string used in the page info whitelist password reuse button."> Site is legitimate </message>
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index f88555a..b7febe4 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -204,6 +204,10 @@ spec_->UpdateWith(std::move(details)); } +void PaymentRequest::NoUpdatedPaymentDetails() { + spec_->RecomputeSpecForDetails(); +} + void PaymentRequest::Abort() { // The API user has decided to abort. If a successful abort message is // returned to the renderer, the Mojo message pipe is closed, which triggers
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h index e6ec003..f6ab391b 100644 --- a/components/payments/content/payment_request.h +++ b/components/payments/content/payment_request.h
@@ -65,6 +65,7 @@ mojom::PaymentOptionsPtr options) override; void Show() override; void UpdateWith(mojom::PaymentDetailsPtr details) override; + void NoUpdatedPaymentDetails() override; void Abort() override; void Complete(mojom::PaymentComplete result) override; void CanMakePayment() override;
diff --git a/components/payments/content/payment_request_spec.cc b/components/payments/content/payment_request_spec.cc index 34b2cea..4d1fe9b8 100644 --- a/components/payments/content/payment_request_spec.cc +++ b/components/payments/content/payment_request_spec.cc
@@ -100,7 +100,11 @@ void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) { details_ = std::move(details); - // We reparse the |details_| and update the observers. + RecomputeSpecForDetails(); +} + +void PaymentRequestSpec::RecomputeSpecForDetails() { + // Reparse the |details_| and update the observers. UpdateSelectedShippingOption(/*after_update=*/true); NotifyOnSpecUpdated(); current_update_reason_ = UpdateReason::NONE;
diff --git a/components/payments/content/payment_request_spec.h b/components/payments/content/payment_request_spec.h index 494f9aa..d95c3fe 100644 --- a/components/payments/content/payment_request_spec.h +++ b/components/payments/content/payment_request_spec.h
@@ -69,6 +69,9 @@ // state that depends on |details|. void UpdateWith(mojom::PaymentDetailsPtr details); + // Recomputes spec based on details. + void RecomputeSpecForDetails(); + void AddObserver(Observer* observer); void RemoveObserver(Observer* observer);
diff --git a/components/printing/common/print_messages.cc b/components/printing/common/print_messages.cc index 6767c4af..5ccf87b2 100644 --- a/components/printing/common/print_messages.cc +++ b/components/printing/common/print_messages.cc
@@ -7,32 +7,56 @@ #include "ui/gfx/geometry/size.h" #define IPC_MESSAGE_IMPL +#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include "components/printing/common/print_messages.h" +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#error "Failed to include header components/printing/common/print_messages.h" +#endif // Generate constructors. #include "ipc/struct_constructor_macros.h" +#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include "components/printing/common/print_messages.h" +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#error "Failed to include header components/printing/common/print_messages.h" +#endif // Generate destructors. #include "ipc/struct_destructor_macros.h" +#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include "components/printing/common/print_messages.h" +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#error "Failed to include header components/printing/common/print_messages.h" +#endif // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC { +#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include "components/printing/common/print_messages.h" +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#error "Failed to include header components/printing/common/print_messages.h" +#endif } // namespace IPC // Generate param traits read methods. #include "ipc/param_traits_read_macros.h" namespace IPC { +#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include "components/printing/common/print_messages.h" +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#error "Failed to include header components/printing/common/print_messages.h" +#endif } // namespace IPC // Generate param traits log methods. #include "ipc/param_traits_log_macros.h" namespace IPC { +#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include "components/printing/common/print_messages.h" +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#error "Failed to include header components/printing/common/print_messages.h" +#endif } // namespace IPC PrintMsg_Print_Params::PrintMsg_Print_Params()
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h index ed443d2..339e63c 100644 --- a/components/printing/common/print_messages.h +++ b/components/printing/common/print_messages.h
@@ -3,7 +3,8 @@ // found in the LICENSE file. // IPC messages for printing. -// Multiply-included message file, hence no include guard. +#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#define COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #include <stdint.h> @@ -30,8 +31,8 @@ // Force multiple inclusion of the param traits file to generate all methods. #undef COMPONENTS_PRINTING_COMMON_PRINTING_PARAM_TRAITS_MACROS_H_ -#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ -#define COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#ifndef INTERNAL_COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#define INTERNAL_COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ struct PrintMsg_Print_Params { PrintMsg_Print_Params(); @@ -97,7 +98,7 @@ }; #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) -#endif // COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ +#endif // INTERNAL_COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ #define IPC_MESSAGE_START PrintMsgStart @@ -485,3 +486,5 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_SetOptionsFromDocument, PrintHostMsg_SetOptionsFromDocument_Params /* params */) #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) + +#endif // COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_
diff --git a/components/reading_list/core/reading_list_store.cc b/components/reading_list/core/reading_list_store.cc index 015c7c3..19e1dbe 100644 --- a/components/reading_list/core/reading_list_store.cc +++ b/components/reading_list/core/reading_list_store.cc
@@ -41,6 +41,7 @@ delegate_ = delegate; clock_ = clock; create_store_callback_.Run( + syncer::READING_LIST, base::Bind(&ReadingListStore::OnStoreCreated, base::AsWeakPtr(this))); }
diff --git a/components/reading_list/core/reading_list_store.h b/components/reading_list/core/reading_list_store.h index d3016f6..e321e1e7 100644 --- a/components/reading_list/core/reading_list_store.h +++ b/components/reading_list/core/reading_list_store.h
@@ -23,6 +23,7 @@ // A ReadingListModelStorage storing and syncing data in protobufs. class ReadingListStore : public ReadingListModelStorage { using StoreFactoryFunction = base::Callback<void( + syncer::ModelType type, const syncer::ModelTypeStore::InitCallback& callback)>; public:
diff --git a/components/safe_browsing/browser/threat_details.cc b/components/safe_browsing/browser/threat_details.cc index 2d978ee..901b2b16 100644 --- a/components/safe_browsing/browser/threat_details.cc +++ b/components/safe_browsing/browser/threat_details.cc
@@ -269,10 +269,11 @@ const security_interstitials::UnsafeResource& unsafe_resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags) override { + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback) override { return new ThreatDetails(ui_manager, web_contents, unsafe_resource, request_context_getter, history_service, - trim_to_ad_tags); + trim_to_ad_tags, done_callback); } private: @@ -294,14 +295,15 @@ const UnsafeResource& resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags) { + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback) { // Set up the factory if this has not been done already (tests do that // before this method is called). if (!factory_) factory_ = g_threat_details_factory_impl.Pointer(); return factory_->CreateThreatDetails(ui_manager, web_contents, resource, request_context_getter, history_service, - trim_to_ad_tags); + trim_to_ad_tags, done_callback); } // Create a ThreatDetails for the given tab. Runs in the UI thread. @@ -311,7 +313,8 @@ const UnsafeResource& resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags) + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback) : content::WebContentsObserver(web_contents), request_context_getter_(request_context_getter), ui_manager_(ui_manager), @@ -321,7 +324,10 @@ num_visits_(0), ambiguous_dom_(false), trim_to_ad_tags_(trim_to_ad_tags), - cache_collector_(new ThreatDetailsCacheCollector) { + cache_collector_(new ThreatDetailsCacheCollector), + done_callback_(done_callback), + all_done_expected_(false), + is_all_done_(false) { redirects_collector_ = new ThreatDetailsRedirectsCollector( history_service ? history_service->AsWeakPtr() : base::WeakPtr<history::HistoryService>()); @@ -335,9 +341,14 @@ did_proceed_(false), num_visits_(0), ambiguous_dom_(false), - trim_to_ad_tags_(false) {} + trim_to_ad_tags_(false), + done_callback_(nullptr), + all_done_expected_(false), + is_all_done_(false) {} -ThreatDetails::~ThreatDetails() {} +ThreatDetails::~ThreatDetails() { + DCHECK(all_done_expected_ == is_all_done_); +} bool ThreatDetails::OnMessageReceived(const IPC::Message& message, RenderFrameHost* render_frame_host) { @@ -646,6 +657,8 @@ void ThreatDetails::FinishCollection(bool did_proceed, int num_visit) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + all_done_expected_ = true; + // Do a second pass over the elements and update iframe elements to have // references to their children. Children may have been received from a // different renderer than the iframe element. @@ -739,14 +752,17 @@ std::string serialized; if (!report_->SerializeToString(&serialized)) { DLOG(ERROR) << "Unable to serialize the threat report."; + AllDone(); return; } // For measuring performance impact of ad sampling reports, we may want to // do all the heavy lifting of creating the report but not actually send it. if (report_->type() == ClientSafeBrowsingReportRequest::AD_SAMPLE && - base::FeatureList::IsEnabled(kAdSamplerCollectButDontSendFeature)) + base::FeatureList::IsEnabled(kAdSamplerCollectButDontSendFeature)) { + AllDone(); return; + } BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, @@ -754,6 +770,14 @@ base::Unretained(WebUIInfoSingleton::GetInstance()), base::Passed(&report_))); ui_manager_->SendSerializedThreatDetails(serialized); + + AllDone(); } +void ThreatDetails::AllDone() { + is_all_done_ = true; + BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(done_callback_, base::Unretained(web_contents()))); +} } // namespace safe_browsing
diff --git a/components/safe_browsing/browser/threat_details.h b/components/safe_browsing/browser/threat_details.h index b633bca..ac38fa92 100644 --- a/components/safe_browsing/browser/threat_details.h +++ b/components/safe_browsing/browser/threat_details.h
@@ -64,6 +64,10 @@ // the Element IDs of the top-level HTML Elements in this frame. using FrameTreeIdToChildIdsMap = base::hash_map<int, std::unordered_set<int>>; +// Callback used to notify a caller that ThreatDetails has finished creating and +// sending a report. +using ThreatDetailsDoneCallback = base::Callback<void(content::WebContents*)>; + class ThreatDetails : public base::RefCountedThreadSafe< ThreatDetails, content::BrowserThread::DeleteOnUIThread>, @@ -78,7 +82,8 @@ const UnsafeResource& resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags); + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback); // Makes the passed |factory| the factory used to instantiate // SafeBrowsingBlockingPage objects. Useful for tests. @@ -111,7 +116,9 @@ const UnsafeResource& resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags); + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback); + // Default constructor for testing only. ThreatDetails(); @@ -179,6 +186,9 @@ const std::vector<AttributeNameValue>& attributes, const ClientSafeBrowsingReportRequest::Resource* resource); + // Called when the report is complete. Runs |done_callback_|. + void AllDone(); + scoped_refptr<BaseUIManager> ui_manager_; const UnsafeResource resource_; @@ -240,6 +250,16 @@ // Used to collect redirect urls from the history service scoped_refptr<ThreatDetailsRedirectsCollector> redirects_collector_; + // Callback to run when the report is finished. + ThreatDetailsDoneCallback done_callback_; + + // Whether this ThreatDetails has begun finalizing the report and is expected + // to invoke |done_callback_| when it finishes. + bool all_done_expected_; + + // Whether the |done_callback_| has been invoked. + bool is_all_done_; + FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HistoryServiceUrls); FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HttpsResourceSanitization); FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HTTPCacheNoEntries); @@ -263,7 +283,8 @@ const security_interstitials::UnsafeResource& unsafe_resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags) = 0; + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback) = 0; }; } // namespace safe_browsing
diff --git a/components/safe_browsing/triggers/trigger_manager.cc b/components/safe_browsing/triggers/trigger_manager.cc index b022eb8..9ce8fad 100644 --- a/components/safe_browsing/triggers/trigger_manager.cc +++ b/components/safe_browsing/triggers/trigger_manager.cc
@@ -14,6 +14,9 @@ #include "content/public/browser/browser_thread.h" #include "net/url_request/url_request_context_getter.h" +DEFINE_WEB_CONTENTS_USER_DATA_KEY( + safe_browsing::TriggerManagerWebContentsHelper); + namespace safe_browsing { namespace { @@ -83,7 +86,9 @@ DataCollectorsContainer::~DataCollectorsContainer() {} TriggerManager::TriggerManager(BaseUIManager* ui_manager) - : ui_manager_(ui_manager), trigger_throttler_(new TriggerThrottler()) {} + : ui_manager_(ui_manager), + trigger_throttler_(new TriggerThrottler()), + weak_factory_(this) {} TriggerManager::~TriggerManager() {} @@ -151,19 +156,19 @@ if (!CanStartDataCollection(error_display_options, trigger_type)) return false; - // Ensure we're not already collecting data on this tab. - // TODO(lpz): this check should be more specific to check that this type of - // data collector is not running on this tab (once additional data collectors - // exist). - if (base::ContainsKey(data_collectors_map_, web_contents)) + // Ensure we're not already collecting ThreatDetails on this tab. Create an + // entry in the map for this |web_contents| if it's not there already. + DataCollectorsContainer* collectors = &data_collectors_map_[web_contents]; + if (collectors->threat_details != nullptr) return false; - DataCollectorsContainer* collectors = &data_collectors_map_[web_contents]; bool should_trim_threat_details = trigger_type == TriggerType::AD_SAMPLE; collectors->threat_details = scoped_refptr<ThreatDetails>(ThreatDetails::NewThreatDetails( ui_manager_, web_contents, resource, request_context_getter, - history_service, should_trim_threat_details)); + history_service, should_trim_threat_details, + base::Bind(&TriggerManager::ThreatDetailsDone, + weak_factory_.GetWeakPtr()))); return true; } @@ -175,39 +180,75 @@ int num_visits, const SBErrorOptions& error_display_options) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // Make sure there's a data collector running on this tab. - // TODO(lpz): this check should be more specific to check that the right type - // of data collector is running on this tab (once additional data collectors - // exist). + // Make sure there's a ThreatDetails collector running on this tab. if (!base::ContainsKey(data_collectors_map_, web_contents)) return false; + DataCollectorsContainer* collectors = &data_collectors_map_[web_contents]; + if (collectors->threat_details == nullptr) + return false; // Determine whether a report should be sent. bool should_send_report = CanSendReport(error_display_options, trigger_type); - DataCollectorsContainer* collectors = &data_collectors_map_[web_contents]; - // Find the data collector and tell it to finish collecting data, and then - // remove it from our map. We release ownership of the data collector here but - // it will live until the end of the FinishCollection call because it - // implements RefCountedThreadSafe. if (should_send_report) { - scoped_refptr<ThreatDetails> threat_details = collectors->threat_details; + // Find the data collector and tell it to finish collecting data. We expect + // it to notify us when it's finished so we can clean up references to it. + content::BrowserThread::PostDelayedTask( content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&ThreatDetails::FinishCollection, threat_details, - did_proceed, num_visits), + base::BindOnce(&ThreatDetails::FinishCollection, + collectors->threat_details, did_proceed, num_visits), delay); // Record that this trigger fired and collected data. trigger_throttler_->TriggerFired(trigger_type); + } else { + // We aren't telling ThreatDetails to finish the report so we should clean + // up our map ourselves. + ThreatDetailsDone(web_contents); } - // Regardless of whether the report got sent, clean up the data collector on - // this tab. - collectors->threat_details = nullptr; - data_collectors_map_.erase(web_contents); - return should_send_report; } +void TriggerManager::ThreatDetailsDone(content::WebContents* web_contents) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // Clean up the ThreatDetailsdata collector on the specified tab. + if (!base::ContainsKey(data_collectors_map_, web_contents)) + return; + + DataCollectorsContainer* collectors = &data_collectors_map_[web_contents]; + collectors->threat_details = nullptr; +} + +void TriggerManager::WebContentsDestroyed(content::WebContents* web_contents) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!base::ContainsKey(data_collectors_map_, web_contents)) + return; + data_collectors_map_.erase(web_contents); +} + +TriggerManagerWebContentsHelper::TriggerManagerWebContentsHelper( + content::WebContents* web_contents, + TriggerManager* trigger_manager) + : content::WebContentsObserver(web_contents), + trigger_manager_(trigger_manager) {} + +TriggerManagerWebContentsHelper::~TriggerManagerWebContentsHelper() {} + +void TriggerManagerWebContentsHelper::CreateForWebContents( + content::WebContents* web_contents, + TriggerManager* trigger_manager) { + DCHECK(web_contents); + if (!FromWebContents(web_contents)) { + web_contents->SetUserData( + UserDataKey(), base::WrapUnique(new TriggerManagerWebContentsHelper( + web_contents, trigger_manager))); + } +} + +void TriggerManagerWebContentsHelper::WebContentsDestroyed() { + trigger_manager_->WebContentsDestroyed(web_contents()); +} + } // namespace safe_browsing
diff --git a/components/safe_browsing/triggers/trigger_manager.h b/components/safe_browsing/triggers/trigger_manager.h index 2cd27eb..c743375a 100644 --- a/components/safe_browsing/triggers/trigger_manager.h +++ b/components/safe_browsing/triggers/trigger_manager.h
@@ -13,6 +13,8 @@ #include "components/security_interstitials/content/unsafe_resource.h" #include "components/security_interstitials/core/base_safe_browsing_error_ui.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" class PrefService; @@ -113,6 +115,14 @@ int num_visits, const SBErrorOptions& error_display_options); + // Called when a ThreatDetails report finishes for the specified + // |web_contents|. + void ThreatDetailsDone(content::WebContents* web_contents); + + // Called when the specified |web_contents| is being destroyed. Used to clean + // up our map. + void WebContentsDestroyed(content::WebContents* web_contents); + private: friend class TriggerManagerTest; @@ -123,15 +133,46 @@ // TODO(lpz): we may only need a the PingManager here. BaseUIManager* ui_manager_; - // Map of the data collectors running on each tabs. + // Map of the data collectors running on each tabs. New keys are added the + // first time any trigger tries to collect data on a tab and are removed when + // the tab is destroyed. The values can be null if a trigger has finished on + // a tab but the tab remains open. DataCollectorsMap data_collectors_map_; // Keeps track of how often triggers fire and throttles them when needed. std::unique_ptr<TriggerThrottler> trigger_throttler_; + base::WeakPtrFactory<TriggerManager> weak_factory_; + // WeakPtrFactory should be last, don't add any members below it. DISALLOW_COPY_AND_ASSIGN(TriggerManager); }; +// A helper class that listens for events happening on a WebContents and can +// notify TriggerManager of any that are relevant. +class TriggerManagerWebContentsHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<TriggerManagerWebContentsHelper> { + public: + ~TriggerManagerWebContentsHelper() override; + + // Creates a TriggerManagerWebContentsHelper and scopes its lifetime to the + // specified |web_contents|. + static void CreateForWebContents(content::WebContents* web_contents, + TriggerManager* trigger_manager); + + // WebContentsObserver implementation. + void WebContentsDestroyed() override; + + private: + friend class content::WebContentsUserData<TriggerManagerWebContentsHelper>; + + TriggerManagerWebContentsHelper(content::WebContents* web_contents, + TriggerManager* trigger_manager); + + // Trigger Manager will be notified of any relevant WebContents events. + TriggerManager* trigger_manager_; +}; + } // namespace safe_browsing #endif // COMPONENTS_SAFE_BROWSING_TRIGGERS_TRIGGER_MANAGER_H_
diff --git a/components/safe_browsing/triggers/trigger_manager_unittest.cc b/components/safe_browsing/triggers/trigger_manager_unittest.cc index fbcddd3..2a2893e 100644 --- a/components/safe_browsing/triggers/trigger_manager_unittest.cc +++ b/components/safe_browsing/triggers/trigger_manager_unittest.cc
@@ -45,7 +45,8 @@ const security_interstitials::UnsafeResource& unsafe_resource, net::URLRequestContextGetter* request_context_getter, history::HistoryService* history_service, - bool trim_to_ad_tags) override { + bool trim_to_ad_tags, + ThreatDetailsDoneCallback done_callback) override { MockThreatDetails* threat_details = new MockThreatDetails(); return threat_details; } @@ -124,8 +125,14 @@ } SBErrorOptions options = TriggerManager::GetSBErrorDisplayOptions(pref_service_, *web_contents); - return trigger_manager_.FinishCollectingThreatDetails( + bool result = trigger_manager_.FinishCollectingThreatDetails( trigger_type, web_contents, base::TimeDelta(), false, 0, options); + + // Invoke the callback if the report was to be sent. + if (expect_report_sent) + trigger_manager_.ThreatDetailsDone(web_contents); + + return result; } const DataCollectorsMap& data_collectors_map() { @@ -159,9 +166,10 @@ EXPECT_TRUE(StartCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1)); EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents1))); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents1).threat_details); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents1).threat_details); // More complex scenarios can happen, where collection happens on two // WebContents at the same time, possibly starting and completing in different @@ -173,36 +181,40 @@ web_contents2)); EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents1), Key(web_contents2))); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents1).threat_details); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents2).threat_details); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents2, true)); - EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents1))); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents1).threat_details); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents2).threat_details); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents1).threat_details); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents2).threat_details); // Calling Start twice with the same WebContents is an error, and will return // false the second time. But it can still be completed normally. EXPECT_TRUE(StartCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1)); - EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents1))); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents1).threat_details); EXPECT_FALSE(StartCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1)); - EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents1))); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents1).threat_details); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents1).threat_details); // Calling Finish twice with the same WebContents is an error, and will return // false the second time. It's basically a no-op. EXPECT_TRUE(StartCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1)); - EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents1))); + EXPECT_NE(nullptr, data_collectors_map().at(web_contents1).threat_details); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents1).threat_details); EXPECT_FALSE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents1, false)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents1).threat_details); } TEST_F(TriggerManagerTest, NoDataCollection_Incognito) { @@ -252,7 +264,7 @@ EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents))); EXPECT_FALSE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents, false)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); } TEST_F(TriggerManagerTest, UserOptsOutOfSBER_DataCollected_NoReportSent) { @@ -268,7 +280,7 @@ EXPECT_FALSE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents, false)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); } TEST_F(TriggerManagerTest, UserOptsInToSBER_DataCollected_ReportSent) { @@ -285,7 +297,7 @@ EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); } TEST_F(TriggerManagerTest, @@ -302,7 +314,7 @@ EXPECT_FALSE(FinishCollectingThreatDetails(TriggerType::SECURITY_INTERSTITIAL, web_contents, false)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); } TEST_F(TriggerManagerTest, NoCollectionWhenOutOfQuota) { @@ -318,14 +330,14 @@ EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents))); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::AD_SAMPLE, web_contents, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); // Turn off the AD_SAMPLE trigger inside the throttler, the trigger should no // longer be able to fire. SetTriggerHasQuota(TriggerType::AD_SAMPLE, false); EXPECT_FALSE( StartCollectingThreatDetails(TriggerType::AD_SAMPLE, web_contents)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); } TEST_F(TriggerManagerTest, AdSamplerTrigger) { @@ -340,7 +352,7 @@ EXPECT_THAT(data_collectors_map(), UnorderedElementsAre(Key(web_contents))); EXPECT_TRUE(FinishCollectingThreatDetails(TriggerType::AD_SAMPLE, web_contents, true)); - EXPECT_TRUE(data_collectors_map().empty()); + EXPECT_EQ(nullptr, data_collectors_map().at(web_contents).threat_details); // Disabling SBEROptInAllowed disables this trigger. SetPref(prefs::kSafeBrowsingExtendedReportingOptInAllowed, false);
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc index e4075eb..670bf21 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc
@@ -50,7 +50,7 @@ DCHECK(!url.is_empty()); auto request = base::MakeUnique<SubresourceFilterSafeBrowsingClientRequest>( - url, request_id, database_manager_, io_task_runner_, this); + request_id, database_manager_, io_task_runner_, this); auto* raw_request = request.get(); DCHECK(requests_.find(raw_request) == requests_.end()); requests_[raw_request] = std::move(request); @@ -58,7 +58,7 @@ "SubresourceFilterSBCheck", raw_request, "check_result", base::MakeUnique<base::trace_event::TracedValue>()); - raw_request->Start(); + raw_request->Start(url); // Careful, |raw_request| can be destroyed after this line. }
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc index d820355..e400801 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc
@@ -14,6 +14,7 @@ #include "base/single_thread_task_runner.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h" #include "content/public/browser/browser_thread.h" +#include "url/gurl.h" namespace subresource_filter { @@ -22,14 +23,12 @@ SubresourceFilterSafeBrowsingClientRequest:: SubresourceFilterSafeBrowsingClientRequest( - const GURL& url, size_t request_id, scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, SubresourceFilterSafeBrowsingClient* client) - : url_(url), - request_id_(request_id), + : request_id_(request_id), database_manager_(std::move(database_manager)), client_(client) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -44,10 +43,10 @@ timer_.Stop(); } -void SubresourceFilterSafeBrowsingClientRequest::Start() { +void SubresourceFilterSafeBrowsingClientRequest::Start(const GURL& url) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); start_time_ = base::TimeTicks::Now(); - if (database_manager_->CheckUrlForSubresourceFilter(url_, this)) { + if (database_manager_->CheckUrlForSubresourceFilter(url, this)) { request_completed_ = true; SendCheckResultToClient(false /* served_from_network */, safe_browsing::SB_THREAT_TYPE_SAFE, @@ -65,7 +64,6 @@ safe_browsing::SBThreatType threat_type, const safe_browsing::ThreatMetadata& metadata) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - DCHECK_EQ(url_, url); request_completed_ = true; SendCheckResultToClient(true /* served_from_network */, threat_type, metadata);
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h index 5f01046..9f9f13d9 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h
@@ -13,7 +13,8 @@ #include "base/timer/timer.h" #include "components/safe_browsing/db/database_manager.h" #include "components/safe_browsing/db/util.h" -#include "url/gurl.h" + +class GURL; namespace base { class SingleThreadTaskRunner; @@ -33,7 +34,6 @@ : public safe_browsing::SafeBrowsingDatabaseManager::Client { public: SubresourceFilterSafeBrowsingClientRequest( - const GURL& url, size_t request_id, scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager, @@ -41,7 +41,7 @@ SubresourceFilterSafeBrowsingClient* client); ~SubresourceFilterSafeBrowsingClientRequest() override; - void Start(); + void Start(const GURL& url); // safe_browsing::SafeBrowsingDatabaseManager::Client: void OnCheckBrowseUrlResult( @@ -49,7 +49,6 @@ safe_browsing::SBThreatType threat_type, const safe_browsing::ThreatMetadata& metadata) override; - const GURL& url() const { return url_; } size_t request_id() const { return request_id_; } // Maximum time in milliseconds to wait for the Safe Browsing service to @@ -68,8 +67,6 @@ safe_browsing::SBThreatType threat_type, const safe_browsing::ThreatMetadata& metadata); - const GURL url_; - // The |request_id_| identifies a particular request, as issued from the // SubresourceFilterSafeBrowsingClient. It will be unique in the scope of a // single navigation (i.e. the scope of the
diff --git a/components/sync/base/data_type_histogram.cc b/components/sync/base/data_type_histogram.cc index 45f563e..18546e4 100644 --- a/components/sync/base/data_type_histogram.cc +++ b/components/sync/base/data_type_histogram.cc
@@ -5,16 +5,9 @@ #include "components/sync/base/data_type_histogram.h" #include "base/metrics/histogram_functions.h" -#include "base/metrics/sparse_histogram.h" const char kModelTypeMemoryHistogramPrefix[] = "Sync.ModelTypeMemoryKB."; -void SyncRecordDatatypeBin(const std::string& name, int sample, int value) { - base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( - name, base::HistogramBase::kUmaTargetedHistogramFlag); - histogram->AddCount(sample, value); -} - void SyncRecordMemoryKbHistogram(const std::string& histogram_name_prefix, syncer::ModelType model_type, size_t value) {
diff --git a/components/sync/base/data_type_histogram.h b/components/sync/base/data_type_histogram.h index 09cc6f3..6eda77f 100644 --- a/components/sync/base/data_type_histogram.h +++ b/components/sync/base/data_type_histogram.h
@@ -14,12 +14,6 @@ // Prefix for histogram recording datatype's memory usage. extern const char kModelTypeMemoryHistogramPrefix[]; -// This function adds |value| to |sample| bucket of histogram |name|. |value| -// should be greater or equal to 1 and |name| can be variable. DataTypes are -// mapped to proper |sample| bucket by using ModelTypeToHistogramInt() function. -// So different DataTypes play the role of different buckets in this histogram. -void SyncRecordDatatypeBin(const std::string& name, int sample, int value); - // Converts memory size |value| into kilobytes and records it into |model_type| // related histogram with prefix |histogram_name_prefix|. void SyncRecordMemoryKbHistogram(const std::string& histogram_name_prefix,
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc index 2f56be14..21d1cae 100644 --- a/components/sync/device_info/device_info_sync_bridge.cc +++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -101,6 +101,7 @@ } store_factory.Run( + DEVICE_INFO, base::Bind(&DeviceInfoSyncBridge::OnStoreCreated, base::AsWeakPtr(this))); }
diff --git a/components/sync/engine_impl/commit.cc b/components/sync/engine_impl/commit.cc index 158e03c..2411e31 100644 --- a/components/sync/engine_impl/commit.cc +++ b/components/sync/engine_impl/commit.cc
@@ -94,19 +94,9 @@ commit_util::AddClientConfigParamsToMessage( enabled_types, cookie_jar_mismatch, commit_message); - int previous_message_size = message.ByteSize(); // Finally, serialize all our contributions. for (const auto& contribution : contributions) { contribution.second->AddToCommitMessage(&message); - int current_entry_size = message.ByteSize() - previous_message_size; - previous_message_size = message.ByteSize(); - int local_integer_model_type = ModelTypeToHistogramInt(contribution.first); - if (current_entry_size > 0) { - SyncRecordDatatypeBin("DataUse.Sync.Upload.Bytes", - local_integer_model_type, current_entry_size); - } - UMA_HISTOGRAM_SPARSE_SLOWLY("DataUse.Sync.Upload.Count", - local_integer_model_type); } // If we made it this far, then we've successfully prepared a commit message.
diff --git a/components/sync/engine_impl/directory_update_handler.cc b/components/sync/engine_impl/directory_update_handler.cc index fcbf0d1..3c7ec4f 100644 --- a/components/sync/engine_impl/directory_update_handler.cc +++ b/components/sync/engine_impl/directory_update_handler.cc
@@ -59,11 +59,6 @@ const SyncEntityList& applicable_updates, StatusController* status) { syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir_); - if (progress_marker.ByteSize() > 0) { - SyncRecordDatatypeBin("DataUse.Sync.ProgressMarker.Bytes", - ModelTypeToHistogramInt(type_), - progress_marker.ByteSize()); - } if (mutated_context.has_context()) { sync_pb::DataTypeContext local_context; dir_->GetDataTypeContext(&trans, type_, &local_context);
diff --git a/components/sync/engine_impl/process_updates_util.cc b/components/sync/engine_impl/process_updates_util.cc index 37c1e3b..5a020b9b 100644 --- a/components/sync/engine_impl/process_updates_util.cc +++ b/components/sync/engine_impl/process_updates_util.cc
@@ -295,12 +295,6 @@ if (verify_result != VERIFY_SUCCESS && verify_result != VERIFY_UNDELETE) continue; ProcessUpdate(*update, dir->GetCryptographer(trans), trans); - if (update->ByteSize() > 0) { - SyncRecordDatatypeBin("DataUse.Sync.Download.Bytes", - ModelTypeToHistogramInt(type), update->ByteSize()); - } - UMA_HISTOGRAM_SPARSE_SLOWLY("DataUse.Sync.Download.Count", - ModelTypeToHistogramInt(type)); } }
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc index 17d61de..310abd7d 100644 --- a/components/sync/engine_impl/syncer_unittest.cc +++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -629,115 +629,6 @@ } } -// This test has three steps. In the first step, a BOOKMARK update is received. -// In the next step, syncing BOOKMARKS is disabled, so no BOOKMARK is sent or -// received. In the last step, a BOOKMARK update is committed. -TEST_F(SyncerTest, DataUseHistogramsTest) { - base::HistogramTester histogram_tester; - sync_pb::EntitySpecifics bookmark_data; - AddDefaultFieldValue(BOOKMARKS, &bookmark_data); - - mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10, foreign_cache_guid(), - "-1"); - int download_bytes_bookmark = 0; - vector<unsigned int> progress_bookmark(3, 0); - vector<unsigned int> progress_all(3, 0); - vector<base::Bucket> samples; - EXPECT_TRUE(SyncShareNudge()); - { - histogram_tester.ExpectTotalCount("DataUse.Sync.Upload.Count", 0); - histogram_tester.ExpectTotalCount("DataUse.Sync.Upload.Bytes", 0); - histogram_tester.ExpectTotalCount("DataUse.Sync.Download.Count", 1); - histogram_tester.ExpectUniqueSample("DataUse.Sync.Download.Count", - BOOKMARKS, 1); - samples = histogram_tester.GetAllSamples("DataUse.Sync.Download.Bytes"); - EXPECT_EQ(1u, samples.size()); - EXPECT_EQ(BOOKMARKS, samples.at(0).min); - EXPECT_GE(samples.at(0).count, 0); - download_bytes_bookmark = samples.at(0).count; - - samples = - histogram_tester.GetAllSamples("DataUse.Sync.ProgressMarker.Bytes"); - - for (const base::Bucket& bucket : samples) { - if (bucket.min == BOOKMARKS) - progress_bookmark.at(0) += bucket.count; - progress_all.at(0) += bucket.count; - } - EXPECT_GT(progress_bookmark.at(0), 0u); - EXPECT_GT(progress_all.at(0), 0u); - - syncable::WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); - MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); - A.PutIsUnsynced(true); - A.PutSpecifics(bookmark_data); - A.PutNonUniqueName("bookmark"); - } - - // Now sync without enabling bookmarks. - mock_server_->ExpectGetUpdatesRequestTypes( - Difference(context_->GetEnabledTypes(), ModelTypeSet(BOOKMARKS))); - ResetCycle(); - syncer_->NormalSyncShare( - Difference(context_->GetEnabledTypes(), ModelTypeSet(BOOKMARKS)), - &nudge_tracker_, cycle_.get()); - - { - // Nothing should have been committed as bookmarks is throttled. - histogram_tester.ExpectTotalCount("DataUse.Sync.Upload.Count", 0); - histogram_tester.ExpectTotalCount("DataUse.Sync.Upload.Bytes", 0); - histogram_tester.ExpectTotalCount("DataUse.Sync.Download.Count", 1); - histogram_tester.ExpectUniqueSample("DataUse.Sync.Download.Count", - BOOKMARKS, 1); - - samples = histogram_tester.GetAllSamples("DataUse.Sync.Download.Bytes"); - EXPECT_EQ(1u, samples.size()); - EXPECT_EQ(BOOKMARKS, samples.at(0).min); - EXPECT_EQ(download_bytes_bookmark, samples.at(0).count); - - samples = - histogram_tester.GetAllSamples("DataUse.Sync.ProgressMarker.Bytes"); - for (const base::Bucket& bucket : samples) { - if (bucket.min == BOOKMARKS) - progress_bookmark.at(1) += bucket.count; - progress_all.at(1) += bucket.count; - } - EXPECT_EQ(progress_bookmark.at(1), progress_bookmark.at(0)); - EXPECT_GT(progress_all.at(1), progress_all.at(0)); - } - - // Sync again with bookmarks enabled. - mock_server_->ExpectGetUpdatesRequestTypes(context_->GetEnabledTypes()); - EXPECT_TRUE(SyncShareNudge()); - { - // It should have been committed. - histogram_tester.ExpectTotalCount("DataUse.Sync.Upload.Count", 1); - histogram_tester.ExpectUniqueSample("DataUse.Sync.Upload.Count", BOOKMARKS, - 1); - samples = histogram_tester.GetAllSamples("DataUse.Sync.Upload.Bytes"); - EXPECT_EQ(1u, samples.size()); - EXPECT_EQ(BOOKMARKS, samples.at(0).min); - EXPECT_GE(samples.at(0).count, 0); - - samples = histogram_tester.GetAllSamples("DataUse.Sync.Download.Bytes"); - EXPECT_EQ(1u, samples.size()); - EXPECT_EQ(BOOKMARKS, samples.at(0).min); - EXPECT_EQ(download_bytes_bookmark, samples.at(0).count); - - histogram_tester.ExpectTotalCount("DataUse.Sync.Download.Count", 1); - - samples = - histogram_tester.GetAllSamples("DataUse.Sync.ProgressMarker.Bytes"); - for (const base::Bucket& bucket : samples) { - if (bucket.min == BOOKMARKS) - progress_bookmark.at(2) += bucket.count; - progress_all.at(2) += bucket.count; - } - EXPECT_GT(progress_bookmark.at(2), progress_bookmark.at(1)); - EXPECT_GT(progress_all.at(2), progress_all.at(1)); - } -} - // We use a macro so we can preserve the error location. #define VERIFY_ENTRY(id, is_unapplied, is_unsynced, prev_initialized, \ parent_id, version, server_version, id_fac, rtrans) \
diff --git a/components/sync/model/model_type_store.cc b/components/sync/model/model_type_store.cc index 8d9dbef..eb2e927 100644 --- a/components/sync/model/model_type_store.cc +++ b/components/sync/model/model_type_store.cc
@@ -17,10 +17,9 @@ } // static -void ModelTypeStore::CreateStore( - ModelType type, - const std::string& path, - const InitCallback& callback) { +void ModelTypeStore::CreateStore(const std::string& path, + ModelType type, + const InitCallback& callback) { ModelTypeStoreImpl::CreateStore(type, path, callback); }
diff --git a/components/sync/model/model_type_store.h b/components/sync/model/model_type_store.h index d52d2ef..8376a18 100644 --- a/components/sync/model/model_type_store.h +++ b/components/sync/model/model_type_store.h
@@ -122,10 +122,9 @@ // CreateStore takes |path|, and will run blocking calls on a task runner // scoped to the given path. Tests likely don't want to use this method. - static void CreateStore( - ModelType type, - const std::string& path, - const InitCallback& callback); + static void CreateStore(const std::string& path, + ModelType type, + const InitCallback& callback); // Creates store object backed by in-memory leveldb database, gets its task // runner from MessageLoop::task_runner(), and should only be used in tests. static void CreateInMemoryStoreForTest(ModelType type, @@ -183,7 +182,7 @@ // Typedef for a store factory that has all params bound except InitCallback. using ModelTypeStoreFactory = - base::Callback<void(const ModelTypeStore::InitCallback&)>; + base::Callback<void(ModelType type, const ModelTypeStore::InitCallback&)>; } // namespace syncer
diff --git a/components/sync/model/model_type_store_test_util.cc b/components/sync/model/model_type_store_test_util.cc index 07b2ac0..7b9fac7a6 100644 --- a/components/sync/model/model_type_store_test_util.cc +++ b/components/sync/model/model_type_store_test_util.cc
@@ -49,6 +49,7 @@ // static void ModelTypeStoreTestUtil::MoveStoreToCallback( std::unique_ptr<ModelTypeStore> store, + ModelType type, const ModelTypeStore::InitCallback& callback) { ASSERT_TRUE(store); callback.Run(Result::SUCCESS, std::move(store));
diff --git a/components/sync/model/model_type_store_test_util.h b/components/sync/model/model_type_store_test_util.h index e911f46..0c3b17b 100644 --- a/components/sync/model/model_type_store_test_util.h +++ b/components/sync/model/model_type_store_test_util.h
@@ -25,6 +25,7 @@ // Can be curried with an owned store object to allow passing an already // created store to a service constructor in a unit test. static void MoveStoreToCallback(std::unique_ptr<ModelTypeStore> store, + ModelType type, const ModelTypeStore::InitCallback& callback); };
diff --git a/components/sync/user_events/user_event_sync_bridge.cc b/components/sync/user_events/user_event_sync_bridge.cc index 0039464..46f827f 100644 --- a/components/sync/user_events/user_event_sync_bridge.cc +++ b/components/sync/user_events/user_event_sync_bridge.cc
@@ -75,6 +75,7 @@ global_id_mapper_(global_id_mapper) { DCHECK(global_id_mapper_); store_factory.Run( + USER_EVENTS, base::Bind(&UserEventSyncBridge::OnStoreCreated, base::AsWeakPtr(this))); global_id_mapper_->AddGlobalIdChangeObserver(base::Bind( &UserEventSyncBridge::HandleGlobalIdChange, base::AsWeakPtr(this)));
diff --git a/components/test/data/payments/no_update_with.js b/components/test/data/payments/no_update_with.js new file mode 100644 index 0000000..4ac1675 --- /dev/null +++ b/components/test/data/payments/no_update_with.js
@@ -0,0 +1,93 @@ +/* + * Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Builds a PaymentRequest that requests a shipping address. + * @return {PaymentRequest} - A new PaymentRequest object. + */ +function buildPaymentRequest() { + try { + return new PaymentRequest( + [{supportedMethods: 'basic-card'}], { + total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}, + shippingOptions: [{ + selected: true, + id: 'freeShipping', + label: 'Free shipping', + amount: {currency: 'USD', value: '0.00'}, + }], + }, + {requestShipping: true}); + } catch (error) { + print(error.message); + } +} + +/** + * Shows the PaymentRequest. + * @param {PaymentRequest} pr - The PaymentRequest object to show. + */ +function showPaymentRequest(pr) { + pr.show() + .then(function(resp) { + resp.complete('success') + .then(function() { + print(JSON.stringify(resp, undefined, 2)); + }) + .catch(function(error) { + print(error); + }); + }) + .catch(function(error) { + print(error); + }); +} + +/** + * Show a PaymentRequest that requests a shipping address, but has no listeners. + */ +function buyWithoutListeners() { // eslint-disable-line no-unused-vars + showPaymentRequest(buildPaymentRequest()); +} + +/** + * Show a PaymentRequest that requests a shipping address, but listeners don't + * call updateWith(). + */ +function buyWithoutCallingUpdateWith() { // eslint-disable-line no-unused-vars + const pr = buildPaymentRequest(); + pr.addEventListener('shippingaddresschange', function(evt) { + print('shippingaddresschange'); + }); + pr.addEventListener('shippingoptionchange', function(evt) { + print('shippingoptionchange'); + }); + showPaymentRequest(pr); +} + +/** + * Show a PaymentRequest that requests a shipping address, but listeners don't + * use promises to update the UI. + */ +function buyWithoutPromises() { // eslint-disable-line no-unused-vars + const pr = buildPaymentRequest(); + const updatedDetails = { + total: {label: 'Updated total', amount: {currency: 'USD', value: '10.00'}}, + shippingOptions: [{ + selected: true, + id: 'updatedShipping', + label: 'Updated shipping', + amount: {currency: 'USD', value: '5.00'}, + }], + }; + pr.addEventListener('shippingaddresschange', function(evt) { + evt.updateWith(updatedDetails); + }); + pr.addEventListener('shippingoptionchange', function(evt) { + evt.updateWith(updatedDetails); + }); + showPaymentRequest(pr); +}
diff --git a/components/test/data/payments/payment_request_no_update_with_test.html b/components/test/data/payments/payment_request_no_update_with_test.html new file mode 100644 index 0000000..54c4edb --- /dev/null +++ b/components/test/data/payments/payment_request_no_update_with_test.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<!-- +Copyright 2017 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> +<title>No updateWith() Test</title> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> +<link rel="stylesheet" type="text/css" href="style.css"> +</head> +<body> +<button onclick="buyWithoutListeners()" id="buyWithoutListeners">Buy without listeners</button> +<button onclick="buyWithoutCallingUpdateWith()" id="buyWithoutCallingUpdateWith">Buy without calling updateWith()</button> +<button onclick="buyWithoutPromises()" id="buyWithoutPromises">Buy without promises</button> +<pre id="result"></pre> +<script src="util.js"></script> +<script src="no_update_with.js"></script> +</body> +</html> \ No newline at end of file
diff --git a/components/ui_devtools/views/BUILD.gn b/components/ui_devtools/views/BUILD.gn index 24df3fe..f4a099a 100644 --- a/components/ui_devtools/views/BUILD.gn +++ b/components/ui_devtools/views/BUILD.gn
@@ -13,8 +13,8 @@ sources = [ "css_agent.cc", "css_agent.h", - "ui_devtools_dom_agent.cc", - "ui_devtools_dom_agent.h", + "dom_agent.cc", + "dom_agent.h", "ui_devtools_overlay_agent.cc", "ui_devtools_overlay_agent.h", "ui_element.cc",
diff --git a/components/ui_devtools/views/css_agent.cc b/components/ui_devtools/views/css_agent.cc index 1b41a1a1..a8167c6 100644 --- a/components/ui_devtools/views/css_agent.cc +++ b/components/ui_devtools/views/css_agent.cc
@@ -118,7 +118,7 @@ } // namespace -CSSAgent::CSSAgent(UIDevToolsDOMAgent* dom_agent) : dom_agent_(dom_agent) { +CSSAgent::CSSAgent(DOMAgent* dom_agent) : dom_agent_(dom_agent) { DCHECK(dom_agent_); }
diff --git a/components/ui_devtools/views/css_agent.h b/components/ui_devtools/views/css_agent.h index 4e8cc52..1ae35ca 100644 --- a/components/ui_devtools/views/css_agent.h +++ b/components/ui_devtools/views/css_agent.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "components/ui_devtools/CSS.h" -#include "components/ui_devtools/views/ui_devtools_dom_agent.h" +#include "components/ui_devtools/views/dom_agent.h" namespace ui_devtools { @@ -15,9 +15,9 @@ class CSSAgent : public ui_devtools::UiDevToolsBaseAgent< ui_devtools::protocol::CSS::Metainfo>, - public UIDevToolsDOMAgentObserver { + public DOMAgentObserver { public: - explicit CSSAgent(UIDevToolsDOMAgent* dom_agent); + explicit CSSAgent(DOMAgent* dom_agent); ~CSSAgent() override; // CSS::Backend: @@ -34,7 +34,7 @@ ui_devtools::protocol::Array<ui_devtools::protocol::CSS::CSSStyle>>* result) override; - // UIDevToolsDOMAgentObserver: + // DOMAgentObserver: void OnElementBoundsChanged(UIElement* ui_element) override; private: @@ -47,7 +47,7 @@ bool SetPropertiesForUIElement(UIElement* ui_element, const gfx::Rect& bounds, bool visible); - UIDevToolsDOMAgent* const dom_agent_; + DOMAgent* const dom_agent_; DISALLOW_COPY_AND_ASSIGN(CSSAgent); };
diff --git a/components/ui_devtools/views/ui_devtools_dom_agent.cc b/components/ui_devtools/views/dom_agent.cc similarity index 93% rename from components/ui_devtools/views/ui_devtools_dom_agent.cc rename to components/ui_devtools/views/dom_agent.cc index 053c325..45acd0c 100644 --- a/components/ui_devtools/views/ui_devtools_dom_agent.cc +++ b/components/ui_devtools/views/dom_agent.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/ui_devtools/views/ui_devtools_dom_agent.h" +#include "components/ui_devtools/views/dom_agent.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" @@ -441,37 +441,36 @@ } // namespace -UIDevToolsDOMAgent::UIDevToolsDOMAgent() +DOMAgent::DOMAgent() : is_building_tree_(false), show_size_on_canvas_(false), highlight_rect_config_(HighlightRectsConfiguration::NO_DRAW) { aura::Env::GetInstance()->AddObserver(this); } -UIDevToolsDOMAgent::~UIDevToolsDOMAgent() { +DOMAgent::~DOMAgent() { aura::Env::GetInstance()->RemoveObserver(this); Reset(); } -ui_devtools::protocol::Response UIDevToolsDOMAgent::disable() { +ui_devtools::protocol::Response DOMAgent::disable() { Reset(); return ui_devtools::protocol::Response::OK(); } -ui_devtools::protocol::Response UIDevToolsDOMAgent::getDocument( +ui_devtools::protocol::Response DOMAgent::getDocument( std::unique_ptr<ui_devtools::protocol::DOM::Node>* out_root) { *out_root = BuildInitialTree(); return ui_devtools::protocol::Response::OK(); } -ui_devtools::protocol::Response UIDevToolsDOMAgent::hideHighlight() { +ui_devtools::protocol::Response DOMAgent::hideHighlight() { if (layer_for_highlighting_ && layer_for_highlighting_->visible()) layer_for_highlighting_->SetVisible(false); return ui_devtools::protocol::Response::OK(); } -ui_devtools::protocol::Response -UIDevToolsDOMAgent::pushNodesByBackendIdsToFrontend( +ui_devtools::protocol::Response DOMAgent::pushNodesByBackendIdsToFrontend( std::unique_ptr<protocol::Array<int>> backend_node_ids, std::unique_ptr<protocol::Array<int>>* result) { *result = protocol::Array<int>::create(); @@ -480,7 +479,7 @@ return ui_devtools::protocol::Response::OK(); } -void UIDevToolsDOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) { +void DOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) { // When parent is null, only need to update |node_id_to_ui_element_|. if (!parent) { node_id_to_ui_element_[child->node_id()] = child; @@ -499,8 +498,7 @@ BuildTreeForUIElement(child)); } -void UIDevToolsDOMAgent::OnUIElementReordered(UIElement* parent, - UIElement* child) { +void DOMAgent::OnUIElementReordered(UIElement* parent, UIElement* child) { DCHECK(node_id_to_ui_element_.count(parent->node_id())); const auto& children = parent->children(); @@ -512,33 +510,32 @@ BuildDomNodeFromUIElement(child)); } -void UIDevToolsDOMAgent::OnUIElementRemoved(UIElement* ui_element) { +void DOMAgent::OnUIElementRemoved(UIElement* ui_element) { DCHECK(node_id_to_ui_element_.count(ui_element->node_id())); RemoveDomNode(ui_element); node_id_to_ui_element_.erase(ui_element->node_id()); } -void UIDevToolsDOMAgent::OnUIElementBoundsChanged(UIElement* ui_element) { +void DOMAgent::OnUIElementBoundsChanged(UIElement* ui_element) { for (auto& observer : observers_) observer.OnElementBoundsChanged(ui_element); } -void UIDevToolsDOMAgent::AddObserver(UIDevToolsDOMAgentObserver* observer) { +void DOMAgent::AddObserver(DOMAgentObserver* observer) { observers_.AddObserver(observer); } -void UIDevToolsDOMAgent::RemoveObserver(UIDevToolsDOMAgentObserver* observer) { +void DOMAgent::RemoveObserver(DOMAgentObserver* observer) { observers_.RemoveObserver(observer); } -UIElement* UIDevToolsDOMAgent::GetElementFromNodeId(int node_id) { +UIElement* DOMAgent::GetElementFromNodeId(int node_id) { return node_id_to_ui_element_[node_id]; } -ui_devtools::protocol::Response UIDevToolsDOMAgent::HighlightNode( - int node_id, - bool show_size) { +ui_devtools::protocol::Response DOMAgent::HighlightNode(int node_id, + bool show_size) { if (!layer_for_highlighting_) { layer_for_highlighting_.reset(new ui::Layer(ui::LayerType::LAYER_TEXTURED)); layer_for_highlighting_->set_name("HighlightingLayer"); @@ -563,9 +560,8 @@ return ui_devtools::protocol::Response::OK(); } -int UIDevToolsDOMAgent::FindElementIdTargetedByPoint( - const gfx::Point& p, - aura::Window* root_window) const { +int DOMAgent::FindElementIdTargetedByPoint(const gfx::Point& p, + aura::Window* root_window) const { aura::Window* targeted_window = root_window->GetEventHandlerForPoint(p); if (!targeted_window) return 0; @@ -590,8 +586,7 @@ targeted_view); } -void UIDevToolsDOMAgent::ShowDistancesInHighlightOverlay(int pinned_id, - int element_id) { +void DOMAgent::ShowDistancesInHighlightOverlay(int pinned_id, int element_id) { const std::pair<aura::Window*, gfx::Rect> pair_r2( node_id_to_ui_element_[element_id]->GetNodeWindowAndBounds()); const std::pair<aura::Window*, gfx::Rect> pair_r1( @@ -637,7 +632,7 @@ } } -int UIDevToolsDOMAgent::GetParentIdOfNodeId(int node_id) const { +int DOMAgent::GetParentIdOfNodeId(int node_id) const { DCHECK(node_id_to_ui_element_.count(node_id)); const UIElement* element = node_id_to_ui_element_.at(node_id); if (element->parent() && element->parent() != window_element_root_.get()) @@ -645,7 +640,7 @@ return 0; } -void UIDevToolsDOMAgent::OnPaintLayer(const ui::PaintContext& context) { +void DOMAgent::OnPaintLayer(const ui::PaintContext& context) { const gfx::Rect& screen_bounds(layer_for_highlighting_->bounds()); ui::PaintRecorder recorder(context, screen_bounds.size()); gfx::Canvas* canvas = recorder.canvas(); @@ -786,17 +781,16 @@ } } -void UIDevToolsDOMAgent::OnHostInitialized(aura::WindowTreeHost* host) { +void DOMAgent::OnHostInitialized(aura::WindowTreeHost* host) { root_windows_.push_back(host->window()); } -void UIDevToolsDOMAgent::OnElementBoundsChanged(UIElement* ui_element) { +void DOMAgent::OnElementBoundsChanged(UIElement* ui_element) { for (auto& observer : observers_) observer.OnElementBoundsChanged(ui_element); } -std::unique_ptr<ui_devtools::protocol::DOM::Node> -UIDevToolsDOMAgent::BuildInitialTree() { +std::unique_ptr<ui_devtools::protocol::DOM::Node> DOMAgent::BuildInitialTree() { is_building_tree_ = true; std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); @@ -819,7 +813,7 @@ } std::unique_ptr<ui_devtools::protocol::DOM::Node> -UIDevToolsDOMAgent::BuildTreeForUIElement(UIElement* ui_element) { +DOMAgent::BuildTreeForUIElement(UIElement* ui_element) { if (ui_element->type() == UIElementType::WINDOW) { return BuildTreeForWindow( ui_element, @@ -836,7 +830,7 @@ return nullptr; } -std::unique_ptr<DOM::Node> UIDevToolsDOMAgent::BuildTreeForWindow( +std::unique_ptr<DOM::Node> DOMAgent::BuildTreeForWindow( UIElement* window_element_root, aura::Window* window) { std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); @@ -861,7 +855,7 @@ return node; } -std::unique_ptr<DOM::Node> UIDevToolsDOMAgent::BuildTreeForRootWidget( +std::unique_ptr<DOM::Node> DOMAgent::BuildTreeForRootWidget( UIElement* widget_element, views::Widget* widget) { std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); @@ -878,9 +872,8 @@ return node; } -std::unique_ptr<DOM::Node> UIDevToolsDOMAgent::BuildTreeForView( - UIElement* view_element, - views::View* view) { +std::unique_ptr<DOM::Node> DOMAgent::BuildTreeForView(UIElement* view_element, + views::View* view) { std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); for (auto* child : view->GetChildrenInZOrder()) { @@ -895,14 +888,14 @@ return node; } -void UIDevToolsDOMAgent::RemoveDomNode(UIElement* ui_element) { +void DOMAgent::RemoveDomNode(UIElement* ui_element) { for (auto* child_element : ui_element->children()) RemoveDomNode(child_element); frontend()->childNodeRemoved(ui_element->parent()->node_id(), ui_element->node_id()); } -void UIDevToolsDOMAgent::Reset() { +void DOMAgent::Reset() { is_building_tree_ = false; render_text_.reset(); layer_for_highlighting_.reset(); @@ -911,7 +904,7 @@ observers_.Clear(); } -void UIDevToolsDOMAgent::UpdateHighlight( +void DOMAgent::UpdateHighlight( const std::pair<aura::Window*, gfx::Rect>& window_and_bounds) { display::Display display = display::Screen::GetScreen()->GetDisplayNearestWindow(
diff --git a/components/ui_devtools/views/ui_devtools_dom_agent.h b/components/ui_devtools/views/dom_agent.h similarity index 85% rename from components/ui_devtools/views/ui_devtools_dom_agent.h rename to components/ui_devtools/views/dom_agent.h index 8cf6042..1a1be99 100644 --- a/components/ui_devtools/views/ui_devtools_dom_agent.h +++ b/components/ui_devtools/views/dom_agent.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_UI_DEVTOOLS_VIEWS_UI_DEVTOOLS_DOM_AGENT_H_ -#define COMPONENTS_UI_DEVTOOLS_VIEWS_UI_DEVTOOLS_DOM_AGENT_H_ +#ifndef COMPONENTS_UI_DEVTOOLS_VIEWS_DOM_AGENT_H_ +#define COMPONENTS_UI_DEVTOOLS_VIEWS_DOM_AGENT_H_ #include "components/ui_devtools/DOM.h" #include "components/ui_devtools/devtools_base_agent.h" @@ -38,19 +38,19 @@ class UIElement; -class UIDevToolsDOMAgentObserver { +class DOMAgentObserver { public: virtual void OnElementBoundsChanged(UIElement* ui_element) = 0; }; -class UIDevToolsDOMAgent : public ui_devtools::UiDevToolsBaseAgent< - ui_devtools::protocol::DOM::Metainfo>, - public UIElementDelegate, - public aura::EnvObserver, - public ui::LayerDelegate { +class DOMAgent : public ui_devtools::UiDevToolsBaseAgent< + ui_devtools::protocol::DOM::Metainfo>, + public UIElementDelegate, + public aura::EnvObserver, + public ui::LayerDelegate { public: - UIDevToolsDOMAgent(); - ~UIDevToolsDOMAgent() override; + DOMAgent(); + ~DOMAgent() override; // DOM::Backend: ui_devtools::protocol::Response disable() override; @@ -67,8 +67,8 @@ void OnUIElementRemoved(UIElement* ui_element) override; void OnUIElementBoundsChanged(UIElement* ui_element) override; - void AddObserver(UIDevToolsDOMAgentObserver* observer); - void RemoveObserver(UIDevToolsDOMAgentObserver* observer); + void AddObserver(DOMAgentObserver* observer); + void RemoveObserver(DOMAgentObserver* observer); UIElement* GetElementFromNodeId(int node_id); UIElement* window_element_root() const { return window_element_root_.get(); }; const std::vector<aura::Window*>& root_windows() const { @@ -139,11 +139,11 @@ std::vector<aura::Window*> root_windows_; gfx::Rect hovered_rect_; gfx::Rect pinned_rect_; - base::ObserverList<UIDevToolsDOMAgentObserver> observers_; + base::ObserverList<DOMAgentObserver> observers_; - DISALLOW_COPY_AND_ASSIGN(UIDevToolsDOMAgent); + DISALLOW_COPY_AND_ASSIGN(DOMAgent); }; } // namespace ui_devtools -#endif // COMPONENTS_UI_DEVTOOLS_VIEWS_UI_DEVTOOLS_DOM_AGENT_H_ +#endif // COMPONENTS_UI_DEVTOOLS_VIEWS_UI_DOM_AGENT_H_
diff --git a/components/ui_devtools/views/ui_devtools_overlay_agent.cc b/components/ui_devtools/views/ui_devtools_overlay_agent.cc index ab876ff..92da51f 100644 --- a/components/ui_devtools/views/ui_devtools_overlay_agent.cc +++ b/components/ui_devtools/views/ui_devtools_overlay_agent.cc
@@ -9,7 +9,7 @@ namespace ui_devtools { -UIDevToolsOverlayAgent::UIDevToolsOverlayAgent(UIDevToolsDOMAgent* dom_agent) +UIDevToolsOverlayAgent::UIDevToolsOverlayAgent(DOMAgent* dom_agent) : dom_agent_(dom_agent) { DCHECK(dom_agent_); }
diff --git a/components/ui_devtools/views/ui_devtools_overlay_agent.h b/components/ui_devtools/views/ui_devtools_overlay_agent.h index 37f8fba..f9370f32 100644 --- a/components/ui_devtools/views/ui_devtools_overlay_agent.h +++ b/components/ui_devtools/views/ui_devtools_overlay_agent.h
@@ -6,7 +6,7 @@ #define COMPONENTS_UI_DEVTOOLS_VIEWS_UI_DEVTOOLS_OVERLAY_AGENT_H_ #include "components/ui_devtools/Overlay.h" -#include "components/ui_devtools/views/ui_devtools_dom_agent.h" +#include "components/ui_devtools/views/dom_agent.h" #include "ui/events/event_handler.h" namespace ui_devtools { @@ -15,7 +15,7 @@ ui_devtools::protocol::Overlay::Metainfo>, public ui::EventHandler { public: - explicit UIDevToolsOverlayAgent(UIDevToolsDOMAgent* dom_agent); + explicit UIDevToolsOverlayAgent(DOMAgent* dom_agent); ~UIDevToolsOverlayAgent() override; int pinned_id() const { return pinned_id_; }; void SetPinnedNodeId(int pinned_id); @@ -36,7 +36,7 @@ void OnMouseEvent(ui::MouseEvent* event) override; void OnKeyEvent(ui::KeyEvent* event) override; - UIDevToolsDOMAgent* const dom_agent_; + DOMAgent* const dom_agent_; int pinned_id_ = 0; DISALLOW_COPY_AND_ASSIGN(UIDevToolsOverlayAgent);
diff --git a/components/ui_devtools/views/ui_devtools_unittest.cc b/components/ui_devtools/views/ui_devtools_unittest.cc index 3ff5272..b6dd544 100644 --- a/components/ui_devtools/views/ui_devtools_unittest.cc +++ b/components/ui_devtools/views/ui_devtools_unittest.cc
@@ -6,7 +6,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "components/ui_devtools/views/css_agent.h" -#include "components/ui_devtools/views/ui_devtools_dom_agent.h" +#include "components/ui_devtools/views/dom_agent.h" #include "components/ui_devtools/views/ui_devtools_overlay_agent.h" #include "components/ui_devtools/views/ui_element.h" #include "components/ui_devtools/views/view_element.h" @@ -224,7 +224,7 @@ fake_frontend_channel_ = base::MakeUnique<FakeFrontendChannel>(); uber_dispatcher_ = base::MakeUnique<UberDispatcher>(fake_frontend_channel_.get()); - dom_agent_ = base::MakeUnique<ui_devtools::UIDevToolsDOMAgent>(); + dom_agent_ = base::MakeUnique<ui_devtools::DOMAgent>(); dom_agent_->Init(uber_dispatcher_.get()); css_agent_ = base::MakeUnique<ui_devtools::CSSAgent>(dom_agent_.get()); css_agent_->Init(uber_dispatcher_.get()); @@ -363,7 +363,7 @@ } ui_devtools::CSSAgent* css_agent() { return css_agent_.get(); } - ui_devtools::UIDevToolsDOMAgent* dom_agent() { return dom_agent_.get(); } + ui_devtools::DOMAgent* dom_agent() { return dom_agent_.get(); } ui_devtools::UIDevToolsOverlayAgent* overlay_agent() { return overlay_agent_.get(); } @@ -375,7 +375,7 @@ private: std::unique_ptr<UberDispatcher> uber_dispatcher_; std::unique_ptr<FakeFrontendChannel> fake_frontend_channel_; - std::unique_ptr<ui_devtools::UIDevToolsDOMAgent> dom_agent_; + std::unique_ptr<ui_devtools::DOMAgent> dom_agent_; std::unique_ptr<ui_devtools::CSSAgent> css_agent_; std::unique_ptr<ui_devtools::UIDevToolsOverlayAgent> overlay_agent_;
diff --git a/components/viz/test/data/mask_as_blending_rotated_circle_underflow.png b/components/viz/test/data/mask_as_blending_rotated_circle_underflow.png index f74995d..5eb0a99 100644 --- a/components/viz/test/data/mask_as_blending_rotated_circle_underflow.png +++ b/components/viz/test/data/mask_as_blending_rotated_circle_underflow.png Binary files differ
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 6265d0e..c330d57 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -116,6 +116,13 @@ RunTest(html_file, "accessibility/html"); } + void RunRegressionTest(const base::FilePath::CharType* file_path) { + base::FilePath test_path = GetTestFilePath("accessibility", "regression"); + base::FilePath test_file = test_path.Append(base::FilePath(file_path)); + + RunTest(test_file, "accessibility/regression"); + } + std::vector<std::string> Dump() override { std::unique_ptr<AccessibilityTreeFormatter> formatter( CreateAccessibilityTreeFormatter()); @@ -1689,4 +1696,14 @@ RunHtmlTest(FILE_PATH_LITERAL("window-crops-items.html")); } +// +// Regression tests. These don't test a specific web platform feature, +// they test a specific web page that crashed or had some bad behavior +// in the past. +// + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, XmlInIframeCrash) { + RunRegressionTest(FILE_PATH_LITERAL("xml-in-iframe-crash.html")); +} + } // namespace content
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc index ce10263..15bd37e 100644 --- a/content/browser/devtools/devtools_agent_host_impl.cc +++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -169,7 +169,7 @@ return; scoped_refptr<DevToolsAgentHostImpl> protect(this); if (!sessions_.empty()) - ForceDetachAllClients(true); + ForceDetachAllClients(); DCHECK(sessions_.empty()); InnerAttachClient(client); } @@ -282,19 +282,19 @@ return false; } -void DevToolsAgentHostImpl::ForceDetachAllClients(bool replaced) { +void DevToolsAgentHostImpl::ForceDetachAllClients() { scoped_refptr<DevToolsAgentHostImpl> protect(this); while (!session_by_client_.empty()) { DevToolsAgentHostClient* client = session_by_client_.begin()->first; InnerDetachClient(client); - client->AgentHostClosed(this, replaced); + client->AgentHostClosed(this); } } void DevToolsAgentHostImpl::ForceDetachSession(DevToolsSession* session) { DevToolsAgentHostClient* client = session->client(); InnerDetachClient(client); - client->AgentHostClosed(this, false); + client->AgentHostClosed(this); } void DevToolsAgentHostImpl::InspectElement( @@ -313,7 +313,7 @@ DevToolsMap copy = g_devtools_instances.Get(); for (DevToolsMap::iterator it(copy.begin()); it != copy.end(); ++it) { DevToolsAgentHostImpl* agent_host = it->second; - agent_host->ForceDetachAllClients(true); + agent_host->ForceDetachAllClients(); } }
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h index 7d7bf9a..810e3aa8 100644 --- a/content/browser/devtools/devtools_agent_host_impl.h +++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -64,7 +64,7 @@ void NotifyCreated(); void NotifyNavigated(); - void ForceDetachAllClients(bool replaced); + void ForceDetachAllClients(); void ForceDetachSession(DevToolsSession* session); DevToolsIOContext* GetIOContext() { return &io_context_; }
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 4468bc4..1f550cf2a 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -279,16 +279,13 @@ agent_host_->DetachClient(this); } - void AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override { + void AgentHostClosed(DevToolsAgentHost* agent_host) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(agent_host == agent_host_.get()); - std::string message = base::StringPrintf( + std::string message = "{ \"method\": \"Inspector.detached\", " - "\"params\": { \"reason\": \"%s\"} }", - replaced_with_another_client ? - "replaced_with_devtools" : "target_closed"); + "\"params\": { \"reason\": \"target_closed\"} }"; DispatchProtocolMessage(agent_host, message); agent_host_ = nullptr;
diff --git a/content/browser/devtools/devtools_manager_unittest.cc b/content/browser/devtools/devtools_manager_unittest.cc index 0f40f6b..9c61be1d 100644 --- a/content/browser/devtools/devtools_manager_unittest.cc +++ b/content/browser/devtools/devtools_manager_unittest.cc
@@ -53,9 +53,7 @@ closed_ = true; } - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override { - FAIL(); - } + void AgentHostClosed(DevToolsAgentHost* agent_host) override { FAIL(); } void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override {
diff --git a/content/browser/devtools/devtools_pipe_handler.cc b/content/browser/devtools/devtools_pipe_handler.cc index 573374e..dce8d28 100644 --- a/content/browser/devtools/devtools_pipe_handler.cc +++ b/content/browser/devtools/devtools_pipe_handler.cc
@@ -265,7 +265,6 @@ FROM_HERE, base::BindOnce(&WriteIntoPipe, write_fd_, std::move(message))); } -void DevToolsPipeHandler::AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) {} +void DevToolsPipeHandler::AgentHostClosed(DevToolsAgentHost* agent_host) {} } // namespace content
diff --git a/content/browser/devtools/devtools_pipe_handler.h b/content/browser/devtools/devtools_pipe_handler.h index d6f708a..ec8be1c 100644 --- a/content/browser/devtools/devtools_pipe_handler.h +++ b/content/browser/devtools/devtools_pipe_handler.h
@@ -28,8 +28,7 @@ // DevToolsAgentHostClient overrides void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override; - void AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override; + void AgentHostClosed(DevToolsAgentHost* agent_host) override; void Shutdown();
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 05c7bd3e..d12c6b8 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -473,7 +473,7 @@ } } - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override { + void AgentHostClosed(DevToolsAgentHost* agent_host) override { if (!agent_host_can_close_) NOTREACHED(); }
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc index 48b47db..eae300c 100644 --- a/content/browser/devtools/protocol/target_handler.cc +++ b/content/browser/devtools/protocol/target_handler.cc
@@ -83,8 +83,7 @@ agent_host_->GetId()); } - void AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override { + void AgentHostClosed(DevToolsAgentHost* agent_host) override { DCHECK(agent_host == agent_host_.get()); Detach(true); }
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index 09f7270a..0c196be 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -929,7 +929,7 @@ UpdateProtocolHandlers(nullptr); if (IsAttached()) OnClientsDetached(); - ForceDetachAllClients(false); + ForceDetachAllClients(); frame_host_ = nullptr; pending_.reset(); current_.reset();
diff --git a/content/browser/devtools/shared_worker_devtools_manager_unittest.cc b/content/browser/devtools/shared_worker_devtools_manager_unittest.cc index abd0280..42a71b492 100644 --- a/content/browser/devtools/shared_worker_devtools_manager_unittest.cc +++ b/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
@@ -31,7 +31,7 @@ ~TestDevToolsClientHost() override {} void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override {} - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {} + void AgentHostClosed(DevToolsAgentHost* agent_host) override {} void InspectAgentHost(DevToolsAgentHost* agent_host) { if (agent_host_.get())
diff --git a/content/browser/devtools/site_per_process_devtools_browsertest.cc b/content/browser/devtools/site_per_process_devtools_browsertest.cc index 8b976de..c40de12 100644 --- a/content/browser/devtools/site_per_process_devtools_browsertest.cc +++ b/content/browser/devtools/site_per_process_devtools_browsertest.cc
@@ -45,9 +45,7 @@ } } - void AgentHostClosed( - DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override { + void AgentHostClosed(DevToolsAgentHost* agent_host) override { closed_ = true; }
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 747475c..b5a5c298d 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -4,7 +4,10 @@ #include "content/browser/frame_host/navigation_request.h" +#include <map> +#include <string> #include <utility> +#include <vector> #include "base/memory/ptr_util.h" #include "base/optional.h" @@ -910,9 +913,15 @@ } DCHECK(render_frame_host); - // Don't ask the renderer to commit an URL if the browser will kill it when - // it does. - DCHECK(render_frame_host->CanCommitURL(common_params_.url)); + // The check below is not valid in case of blocked requests, because blocked + // requests are committed in the old process (which might not pass the + // CanCommitURL check, but this is okay because we will commit a + // chrome-error:// page). + if (net_error != net::ERR_BLOCKED_BY_CLIENT) { + // Don't ask the renderer to commit an URL if the browser will kill it when + // it does. + DCHECK(render_frame_host->CanCommitURL(common_params_.url)); + } NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host, common_params_.url);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index a955108..9d2145d 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1546,10 +1546,17 @@ 100); } + // Blocked navigations are expected to commit in the old renderer + // (and therefore such navigations do not go through CanCommitURL checks + // below). + bool is_blocked_navigation = + navigation_handle_ && + navigation_handle_->GetNetErrorCode() == net::ERR_BLOCKED_BY_CLIENT; + // Attempts to commit certain off-limits URL should be caught more strictly // than our FilterURL checks below. If a renderer violates this policy, it // should be killed. - if (!CanCommitURL(validated_params->url)) { + if (!is_blocked_navigation && !CanCommitURL(validated_params->url)) { VLOG(1) << "Blocked URL " << validated_params->url.spec(); // Kills the process. bad_message::ReceivedBadMessage(process, @@ -3685,6 +3692,23 @@ // out-of-process iframes implementation is ready, we should check for // cross-site URLs that are not allowed to commit in this process. + // WebView guests can commit any origin. + // This is safe, because: + // 1) WebView guests are in a different StoragePartition, essentially outside + // the browser. + // 2) The user has to trust the app that's providing the webview (e.g. + // Webviews don't have reliable address bars so the user has to trust that + // the Webview won't contain any malicious or phishing sites). + // This is difficult to change, because: + // 1) WebView guests cannot contain OOPIFs today. + // 2) extensions::ProcessMap doesn't track webview accessible resources + // (see WebViewTest.ReloadWebviewAccessibleResource). + // + // TODO(lukasza): https://crbug.com/614463: Removes this exception once + // WebView guests support OOPIFs. + if (GetSiteInstance()->GetSiteURL().SchemeIs(kGuestScheme)) + return true; + // Give the client a chance to disallow URLs from committing. return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); }
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index cdf4622..95dbba3 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -38,11 +38,13 @@ namespace content { +#if defined(OS_ANDROID) namespace { void TimedOut() { LOG(FATAL) << "Timed out waiting for GPU channel."; } } // namespace +#endif // OS_ANDROID BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; @@ -351,15 +353,12 @@ void BrowserGpuChannelHostFactory::RestartTimeout() { DCHECK(IsMainThread()); +// Only implement timeout on Android, which does not have a software fallback. #if defined(OS_ANDROID) if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableTimeoutsForProfiling)) { return; } -#else - // Only implement timeout on Android, which does not have a software fallback. - return; -#endif if (!pending_request_) return; @@ -376,6 +375,7 @@ timeout_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds), base::Bind(&TimedOut)); +#endif // OS_ANDROID } // static
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc index d905d071..2c733c7 100644 --- a/content/browser/media/capture/desktop_capture_device.cc +++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -434,7 +434,8 @@ webrtc::DesktopCapturer::CreateScreenCapturer(options)); if (screen_capturer && screen_capturer->SelectSource(source.id)) { capturer.reset(new webrtc::DesktopAndCursorComposer( - std::move(screen_capturer), options)); + screen_capturer.release(), + webrtc::MouseCursorMonitor::CreateForScreen(options, source.id))); IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED); IncrementDesktopCaptureCounter( source.audio_share ? SCREEN_CAPTURER_CREATED_WITH_AUDIO @@ -449,7 +450,8 @@ if (window_capturer && window_capturer->SelectSource(source.id)) { window_capturer->FocusOnSelectedSource(); capturer.reset(new webrtc::DesktopAndCursorComposer( - std::move(window_capturer), options)); + window_capturer.release(), + webrtc::MouseCursorMonitor::CreateForWindow(options, source.id))); IncrementDesktopCaptureCounter(WINDOW_CAPTURER_CREATED); } break;
diff --git a/content/browser/media/session/audio_focus_manager_unittest.cc b/content/browser/media/session/audio_focus_manager_unittest.cc index aa89b54..46d2c1c 100644 --- a/content/browser/media/session/audio_focus_manager_unittest.cc +++ b/content/browser/media/session/audio_focus_manager_unittest.cc
@@ -23,6 +23,8 @@ public: void OnSuspend(int player_id) override {} void OnResume(int player_id) override {} + void OnSeekForward(int player_id, base::TimeDelta seek_time) override {} + void OnSeekBackward(int player_id, base::TimeDelta seek_time) override {} void OnSetVolumeMultiplier( int player_id, double volume_multiplier) override {} RenderFrameHost* render_frame_host() const override { return nullptr; }
diff --git a/content/browser/media/session/media_session_android.cc b/content/browser/media/session/media_session_android.cc index 48f3e1f..ff8ad02 100644 --- a/content/browser/media/session/media_session_android.cc +++ b/content/browser/media/session/media_session_android.cc
@@ -5,6 +5,7 @@ #include "content/browser/media/session/media_session_android.h" #include "base/android/jni_array.h" +#include "base/time/time.h" #include "content/browser/media/session/media_session_impl.h" #include "content/browser/web_contents/web_contents_android.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -134,6 +135,26 @@ media_session()->Stop(MediaSession::SuspendType::UI); } +void MediaSessionAndroid::SeekForward( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_obj, + const jlong millis) { + DCHECK(media_session()); + DCHECK_GE(millis, 0) + << "Attempted to seek by a negative number of milliseconds"; + media_session()->SeekForward(base::TimeDelta::FromMilliseconds(millis)); +} + +void MediaSessionAndroid::SeekBackward( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_obj, + const jlong millis) { + DCHECK(media_session()); + DCHECK_GE(millis, 0) + << "Attempted to seek by a negative number of milliseconds"; + media_session()->SeekBackward(base::TimeDelta::FromMilliseconds(millis)); +} + void MediaSessionAndroid::DidReceiveAction(JNIEnv* env, const JavaParamRef<jobject>& obj, int action) {
diff --git a/content/browser/media/session/media_session_android.h b/content/browser/media/session/media_session_android.h index 614f450..3d3ea8e 100644 --- a/content/browser/media/session/media_session_android.h +++ b/content/browser/media/session/media_session_android.h
@@ -44,6 +44,12 @@ void Resume(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj); void Suspend(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj); void Stop(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj); + void SeekForward(JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_obj, + const jlong millis); + void SeekBackward(JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_obj, + const jlong millis); void DidReceiveAction(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj, jint action);
diff --git a/content/browser/media/session/media_session_controller.cc b/content/browser/media/session/media_session_controller.cc index b9334dc..3a59f89f 100644 --- a/content/browser/media/session/media_session_controller.cc +++ b/content/browser/media/session/media_session_controller.cc
@@ -87,6 +87,20 @@ new MediaPlayerDelegateMsg_Play(id_.first->GetRoutingID(), id_.second)); } +void MediaSessionController::OnSeekForward(int player_id, + base::TimeDelta seek_time) { + DCHECK_EQ(player_id_, player_id); + id_.first->Send(new MediaPlayerDelegateMsg_SeekForward( + id_.first->GetRoutingID(), id_.second, seek_time)); +} + +void MediaSessionController::OnSeekBackward(int player_id, + base::TimeDelta seek_time) { + DCHECK_EQ(player_id_, player_id); + id_.first->Send(new MediaPlayerDelegateMsg_SeekBackward( + id_.first->GetRoutingID(), id_.second, seek_time)); +} + void MediaSessionController::OnSetVolumeMultiplier(int player_id, double volume_multiplier) { DCHECK_EQ(player_id_, player_id);
diff --git a/content/browser/media/session/media_session_controller.h b/content/browser/media/session/media_session_controller.h index 5a35b25..ca3a8874 100644 --- a/content/browser/media/session/media_session_controller.h +++ b/content/browser/media/session/media_session_controller.h
@@ -49,6 +49,8 @@ // MediaSessionObserver implementation. void OnSuspend(int player_id) override; void OnResume(int player_id) override; + void OnSeekForward(int player_id, base::TimeDelta seek_time) override; + void OnSeekBackward(int player_id, base::TimeDelta seek_time) override; void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override; RenderFrameHost* render_frame_host() const override;
diff --git a/content/browser/media/session/media_session_controller_unittest.cc b/content/browser/media/session/media_session_controller_unittest.cc index b4c4f8c..96fd8a37 100644 --- a/content/browser/media/session/media_session_controller_unittest.cc +++ b/content/browser/media/session/media_session_controller_unittest.cc
@@ -49,6 +49,16 @@ controller_->OnResume(controller_->get_player_id_for_testing()); } + void SeekForward(base::TimeDelta seek_time) { + controller_->OnSeekForward(controller_->get_player_id_for_testing(), + seek_time); + } + + void SeekBackward(base::TimeDelta seek_time) { + controller_->OnSeekBackward(controller_->get_player_id_for_testing(), + seek_time); + } + void SetVolumeMultiplier(double multiplier) { controller_->OnSetVolumeMultiplier(controller_->get_player_id_for_testing(), multiplier); @@ -70,6 +80,25 @@ } template <typename T> + bool ReceivedMessageSeek(base::TimeDelta expected_seek_time) { + const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID); + if (!msg) + return false; + + std::tuple<int, base::TimeDelta> result; + if (!T::Read(msg, &result)) + return false; + + EXPECT_EQ(id_.second, std::get<0>(result)); + if (id_.second != std::get<0>(result)) + return false; + + EXPECT_EQ(expected_seek_time, std::get<1>(result)); + test_sink().ClearMessages(); + return expected_seek_time == std::get<1>(result); + } + + template <typename T> bool ReceivedMessageVolumeMultiplierUpdate(double expected_multiplier) { const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID); if (!msg) @@ -127,6 +156,16 @@ Resume(); EXPECT_TRUE(ReceivedMessagePlayPause<MediaPlayerDelegateMsg_Play>()); + // ...as well as the seek behavior. + const base::TimeDelta kTestSeekForwardTime = base::TimeDelta::FromSeconds(1); + SeekForward(kTestSeekForwardTime); + EXPECT_TRUE(ReceivedMessageSeek<MediaPlayerDelegateMsg_SeekForward>( + kTestSeekForwardTime)); + const base::TimeDelta kTestSeekBackwardTime = base::TimeDelta::FromSeconds(2); + SeekBackward(kTestSeekBackwardTime); + EXPECT_TRUE(ReceivedMessageSeek<MediaPlayerDelegateMsg_SeekBackward>( + kTestSeekBackwardTime)); + // Verify destruction of the controller removes its session. controller_.reset(); EXPECT_FALSE(media_session()->IsActive());
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index 5a2642d..fdc752d 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -395,6 +395,16 @@ AbandonSystemAudioFocusIfNeeded(); } +void MediaSessionImpl::SeekForward(base::TimeDelta seek_time) { + for (const auto& it : normal_players_) + it.observer->OnSeekForward(it.player_id, seek_time); +} + +void MediaSessionImpl::SeekBackward(base::TimeDelta seek_time) { + for (const auto& it : normal_players_) + it.observer->OnSeekBackward(it.player_id, seek_time); +} + bool MediaSessionImpl::IsControllable() const { // Only media session having focus Gain can be controllable unless it is // inactive. Also, the session will be uncontrollable if it contains one-shot
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index 407adfea..0bcdca3 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -127,6 +127,12 @@ // |type| represents the origin of the request. CONTENT_EXPORT void Stop(MediaSession::SuspendType suspend_type) override; + // Seek the media session forward. + CONTENT_EXPORT void SeekForward(base::TimeDelta seek_time) override; + + // Seek the media session backward. + CONTENT_EXPORT void SeekBackward(base::TimeDelta seek_time) override; + // Returns if the session can be controlled by Resume() and Suspend() calls // above. CONTENT_EXPORT bool IsControllable() const override;
diff --git a/content/browser/media/session/media_session_impl_browsertest.cc b/content/browser/media/session/media_session_impl_browsertest.cc index 5d41afd0..e8f27ad 100644 --- a/content/browser/media/session/media_session_impl_browsertest.cc +++ b/content/browser/media/session/media_session_impl_browsertest.cc
@@ -141,6 +141,14 @@ : MediaSessionImpl::State::INACTIVE); } + void UISeekForward() { + media_session_->SeekForward(base::TimeDelta::FromSeconds(1)); + } + + void UISeekBackward() { + media_session_->SeekBackward(base::TimeDelta::FromSeconds(1)); + } + void SystemStartDucking() { media_session_->StartDucking(); } void SystemStopDucking() { media_session_->StopDucking(); } @@ -414,7 +422,7 @@ } IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, - ResumeSuspendAreSentOnlyOncePerPlayers) { + ResumeSuspendSeekAreSentOnlyOncePerPlayers) { auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(); StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent); @@ -423,16 +431,24 @@ EXPECT_EQ(0, player_observer->received_suspend_calls()); EXPECT_EQ(0, player_observer->received_resume_calls()); + EXPECT_EQ(0, player_observer->received_seek_forward_calls()); + EXPECT_EQ(0, player_observer->received_seek_backward_calls()); SystemSuspend(true); EXPECT_EQ(3, player_observer->received_suspend_calls()); SystemResume(); EXPECT_EQ(3, player_observer->received_resume_calls()); + + UISeekForward(); + EXPECT_EQ(3, player_observer->received_seek_forward_calls()); + + UISeekBackward(); + EXPECT_EQ(3, player_observer->received_seek_backward_calls()); } IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, - ResumeSuspendAreSentOnlyOncePerPlayersAddedTwice) { + ResumeSuspendSeekAreSentOnlyOncePerPlayersAddedTwice) { auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(); StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent); @@ -449,12 +465,20 @@ EXPECT_EQ(0, player_observer->received_suspend_calls()); EXPECT_EQ(0, player_observer->received_resume_calls()); + EXPECT_EQ(0, player_observer->received_seek_forward_calls()); + EXPECT_EQ(0, player_observer->received_seek_backward_calls()); SystemSuspend(true); EXPECT_EQ(3, player_observer->received_suspend_calls()); SystemResume(); EXPECT_EQ(3, player_observer->received_resume_calls()); + + UISeekForward(); + EXPECT_EQ(3, player_observer->received_seek_forward_calls()); + + UISeekBackward(); + EXPECT_EQ(3, player_observer->received_seek_backward_calls()); } IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
diff --git a/content/browser/media/session/media_session_impl_service_routing_unittest.cc b/content/browser/media/session/media_session_impl_service_routing_unittest.cc index dbc1f2ef..7933899d 100644 --- a/content/browser/media/session/media_session_impl_service_routing_unittest.cc +++ b/content/browser/media/session/media_session_impl_service_routing_unittest.cc
@@ -64,6 +64,8 @@ MOCK_METHOD1(OnSuspend, void(int player_id)); MOCK_METHOD1(OnResume, void(int player_id)); + MOCK_METHOD2(OnSeekForward, void(int player_id, base::TimeDelta seek_time)); + MOCK_METHOD2(OnSeekBackward, void(int player_id, base::TimeDelta seek_time)); MOCK_METHOD2(OnSetVolumeMultiplier, void(int player_id, double volume_multiplier));
diff --git a/content/browser/media/session/media_session_impl_uma_unittest.cc b/content/browser/media/session/media_session_impl_uma_unittest.cc index 523a52e..cf8d5d3 100644 --- a/content/browser/media/session/media_session_impl_uma_unittest.cc +++ b/content/browser/media/session/media_session_impl_uma_unittest.cc
@@ -34,6 +34,8 @@ void OnSuspend(int player_id) override {} void OnResume(int player_id) override {} + void OnSeekForward(int player_id, base::TimeDelta seek_time) override {} + void OnSeekBackward(int player_id, base::TimeDelta seek_time) override {} void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override { }
diff --git a/content/browser/media/session/media_session_player_observer.h b/content/browser/media/session/media_session_player_observer.h index 613da019..93b62471 100644 --- a/content/browser/media/session/media_session_player_observer.h +++ b/content/browser/media/session/media_session_player_observer.h
@@ -5,6 +5,8 @@ #ifndef CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_PLAYER_OBSERVER_H_ #define CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_PLAYER_OBSERVER_H_ +#include "base/time/time.h" + namespace content { class RenderFrameHost; @@ -20,6 +22,12 @@ // The given |player_id| has been resumed by the MediaSession. virtual void OnResume(int player_id) = 0; + // The given |player_id| has been seeked forward by the MediaSession. + virtual void OnSeekForward(int player_id, base::TimeDelta seek_time) = 0; + + // The given |player_id| has been seeked backward by the MediaSession. + virtual void OnSeekBackward(int player_id, base::TimeDelta seek_time) = 0; + // The given |player_id| has been set a new volume multiplier by // the MediaSession. virtual void OnSetVolumeMultiplier(int player_id,
diff --git a/content/browser/media/session/media_session_service_impl_browsertest.cc b/content/browser/media/session/media_session_service_impl_browsertest.cc index 676dc1c..2a11394 100644 --- a/content/browser/media/session/media_session_service_impl_browsertest.cc +++ b/content/browser/media/session/media_session_service_impl_browsertest.cc
@@ -64,6 +64,8 @@ void OnSuspend(int player_id) override {} void OnResume(int player_id) override {} + void OnSeekForward(int player_id, base::TimeDelta seek_time) override {} + void OnSeekBackward(int player_id, base::TimeDelta seek_time) override {} void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override { }
diff --git a/content/browser/media/session/mock_media_session_player_observer.cc b/content/browser/media/session/mock_media_session_player_observer.cc index 0de898a..8b6af939 100644 --- a/content/browser/media/session/mock_media_session_player_observer.cc +++ b/content/browser/media/session/mock_media_session_player_observer.cc
@@ -30,6 +30,20 @@ players_[player_id].is_playing_ = true; } +void MockMediaSessionPlayerObserver::OnSeekForward(int player_id, + base::TimeDelta seek_time) { + EXPECT_GE(player_id, 0); + EXPECT_GT(players_.size(), static_cast<size_t>(player_id)); + ++received_seek_forward_calls_; +} + +void MockMediaSessionPlayerObserver::OnSeekBackward(int player_id, + base::TimeDelta seek_time) { + EXPECT_GE(player_id, 0); + EXPECT_GT(players_.size(), static_cast<size_t>(player_id)); + ++received_seek_backward_calls_; +} + void MockMediaSessionPlayerObserver::OnSetVolumeMultiplier( int player_id, double volume_multiplier) { @@ -75,4 +89,12 @@ return received_resume_calls_; } +int MockMediaSessionPlayerObserver::received_seek_forward_calls() const { + return received_seek_forward_calls_; +} + +int MockMediaSessionPlayerObserver::received_seek_backward_calls() const { + return received_seek_backward_calls_; +} + } // namespace content
diff --git a/content/browser/media/session/mock_media_session_player_observer.h b/content/browser/media/session/mock_media_session_player_observer.h index 2ebe187..967672c5 100644 --- a/content/browser/media/session/mock_media_session_player_observer.h +++ b/content/browser/media/session/mock_media_session_player_observer.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <vector> +#include "base/time/time.h" #include "content/browser/media/session/media_session_player_observer.h" namespace content { @@ -23,6 +24,8 @@ // Implements MediaSessionPlayerObserver. void OnSuspend(int player_id) override; void OnResume(int player_id) override; + void OnSeekForward(int player_id, base::TimeDelta seek_time) override; + void OnSeekBackward(int player_id, base::TimeDelta seek_time) override; void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override; RenderFrameHost* render_frame_host() const override; @@ -41,6 +44,8 @@ int received_suspend_calls() const; int received_resume_calls() const; + int received_seek_forward_calls() const; + int received_seek_backward_calls() const; private: // Internal representation of the players to keep track of their statuses. @@ -60,6 +65,8 @@ int received_resume_calls_ = 0; int received_suspend_calls_ = 0; + int received_seek_forward_calls_ = 0; + int received_seek_backward_calls_ = 0; }; } // namespace content
diff --git a/content/browser/media/session/pepper_player_delegate.cc b/content/browser/media/session/pepper_player_delegate.cc index dd04beb6..d3e23c45 100644 --- a/content/browser/media/session/pepper_player_delegate.cc +++ b/content/browser/media/session/pepper_player_delegate.cc
@@ -44,6 +44,16 @@ SetVolume(player_id, 1.0f); } +void PepperPlayerDelegate::OnSeekForward(int player_id, + base::TimeDelta seek_time) { + // Cannot seek pepper player. Do nothing. +} + +void PepperPlayerDelegate::OnSeekBackward(int player_id, + base::TimeDelta seek_time) { + // Cannot seek pepper player. Do nothing. +} + void PepperPlayerDelegate::OnSetVolumeMultiplier(int player_id, double volume_multiplier) { if (!media::IsAudioFocusDuckFlashEnabled())
diff --git a/content/browser/media/session/pepper_player_delegate.h b/content/browser/media/session/pepper_player_delegate.h index 78142f5..5e48ca8 100644 --- a/content/browser/media/session/pepper_player_delegate.h +++ b/content/browser/media/session/pepper_player_delegate.h
@@ -26,6 +26,8 @@ // MediaSessionPlayerObserver implementation. void OnSuspend(int player_id) override; void OnResume(int player_id) override; + void OnSeekForward(int player_id, base::TimeDelta seek_time) override; + void OnSeekBackward(int player_id, base::TimeDelta seek_time) override; void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override; RenderFrameHost* render_frame_host() const override;
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index 6d32aec..5b14a8a 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -1584,7 +1584,6 @@ void MediaStreamManager::WillDestroyCurrentMessageLoop() { DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()"; DCHECK(CalledOnIOThread()); - DCHECK(requests_.empty()); if (media_devices_manager_) media_devices_manager_->StopMonitoring(); if (video_capture_manager_) @@ -1596,6 +1595,7 @@ video_capture_manager_ = nullptr; media_devices_manager_ = nullptr; g_media_stream_manager_tls_ptr.Pointer()->Set(nullptr); + requests_.clear(); } void MediaStreamManager::NotifyDevicesChanged(
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 3a5b4c4..0a4590f0a 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -777,39 +777,6 @@ render_thread_id_, registration_handle_id)); } -void ServiceWorkerProviderHost::SendSetVersionAttributesMessage( - int registration_handle_id, - ChangedVersionAttributesMask changed_mask, - ServiceWorkerVersion* installing_version, - ServiceWorkerVersion* waiting_version, - ServiceWorkerVersion* active_version) { - if (!dispatcher_host_) - return; - if (!changed_mask.changed()) - return; - - if (!IsReadyToSendMessages()) { - queued_events_.push_back(base::Bind( - &ServiceWorkerProviderHost::SendSetVersionAttributesMessage, - AsWeakPtr(), registration_handle_id, changed_mask, - base::RetainedRef(installing_version), - base::RetainedRef(waiting_version), base::RetainedRef(active_version))); - return; - } - - ServiceWorkerVersionAttributes attrs; - if (changed_mask.installing_changed()) - attrs.installing = *GetOrCreateServiceWorkerHandle(installing_version); - if (changed_mask.waiting_changed()) - attrs.waiting = *GetOrCreateServiceWorkerHandle(waiting_version); - if (changed_mask.active_changed()) - attrs.active = *GetOrCreateServiceWorkerHandle(active_version); - - Send(new ServiceWorkerMsg_SetVersionAttributes( - render_thread_id_, registration_handle_id, changed_mask.changed(), - attrs)); -} - void ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage( int worker_handle_id, blink::mojom::ServiceWorkerState state) {
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 89435fe1..1130436d 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -307,12 +307,6 @@ // until the worker thread id is known via SetReadyToSendMessagesToWorker(). void SendUpdateFoundMessage( int registration_handle_id); - void SendSetVersionAttributesMessage( - int registration_handle_id, - ChangedVersionAttributesMask changed_mask, - ServiceWorkerVersion* installing_version, - ServiceWorkerVersion* waiting_version, - ServiceWorkerVersion* active_version); void SendServiceWorkerStateChangedMessage( int worker_handle_id, blink::mojom::ServiceWorkerState state);
diff --git a/content/browser/service_worker/service_worker_registration_handle.cc b/content/browser/service_worker/service_worker_registration_handle.cc index 660147b..7b06938 100644 --- a/content/browser/service_worker/service_worker_registration_handle.cc +++ b/content/browser/service_worker/service_worker_registration_handle.cc
@@ -239,11 +239,24 @@ ServiceWorkerVersion* active_version) { if (!provider_host_) return; // Could be nullptr in some tests. - provider_host_->SendSetVersionAttributesMessage(handle_id_, - changed_mask, - installing_version, - waiting_version, - active_version); + if (!changed_mask.changed()) + return; + + blink::mojom::ServiceWorkerObjectInfoPtr installing; + blink::mojom::ServiceWorkerObjectInfoPtr waiting; + blink::mojom::ServiceWorkerObjectInfoPtr active; + if (changed_mask.installing_changed()) { + installing = + provider_host_->GetOrCreateServiceWorkerHandle(installing_version); + } + if (changed_mask.waiting_changed()) + waiting = provider_host_->GetOrCreateServiceWorkerHandle(waiting_version); + if (changed_mask.active_changed()) + active = provider_host_->GetOrCreateServiceWorkerHandle(active_version); + DCHECK(remote_registration_); + remote_registration_->SetVersionAttributes( + changed_mask.changed(), std::move(installing), std::move(waiting), + std::move(active)); } void ServiceWorkerRegistrationHandle::OnConnectionError() {
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc index d18e0d7..348b284 100644 --- a/content/browser/service_worker/service_worker_registration_unittest.cc +++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -66,6 +66,50 @@ } }; +class MockServiceWorkerRegistrationObject + : public blink::mojom::ServiceWorkerRegistrationObject { + public: + explicit MockServiceWorkerRegistrationObject( + blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest request) + : binding_(this) { + binding_.Bind(std::move(request)); + } + ~MockServiceWorkerRegistrationObject() override = default; + + int set_version_attributes_called_count() { + return set_version_attributes_called_count_; + }; + int changed_mask() { return changed_mask_; } + const blink::mojom::ServiceWorkerObjectInfoPtr& installing() { + return installing_; + } + const blink::mojom::ServiceWorkerObjectInfoPtr& waiting() { return waiting_; } + const blink::mojom::ServiceWorkerObjectInfoPtr& active() { return active_; } + + private: + // Implements blink::mojom::ServiceWorkerRegistrationObject. + void SetVersionAttributes( + int changed_mask, + blink::mojom::ServiceWorkerObjectInfoPtr installing, + blink::mojom::ServiceWorkerObjectInfoPtr waiting, + blink::mojom::ServiceWorkerObjectInfoPtr active) override { + set_version_attributes_called_count_++; + changed_mask_ = changed_mask; + installing_ = std::move(installing); + waiting_ = std::move(waiting); + active_ = std::move(active); + } + + int set_version_attributes_called_count_ = 0; + int changed_mask_ = 0; + blink::mojom::ServiceWorkerObjectInfoPtr installing_; + blink::mojom::ServiceWorkerObjectInfoPtr waiting_; + blink::mojom::ServiceWorkerObjectInfoPtr active_; + + mojo::AssociatedBinding<blink::mojom::ServiceWorkerRegistrationObject> + binding_; +}; + } // namespace class ServiceWorkerRegistrationTest : public testing::Test { @@ -671,7 +715,7 @@ return remote_endpoint; } - blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr GetRegistrationFromRemote(mojom::ServiceWorkerContainerHost* container_host, const GURL& url) { blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info; @@ -689,11 +733,8 @@ }, ®istration_info)); base::RunLoop().RunUntilIdle(); - blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr; EXPECT_TRUE(registration_info->host_ptr_info.is_valid()); - registration_host_ptr.Bind(std::move(registration_info->host_ptr_info)); - return registration_host_ptr; + return registration_info; } ServiceWorkerDispatcherHost* dispatcher_host() { @@ -713,9 +754,11 @@ const int64_t kProviderId = 99; // Dummy value ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + registration_host_ptr.Bind(std::move(info->host_ptr_info)); EXPECT_NE(nullptr, context()->GetLiveRegistration(registration_id)); registration_host_ptr.reset(); @@ -731,8 +774,15 @@ ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr.Bind(std::move(info->host_ptr_info)); + // Ignore the messages to the registration object, otherwise the callbacks + // issued from |registration_host_ptr| may wait for receiving the messages to + // |info->request|. + info->request = nullptr; EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone, CallUpdate(registration_host_ptr.get())); @@ -745,9 +795,11 @@ const int64_t kProviderId = 99; // Dummy value ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + registration_host_ptr.Bind(std::move(info->host_ptr_info)); ASSERT_TRUE(bad_messages_.empty()); context() @@ -765,9 +817,11 @@ const int64_t kProviderId = 99; // Dummy value ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + registration_host_ptr.Bind(std::move(info->host_ptr_info)); ServiceWorkerTestContentBrowserClient test_browser_client; ContentBrowserClient* old_browser_client = @@ -785,8 +839,14 @@ ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr.Bind(std::move(info->host_ptr_info)); + // Ignore the messages to the registration object, otherwise the callbacks + // issued from |registration_host_ptr| may wait for receiving the messages to + // |info->request|. + info->request = nullptr; EXPECT_EQ(SERVICE_WORKER_OK, FindRegistrationInStorage(registration_id, kScope)); @@ -806,9 +866,11 @@ const int64_t kProviderId = 99; // Dummy value ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + registration_host_ptr.Bind(std::move(info->host_ptr_info)); ASSERT_TRUE(bad_messages_.empty()); context() @@ -826,9 +888,11 @@ const int64_t kProviderId = 99; // Dummy value ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareProviderHost(kProviderId, kScope); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr - registration_host_ptr = - GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + registration_host_ptr; + registration_host_ptr.Bind(std::move(info->host_ptr_info)); ServiceWorkerTestContentBrowserClient test_browser_client; ContentBrowserClient* old_browser_client = @@ -838,4 +902,111 @@ SetBrowserClientForTesting(old_browser_client); } +TEST_F(ServiceWorkerRegistrationHandleTest, SetVersionAttributes) { + const GURL kScope("https://www.example.com/"); + const GURL kScriptUrl("https://www.example.com/sw.js"); + int64_t registration_id = SetUpRegistration(kScope, kScriptUrl); + const int64_t kProviderId = 99; // Dummy value + ServiceWorkerRemoteProviderEndpoint remote_endpoint = + PrepareProviderHost(kProviderId, kScope); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = + GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope); + EXPECT_EQ(registration_id, info->registration_id); + EXPECT_TRUE(info->request.is_pending()); + auto mock_registration_object = + std::make_unique<MockServiceWorkerRegistrationObject>( + std::move(info->request)); + + ServiceWorkerRegistration* registration = + context()->GetLiveRegistration(registration_id); + ASSERT_NE(nullptr, registration); + const int64_t version_1_id = 1L; + const int64_t version_2_id = 2L; + scoped_refptr<ServiceWorkerVersion> version_1 = + base::MakeRefCounted<ServiceWorkerVersion>( + registration, kScriptUrl, version_1_id, context()->AsWeakPtr()); + scoped_refptr<ServiceWorkerVersion> version_2 = + base::MakeRefCounted<ServiceWorkerVersion>( + registration, kScriptUrl, version_2_id, context()->AsWeakPtr()); + + // Set an active worker. + { + registration->SetActiveVersion(version_1); + EXPECT_EQ(version_1.get(), registration->active_version()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, + mock_registration_object->set_version_attributes_called_count()); + ChangedVersionAttributesMask mask(mock_registration_object->changed_mask()); + EXPECT_FALSE(mask.installing_changed()); + EXPECT_FALSE(mock_registration_object->installing()); + EXPECT_FALSE(mask.waiting_changed()); + EXPECT_FALSE(mock_registration_object->waiting()); + EXPECT_TRUE(mask.active_changed()); + EXPECT_TRUE(mock_registration_object->active()); + EXPECT_EQ(version_1_id, mock_registration_object->active()->version_id); + EXPECT_EQ(kScriptUrl, mock_registration_object->active()->url); + } + + // Set an installing worker. + { + registration->SetInstallingVersion(version_2); + EXPECT_EQ(version_2.get(), registration->installing_version()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2, + mock_registration_object->set_version_attributes_called_count()); + ChangedVersionAttributesMask mask(mock_registration_object->changed_mask()); + EXPECT_TRUE(mask.installing_changed()); + EXPECT_TRUE(mock_registration_object->installing()); + EXPECT_FALSE(mask.waiting_changed()); + EXPECT_FALSE(mock_registration_object->waiting()); + EXPECT_FALSE(mask.active_changed()); + EXPECT_FALSE(mock_registration_object->active()); + EXPECT_EQ(version_2_id, mock_registration_object->installing()->version_id); + EXPECT_EQ(kScriptUrl, mock_registration_object->installing()->url); + } + + // Promote the installing worker to waiting. + { + registration->SetWaitingVersion(version_2); + EXPECT_EQ(version_2.get(), registration->waiting_version()); + EXPECT_FALSE(registration->installing_version()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(3, + mock_registration_object->set_version_attributes_called_count()); + ChangedVersionAttributesMask mask(mock_registration_object->changed_mask()); + EXPECT_TRUE(mask.installing_changed()); + EXPECT_TRUE(mock_registration_object->installing()); + EXPECT_TRUE(mask.waiting_changed()); + EXPECT_TRUE(mock_registration_object->waiting()); + EXPECT_FALSE(mask.active_changed()); + EXPECT_FALSE(mock_registration_object->active()); + EXPECT_EQ(version_2_id, mock_registration_object->waiting()->version_id); + EXPECT_EQ(kScriptUrl, mock_registration_object->waiting()->url); + EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId, + mock_registration_object->installing()->version_id); + EXPECT_EQ(blink::mojom::kInvalidServiceWorkerHandleId, + mock_registration_object->installing()->handle_id); + } + + // Remove the waiting worker. + { + registration->UnsetVersion(version_2.get()); + EXPECT_FALSE(registration->waiting_version()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(4, + mock_registration_object->set_version_attributes_called_count()); + ChangedVersionAttributesMask mask(mock_registration_object->changed_mask()); + EXPECT_FALSE(mask.installing_changed()); + EXPECT_FALSE(mock_registration_object->installing()); + EXPECT_TRUE(mask.waiting_changed()); + EXPECT_TRUE(mock_registration_object->waiting()); + EXPECT_FALSE(mask.active_changed()); + EXPECT_FALSE(mock_registration_object->active()); + EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId, + mock_registration_object->waiting()->version_id); + EXPECT_EQ(blink::mojom::kInvalidServiceWorkerHandleId, + mock_registration_object->waiting()->handle_id); + } +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc index d30c28bd..316fb444 100644 --- a/content/browser/service_worker/service_worker_test_utils.cc +++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -102,6 +102,9 @@ client_request_ = std::move(info->client_request); host_ptr_.Bind(std::move(info->host_ptr_info)); registration_object_info_ = std::move(info->registration); + // To enable the caller end point to make calls safely with no need to pass + // |registration_object_info_->request| through a message pipe endpoint. + mojo::GetIsolatedInterface(registration_object_info_->request.PassHandle()); } std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index e2f2b67..8bb3eaa 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -607,8 +607,7 @@ // Create the URLLoaderFactory as needed. if (!url_loader_factory_for_browser_process_) { GetNetworkContext()->CreateURLLoaderFactory( - mojo::MakeRequest(&url_loader_factory_for_browser_process_), - base::GetUniqueIdForProcess()); + mojo::MakeRequest(&url_loader_factory_for_browser_process_), 0); } return url_loader_factory_for_browser_process_.get(); }
diff --git a/content/common/media/media_player_delegate_messages.h b/content/common/media/media_player_delegate_messages.h index 69f37234..3791fc1 100644 --- a/content/common/media/media_player_delegate_messages.h +++ b/content/common/media/media_player_delegate_messages.h
@@ -31,6 +31,14 @@ IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Play, int /* delegate_id, distinguishes instances */) +IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_SeekForward, + int /* delegate_id, distinguishes instances */, + base::TimeDelta /* seek_time */) + +IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_SeekBackward, + int /* delegate_id, distinguishes instances */, + base::TimeDelta /* seek_time */) + IPC_MESSAGE_ROUTED0(MediaPlayerDelegateMsg_SuspendAllMediaPlayers) IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_UpdateVolumeMultiplier,
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h index c92a16cd..8daf4788 100644 --- a/content/common/service_worker/service_worker_messages.h +++ b/content/common/service_worker/service_worker_messages.h
@@ -108,12 +108,6 @@ IPC_STRUCT_TRAITS_MEMBER(version_id) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerVersionAttributes) - IPC_STRUCT_TRAITS_MEMBER(installing) - IPC_STRUCT_TRAITS_MEMBER(waiting) - IPC_STRUCT_TRAITS_MEMBER(active) -IPC_STRUCT_TRAITS_END() - IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerClientInfo) IPC_STRUCT_TRAITS_MEMBER(client_uuid) IPC_STRUCT_TRAITS_MEMBER(page_visibility_state) @@ -244,13 +238,6 @@ int /* handle_id */, blink::mojom::ServiceWorkerState) -// Tells the child process to set service workers for the given registration. -IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_SetVersionAttributes, - int /* thread_id */, - int /* registration_handle_id */, - int /* changed_mask */, - content::ServiceWorkerVersionAttributes) - // Informs the child process that new ServiceWorker enters the installation // phase. IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_UpdateFound,
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h index 606379e..3af882f2 100644 --- a/content/common/service_worker/service_worker_types.h +++ b/content/common/service_worker/service_worker_types.h
@@ -177,12 +177,6 @@ ServiceWorkerHeaderList cors_exposed_header_names; }; -struct CONTENT_EXPORT ServiceWorkerVersionAttributes { - blink::mojom::ServiceWorkerObjectInfo installing; - blink::mojom::ServiceWorkerObjectInfo waiting; - blink::mojom::ServiceWorkerObjectInfo active; -}; - class ChangedVersionAttributesMask { public: enum {
diff --git a/content/common/service_worker/service_worker_types.mojom b/content/common/service_worker/service_worker_types.mojom index ae8c0bd..31b3acd 100644 --- a/content/common/service_worker/service_worker_types.mojom +++ b/content/common/service_worker/service_worker_types.mojom
@@ -18,9 +18,3 @@ SERVICE_WORKER_PROVIDER_TYPE_LAST = SERVICE_WORKER_PROVIDER_FOR_CONTROLLER }; - -// Struct for delivering the information about the installing, waiting and -// active ServiceWorkers. -// Defined in service_worker_types.h. -[Native] -struct ServiceWorkerVersionAttributes;
diff --git a/content/common/service_worker/service_worker_types.typemap b/content/common/service_worker/service_worker_types.typemap index ed63135..9e68f09 100644 --- a/content/common/service_worker/service_worker_types.typemap +++ b/content/common/service_worker/service_worker_types.typemap
@@ -14,7 +14,4 @@ sources = [ "//content/common/service_worker/service_worker_types_struct_traits.cc", ] -type_mappings = [ - "content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType", - "content.mojom.ServiceWorkerVersionAttributes=::content::ServiceWorkerVersionAttributes", -] +type_mappings = [ "content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType" ]
diff --git a/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java b/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java index f5cc2d03..15332db0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java
@@ -59,6 +59,18 @@ } @Override + public void seekForward(long millis) { + assert millis >= 0 : "Attempted to seek by a negative number of milliseconds"; + nativeSeekForward(mNativeMediaSessionAndroid, millis); + } + + @Override + public void seekBackward(long millis) { + assert millis >= 0 : "Attempted to seek by a negative number of milliseconds"; + nativeSeekBackward(mNativeMediaSessionAndroid, millis); + } + + @Override public void didReceiveAction(int action) { nativeDidReceiveAction(mNativeMediaSessionAndroid, action); } @@ -118,6 +130,8 @@ private native void nativeResume(long nativeMediaSessionAndroid); private native void nativeSuspend(long nativeMediaSessionAndroid); private native void nativeStop(long nativeMediaSessionAndroid); + private native void nativeSeekForward(long nativeMediaSessionAndroid, long millis); + private native void nativeSeekBackward(long nativeMediaSessionAndroid, long millis); private native void nativeDidReceiveAction(long nativeMediaSessionAndroid, int action); private static native MediaSessionImpl nativeGetMediaSessionFromWebContents( WebContents contents);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java b/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java index 939d361..de2abaf 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java
@@ -46,6 +46,16 @@ public abstract void stop(); /** + * Seeks the media session forward by the specified number of milliseconds. + */ + public abstract void seekForward(long millis); + + /** + * Seeks the media session backward by the specified number of milliseconds. + */ + public abstract void seekBackward(long millis); + + /** * Notify the media session that an action has been performed. */ public abstract void didReceiveAction(int action);
diff --git a/content/public/browser/devtools_agent_host_client.h b/content/public/browser/devtools_agent_host_client.h index be5d33757..c8f0811 100644 --- a/content/public/browser/devtools_agent_host_client.h +++ b/content/public/browser/devtools_agent_host_client.h
@@ -24,8 +24,7 @@ const std::string& message) = 0; // This method is called when attached agent host is closed. - virtual void AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced_with_another_client) = 0; + virtual void AgentHostClosed(DevToolsAgentHost* agent_host) = 0; }; } // namespace content
diff --git a/content/public/browser/media_session.h b/content/public/browser/media_session.h index 914812cb..1a5ce98 100644 --- a/content/public/browser/media_session.h +++ b/content/public/browser/media_session.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_MEDIA_SESSION_H_ #include "base/macros.h" +#include "base/time/time.h" #include "content/common/content_export.h" namespace blink { @@ -45,14 +46,20 @@ // |type| represents the origin of the request. virtual void Resume(SuspendType suspend_type) = 0; - // Resume the media session. + // Suspend the media session. // |type| represents the origin of the request. virtual void Suspend(SuspendType suspend_type) = 0; - // Resume the media session. + // Stop the media session. // |type| represents the origin of the request. virtual void Stop(SuspendType suspend_type) = 0; + // Seek the media session forward. + virtual void SeekForward(base::TimeDelta seek_time) = 0; + + // Seek the media session backward. + virtual void SeekBackward(base::TimeDelta seek_time) = 0; + // Return if the session can be controlled by Resume() and Suspend() calls // above. virtual bool IsControllable() const = 0;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index e8adfaa4..01eb739 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -138,14 +138,8 @@ base::FEATURE_DISABLED_BY_DEFAULT}; // Use Mojo IPC for resource loading. -const base::Feature kLoadingWithMojo { - "LoadingWithMojo", -#if defined(OS_ANDROID) - base::FEATURE_DISABLED_BY_DEFAULT -#else - base::FEATURE_ENABLED_BY_DEFAULT -#endif -}; +const base::Feature kLoadingWithMojo{"LoadingWithMojo", + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables the memory coordinator. // WARNING:
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc index 0a927d6..165f17ab 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -222,6 +222,10 @@ IPC_BEGIN_MESSAGE_MAP(RendererWebMediaPlayerDelegate, msg) IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Pause, OnMediaDelegatePause) IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Play, OnMediaDelegatePlay) + IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SeekForward, + OnMediaDelegateSeekForward) + IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SeekBackward, + OnMediaDelegateSeekBackward) IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SuspendAllMediaPlayers, OnMediaDelegateSuspendAllMediaPlayers) IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_UpdateVolumeMultiplier, @@ -288,6 +292,26 @@ } } +void RendererWebMediaPlayerDelegate::OnMediaDelegateSeekForward( + int player_id, + base::TimeDelta seek_time) { + RecordAction(base::UserMetricsAction("Media.Controls.RemoteSeekForward")); + + Observer* observer = id_map_.Lookup(player_id); + if (observer) + observer->OnSeekForward(seek_time.InSecondsF()); +} + +void RendererWebMediaPlayerDelegate::OnMediaDelegateSeekBackward( + int player_id, + base::TimeDelta seek_time) { + RecordAction(base::UserMetricsAction("Media.Controls.RemoteSeekBackward")); + + Observer* observer = id_map_.Lookup(player_id); + if (observer) + observer->OnSeekBackward(seek_time.InSecondsF()); +} + void RendererWebMediaPlayerDelegate::OnMediaDelegateSuspendAllMediaPlayers() { is_frame_closed_ = true;
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h index 21744a52..eaf3ccb 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.h +++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -83,6 +83,8 @@ private: void OnMediaDelegatePause(int player_id); void OnMediaDelegatePlay(int player_id); + void OnMediaDelegateSeekForward(int player_id, base::TimeDelta seek_time); + void OnMediaDelegateSeekBackward(int player_id, base::TimeDelta seek_time); void OnMediaDelegateSuspendAllMediaPlayers(); void OnMediaDelegateVolumeMultiplierUpdate(int player_id, double multiplier); void OnMediaDelegateBecamePersistentVideo(int player_id, bool value);
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc b/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc index 2015354..2eae16d 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
@@ -43,6 +43,8 @@ MOCK_METHOD0(OnIdleTimeout, void()); MOCK_METHOD0(OnPlay, void()); MOCK_METHOD0(OnPause, void()); + MOCK_METHOD1(OnSeekForward, void(double)); + MOCK_METHOD1(OnSeekBackward, void(double)); MOCK_METHOD1(OnVolumeMultiplierUpdate, void(double)); MOCK_METHOD1(OnBecamePersistentVideo, void(bool)); }; @@ -208,6 +210,18 @@ MediaPlayerDelegateMsg_Play play_msg(0, delegate_id); delegate_manager_->OnMessageReceived(play_msg); + const double kTestSeekForwardSeconds = 1.0; + EXPECT_CALL(observer_1_, OnSeekForward(kTestSeekForwardSeconds)); + MediaPlayerDelegateMsg_SeekForward seek_forward_msg( + 0, delegate_id, base::TimeDelta::FromSeconds(kTestSeekForwardSeconds)); + delegate_manager_->OnMessageReceived(seek_forward_msg); + + const double kTestSeekBackwardSeconds = 2.0; + EXPECT_CALL(observer_1_, OnSeekBackward(kTestSeekBackwardSeconds)); + MediaPlayerDelegateMsg_SeekBackward seek_backward_msg( + 0, delegate_id, base::TimeDelta::FromSeconds(kTestSeekBackwardSeconds)); + delegate_manager_->OnMessageReceived(seek_backward_msg); + const double kTestMultiplier = 0.5; EXPECT_CALL(observer_1_, OnVolumeMultiplierUpdate(kTestMultiplier)); MediaPlayerDelegateMsg_UpdateVolumeMultiplier volume_msg(0, delegate_id,
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc index 0542d9f..3f5ebc6f 100644 --- a/content/renderer/media/webmediaplayer_ms.cc +++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -749,6 +749,14 @@ // TODO(perkj, magjed): See TODO in OnPlay(). } +void WebMediaPlayerMS::OnSeekForward(double seconds) { + // TODO(perkj, magjed): See TODO in OnPlay(). +} + +void WebMediaPlayerMS::OnSeekBackward(double seconds) { + // TODO(perkj, magjed): See TODO in OnPlay(). +} + void WebMediaPlayerMS::OnVolumeMultiplierUpdate(double multiplier) { // TODO(perkj, magjed): See TODO in OnPlay(). }
diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h index f148c90b..8e0644b 100644 --- a/content/renderer/media/webmediaplayer_ms.h +++ b/content/renderer/media/webmediaplayer_ms.h
@@ -156,6 +156,8 @@ void OnIdleTimeout() override; void OnPlay() override; void OnPause() override; + void OnSeekForward(double seconds) override; + void OnSeekBackward(double seconds) override; void OnVolumeMultiplierUpdate(double multiplier) override; void OnBecamePersistentVideo(bool value) override;
diff --git a/content/renderer/service_worker/service_worker_dispatcher.cc b/content/renderer/service_worker/service_worker_dispatcher.cc index 5e8912b..1de2c5bb 100644 --- a/content/renderer/service_worker/service_worker_dispatcher.cc +++ b/content/renderer/service_worker/service_worker_dispatcher.cc
@@ -78,8 +78,6 @@ OnSetNavigationPreloadHeaderError) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged, OnServiceWorkerStateChanged) - IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes, - OnSetVersionAttributes) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound, OnUpdateFound) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CountFeature, OnCountFeature) @@ -340,39 +338,6 @@ worker->second->OnStateChanged(state); } -void ServiceWorkerDispatcher::OnSetVersionAttributes( - int thread_id, - int registration_handle_id, - int changed_mask, - const ServiceWorkerVersionAttributes& attrs) { - TRACE_EVENT1("ServiceWorker", - "ServiceWorkerDispatcher::OnSetVersionAttributes", - "Thread ID", thread_id); - - // Adopt the references sent from the browser process and pass it to the - // registration if it exists. - std::unique_ptr<ServiceWorkerHandleReference> installing = - Adopt(attrs.installing.Clone()); - std::unique_ptr<ServiceWorkerHandleReference> waiting = - Adopt(attrs.waiting.Clone()); - std::unique_ptr<ServiceWorkerHandleReference> active = - Adopt(attrs.active.Clone()); - - RegistrationObjectMap::iterator found = - registrations_.find(registration_handle_id); - if (found != registrations_.end()) { - // Populate the version fields (eg. .installing) with worker objects. - ChangedVersionAttributesMask mask(changed_mask); - if (mask.installing_changed()) - found->second->SetInstalling( - GetOrCreateServiceWorker(std::move(installing))); - if (mask.waiting_changed()) - found->second->SetWaiting(GetOrCreateServiceWorker(std::move(waiting))); - if (mask.active_changed()) - found->second->SetActive(GetOrCreateServiceWorker(std::move(active))); - } -} - void ServiceWorkerDispatcher::OnUpdateFound( int thread_id, int registration_handle_id) {
diff --git a/content/renderer/service_worker/service_worker_dispatcher.h b/content/renderer/service_worker/service_worker_dispatcher.h index 745936e..8264418cb 100644 --- a/content/renderer/service_worker/service_worker_dispatcher.h +++ b/content/renderer/service_worker/service_worker_dispatcher.h
@@ -41,7 +41,6 @@ class ThreadSafeSender; class WebServiceWorkerImpl; class WebServiceWorkerRegistrationImpl; -struct ServiceWorkerVersionAttributes; // This class manages communication with the browser process about // registration of the service worker, exposed to renderer and worker @@ -163,10 +162,6 @@ void OnServiceWorkerStateChanged(int thread_id, int handle_id, blink::mojom::ServiceWorkerState state); - void OnSetVersionAttributes(int thread_id, - int registration_handle_id, - int changed_mask, - const ServiceWorkerVersionAttributes& attributes); void OnUpdateFound(int thread_id, int registration_handle_id); void OnCountFeature(int thread_id, int provider_id, uint32_t feature);
diff --git a/content/renderer/service_worker/service_worker_message_filter.cc b/content/renderer/service_worker/service_worker_message_filter.cc index 82ebaf89..eaab92ca 100644 --- a/content/renderer/service_worker/service_worker_message_filter.cc +++ b/content/renderer/service_worker/service_worker_message_filter.cc
@@ -6,30 +6,12 @@ #include <stddef.h> -#include "content/child/thread_safe_sender.h" #include "content/common/service_worker/service_worker_messages.h" -#include "content/common/service_worker/service_worker_types.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" #include "ipc/ipc_message_macros.h" -#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h" namespace content { -namespace { - -// Sends a ServiceWorkerObjectDestroyed message to the browser so it can delete -// the ServiceWorker handle. -void SendServiceWorkerObjectDestroyed( - ThreadSafeSender* sender, - int handle_id) { - if (handle_id == blink::mojom::kInvalidServiceWorkerHandleId) - return; - sender->Send( - new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id)); -} - -} // namespace - ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender) : WorkerThreadMessageFilter(sender) { } @@ -54,29 +36,4 @@ return base::PickleIterator(msg).ReadInt(ipc_thread_id); } -void ServiceWorkerMessageFilter::OnStaleMessageReceived( - const IPC::Message& msg) { - // Specifically handle some messages in case we failed to post task - // to the thread (meaning that the context on the thread is now gone). - IPC_BEGIN_MESSAGE_MAP(ServiceWorkerMessageFilter, msg) - IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes, - OnStaleSetVersionAttributes) - IPC_END_MESSAGE_MAP() -} - -void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes( - int thread_id, - int registration_handle_id, - int changed_mask, - const ServiceWorkerVersionAttributes& attrs) { - SendServiceWorkerObjectDestroyed(thread_safe_sender(), - attrs.installing.handle_id); - SendServiceWorkerObjectDestroyed(thread_safe_sender(), - attrs.waiting.handle_id); - SendServiceWorkerObjectDestroyed(thread_safe_sender(), - attrs.active.handle_id); - // Don't have to decrement registration refcount because the sender of the - // SetVersionAttributes message doesn't increment it. -} - } // namespace content
diff --git a/content/renderer/service_worker/service_worker_message_filter.h b/content/renderer/service_worker/service_worker_message_filter.h index 1a2f385..fcad144 100644 --- a/content/renderer/service_worker/service_worker_message_filter.h +++ b/content/renderer/service_worker/service_worker_message_filter.h
@@ -5,17 +5,12 @@ #ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_ #define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_ -#include <set> -#include <vector> - #include "base/macros.h" #include "content/common/content_export.h" #include "content/renderer/worker_thread_message_filter.h" namespace content { -struct ServiceWorkerVersionAttributes; - class CONTENT_EXPORT ServiceWorkerMessageFilter : public WorkerThreadMessageFilter { public: @@ -31,16 +26,6 @@ bool GetWorkerThreadIdForMessage(const IPC::Message& msg, int* ipc_thread_id) override; - // ChildMessageFilter: - void OnStaleMessageReceived(const IPC::Message& msg) override; - - // Message handlers for stale messages. - void OnStaleSetVersionAttributes( - int thread_id, - int registration_handle_id, - int changed_mask, - const ServiceWorkerVersionAttributes& attrs); - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMessageFilter); };
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc index 891260b..e1f3688 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.cc +++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -12,6 +12,7 @@ #include "content/child/child_process.h" #include "content/common/service_worker/service_worker_types.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" +#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/web_service_worker_impl.h" #include "content/renderer/service_worker/web_service_worker_provider_impl.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h" @@ -401,4 +402,41 @@ dispatcher->RemoveServiceWorkerRegistration(handle_id_); } +void WebServiceWorkerRegistrationImpl::SetVersionAttributes( + int changed_mask, + blink::mojom::ServiceWorkerObjectInfoPtr installing, + blink::mojom::ServiceWorkerObjectInfoPtr waiting, + blink::mojom::ServiceWorkerObjectInfoPtr active) { + if (!creation_task_runner_->RunsTasksInCurrentSequence()) { + // As this posted task will definitely run before OnConnectionError() on the + // |creation_task_runner_|, using base::Unretained() here is safe. + creation_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&WebServiceWorkerRegistrationImpl::SetVersionAttributes, + base::Unretained(this), changed_mask, + std::move(installing), std::move(waiting), + std::move(active))); + return; + } + ServiceWorkerDispatcher* dispatcher = + ServiceWorkerDispatcher::GetThreadSpecificInstance(); + DCHECK(dispatcher); + ChangedVersionAttributesMask mask(changed_mask); + if (mask.installing_changed()) { + DCHECK(installing); + SetInstalling(dispatcher->GetOrCreateServiceWorker( + dispatcher->Adopt(std::move(installing)))); + } + if (mask.waiting_changed()) { + DCHECK(waiting); + SetWaiting(dispatcher->GetOrCreateServiceWorker( + dispatcher->Adopt(std::move(waiting)))); + } + if (mask.active_changed()) { + DCHECK(active); + SetActive(dispatcher->GetOrCreateServiceWorker( + dispatcher->Adopt(std::move(active)))); + } +} + } // namespace content
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.h b/content/renderer/service_worker/web_service_worker_registration_impl.h index 925f7e5d..0530595 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.h +++ b/content/renderer/service_worker/web_service_worker_registration_impl.h
@@ -133,6 +133,13 @@ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info); ~WebServiceWorkerRegistrationImpl() override; + // Implements blink::mojom::ServiceWorkerRegistrationObject. + void SetVersionAttributes( + int changed_mask, + blink::mojom::ServiceWorkerObjectInfoPtr installing, + blink::mojom::ServiceWorkerObjectInfoPtr waiting, + blink::mojom::ServiceWorkerObjectInfoPtr active) override; + // RefCounted traits implementation, rather than delete |impl| directly, calls // |impl->DetachAndMaybeDestroy()| to notify that the last reference to it has // gone away. @@ -160,7 +167,7 @@ // - |kDetached| --> |kAttachedAndBound| // When |this| is in |kDetached| state, if an inflight // ServiceWorkerRegistrationObjectInfo for the same JavaScript registration - // object arrived, |this| is resued to be provided to Blink. In such a case + // object arrived, |this| is reused to be provided to Blink. In such a case // AttachForServiceWorkerGlobalScope() or AttachForServiceWorkerClient() // sets |state_| to |kAttachedAndBound|. enum class LifecycleState {
diff --git a/content/shell/browser/layout_test/devtools_protocol_test_bindings.cc b/content/shell/browser/layout_test/devtools_protocol_test_bindings.cc index 3133fa83..deedca5d 100644 --- a/content/shell/browser/layout_test/devtools_protocol_test_bindings.cc +++ b/content/shell/browser/layout_test/devtools_protocol_test_bindings.cc
@@ -126,8 +126,7 @@ } void DevToolsProtocolTestBindings::AgentHostClosed( - DevToolsAgentHost* agent_host, - bool replaced) { + DevToolsAgentHost* agent_host) { agent_host_ = nullptr; }
diff --git a/content/shell/browser/layout_test/devtools_protocol_test_bindings.h b/content/shell/browser/layout_test/devtools_protocol_test_bindings.h index dc82113..045dd3b 100644 --- a/content/shell/browser/layout_test/devtools_protocol_test_bindings.h +++ b/content/shell/browser/layout_test/devtools_protocol_test_bindings.h
@@ -26,7 +26,7 @@ private: // content::DevToolsAgentHostClient implementation. - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override; + void AgentHostClosed(DevToolsAgentHost* agent_host) override; void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override;
diff --git a/content/shell/browser/shell_devtools_bindings.cc b/content/shell/browser/shell_devtools_bindings.cc index 6cb5a3e..eefddf4bf 100644 --- a/content/shell/browser/shell_devtools_bindings.cc +++ b/content/shell/browser/shell_devtools_bindings.cc
@@ -382,8 +382,7 @@ CallClientFunction("DevToolsAPI.embedderMessageAck", &id_value, arg, nullptr); } -void ShellDevToolsBindings::AgentHostClosed(DevToolsAgentHost* agent_host, - bool replaced) { +void ShellDevToolsBindings::AgentHostClosed(DevToolsAgentHost* agent_host) { agent_host_ = nullptr; if (delegate_) delegate_->Close();
diff --git a/content/shell/browser/shell_devtools_bindings.h b/content/shell/browser/shell_devtools_bindings.h index 924ab60..01e5197 100644 --- a/content/shell/browser/shell_devtools_bindings.h +++ b/content/shell/browser/shell_devtools_bindings.h
@@ -55,7 +55,7 @@ protected: // content::DevToolsAgentHostClient implementation. - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override; + void AgentHostClosed(DevToolsAgentHost* agent_host) override; void DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) override;
diff --git a/content/test/data/accessibility/html/bounds-inherits-expected-blink.txt b/content/test/data/accessibility/html/bounds-inherits-expected-blink.txt index 67af2e9b..b4db5c9ec 100644 --- a/content/test/data/accessibility/html/bounds-inherits-expected-blink.txt +++ b/content/test/data/accessibility/html/bounds-inherits-expected-blink.txt
@@ -1,4 +1,4 @@ -rootWebArea size=(800, 600) +rootWebArea ++genericContainer size=(200, 200) ++++genericContainer offscreen size=(0, 0) ++++++genericContainer offscreen size=(0, 0)
diff --git a/content/test/data/accessibility/html/bounds-inherits.html b/content/test/data/accessibility/html/bounds-inherits.html index a52869c..fa246719 100644 --- a/content/test/data/accessibility/html/bounds-inherits.html +++ b/content/test/data/accessibility/html/bounds-inherits.html
@@ -1,6 +1,7 @@ <!-- @BLINK-ALLOW:offscreen -@BLINK-ALLOW:size* +@BLINK-ALLOW:size=(200, 200) +@BLINK-ALLOW:size=(0, 0) --> <html> <body>
diff --git a/content/test/data/accessibility/regression/xml-in-iframe-crash-expected-blink.txt b/content/test/data/accessibility/regression/xml-in-iframe-crash-expected-blink.txt new file mode 100644 index 0000000..ab8ac60a --- /dev/null +++ b/content/test/data/accessibility/regression/xml-in-iframe-crash-expected-blink.txt
@@ -0,0 +1,3 @@ +rootWebArea +++iframe +++++rootWebArea
diff --git a/content/test/data/accessibility/regression/xml-in-iframe-crash.html b/content/test/data/accessibility/regression/xml-in-iframe-crash.html new file mode 100644 index 0000000..53482dff --- /dev/null +++ b/content/test/data/accessibility/regression/xml-in-iframe-crash.html
@@ -0,0 +1,9 @@ +<script> +function shouldNotBeExecuted() +{ + var divElement = document.createElement("div"); + document.body.appendChild(divElement); +} +</script> +<body onLoad="shouldNotBeExecuted();"> + <iframe src="foo.xml"/>
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index 9775942..c04ac98 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -17,15 +17,24 @@ THIS_DIR = os.path.dirname(os.path.abspath(__file__)) SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(THIS_DIR))) -# Current stable Windows NVIDIA GT 610 device/driver identifier. +# Current stable Windows NVIDIA GeForce GT 610 device/driver identifier. WIN_NVIDIA_GEFORCE_610_STABLE_DRIVER = '10de:104a-23.21.13.8792' -# Current experimental Windows NVIDIA GT 610 device/driver identifier. +# Current stable Windows NVIDIA Quadro P400 device/driver identifier. +WIN_NVIDIA_QUADRO_P400_STABLE_DRIVER = '10de:1cb3-23.21.13.8792' + +# Current experimental Windows NVIDIA GeForce GT 610 device/driver identifier. WIN_NVIDIA_GEFORCE_610_EXPERIMENTAL_DRIVER = '10de:104a-23.21.13.8792' -# Use this to match all drivers for the NVIDIA GT 610. +# Use this to match all drivers for the NVIDIA GeForce GT 610. NVIDIA_GEFORCE_610_ALL_DRIVERS = '10de:104a-*' +# Linux NVIDIA GeForce GT 610. +LINUX_GEFORCE_610_STABLE_DRIVER = '10de:104a' + +# Linux NVIDIA Quadro P400. +LINUX_QUADRO_P400_STABLE_DRIVER = '10de:1cb3-384.90' + # "Types" of waterfalls and bots. A bot's type is the union of its own # type and the type of its waterfall. Predicates can apply to these # sets in order to run tests only on a certain subset of the bots. @@ -193,7 +202,7 @@ 'Linux Release (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -205,7 +214,7 @@ 'Linux Debug (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -258,6 +267,18 @@ 'swarming': True, 'os_type': 'win', }, + 'Win7 Release (NVIDIA Quadro P400)': { + 'swarming_dimensions': [ + { + 'gpu': WIN_NVIDIA_QUADRO_P400_STABLE_DRIVER, + 'os': 'Windows-2008ServerR2-SP1', + 'pool': 'Chrome-GPU', + }, + ], + 'build_config': 'Release', + 'swarming': True, + 'os_type': 'win', + }, 'Win7 dEQP Release (NVIDIA)': { 'swarming_dimensions': [ { @@ -608,7 +629,7 @@ 'Linux Release (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -620,20 +641,19 @@ 'Linux Release (NVIDIA Quadro P400)': { 'swarming_dimensions': [ { - 'gpu': '10de:1cb3', - 'os': 'Ubuntu' + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', }, ], 'build_config': 'Release', - # This bot is a one-off and doesn't have similar slaves in the - # swarming pool. - 'swarming': False, + 'swarming': True, 'os_type': 'linux', }, 'Linux Debug (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -645,7 +665,7 @@ 'Linux dEQP Release (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -684,7 +704,7 @@ 'Linux GPU TSAN Release': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -867,7 +887,7 @@ 'Optional Linux Release (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -991,7 +1011,7 @@ 'Linux Release (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -1003,7 +1023,7 @@ 'Linux Release - concurrent marking (NVIDIA)': { 'swarming_dimensions': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -1100,9 +1120,14 @@ { 'predicate': Predicates.DEQP, 'swarming_dimension_sets': [ - # Linux NVIDIA + # Linux NVIDIA GeForce GT 610 { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, + 'os': 'Ubuntu' + }, + # Linux NVIDIA Quadro P400 + { + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, 'os': 'Ubuntu' }, # Mac Intel @@ -1260,9 +1285,14 @@ # TODO(jmadill): Run this on ANGLE roll tryservers. 'predicate': Predicates.DEQP, 'swarming_dimension_sets': [ - # NVIDIA Linux + # NVIDIA Linux GeForce GT 610 { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, + 'os': 'Ubuntu' + }, + # NVIDIA Linux Quadro P400 + { + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, 'os': 'Ubuntu' }, # Mac Intel @@ -1335,7 +1365,11 @@ 'os': 'Windows-2008ServerR2-SP1' }, { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, + 'os': 'Ubuntu' + }, + { + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, 'os': 'Ubuntu' } ], @@ -2142,7 +2176,11 @@ # Only run on the NVIDIA Release and Intel Release Linux bots. 'swarming_dimension_sets': [ { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, + 'os': 'Ubuntu' + }, + { + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, 'os': 'Ubuntu' }, { @@ -2284,7 +2322,11 @@ 'os': 'Windows-2008ServerR2-SP1' }, { - 'gpu': '10de:104a', + 'gpu': LINUX_GEFORCE_610_STABLE_DRIVER, + 'os': 'Ubuntu' + }, + { + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, 'os': 'Ubuntu' }, {
diff --git a/extensions/browser/computed_hashes.cc b/extensions/browser/computed_hashes.cc index a1ea2ba..d66cc0c3 100644 --- a/extensions/browser/computed_hashes.cc +++ b/extensions/browser/computed_hashes.cc
@@ -69,7 +69,6 @@ return false; if (block_size <= 0 || ((block_size % 1024) != 0)) { LOG(ERROR) << "Invalid block size: " << block_size; - block_size = 0; return false; }
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 5e075f73..51632c0 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1778,11 +1778,18 @@ use_distance_field_text, pixel_config); } void GL_APIENTRY GLES2RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) { - gles2::GetGLContext()->RasterCHROMIUM(list, x, y, w, h); + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) { + gles2::GetGLContext()->RasterCHROMIUM( + list, translate_x, translate_y, clip_x, clip_y, clip_w, clip_h, + post_translate_x, post_translate_y, post_scale); } void GL_APIENTRY GLES2EndRasterCHROMIUM() { gles2::GetGLContext()->EndRasterCHROMIUM();
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 60e4aedc..49386809 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -52,6 +52,8 @@ #if !defined(OS_NACL) #include "cc/paint/display_item_list.h" // nogncheck #include "third_party/skia/include/utils/SkNoDrawCanvas.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/skia_util.h" #endif #if !defined(__native_client__) @@ -7176,6 +7178,14 @@ free_bytes_ -= size; } + int Save(const cc::PlaybackParams& playback_params) { + int save_count = canvas_.getSaveCount(); + cc::SaveOp save_op; + save_op.type = static_cast<uint8_t>(cc::PaintOpType::Save); + Serialize(&save_op, playback_params); + return save_count; + } + void RestoreTo(int count, const cc::PlaybackParams& playback_params) { cc::RestoreOp restore_op; restore_op.type = static_cast<uint8_t>(cc::PaintOpType::Restore); @@ -7201,10 +7211,6 @@ cc::PaintOp::SerializeOptions& options_; ScopedTransferBufferPtr transfer_buffer_; GLES2CmdHelper* helper_; - // TODO(enne): this canvas needs to persist across multiple raster calls. - // Probably the solution here is to move the "preamble" into the raster - // command itself so that the entire raster call + preamble happens in - // one call to GLES2Implementation::RasterChromium. SkNoDrawCanvas canvas_; size_t written_bytes_ = 0; @@ -7215,44 +7221,47 @@ const std::vector<size_t>* indices, SerializeHelper* serializer) { cc::PlaybackParams params(nullptr, serializer->canvas()->getTotalMatrix()); - int save_count = serializer->canvas()->getSaveCount(); for (cc::PaintOpBuffer::CompositeIterator iter(buffer, indices); iter; ++iter) { const cc::PaintOp* op = *iter; if (op->GetType() == cc::PaintOpType::DrawRecord) { // TODO(enne): Add some flag here to save ctm, or adjust setmatrix ops. - cc::SaveOp save_op; - save_op.type = static_cast<uint8_t>(cc::PaintOpType::Save); - serializer->Serialize(&save_op, params); - + int save_count = serializer->Save(params); SerializeRecursive(static_cast<const cc::DrawRecordOp*>(op)->record.get(), nullptr, serializer); - - cc::RestoreOp restore_op; - restore_op.type = static_cast<uint8_t>(cc::PaintOpType::Restore); - serializer->Serialize(&restore_op, params); - continue; + serializer->RestoreTo(save_count, params); + } else { + serializer->Serialize(op, params); } - - serializer->Serialize(op, params); } - - serializer->RestoreTo(save_count, params); } #endif void GLES2Implementation::RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) { + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) { #if defined(OS_NACL) NOTREACHED(); #else GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRasterChromium(" << list << ", " - << x << ", " << y << ", " << w << ", " << h << ")"); + << translate_x << ", " << translate_y << ", " << clip_x + << ", " << clip_y << ", " << clip_w << ", " << clip_h + << ", " << post_translate_x << ", " << post_translate_y + << ", " << post_scale << ")"); + + gfx::Rect playback_rect(clip_x, clip_y, clip_w, clip_h); + std::vector<size_t> indices = list->rtree_.Search(playback_rect); + if (indices.empty()) + return; // TODO(enne): tune these numbers // TODO(enne): convert these types here and in transfer buffer to be size_t. @@ -7261,11 +7270,35 @@ cc::PaintOp::SerializeOptions options; SerializeHelper serializer(options, free_size, transfer_buffer_, helper_); + // This section duplicates RasterSource::PlaybackToCanvas setup preamble. + cc::PlaybackParams params(nullptr, serializer.canvas()->getTotalMatrix()); + // Bookend with save/restore so each RasterCHROMIUM command is independent. + int save_count = serializer.Save(params); + + cc::TranslateOp translate(-translate_x, -translate_y); + translate.type = static_cast<uint8_t>(cc::PaintOpType::Translate); + serializer.Serialize(&translate, params); + + cc::ClipRectOp clip(SkRect::MakeFromIRect(gfx::RectToSkIRect(playback_rect)), + SkClipOp::kIntersect, false); + clip.type = static_cast<uint8_t>(cc::PaintOpType::ClipRect); + serializer.Serialize(&clip, params); + + if (post_translate_x != 0.f || post_translate_y != 0.f) { + cc::TranslateOp post_translate(post_translate_x, post_translate_y); + post_translate.type = static_cast<uint8_t>(cc::PaintOpType::Translate); + serializer.Serialize(&post_translate, params); + } + if (post_scale != 1.f) { + cc::ScaleOp scale(post_scale, post_scale); + scale.type = static_cast<uint8_t>(cc::PaintOpType::Scale); + serializer.Serialize(&scale, params); + } + // TODO(enne): need to implement alpha folding optimization from POB. // TODO(enne): don't access private members of DisplayItemList. - gfx::Rect playback_rect(x, y, w, h); - std::vector<size_t> indices = list->rtree_.Search(playback_rect); SerializeRecursive(&list->paint_op_buffer_, &indices, &serializer); + serializer.RestoreTo(save_count, params); serializer.SendSerializedData(); CheckGLError();
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 6594e53..3ccf84f 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1247,10 +1247,15 @@ GLint pixel_config) override; void RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) override; + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) override; void EndRasterCHROMIUM() override;
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 1d30149..e680647 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -926,10 +926,15 @@ GLboolean use_distance_field_text, GLint pixel_config) = 0; virtual void RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) = 0; + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) = 0; virtual void EndRasterCHROMIUM() = 0; virtual void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 9b25a5c..63cfe3f 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -899,10 +899,15 @@ GLboolean use_distance_field_text, GLint pixel_config) override; void RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) override; + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) override; void EndRasterCHROMIUM() override; void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index c6410449..94e0aea 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1210,10 +1210,15 @@ GLboolean /* use_distance_field_text */, GLint /* pixel_config */) {} void GLES2InterfaceStub::RasterCHROMIUM(const cc::DisplayItemList* /* list */, - GLint /* x */, - GLint /* y */, - GLint /* w */, - GLint /* h */) {} + GLint /* translate_x */, + GLint /* translate_y */, + GLint /* clip_x */, + GLint /* clip_y */, + GLint /* clip_w */, + GLint /* clip_h */, + GLfloat /* post_translate_x */, + GLfloat /* post_translate_y */, + GLfloat /* post_scale */) {} void GLES2InterfaceStub::EndRasterCHROMIUM() {} void GLES2InterfaceStub::TexStorage2DImageCHROMIUM(GLenum /* target */, GLenum /* internalFormat */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 2ff931f..21dc439 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -899,10 +899,15 @@ GLboolean use_distance_field_text, GLint pixel_config) override; void RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) override; + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) override; void EndRasterCHROMIUM() override; void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index e71369e1..d6769f8 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2584,12 +2584,18 @@ } void GLES2TraceImplementation::RasterCHROMIUM(const cc::DisplayItemList* list, - GLint x, - GLint y, - GLint w, - GLint h) { + GLint translate_x, + GLint translate_y, + GLint clip_x, + GLint clip_y, + GLint clip_w, + GLint clip_h, + GLfloat post_translate_x, + GLfloat post_translate_y, + GLfloat post_scale) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::RasterCHROMIUM"); - gl_->RasterCHROMIUM(list, x, y, w, h); + gl_->RasterCHROMIUM(list, translate_x, translate_y, clip_x, clip_y, clip_w, + clip_h, post_translate_x, post_translate_y, post_scale); } void GLES2TraceImplementation::EndRasterCHROMIUM() {
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 32567a5..87cbc39 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -379,7 +379,7 @@ // Extension CHROMIUM_raster_transport GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint texture_id, GLuint sk_color, GLuint msaa_sample_count, GLboolean can_use_lcd_text, GLboolean use_distance_field_text, GLint pixel_config); -GL_APICALL void GL_APIENTRY glRasterCHROMIUM (const cc::DisplayItemList* list, GLint x, GLint y, GLint w, GLint h); +GL_APICALL void GL_APIENTRY glRasterCHROMIUM (const cc::DisplayItemList* list, GLint translate_x, GLint translate_y, GLint clip_x, GLint clip_y, GLint clip_w, GLint clip_h, GLfloat post_translate_x, GLfloat post_translate_y, GLfloat post_scale); GL_APICALL void GL_APIENTRY glEndRasterCHROMIUM (void); // Extension CHROMIUM_texture_storage_image
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index d24e73c9..babc44b0 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -1749,18 +1749,8 @@ return IsWebGL2OrES3ContextType(context_type_); } -void FeatureInfo::AddExtensionString(const char* s) { - std::string str(s); - size_t pos = extensions_.find(str); - while (pos != std::string::npos && - pos + str.length() < extensions_.length() && - extensions_.substr(pos + str.length(), 1) != " ") { - // This extension name is a substring of another. - pos = extensions_.find(str, pos + str.length()); - } - if (pos == std::string::npos) { - extensions_ += (extensions_.empty() ? "" : " ") + str; - } +void FeatureInfo::AddExtensionString(const base::StringPiece& extension) { + extensions_.insert(extension); } FeatureInfo::~FeatureInfo() {
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index d9fbdad..3f8f668 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h
@@ -148,9 +148,7 @@ ContextType context_type() const { return context_type_; } - const std::string& extensions() const { - return extensions_; - } + const gl::ExtensionSet& extensions() const { return extensions_; } const FeatureFlags& feature_flags() const { return feature_flags_; @@ -201,7 +199,7 @@ ~FeatureInfo(); - void AddExtensionString(const char* s); + void AddExtensionString(const base::StringPiece& s); void InitializeBasicState(const base::CommandLine* command_line); void InitializeFeatures(); void InitializeFloatAndHalfFloatFeatures(const gl::ExtensionSet& extensions); @@ -212,8 +210,8 @@ ContextType context_type_ = CONTEXT_TYPE_OPENGLES2; - // The extensions string returned by glGetString(GL_EXTENSIONS); - std::string extensions_; + // The set of extensions returned by glGetString(GL_EXTENSIONS); + gl::ExtensionSet extensions_; // Flags for some features FeatureFlags feature_flags_;
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 0e18fab..4d96019 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -208,12 +208,15 @@ TEST_P(FeatureInfoTest, InitializeNoExtensions) { SetupInitExpectations(""); // Check default extensions are there - EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_resource_safe")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_strict_attribs")); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_ANGLE_translated_shader_source")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_trace_marker")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_unpack_subimage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_resource_safe")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_strict_attribs")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_ANGLE_translated_shader_source")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_trace_marker")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_unpack_subimage")); bool expect_ext_srgb = false; switch (GetParam()) { @@ -233,7 +236,7 @@ // which is not part of the ES3 core, we have to be careful to search for // "GL_EXT_sRGB ", and append a space to the end of the extension string. if (expect_ext_srgb) { - EXPECT_THAT(info_->extensions() + " ", HasSubstr("GL_EXT_sRGB ")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_sRGB")); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT)); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_ALPHA_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -245,7 +248,7 @@ EXPECT_TRUE(info_->validators()->framebuffer_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } else { - EXPECT_THAT(info_->extensions() + " ", Not(HasSubstr("GL_EXT_sRGB "))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_EXT_sRGB")); EXPECT_FALSE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT)); EXPECT_FALSE(info_->validators()->texture_format.IsValid( GL_SRGB_ALPHA_EXT)); @@ -260,25 +263,23 @@ } // Check a couple of random extensions that should not be there. - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_npot"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_compression_dxt1"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_texture_compression_dxt3"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_texture_compression_dxt5"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_ANGLE_texture_usage"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_storage"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_compressed_ETC1_RGB8_texture"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_AMD_compressed_ATC_texture"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_IMG_texture_compression_pvrtc"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_compression_s3tc_srgb"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_OES_texture_npot")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_compression_dxt1")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_texture_compression_dxt3")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_texture_compression_dxt5")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_ANGLE_texture_usage")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_OES_compressed_ETC1_RGB8_texture")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_AMD_compressed_ATC_texture")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_IMG_texture_compression_pvrtc")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_EXT_texture_compression_s3tc_srgb")); EXPECT_FALSE(info_->feature_flags().npot_ok); EXPECT_FALSE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_RGB_S3TC_DXT1_EXT)); @@ -364,20 +365,20 @@ TEST_P(FeatureInfoTest, InitializeNPOTExtensionGLES) { SetupInitExpectations("GL_OES_texture_npot"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_npot")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_texture_npot")); EXPECT_TRUE(info_->feature_flags().npot_ok); } TEST_P(FeatureInfoTest, InitializeNPOTExtensionGL) { SetupInitExpectations("GL_ARB_texture_non_power_of_two"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_npot")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_texture_npot")); EXPECT_TRUE(info_->feature_flags().npot_ok); } TEST_P(FeatureInfoTest, InitializeDXTExtensionGLES2) { SetupInitExpectations("GL_EXT_texture_compression_dxt1"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_compression_dxt1")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_compression_dxt1")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_RGB_S3TC_DXT1_EXT)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -390,12 +391,12 @@ TEST_P(FeatureInfoTest, InitializeDXTExtensionGL) { SetupInitExpectations("GL_EXT_texture_compression_s3tc"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_compression_dxt1")); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_texture_compression_dxt3")); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_texture_compression_dxt5")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_compression_dxt1")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_texture_compression_dxt3")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_texture_compression_dxt5")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_RGB_S3TC_DXT1_EXT)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -409,8 +410,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_compression_s3tc_srgb) { SetupInitExpectationsWithGLVersion("GL_NV_sRGB_formats", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_compression_s3tc_srgb")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_texture_compression_s3tc_srgb")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_SRGB_S3TC_DXT1_EXT)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -423,8 +424,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_compression_s3tc_srgbGL) { SetupInitExpectations("GL_EXT_texture_sRGB GL_EXT_texture_compression_s3tc"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_compression_s3tc_srgb")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_texture_compression_s3tc_srgb")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_SRGB_S3TC_DXT1_EXT)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -438,8 +439,8 @@ TEST_P(FeatureInfoTest, InitializeCHROMIUM_compressed_texture_etc) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_compressed_texture_etc")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_compressed_texture_etc")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_R11_EAC)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -486,8 +487,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GLES2) { SetupInitExpectationsWithGLVersion("GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); EXPECT_TRUE(info_->validators()->texture_format.IsValid( GL_BGRA_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -504,8 +505,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { SetupInitExpectationsWithGLVersion("", "", "OpenGL 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); EXPECT_TRUE(info_->validators()->texture_format.IsValid( GL_BGRA_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -515,8 +516,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) { SetupInitExpectationsWithGLVersion("GL_APPLE_texture_format_BGRA8888", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); EXPECT_TRUE(info_->validators()->texture_format.IsValid( GL_BGRA_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -533,8 +534,8 @@ TEST_P(FeatureInfoTest, InitializeGLES_no_EXT_texture_format_BGRA8888GL) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_format_BGRA8888"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); EXPECT_FALSE(info_->validators()->texture_format.IsValid(GL_BGRA_EXT)); EXPECT_FALSE( info_->validators()->texture_internal_format.IsValid(GL_BGRA_EXT)); @@ -543,8 +544,7 @@ TEST_P(FeatureInfoTest, InitializeGLES2EXT_read_format_bgra) { SetupInitExpectationsWithGLVersion( "GL_EXT_read_format_bgra", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_read_format_bgra")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_read_format_bgra")); EXPECT_TRUE(info_->feature_flags().ext_read_format_bgra); EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid( GL_BGRA_EXT)); @@ -561,8 +561,7 @@ TEST_P(FeatureInfoTest, InitializeGLEXT_read_format_bgra) { SetupInitExpectationsWithGLVersion("", "", "OpenGL 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_read_format_bgra")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_read_format_bgra")); EXPECT_TRUE(info_->feature_flags().ext_read_format_bgra); EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid( GL_BGRA_EXT)); @@ -570,7 +569,8 @@ TEST_P(FeatureInfoTest, InitializeGLES_no_EXT_read_format_bgra) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_read_format_bgra"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_read_format_bgra")); EXPECT_FALSE(info_->feature_flags().ext_read_format_bgra); EXPECT_FALSE(info_->validators()->read_pixel_format.IsValid(GL_BGRA_EXT)); } @@ -579,7 +579,7 @@ SetupInitExpectations("GL_EXT_sRGB GL_OES_rgb8_rgba8"); if (GetContextType() == CONTEXT_TYPE_OPENGLES3) { - EXPECT_THAT(info_->extensions() + " ", Not(HasSubstr("GL_EXT_sRGB "))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_EXT_sRGB")); EXPECT_FALSE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT)); EXPECT_FALSE( info_->validators()->texture_format.IsValid(GL_SRGB_ALPHA_EXT)); @@ -592,7 +592,7 @@ EXPECT_FALSE(info_->validators()->framebuffer_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } else { - EXPECT_THAT(info_->extensions() + " ", HasSubstr("GL_EXT_sRGB ")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_sRGB")); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_EXT)); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_SRGB_ALPHA_EXT)); EXPECT_TRUE( @@ -610,7 +610,7 @@ SetupInitExpectationsWithGLVersion( "GL_EXT_texture_storage", "", "OpenGL ES 2.0"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); EXPECT_TRUE(info_->validators()->texture_parameter.IsValid( GL_TEXTURE_IMMUTABLE_FORMAT_EXT)); EXPECT_FALSE(info_->validators()->texture_internal_format_storage.IsValid( @@ -640,7 +640,7 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_storage) { SetupInitExpectations("GL_EXT_texture_storage"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); EXPECT_TRUE(info_->validators()->texture_parameter.IsValid( GL_TEXTURE_IMMUTABLE_FORMAT_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( @@ -670,7 +670,7 @@ TEST_P(FeatureInfoTest, InitializeARB_texture_storage) { SetupInitExpectations("GL_ARB_texture_storage"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); EXPECT_TRUE(info_->validators()->texture_parameter.IsValid( GL_TEXTURE_IMMUTABLE_FORMAT_EXT)); } @@ -679,37 +679,41 @@ SetupInitExpectationsWithGLVersion("GL_EXT_texture_storage", "", "OpenGL 2.0"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( GL_BGRA8_EXT)); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } TEST_P(FeatureInfoTest, InitializeARB_texture_storage_BGRA) { SetupInitExpectationsWithGLVersion("GL_ARB_texture_storage", "", "OpenGL 2.0"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( GL_BGRA8_EXT)); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_BGRA8888) { SetupInitExpectations( "GL_EXT_texture_storage GL_EXT_texture_format_BGRA8888"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( GL_BGRA8_EXT)); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_float) { SetupInitExpectations("GL_EXT_texture_storage GL_OES_texture_float"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_float")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_texture_float")); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( GL_RGBA32F_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( @@ -724,8 +728,9 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_half_float) { SetupInitExpectations("GL_EXT_texture_storage GL_OES_texture_half_float"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_half_float")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_half_float")); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( GL_RGBA16F_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format_storage.IsValid( @@ -743,8 +748,8 @@ TEST_P(FeatureInfoTest, InitializeGL_renderbuffer_format_BGRA8888) { SetupInitExpectationsWithGLVersion("", "", "OpenGL 2.0"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_renderbuffer_format_BGRA8888")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_renderbuffer_format_BGRA8888")); EXPECT_TRUE(info_->feature_flags().ext_render_buffer_format_bgra8888); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_BGRA8_EXT)); } @@ -757,9 +762,9 @@ TEST_P(FeatureInfoTest, InitializeGLES2_texture_storage) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_storage", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_format_BGRA8888"))); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 2- ES2 + GL_EXT_texture_storage + (GL_EXT_texture_format_BGRA8888 or @@ -769,25 +774,27 @@ "GL_EXT_texture_storage GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 3- ES2 + GL_EXT_texture_format_BGRA8888 or GL_APPLE_texture_format_bgra8888 TEST_P(FeatureInfoTest, InitializeGLES2_texture_format_BGRA) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_storage"))); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 4- ES2 (neither GL_EXT_texture_storage nor GL_EXT_texture_format_BGRA8888) -> // nothing TEST_P(FeatureInfoTest, InitializeGLES2_neither_texture_storage_nor_BGRA) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 2.0"); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_storage"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_format_BGRA8888"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 5- ES3 + GL_EXT_texture_format_BGRA8888 @@ -799,13 +806,15 @@ SetupInitExpectationsWithGLVersion( "GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 3.0"); if (GetContextType() == CONTEXT_TYPE_OPENGLES3) { - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_format_BGRA8888"))); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_EXT_texture_format_BGRA8888")); } else { - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_storage"))); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_texture_format_BGRA8888")); } } @@ -815,8 +824,9 @@ TEST_P(FeatureInfoTest, InitializeGLES3_texture_storage_APPLE_BGRA) { SetupInitExpectationsWithGLVersion( "GL_APPLE_texture_format_BGRA8888", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 7- ES3 + GL_EXT_texture_storage + GL_EXT_texture_format_BGRA8888 -> @@ -827,17 +837,18 @@ "GL_EXT_texture_storage GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 8- ES3 + none of the above -> GL_EXT_texture_storage (and no // GL_EXT_texture_format_BGRA8888 - we don't claim to handle GL_BGRA8) TEST_P(FeatureInfoTest, InitializeGLES3_texture_storage) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_EXT_texture_format_BGRA8888"))); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_texture_storage")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_EXT_texture_format_BGRA8888")); } // 9- ANGLE will add the GL_CHROMIUM_renderbuffer_format_BGRA8888 extension and @@ -845,8 +856,8 @@ TEST_P(FeatureInfoTest, InitializeWithANGLE_BGRA8) { SetupInitExpectationsWithGLVersion("", kGLRendererStringANGLE, ""); EXPECT_TRUE(info_->gl_version_info().is_angle); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_renderbuffer_format_BGRA8888")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_renderbuffer_format_BGRA8888")); EXPECT_TRUE(info_->feature_flags().ext_render_buffer_format_bgra8888); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_BGRA8_EXT)); } @@ -856,8 +867,8 @@ InitializeGLES2_no_CHROMIUM_renderbuffer_format_BGRA8888) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 2.0"); EXPECT_FALSE(info_->feature_flags().ext_render_buffer_format_bgra8888); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_renderbuffer_format_BGRA8888"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_renderbuffer_format_BGRA8888")); } TEST_P(FeatureInfoTest, InitializeARB_texture_float) { @@ -866,30 +877,30 @@ disallowed_features.chromium_color_buffer_float_rgba = true; SetupInitExpectationsWithGLVersionAndDisallowedFeatures( "GL_ARB_texture_float", "", "3.0", disallowed_features); - std::string extensions = info_->extensions() + " "; - EXPECT_THAT(extensions, - Not(HasSubstr("GL_CHROMIUM_color_buffer_float_rgb "))); - EXPECT_THAT(extensions, - Not(HasSubstr("GL_CHROMIUM_color_buffer_float_rgba"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_color_buffer_float_rgb")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_color_buffer_float_rgba")); EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( GL_RGBA32F)); EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( GL_RGB32F)); info_->EnableCHROMIUMColorBufferFloatRGBA(); - extensions = info_->extensions() + " "; - EXPECT_THAT(extensions, - Not(HasSubstr("GL_CHROMIUM_color_buffer_float_rgb "))); - EXPECT_THAT(extensions, HasSubstr("GL_CHROMIUM_color_buffer_float_rgba")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_color_buffer_float_rgb")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_color_buffer_float_rgba")); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( GL_RGBA32F)); EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( GL_RGB32F)); info_->EnableCHROMIUMColorBufferFloatRGB(); - extensions = info_->extensions() + " "; - EXPECT_THAT(extensions, HasSubstr("GL_CHROMIUM_color_buffer_float_rgb ")); - EXPECT_THAT(extensions, HasSubstr("GL_CHROMIUM_color_buffer_float_rgba")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_color_buffer_float_rgb")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_color_buffer_float_rgba")); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( GL_RGBA32F)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -898,17 +909,18 @@ TEST_P(FeatureInfoTest, Initialize_texture_floatGLES3) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_float"))); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_half_float"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_float_linear"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_half_float_linear"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_OES_texture_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_half_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_float_linear")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_OES_texture_half_float_linear")); } TEST_P(FeatureInfoTest, Initialize_sRGBGLES3) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions() + " ", Not(HasSubstr("GL_EXT_sRGB "))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_EXT_sRGB")); EXPECT_FALSE(info_->validators()->texture_format.IsValid( GL_SRGB_EXT)); EXPECT_FALSE(info_->validators()->texture_format.IsValid( @@ -927,12 +939,13 @@ SetupInitExpectations("GL_OES_texture_float"); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_float")); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_half_float"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_float_linear"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_half_float_linear"))); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_texture_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_half_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_float_linear")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_OES_texture_half_float_linear")); EXPECT_TRUE(info_->validators()->pixel_type.IsValid(GL_FLOAT)); EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES)); } @@ -941,11 +954,13 @@ SetupInitExpectations("GL_OES_texture_float GL_OES_texture_float_linear"); EXPECT_TRUE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_float")); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_half_float"))); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_float_linear")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_half_float_linear"))); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_texture_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_half_float")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_float_linear")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_OES_texture_half_float_linear")); EXPECT_TRUE(info_->validators()->pixel_type.IsValid(GL_FLOAT)); EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES)); } @@ -954,12 +969,13 @@ SetupInitExpectations("GL_OES_texture_half_float"); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_float"))); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_half_float")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_float_linear"))); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_half_float_linear"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_OES_texture_float")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_half_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_float_linear")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_OES_texture_half_float_linear")); EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_FLOAT)); EXPECT_TRUE(info_->validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES)); } @@ -969,12 +985,13 @@ "GL_OES_texture_half_float GL_OES_texture_half_float_linear"); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_TRUE(info_->feature_flags().enable_texture_half_float_linear); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_float"))); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_half_float")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_OES_texture_float_linear"))); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_texture_half_float_linear")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_OES_texture_float")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_half_float")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_OES_texture_float_linear")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_OES_texture_half_float_linear")); EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_FLOAT)); EXPECT_TRUE(info_->validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES)); } @@ -982,8 +999,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { SetupInitExpectations("GL_EXT_framebuffer_multisample"); EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_framebuffer_multisample")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_framebuffer_multisample")); EXPECT_TRUE(info_->validators()->framebuffer_target.IsValid( GL_READ_FRAMEBUFFER_EXT)); EXPECT_TRUE(info_->validators()->framebuffer_target.IsValid( @@ -1000,8 +1017,8 @@ SetupInitExpectationsWithGLVersion( "GL_ANGLE_framebuffer_multisample", kGLRendererStringANGLE, ""); EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_framebuffer_multisample")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_framebuffer_multisample")); EXPECT_TRUE(info_->validators()->framebuffer_target.IsValid( GL_READ_FRAMEBUFFER_EXT)); EXPECT_TRUE(info_->validators()->framebuffer_target.IsValid( @@ -1020,8 +1037,8 @@ TEST_P(FeatureInfoTest, InitializeANGLE_framebuffer_multisampleWithoutANGLE) { SetupInitExpectations("GL_ANGLE_framebuffer_multisample"); EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_framebuffer_multisample"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_framebuffer_multisample")); EXPECT_FALSE(info_->validators()->framebuffer_target.IsValid( GL_READ_FRAMEBUFFER_EXT)); EXPECT_FALSE(info_->validators()->framebuffer_target.IsValid( @@ -1040,8 +1057,8 @@ ).multisampled_render_to_texture); EXPECT_FALSE(info_->feature_flags( ).use_img_for_multisampled_render_to_texture); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_multisampled_render_to_texture")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_multisampled_render_to_texture")); EXPECT_TRUE(info_->validators()->g_l_state.IsValid( GL_MAX_SAMPLES_EXT)); EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( @@ -1056,8 +1073,8 @@ ).multisampled_render_to_texture); EXPECT_TRUE(info_->feature_flags( ).use_img_for_multisampled_render_to_texture); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_multisampled_render_to_texture")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_multisampled_render_to_texture")); EXPECT_TRUE(info_->validators()->g_l_state.IsValid( GL_MAX_SAMPLES_EXT)); EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( @@ -1068,8 +1085,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_texture_filter_anisotropic) { SetupInitExpectations("GL_EXT_texture_filter_anisotropic"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_texture_filter_anisotropic")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_texture_filter_anisotropic")); EXPECT_TRUE(info_->validators()->texture_parameter.IsValid( GL_TEXTURE_MAX_ANISOTROPY_EXT)); EXPECT_TRUE(info_->validators()->g_l_state.IsValid( @@ -1078,10 +1095,9 @@ TEST_P(FeatureInfoTest, InitializeEXT_ARB_depth_texture) { SetupInitExpectations("GL_ARB_depth_texture"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_GOOGLE_depth_texture")); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_depth_texture")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_GOOGLE_depth_texture")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_depth_texture")); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( GL_DEPTH_COMPONENT)); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_DEPTH_COMPONENT)); @@ -1092,10 +1108,9 @@ TEST_P(FeatureInfoTest, InitializeOES_ARB_depth_texture) { SetupInitExpectations("GL_OES_depth_texture"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_GOOGLE_depth_texture")); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_depth_texture")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_GOOGLE_depth_texture")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_depth_texture")); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( GL_DEPTH_COMPONENT)); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_DEPTH_COMPONENT)); @@ -1106,12 +1121,10 @@ TEST_P(FeatureInfoTest, InitializeANGLE_depth_texture) { SetupInitExpectations("GL_ANGLE_depth_texture"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_GOOGLE_depth_texture")); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_depth_texture")); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_ANGLE_depth_texture"))); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_GOOGLE_depth_texture")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_depth_texture")); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), "GL_ANGLE_depth_texture")); EXPECT_TRUE(info_->feature_flags().angle_depth_texture); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( GL_DEPTH_COMPONENT)); @@ -1129,8 +1142,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_packed_depth_stencil) { SetupInitExpectations("GL_EXT_packed_depth_stencil"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_packed_depth_stencil")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_packed_depth_stencil")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_DEPTH24_STENCIL8)); EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( @@ -1142,8 +1155,8 @@ TEST_P(FeatureInfoTest, InitializeOES_packed_depth_stencil) { SetupInitExpectations("GL_OES_packed_depth_stencil"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_packed_depth_stencil")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_packed_depth_stencil")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_DEPTH24_STENCIL8)); EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( @@ -1156,8 +1169,8 @@ TEST_P(FeatureInfoTest, InitializeOES_packed_depth_stencil_and_GL_ARB_depth_texture) { SetupInitExpectations("GL_OES_packed_depth_stencil GL_ARB_depth_texture"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_packed_depth_stencil")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_packed_depth_stencil")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_DEPTH24_STENCIL8)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -1171,14 +1184,15 @@ TEST_P(FeatureInfoTest, InitializeOES_depth24) { SetupInitExpectations("GL_OES_depth24"); EXPECT_TRUE(info_->feature_flags().oes_depth24); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_depth24")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_DEPTH_COMPONENT24)); } TEST_P(FeatureInfoTest, InitializeOES_standard_derivatives) { SetupInitExpectations("GL_OES_standard_derivatives"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_standard_derivatives")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_standard_derivatives")); EXPECT_TRUE(info_->feature_flags().oes_standard_derivatives); EXPECT_TRUE(info_->validators()->hint_target.IsValid( GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES)); @@ -1188,8 +1202,7 @@ TEST_P(FeatureInfoTest, InitializeOES_rgb8_rgba8) { SetupInitExpectations("GL_OES_rgb8_rgba8"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_rgb8_rgba8")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_rgb8_rgba8")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_RGB8_OES)); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( @@ -1198,8 +1211,8 @@ TEST_P(FeatureInfoTest, InitializeOES_EGL_image_external) { SetupInitExpectations("GL_OES_EGL_image_external"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_EGL_image_external")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_EGL_image_external")); EXPECT_TRUE(info_->feature_flags().oes_egl_image_external); EXPECT_TRUE(info_->validators()->texture_bind_target.IsValid( GL_TEXTURE_EXTERNAL_OES)); @@ -1213,8 +1226,8 @@ TEST_P(FeatureInfoTest, InitializeNV_EGL_stream_consumer_external) { SetupInitExpectations("GL_NV_EGL_stream_consumer_external"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_NV_EGL_stream_consumer_external")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_NV_EGL_stream_consumer_external")); EXPECT_TRUE(info_->feature_flags().nv_egl_stream_consumer_external); EXPECT_TRUE(info_->validators()->texture_bind_target.IsValid( GL_TEXTURE_EXTERNAL_OES)); @@ -1228,8 +1241,8 @@ TEST_P(FeatureInfoTest, InitializeOES_compressed_ETC1_RGB8_texture) { SetupInitExpectations("GL_OES_compressed_ETC1_RGB8_texture"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_compressed_ETC1_RGB8_texture")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_OES_compressed_ETC1_RGB8_texture")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_ETC1_RGB8_OES)); EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( @@ -1238,8 +1251,8 @@ TEST_P(FeatureInfoTest, InitializeAMD_compressed_ATC_texture) { SetupInitExpectations("GL_AMD_compressed_ATC_texture"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_AMD_compressed_ATC_texture")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_AMD_compressed_ATC_texture")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_ATC_RGB_AMD)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -1250,8 +1263,8 @@ TEST_P(FeatureInfoTest, InitializeIMG_texture_compression_pvrtc) { SetupInitExpectations("GL_IMG_texture_compression_pvrtc"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_IMG_texture_compression_pvrtc")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_IMG_texture_compression_pvrtc")); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG)); EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid( @@ -1265,8 +1278,8 @@ TEST_P(FeatureInfoTest, InitializeEXT_occlusion_query_boolean) { SetupInitExpectations("GL_EXT_occlusion_query_boolean"); if (GetContextType() == CONTEXT_TYPE_OPENGLES2) { - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_occlusion_query_boolean")); } EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); EXPECT_FALSE(info_->feature_flags( @@ -1278,8 +1291,8 @@ TEST_P(FeatureInfoTest, InitializeARB_occlusion_query) { SetupInitExpectations("GL_ARB_occlusion_query"); if (GetContextType() == CONTEXT_TYPE_OPENGLES2) { - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_occlusion_query_boolean")); } EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); EXPECT_FALSE(info_->feature_flags( @@ -1291,8 +1304,8 @@ TEST_P(FeatureInfoTest, InitializeARB_occlusion_query2) { SetupInitExpectations("GL_ARB_occlusion_query2 GL_ARB_occlusion_query2"); if (GetContextType() == CONTEXT_TYPE_OPENGLES2) { - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_occlusion_query_boolean")); } EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); EXPECT_TRUE(info_->feature_flags( @@ -1304,8 +1317,8 @@ TEST_P(FeatureInfoTest, InitializeGLES3_occlusion_query_boolean) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); if (GetContextType() == CONTEXT_TYPE_OPENGLES2) { - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_occlusion_query_boolean")); } EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); } @@ -1313,8 +1326,8 @@ TEST_P(FeatureInfoTest, InitializeGL33_occlusion_query2) { SetupInitExpectationsWithGLVersion("", "", "3.3"); if (GetContextType() == CONTEXT_TYPE_OPENGLES2) { - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_occlusion_query_boolean")); } EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); EXPECT_TRUE(info_->feature_flags( @@ -1324,8 +1337,8 @@ TEST_P(FeatureInfoTest, InitializeGL43_occlusion_query2) { SetupInitExpectationsWithGLVersion("", "", "4.3"); if (GetContextType() == CONTEXT_TYPE_OPENGLES2) { - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_EXT_occlusion_query_boolean")); } EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); EXPECT_FALSE(info_->feature_flags( @@ -1334,22 +1347,22 @@ TEST_P(FeatureInfoTest, InitializeOES_vertex_array_object) { SetupInitExpectations("GL_OES_vertex_array_object"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_vertex_array_object")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_vertex_array_object")); EXPECT_TRUE(info_->feature_flags().native_vertex_array_object); } TEST_P(FeatureInfoTest, InitializeARB_vertex_array_object) { SetupInitExpectations("GL_ARB_vertex_array_object"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_vertex_array_object")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_vertex_array_object")); EXPECT_TRUE(info_->feature_flags().native_vertex_array_object); } TEST_P(FeatureInfoTest, InitializeAPPLE_vertex_array_object) { SetupInitExpectations("GL_APPLE_vertex_array_object"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_vertex_array_object")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_vertex_array_object")); EXPECT_TRUE(info_->feature_flags().native_vertex_array_object); } @@ -1358,15 +1371,15 @@ // Even if the native extensions are not available the implementation // may still emulate the GL_OES_vertex_array_object functionality. In this // scenario native_vertex_array_object must be false. - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_vertex_array_object")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_vertex_array_object")); EXPECT_FALSE(info_->feature_flags().native_vertex_array_object); } TEST_P(FeatureInfoTest, InitializeOES_element_index_uint) { SetupInitExpectations("GL_OES_element_index_uint"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_OES_element_index_uint")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_OES_element_index_uint")); EXPECT_TRUE(info_->validators()->index_type.IsValid(GL_UNSIGNED_INT)); } @@ -1381,7 +1394,7 @@ TEST_P(FeatureInfoTest, InitializeEXT_blend_minmax) { SetupInitExpectations("GL_EXT_blend_minmax"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_blend_minmax")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_blend_minmax")); EXPECT_TRUE(info_->validators()->equation.IsValid(GL_MIN_EXT)); EXPECT_TRUE(info_->validators()->equation.IsValid(GL_MAX_EXT)); } @@ -1389,19 +1402,21 @@ TEST_P(FeatureInfoTest, InitializeEXT_frag_depth) { SetupInitExpectations("GL_EXT_frag_depth"); EXPECT_TRUE(info_->feature_flags().ext_frag_depth); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_frag_depth")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_EXT_frag_depth")); } TEST_P(FeatureInfoTest, InitializeEXT_shader_texture_lod) { SetupInitExpectations("GL_EXT_shader_texture_lod"); EXPECT_TRUE(info_->feature_flags().ext_shader_texture_lod); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_shader_texture_lod")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_shader_texture_lod")); } TEST_P(FeatureInfoTest, InitializeEXT_discard_framebuffer) { SetupInitExpectations("GL_EXT_discard_framebuffer"); EXPECT_TRUE(info_->feature_flags().ext_discard_framebuffer); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_discard_framebuffer")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_discard_framebuffer")); } TEST_P(FeatureInfoTest, InitializeSamplersWithARBSamplerObjects) { @@ -1414,13 +1429,15 @@ SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); EXPECT_TRUE(info_->feature_flags().use_core_framebuffer_multisample); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_CHROMIUM_framebuffer_multisample")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_CHROMIUM_framebuffer_multisample")); EXPECT_TRUE(info_->feature_flags().use_async_readpixels); EXPECT_TRUE(info_->feature_flags().oes_standard_derivatives); EXPECT_TRUE(info_->feature_flags().oes_depth24); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_GOOGLE_depth_texture"))); - EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_depth_texture"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_GOOGLE_depth_texture")); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_depth_texture")); EXPECT_FALSE( info_->validators()->texture_internal_format.IsValid(GL_DEPTH_COMPONENT)); EXPECT_FALSE( @@ -1431,7 +1448,7 @@ EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_UNSIGNED_INT)); EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_UNSIGNED_INT_24_8)); EXPECT_TRUE(info_->feature_flags().packed_depth24_stencil8); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_OES_depth24")); EXPECT_TRUE( info_->validators()->render_buffer_format.IsValid(GL_DEPTH_COMPONENT24)); EXPECT_TRUE( @@ -1444,7 +1461,8 @@ EXPECT_TRUE(info_->feature_flags().enable_samplers); EXPECT_TRUE(info_->feature_flags().map_buffer_range); EXPECT_TRUE(info_->feature_flags().ext_discard_framebuffer); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_discard_framebuffer")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_EXT_discard_framebuffer")); EXPECT_TRUE(info_->feature_flags().chromium_sync_query); EXPECT_TRUE(gl::GLFence::IsSupported()); } @@ -1452,8 +1470,9 @@ TEST_P(FeatureInfoTest, InitializeWithES3AndDepthTexture) { SetupInitExpectationsWithGLVersion( "GL_ANGLE_depth_texture", "", "OpenGL ES 3.0"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_GOOGLE_depth_texture")); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_depth_texture")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), "GL_GOOGLE_depth_texture")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_depth_texture")); EXPECT_TRUE( info_->validators()->texture_internal_format.IsValid(GL_DEPTH_COMPONENT)); EXPECT_TRUE( @@ -1535,7 +1554,8 @@ "GL_NV_framebuffer_mixed_samples", "", "4.3"); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering2) { @@ -1543,22 +1563,23 @@ "GL_NV_path_rendering GL_NV_framebuffer_mixed_samples", "", "OpenGL ES 3.1"); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering) { SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_path_rendering"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering2) { SetupInitExpectationsWithGLVersion( "GL_ARB_compatibility GL_NV_path_rendering", "", "4.3"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_path_rendering"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering3) { @@ -1566,40 +1587,42 @@ SetupInitExpectationsWithGLVersion("GL_NV_path_rendering", "", "OpenGL ES 3.1"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_CHROMIUM_path_rendering"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced) { SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); EXPECT_FALSE(info_->feature_flags().blend_equation_advanced); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_KHR_blend_equation_advanced"))); + EXPECT_FALSE( + gl::HasExtension(info_->extensions(), "GL_KHR_blend_equation_advanced")); } TEST_P(FeatureInfoTest, InitializeKHR_blend_equations_advanced) { SetupInitExpectations("GL_KHR_blend_equation_advanced"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_KHR_blend_equation_advanced")); EXPECT_TRUE(info_->feature_flags().blend_equation_advanced); } TEST_P(FeatureInfoTest, InitializeNV_blend_equations_advanced) { SetupInitExpectations("GL_NV_blend_equation_advanced"); - EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced")); + EXPECT_TRUE( + gl::HasExtension(info_->extensions(), "GL_KHR_blend_equation_advanced")); EXPECT_TRUE(info_->feature_flags().blend_equation_advanced); } TEST_P(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced_coherent) { SetupInitExpectationsWithGLVersion("GL_ARB_compatibility ", "", "4.3"); EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent); - EXPECT_THAT(info_->extensions(), - Not(HasSubstr("GL_KHR_blend_equation_advanced_coherent"))); + EXPECT_FALSE(gl::HasExtension(info_->extensions(), + "GL_KHR_blend_equation_advanced_coherent")); } TEST_P(FeatureInfoTest, InitializeKHR_blend_equations_advanced_coherent) { SetupInitExpectations("GL_KHR_blend_equation_advanced_coherent"); - EXPECT_THAT(info_->extensions(), - HasSubstr("GL_KHR_blend_equation_advanced_coherent")); + EXPECT_TRUE(gl::HasExtension(info_->extensions(), + "GL_KHR_blend_equation_advanced_coherent")); EXPECT_TRUE(info_->feature_flags().blend_equation_advanced); EXPECT_TRUE(info_->feature_flags().blend_equation_advanced_coherent); }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 166da82..4fcb9b7b2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -12856,49 +12856,26 @@ case GL_SHADING_LANGUAGE_VERSION: str = GetServiceShadingLanguageVersionString(feature_info_.get()); break; - case GL_EXTENSIONS: - { - // For WebGL contexts, strip out shader extensions if they have not - // been enabled on WebGL1 or no longer exist (become core) in WebGL2. - if (feature_info_->IsWebGLContext()) { - extensions = feature_info_->extensions(); - if (!derivatives_explicitly_enabled_) { - size_t offset = extensions.find(kOESDerivativeExtension); - if (std::string::npos != offset) { - extensions.replace(offset, arraysize(kOESDerivativeExtension), - std::string()); - } - } - if (!frag_depth_explicitly_enabled_) { - size_t offset = extensions.find(kEXTFragDepthExtension); - if (std::string::npos != offset) { - extensions.replace(offset, arraysize(kEXTFragDepthExtension), - std::string()); - } - } - if (!draw_buffers_explicitly_enabled_) { - size_t offset = extensions.find(kEXTDrawBuffersExtension); - if (std::string::npos != offset) { - extensions.replace(offset, arraysize(kEXTDrawBuffersExtension), - std::string()); - } - } - if (!shader_texture_lod_explicitly_enabled_) { - size_t offset = extensions.find(kEXTShaderTextureLodExtension); - if (std::string::npos != offset) { - extensions.replace(offset, - arraysize(kEXTShaderTextureLodExtension), - std::string()); - } - } - } else { - extensions = feature_info_->extensions().c_str(); - } - if (supports_post_sub_buffer_) - extensions += " GL_CHROMIUM_post_sub_buffer"; - str = extensions.c_str(); + case GL_EXTENSIONS: { + gl::ExtensionSet extension_set = feature_info_->extensions(); + // For WebGL contexts, strip out shader extensions if they have not + // been enabled on WebGL1 or no longer exist (become core) in WebGL2. + if (feature_info_->IsWebGLContext()) { + if (!derivatives_explicitly_enabled_) + extension_set.erase(kOESDerivativeExtension); + if (!frag_depth_explicitly_enabled_) + extension_set.erase(kEXTFragDepthExtension); + if (!draw_buffers_explicitly_enabled_) + extension_set.erase(kEXTDrawBuffersExtension); + if (!shader_texture_lod_explicitly_enabled_) + extension_set.erase(kEXTShaderTextureLodExtension); } + if (supports_post_sub_buffer_) + extension_set.insert("GL_CHROMIUM_post_sub_buffer"); + extensions = gl::MakeExtensionString(extension_set); + str = extensions.c_str(); break; + } default: str = reinterpret_cast<const char*>(api()->glGetStringFn(name)); break; @@ -16094,7 +16071,7 @@ DisallowedFeatures disallowed_features = feature_info_->disallowed_features(); disallowed_features.AllowExtensions(); info->Initialize(feature_info_->context_type(), disallowed_features); - bucket->SetFromString(info->extensions().c_str()); + bucket->SetFromString(gl::MakeExtensionString(info->extensions()).c_str()); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 816c8b7..d289f98 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -316,7 +316,7 @@ GLint* precision, int32_t* success); error::Error DoGetShaderSource(GLuint shader, std::string* source); -error::Error DoGetString(GLenum name, const char** result); +error::Error DoGetString(GLenum name, uint32_t bucket_id); error::Error DoGetSynciv(GLuint sync, GLenum pname, GLsizei bufsize,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index fd4801d..9e3d820 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1656,22 +1656,29 @@ } error::Error GLES2DecoderPassthroughImpl::DoGetString(GLenum name, - const char** result) { + uint32_t bucket_id) { + std::string extensions; + const char* str = nullptr; + switch (name) { case GL_VERSION: - *result = GetServiceVersionString(feature_info_.get()); + str = GetServiceVersionString(feature_info_.get()); break; case GL_SHADING_LANGUAGE_VERSION: - *result = GetServiceShadingLanguageVersionString(feature_info_.get()); + str = GetServiceShadingLanguageVersionString(feature_info_.get()); break; - case GL_EXTENSIONS: - *result = feature_info_->extensions().c_str(); + case GL_EXTENSIONS: { + extensions = gl::MakeExtensionString(feature_info_->extensions()); + str = extensions.c_str(); break; + } default: - *result = reinterpret_cast<const char*>(api()->glGetStringFn(name)); + str = reinterpret_cast<const char*>(api()->glGetStringFn(name)); break; } + Bucket* bucket = CreateBucket(bucket_id); + bucket->SetFromString(str); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc index ae09c237..02f20d9b8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc
@@ -581,18 +581,7 @@ GLenum name = static_cast<GLenum>(c.name); uint32_t bucket_id = c.bucket_id; - const char* str = nullptr; - error::Error error = DoGetString(name, &str); - if (error != error::kNoError) { - return error; - } - if (!str) { - return error::kOutOfBounds; - } - Bucket* bucket = CreateBucket(bucket_id); - bucket->SetFromString(str); - - return error::kNoError; + return DoGetString(name, bucket_id); } error::Error GLES2DecoderPassthroughImpl::HandleGetTransformFeedbackVarying(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc index de10d51c..6a615c42 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc
@@ -228,6 +228,62 @@ ClearCurrentDecoderError(); } +TEST_P(GLES2DecoderLostContextTest, QueryDestroyAfterLostFromMakeCurrent) { + InitState init; + init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync"; + init.gl_version = "2.0"; + init.has_alpha = true; + init.request_alpha = true; + init.bind_generates_resource = true; + InitDecoder(init); + + const GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef); + GenHelper<GenQueriesEXTImmediate>(kNewClientId); + + BeginQueryEXT begin_cmd; + begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, kNewClientId, + shared_memory_id_, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + QueryManager* query_manager = decoder_->GetQueryManager(); + ASSERT_TRUE(query_manager != nullptr); + QueryManager::Query* query = query_manager->GetQuery(kNewClientId); + ASSERT_TRUE(query != nullptr); + EXPECT_FALSE(query->IsPending()); + + EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation(); + EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) + .WillOnce(Return(kGlSync)) + .RetiresOnSaturation(); +#if DCHECK_IS_ON() + EXPECT_CALL(*gl_, IsSync(kGlSync)) + .WillOnce(Return(GL_TRUE)) + .RetiresOnSaturation(); +#endif + + EndQueryEXT end_cmd; + end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + +#if DCHECK_IS_ON() + EXPECT_CALL(*gl_, IsSync(kGlSync)).Times(0).RetiresOnSaturation(); +#endif + EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(0).RetiresOnSaturation(); + + // Force context lost for MakeCurrent(). + EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(false)); + // Expect the group to be lost. + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1); + + decoder_->MakeCurrent(); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kMakeCurrentFailed, GetContextLostReason()); + ClearCurrentDecoderError(); + ResetDecoder(); +} + TEST_P(GLES2DecoderLostContextTest, LostFromResetAfterMakeCurrent) { Init(true); // with robustness InSequence seq;
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc index dd584d0..d036a7c3 100644 --- a/gpu/command_buffer/service/query_manager.cc +++ b/gpu/command_buffer/service/query_manager.cc
@@ -482,8 +482,7 @@ void CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) { if (fence_ && fence_->ResetSupported()) { fence_->ResetState(); - } - else { + } else { fence_.reset(gl::GLFence::Create()); } DCHECK(fence_); @@ -509,6 +508,8 @@ if (have_context && !IsDeleted()) { fence_.reset(); MarkAsDeleted(); + } else if (fence_ && !have_context) { + fence_->Invalidate(); } }
diff --git a/gpu/command_buffer/tests/fuzzer_main.cc b/gpu/command_buffer/tests/fuzzer_main.cc index 7084c62..eb35e653 100644 --- a/gpu/command_buffer/tests/fuzzer_main.cc +++ b/gpu/command_buffer/tests/fuzzer_main.cc
@@ -351,8 +351,13 @@ // Keep a reference to the translators, which keeps them in the cache even // after the decoder is reset. They are expensive to initialize, but they // don't keep state. - decoder_->GetTranslator(GL_VERTEX_SHADER)->AddRef(); - decoder_->GetTranslator(GL_FRAGMENT_SHADER)->AddRef(); + scoped_refptr<gles2::ShaderTranslatorInterface> translator = + decoder_->GetTranslator(GL_VERTEX_SHADER); + if (translator) + translator->AddRef(); + translator = decoder_->GetTranslator(GL_FRAGMENT_SHADER); + if (translator) + translator->AddRef(); return decoder_->MakeCurrent(); }
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc index f92a385c..7837c50 100644 --- a/headless/lib/browser/headless_browser_context_impl.cc +++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -83,9 +83,9 @@ std::unique_ptr<HeadlessBrowserContextOptions> context_options) : browser_(browser), context_options_(std::move(context_options)), - resource_context_(new HeadlessResourceContext), + resource_context_(std::make_unique<HeadlessResourceContext>()), should_remove_headers_(true), - permission_manager_(new HeadlessPermissionManager()), + permission_manager_(std::make_unique<HeadlessPermissionManager>(this)), id_(base::GenerateGUID()) { InitWhileIOAllowed(); } @@ -254,8 +254,6 @@ } content::PermissionManager* HeadlessBrowserContextImpl::GetPermissionManager() { - if (!permission_manager_.get()) - permission_manager_.reset(new HeadlessPermissionManager()); return permission_manager_.get(); }
diff --git a/headless/lib/browser/headless_devtools_client_impl.cc b/headless/lib/browser/headless_devtools_client_impl.cc index a83f8b5..11cb530 100644 --- a/headless/lib/browser/headless_devtools_client_impl.cc +++ b/headless/lib/browser/headless_devtools_client_impl.cc
@@ -229,8 +229,7 @@ } void HeadlessDevToolsClientImpl::AgentHostClosed( - content::DevToolsAgentHost* agent_host, - bool replaced_with_another_client) { + content::DevToolsAgentHost* agent_host) { DCHECK_EQ(agent_host_, agent_host); agent_host = nullptr; pending_messages_.clear();
diff --git a/headless/lib/browser/headless_permission_manager.cc b/headless/lib/browser/headless_permission_manager.cc index a75ee4c..f135b28 100644 --- a/headless/lib/browser/headless_permission_manager.cc +++ b/headless/lib/browser/headless_permission_manager.cc
@@ -5,11 +5,14 @@ #include "headless/lib/browser/headless_permission_manager.h" #include "base/callback.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/permission_type.h" namespace headless { -HeadlessPermissionManager::HeadlessPermissionManager() : PermissionManager() {} +HeadlessPermissionManager::HeadlessPermissionManager( + content::BrowserContext* browser_context) + : browser_context_(browser_context) {} HeadlessPermissionManager::~HeadlessPermissionManager() {} @@ -20,7 +23,15 @@ bool user_gesture, const base::Callback<void(blink::mojom::PermissionStatus)>& callback) { // In headless mode we just pretent the user "closes" any permission prompt, - // without accepting or denying. + // without accepting or denying. Push Notifications are the exception to this, + // which are explicitly disabled in Incognito mode. + if (browser_context_->IsOffTheRecord() && + (permission == content::PermissionType::PUSH_MESSAGING || + permission == content::PermissionType::NOTIFICATIONS)) { + callback.Run(blink::mojom::PermissionStatus::DENIED); + return kNoPendingOperation; + } + callback.Run(blink::mojom::PermissionStatus::ASK); return kNoPendingOperation; }
diff --git a/headless/lib/browser/headless_permission_manager.h b/headless/lib/browser/headless_permission_manager.h index 5eb31859c..f9a12522 100644 --- a/headless/lib/browser/headless_permission_manager.h +++ b/headless/lib/browser/headless_permission_manager.h
@@ -9,11 +9,15 @@ #include "base/macros.h" #include "content/public/browser/permission_manager.h" +namespace content { +class BrowserContext; +} + namespace headless { class HeadlessPermissionManager : public content::PermissionManager { public: - HeadlessPermissionManager(); + explicit HeadlessPermissionManager(content::BrowserContext* browser_context); ~HeadlessPermissionManager() override; // PermissionManager implementation. @@ -49,6 +53,8 @@ void UnsubscribePermissionStatusChange(int subscription_id) override; private: + content::BrowserContext* browser_context_; + DISALLOW_COPY_AND_ASSIGN(HeadlessPermissionManager); };
diff --git a/headless/lib/dom_tree_extraction_expected_nodes.txt b/headless/lib/dom_tree_extraction_expected_nodes.txt index 5799ee0..588c8b0 100644 --- a/headless/lib/dom_tree_extraction_expected_nodes.txt +++ b/headless/lib/dom_tree_extraction_expected_nodes.txt
@@ -237,8 +237,8 @@ "boundingBox": { "height": 200.0, "width": 400.0, - "x": 10.0, - "y": 63.0 + "x": 0.0, + "y": 0.0 }, "childNodeIndexes": [ 20, 21 ], "frameId": "?", @@ -259,8 +259,8 @@ "boundingBox": { "height": 171.0, "width": 384.0, - "x": 18.0, - "y": 71.0 + "x": 8.0, + "y": 8.0 }, "childNodeIndexes": [ 22, 23, 25 ], "layoutNodeIndex": 9, @@ -280,8 +280,8 @@ "boundingBox": { "height": 37.0, "width": 384.0, - "x": 18.0, - "y": 71.0 + "x": 8.0, + "y": 8.0 }, "childNodeIndexes": [ 24 ], "layoutNodeIndex": 10, @@ -520,10 +520,10 @@ { "backendNodeId": 42, "boundingBox": { - "height": 0.0, + "height": 17.0, "width": 0.0, - "x": 0.0, - "y": 0.0 + "x": 8.0, + "y": 329.0 }, "inlineTextNodes": [ { "boundingBox": {
diff --git a/headless/public/internal/headless_devtools_client_impl.h b/headless/public/internal/headless_devtools_client_impl.h index 9272de3..d9b89ea 100644 --- a/headless/public/internal/headless_devtools_client_impl.h +++ b/headless/public/internal/headless_devtools_client_impl.h
@@ -107,11 +107,10 @@ void SendRawDevToolsMessage(const std::string& json_message) override; void SendRawDevToolsMessage(const base::DictionaryValue& message) override; - // content::DevToolstAgentHostClient implementation: + // content::DevToolsAgentHostClient implementation: void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, const std::string& json_message) override; - void AgentHostClosed(content::DevToolsAgentHost* agent_host, - bool replaced_with_another_client) override; + void AgentHostClosed(content::DevToolsAgentHost* agent_host) override; // internal::MessageDispatcher implementation: void SendMessage(const char* method,
diff --git a/headless/public/util/generic_url_request_job.cc b/headless/public/util/generic_url_request_job.cc index c8c5c5c..39ddc99 100644 --- a/headless/public/util/generic_url_request_job.cc +++ b/headless/public/util/generic_url_request_job.cc
@@ -299,6 +299,12 @@ return true; } +bool GenericURLRequestJob::IsBrowserSideFetch() const { + if (!request_resource_info_) + return false; + return request_resource_info_->GetFrameTreeNodeId() != -1; +} + namespace { void CompletionCallback(int* dest, base::Closure* quit_closure, int value) { *dest = value;
diff --git a/headless/public/util/generic_url_request_job.h b/headless/public/util/generic_url_request_job.h index 192e754..c9b6dc83 100644 --- a/headless/public/util/generic_url_request_job.h +++ b/headless/public/util/generic_url_request_job.h
@@ -56,6 +56,9 @@ // Returns the size of the POST data, if any, from the net::URLRequest. virtual uint64_t GetPostDataSize() const = 0; + // Returns true if the fetch was issues by the browser. + virtual bool IsBrowserSideFetch() const = 0; + enum class ResourceType { MAIN_FRAME = 0, SUB_FRAME = 1, @@ -159,6 +162,7 @@ uint64_t GetPostDataSize() const override; ResourceType GetResourceType() const override; bool IsAsync() const override; + bool IsBrowserSideFetch() const override; private: void PrepareCookies(const GURL& rewritten_url,
diff --git a/ios/chrome/browser/reading_list/reading_list_model_factory.cc b/ios/chrome/browser/reading_list/reading_list_model_factory.cc index 1bfd81a..f35b6f5 100644 --- a/ios/chrome/browser/reading_list/reading_list_model_factory.cc +++ b/ios/chrome/browser/reading_list/reading_list_model_factory.cc
@@ -63,7 +63,7 @@ const syncer::ModelTypeStoreFactory& store_factory = browser_sync::ProfileSyncService::GetModelTypeStoreFactory( - syncer::READING_LIST, chrome_browser_state->GetStatePath()); + chrome_browser_state->GetStatePath()); std::unique_ptr<ReadingListStore> store = base::MakeUnique<ReadingListStore>( store_factory, base::Bind(&syncer::ModelTypeChangeProcessor::Create,
diff --git a/ios/chrome/browser/sync/ios_user_event_service_factory.cc b/ios/chrome/browser/sync/ios_user_event_service_factory.cc index 4565582..ddebd40 100644 --- a/ios/chrome/browser/sync/ios_user_event_service_factory.cc +++ b/ios/chrome/browser/sync/ios_user_event_service_factory.cc
@@ -53,7 +53,7 @@ syncer::ModelTypeStoreFactory store_factory = browser_sync::ProfileSyncService::GetModelTypeStoreFactory( - syncer::USER_EVENTS, browser_state->GetStatePath()); + browser_state->GetStatePath()); syncer::ModelTypeSyncBridge::ChangeProcessorFactory processor_factory = base::BindRepeating(&syncer::ModelTypeChangeProcessor::Create, base::BindRepeating(&syncer::ReportUnrecoverableError,
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn index aea3e2a..2e60a95 100644 --- a/ios/chrome/browser/ui/bookmarks/BUILD.gn +++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -130,6 +130,7 @@ "//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/ntp", + "//ios/chrome/browser/ui/util", "//ios/chrome/browser/undo", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/ui",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm index edb9dfa..be5aba1 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
@@ -29,6 +29,7 @@ #import "ios/chrome/browser/ui/commands/application_commands.h" #include "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/browser/ui/url_loader.h" +#import "ios/chrome/browser/ui/util/form_sheet_navigation_controller.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" #include "ios/web/public/referrer.h" @@ -185,8 +186,9 @@ if (bookmark_utils_ios::GetBookmarkUIPositionCache(self.bookmarkModel)) { self.bookmarkBrowser.isReconstructingFromCache = YES; } - UINavigationController* navController = [[UINavigationController alloc] - initWithRootViewController:self.bookmarkBrowser]; + FormSheetNavigationController* navController = + [[FormSheetNavigationController alloc] + initWithRootViewController:self.bookmarkBrowser]; [navController setModalPresentationStyle:UIModalPresentationFormSheet]; [_parentController presentViewController:navController animated:YES
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn index 955eb1d..353fdc9 100644 --- a/ios/chrome/browser/ui/payments/BUILD.gn +++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -216,6 +216,7 @@ "//ios/web/public/test", "//testing/gmock", "//testing/gtest", + "//third_party/libaddressinput:strings_grit", "//third_party/ocmock", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator_unittest.mm b/ios/chrome/browser/ui/payments/address_edit_mediator_unittest.mm index 9ddf965..490bc9b 100644 --- a/ios/chrome/browser/ui/payments/address_edit_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/address_edit_mediator_unittest.mm
@@ -4,13 +4,20 @@ #import "ios/chrome/browser/ui/payments/address_edit_mediator.h" +#include "base/mac/foundation_util.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/autofill/core/browser/country_names.h" +#include "components/autofill/core/browser/test_region_data_loader.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/payments/payment_request_unittest_base.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" +#import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h" #import "ios/chrome/browser/ui/payments/payment_request_editor_field.h" +#include "ios/chrome/grit/ios_strings.h" #include "testing/platform_test.h" +#include "third_party/libaddressinput/messages.h" +#include "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/gtest_support.h" #include "ui/base/l10n/l10n_util.h" @@ -24,12 +31,199 @@ void SetUp() override { PaymentRequestUnitTestBase::SetUp(); + autofill::CountryNames::SetLocaleString("en-US"); + CreateTestPaymentRequest(); + + test_region_data_loader_.set_synchronous_callback(true); + payment_request()->SetRegionDataLoader(&test_region_data_loader_); } void TearDown() override { PaymentRequestUnitTestBase::TearDown(); } + + autofill::TestRegionDataLoader test_region_data_loader_; }; +// Tests that the expected editor fields are created when creating an address. +TEST_F(PaymentRequestAddressEditMediatorTest, TestFieldsWhenCreate) { + id check_block = ^BOOL(id value) { + EXPECT_TRUE([value isKindOfClass:[NSArray class]]); + NSArray* fields = base::mac::ObjCCastStrict<NSArray>(value); + EXPECT_EQ(8U, fields.count); + + id field = fields[0]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + EditorField* editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileFullName, editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_RECIPIENT_LABEL)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_FALSE(editor_field.isRequired); + + field = fields[1]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileHomeAddressCountry, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeSelector, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL)]); + EXPECT_TRUE([editor_field.value isEqualToString:@"US"]); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[2]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileCompanyName, editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_ORGANIZATION_LABEL)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_FALSE(editor_field.isRequired); + + field = fields[3]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileHomeAddressStreet, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_ADDRESS_LINE_1_LABEL)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[4]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileHomeAddressCity, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_LOCALITY_LABEL)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[5]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileHomeAddressState, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString(IDS_LIBADDRESSINPUT_STATE)]); + EXPECT_TRUE([editor_field.value + isEqualToString:l10n_util::GetNSString(IDS_AUTOFILL_LOADING_REGIONS)]); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[6]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileHomeAddressZip, editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[7]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeProfileHomePhoneWholeNumber, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString(IDS_IOS_AUTOFILL_PHONE)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + return YES; + }; + + // Mock the consumer. + id consumer = + [OCMockObject mockForProtocol:@protocol(PaymentRequestEditConsumer)]; + [[consumer expect] setEditorFields:[OCMArg checkWithBlock:check_block]]; + + AddressEditMediator* mediator = + [[AddressEditMediator alloc] initWithPaymentRequest:payment_request() + address:nil]; + [mediator setConsumer:consumer]; + + EXPECT_OCMOCK_VERIFY(consumer); +} + +// Tests that the expected editor fields are created when editing an address. +TEST_F(PaymentRequestAddressEditMediatorTest, TestFieldsWhenEdit) { + id check_block = ^BOOL(id value) { + EXPECT_TRUE([value isKindOfClass:[NSArray class]]); + NSArray* fields = base::mac::ObjCCastStrict<NSArray>(value); + EXPECT_EQ(8U, fields.count); + + id field = fields[0]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + EditorField* editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"John H. Doe"]); + + field = fields[1]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"US"]); + + field = fields[2]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"Underworld"]); + + field = fields[3]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"666 Erebus St.\nApt 8"]); + + field = fields[4]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"Elysium"]); + + field = fields[5]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value + isEqualToString:l10n_util::GetNSString(IDS_AUTOFILL_LOADING_REGIONS)]); + + field = fields[6]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"91111"]); + + field = fields[7]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"+1 650-211-1111"]); + + return YES; + }; + + // Mock the consumer. + id consumer = + [OCMockObject mockForProtocol:@protocol(PaymentRequestEditConsumer)]; + [[consumer expect] setEditorFields:[OCMArg checkWithBlock:check_block]]; + + autofill::AutofillProfile autofill_profile = autofill::test::GetFullProfile(); + AddressEditMediator* mediator = + [[AddressEditMediator alloc] initWithPaymentRequest:payment_request() + address:&autofill_profile]; + [mediator setConsumer:consumer]; + + EXPECT_OCMOCK_VERIFY(consumer); +} + // Tests that no validation error should be expected if validating an empty // field that is not required. TEST_F(PaymentRequestAddressEditMediatorTest, ValidateEmptyField) {
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm b/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm index d02c51b..372d8c6 100644 --- a/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm
@@ -52,6 +52,7 @@ isEqualToString:l10n_util::GetNSString( IDS_PAYMENTS_NAME_FIELD_IN_CONTACT_DETAILS)]); EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); field = fields[1]; EXPECT_TRUE([field isKindOfClass:[EditorField class]]); @@ -63,6 +64,7 @@ isEqualToString:l10n_util::GetNSString( IDS_PAYMENTS_PHONE_FIELD_IN_CONTACT_DETAILS)]); EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); field = fields[2]; EXPECT_TRUE([field isKindOfClass:[EditorField class]]); @@ -73,6 +75,7 @@ isEqualToString:l10n_util::GetNSString( IDS_PAYMENTS_EMAIL_FIELD_IN_CONTACT_DETAILS)]); EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); return YES; };
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm index 0563b75a..a3faf53 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm
@@ -40,7 +40,7 @@ @property(nonatomic, strong) PaymentRequestEditViewController* editViewController; -@property(nonatomic, strong) CreditCardEditViewControllerMediator* mediator; +@property(nonatomic, strong) CreditCardEditMediator* mediator; @end @@ -62,9 +62,9 @@ _editViewController = [[PaymentRequestEditViewController alloc] init]; [_editViewController setDelegate:self]; - _mediator = [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:_paymentRequest - creditCard:_creditCard]; + _mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:_paymentRequest + creditCard:_creditCard]; [_mediator setConsumer:_editViewController]; [_editViewController setDataSource:_mediator]; [_editViewController setValidatorDelegate:_mediator];
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.h b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.h index 7b4ddcd..6de99d1 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.h +++ b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.h
@@ -20,7 +20,7 @@ } // namespace payments // Serves as data source for CreditCardEditViewController. -@interface CreditCardEditViewControllerMediator +@interface CreditCardEditMediator : NSObject<PaymentRequestEditViewControllerDataSource, PaymentRequestEditViewControllerValidator>
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm index 88206f8c..106ad9b 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm
@@ -72,7 +72,7 @@ } // namespace -@interface CreditCardEditViewControllerMediator () +@interface CreditCardEditMediator () // The PaymentRequest object owning an instance of payments::WebPaymentRequest // as provided by the page invoking the Payment Request API. This is a weak @@ -96,7 +96,7 @@ @end -@implementation CreditCardEditViewControllerMediator +@implementation CreditCardEditMediator @synthesize state = _state; @synthesize consumer = _consumer; @@ -293,7 +293,7 @@ } // Notify the view controller asynchronously to allow for the view to update. - __weak CreditCardEditViewControllerMediator* weakSelf = self; + __weak CreditCardEditMediator* weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.consumer setOptions:@[ months, years ] forEditorField:weakSelf.creditCardExpDateField];
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_mediator_unittest.mm b/ios/chrome/browser/ui/payments/credit_card_edit_mediator_unittest.mm index f6d3ad7..7c03ace 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_mediator_unittest.mm
@@ -4,13 +4,17 @@ #import "ios/chrome/browser/ui/payments/credit_card_edit_mediator.h" +#import "base/mac/foundation_util.h" +#include "base/strings/sys_string_conversions.h" #include "base/time/time.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_autofill_clock.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/payments/payment_request_unittest_base.h" +#import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h" #import "ios/chrome/browser/ui/payments/payment_request_editor_field.h" #include "testing/platform_test.h" +#include "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/gtest_support.h" #include "ui/base/l10n/l10n_util.h" @@ -38,13 +42,178 @@ void TearDown() override { PaymentRequestUnitTestBase::TearDown(); } }; +// Tests that the expected editor fields are created when creating a card. +TEST_F(PaymentRequestCreditCardEditMediatorTest, TestFieldsWhenCreate) { + id check_block = ^BOOL(id value) { + EXPECT_TRUE([value isKindOfClass:[NSArray class]]); + NSArray* fields = base::mac::ObjCCastStrict<NSArray>(value); + EXPECT_EQ(5U, fields.count); + + id field = fields[0]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + EditorField* editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeCreditCardNumber, editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_CARD_NUMBER)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[1]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeCreditCardHolderFullName, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_NAME_ON_CARD)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[2]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeCreditCardExpDate, editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeTextField, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_EXP_DATE)]); + NSDateComponents* dateComponents = [[NSCalendar currentCalendar] + components:NSCalendarUnitMonth | NSCalendarUnitYear + fromDate:[NSDate date]]; + int currentMonth = [dateComponents month]; + int currentYear = [dateComponents year]; + NSString* currentDate = + [NSString stringWithFormat:@"%02d / %04d", currentMonth, currentYear]; + EXPECT_TRUE([editor_field.value isEqualToString:currentDate]); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[3]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeCreditCardBillingAddress, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeSelector, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_BILLING_ADDRESS)]); + EXPECT_EQ(nil, editor_field.value); + EXPECT_TRUE(editor_field.isRequired); + + field = fields[4]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_EQ(AutofillUITypeCreditCardSaveToChrome, + editor_field.autofillUIType); + EXPECT_EQ(EditorFieldTypeSwitch, editor_field.fieldType); + EXPECT_TRUE([editor_field.label + isEqualToString:l10n_util::GetNSString( + IDS_PAYMENTS_SAVE_CARD_TO_DEVICE_CHECKBOX)]); + EXPECT_TRUE([editor_field.value isEqualToString:@"YES"]); + EXPECT_TRUE(editor_field.isRequired); + + return YES; + }; + + // Mock the consumer. + id consumer = + [OCMockObject mockForProtocol:@protocol(PaymentRequestEditConsumer)]; + [[consumer expect] setEditorFields:[OCMArg checkWithBlock:check_block]]; + + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:nil]; + [mediator setConsumer:consumer]; + + EXPECT_OCMOCK_VERIFY(consumer); +} + +// Tests that the expected editor fields are created when editing a card. +TEST_F(PaymentRequestCreditCardEditMediatorTest, TestFieldsWhenEdit) { + id check_block = ^BOOL(id value) { + EXPECT_TRUE([value isKindOfClass:[NSArray class]]); + NSArray* fields = base::mac::ObjCCastStrict<NSArray>(value); + EXPECT_EQ(5U, fields.count); + + id field = fields[0]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + EditorField* editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"4111 1111 1111 1111"]); + + field = fields[1]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"Test User"]); + + field = fields[2]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"11 / 2022"]); + + field = fields[3]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value + isEqualToString:base::SysUTF8ToNSString(profiles()[0]->guid())]); + + field = fields[4]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value isEqualToString:@"YES"]); + + return YES; + }; + + // Mock the consumer. + id consumer = + [OCMockObject mockForProtocol:@protocol(PaymentRequestEditConsumer)]; + [[consumer expect] setEditorFields:[OCMArg checkWithBlock:check_block]]; + + autofill::CreditCard card = autofill::test::GetCreditCard(); + card.set_billing_address_id(profiles()[0]->guid()); + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:&card]; + [mediator setConsumer:consumer]; + + EXPECT_OCMOCK_VERIFY(consumer); +} + +// Tests that the expected editor fields are created when editing a server card. +TEST_F(PaymentRequestCreditCardEditMediatorTest, TestFieldsWhenEditServerCard) { + id check_block = ^BOOL(id value) { + EXPECT_TRUE([value isKindOfClass:[NSArray class]]); + NSArray* fields = base::mac::ObjCCastStrict<NSArray>(value); + EXPECT_EQ(1U, fields.count); + + id field = fields[0]; + EXPECT_TRUE([field isKindOfClass:[EditorField class]]); + EditorField* editor_field = base::mac::ObjCCastStrict<EditorField>(field); + EXPECT_TRUE([editor_field.value + isEqualToString:base::SysUTF8ToNSString(profiles()[0]->guid())]); + + return YES; + }; + + // Mock the consumer. + id consumer = + [OCMockObject mockForProtocol:@protocol(PaymentRequestEditConsumer)]; + [[consumer expect] setEditorFields:[OCMArg checkWithBlock:check_block]]; + + autofill::CreditCard card = autofill::test::GetMaskedServerCard(); + card.set_billing_address_id(profiles()[0]->guid()); + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:&card]; + [mediator setConsumer:consumer]; + + EXPECT_OCMOCK_VERIFY(consumer); +} + // Tests that no validation error should be expected if validating an empty // field that is not required. TEST_F(PaymentRequestCreditCardEditMediatorTest, ValidateEmptyField) { - CreditCardEditViewControllerMediator* mediator = - [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:nil]; + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:nil]; EditorField* field = [[EditorField alloc] initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber @@ -61,10 +230,9 @@ // Tests that the appropriate validation error should be expected if validating // an empty field that is required. TEST_F(PaymentRequestCreditCardEditMediatorTest, ValidateEmptyRequiredField) { - CreditCardEditViewControllerMediator* mediator = - [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:nil]; + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:nil]; EditorField* field = [[EditorField alloc] initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber @@ -83,10 +251,9 @@ // Tests that the appropriate validation error should be expected if validating // a field with an invalid value. TEST_F(PaymentRequestCreditCardEditMediatorTest, ValidateFieldInvalidValue) { - CreditCardEditViewControllerMediator* mediator = - [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:nil]; + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:nil]; EditorField* field = [[EditorField alloc] initWithAutofillUIType:AutofillUITypeCreditCardNumber @@ -123,10 +290,9 @@ // Tests that the editor's title is correct in various situations. TEST_F(PaymentRequestCreditCardEditMediatorTest, Title) { // No card, so the title should ask to add a card. - CreditCardEditViewControllerMediator* mediator = - [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:nil]; + CreditCardEditMediator* mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:nil]; EXPECT_TRUE([mediator.title isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_ADD_CARD_LABEL)]); @@ -136,9 +302,9 @@ autofill::CreditCard credit_card = autofill::test::GetCreditCard(); autofill::test::SetCreditCardInfo(&credit_card, nullptr, nullptr, nullptr, nullptr, billing_address.guid()); - mediator = [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:&credit_card]; + mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:&credit_card]; EXPECT_TRUE([mediator.title isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CARD)]); @@ -146,9 +312,9 @@ autofill::test::SetCreditCardInfo(&credit_card, /* name_on_card= */ "", nullptr, nullptr, nullptr, billing_address.guid()); - mediator = [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:&credit_card]; + mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:&credit_card]; EXPECT_TRUE([mediator.title isEqualToString:l10n_util::GetNSString(IDS_PAYMENTS_ADD_NAME_ON_CARD)]); @@ -156,9 +322,9 @@ autofill::test::SetCreditCardInfo(&credit_card, /* name_on_card= */ "", nullptr, nullptr, nullptr, /* billing_address_id= */ ""); - mediator = [[CreditCardEditViewControllerMediator alloc] - initWithPaymentRequest:payment_request() - creditCard:&credit_card]; + mediator = + [[CreditCardEditMediator alloc] initWithPaymentRequest:payment_request() + creditCard:&credit_card]; EXPECT_TRUE( [mediator.title isEqualToString:l10n_util::GetNSString( IDS_PAYMENTS_ADD_MORE_INFORMATION)]);
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index a22ff61..206c8db 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -15,7 +15,6 @@ "toolbar_controller.mm", "toolbar_coordinator.h", "toolbar_coordinator.mm", - "toolbar_frame_delegate.h", "toolbar_model_delegate_ios.h", "toolbar_model_delegate_ios.mm", "toolbar_model_impl_ios.h", @@ -27,6 +26,7 @@ "toolbar_tools_menu_button.mm", "toolbar_view.h", "toolbar_view.mm", + "toolbar_view_delegate.h", "tools_menu_button_observer_bridge.h", "tools_menu_button_observer_bridge.mm", "web_toolbar_controller.h",
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_frame_delegate.h b/ios/chrome/browser/ui/toolbar/toolbar_frame_delegate.h deleted file mode 100644 index 4def7ba..0000000 --- a/ios/chrome/browser/ui/toolbar/toolbar_frame_delegate.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_FRAME_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_FRAME_DELEGATE_H_ - -#import <Foundation/Foundation.h> - -// Create a thin wrapper around UIImageView to catch frame change and window -// events. -@protocol ToolbarFrameDelegate<NSObject> -- (void)frameDidChangeFrame:(CGRect)newFrame fromFrame:(CGRect)oldFrame; -- (void)windowDidChange; -- (void)traitCollectionDidChange; -@end - -#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_FRAME_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_view.h b/ios/chrome/browser/ui/toolbar/toolbar_view.h index 8712d73..d37320b 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_view.h +++ b/ios/chrome/browser/ui/toolbar/toolbar_view.h
@@ -9,7 +9,7 @@ #import "ios/chrome/browser/ui/util/relaxed_bounds_constraints_hittest.h" -@protocol ToolbarFrameDelegate; +@protocol ToolbarViewDelegate; @interface ToolbarView : UIView<RelaxedBoundsConstraintsHitTestSupport> - (instancetype)initWithNibName:(NSString*)name @@ -17,7 +17,7 @@ - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE; // The delegate used to handle frame changes and windows events. -@property(nonatomic, weak) id<ToolbarFrameDelegate> delegate; +@property(nonatomic, weak) id<ToolbarViewDelegate> delegate; // Records whether or not the toolbar is currently involved in a transition // animation. @property(nonatomic, assign, getter=isAnimatingTransition)
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_view.mm b/ios/chrome/browser/ui/toolbar/toolbar_view.mm index a83a149f..8dce291 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_view.mm
@@ -5,7 +5,7 @@ #import "ios/chrome/browser/ui/toolbar/toolbar_view.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h" -#import "ios/chrome/browser/ui/toolbar/toolbar_frame_delegate.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h" @implementation ToolbarView @@ -57,10 +57,9 @@ return hitView; } -- (void)setFrame:(CGRect)frame { - CGRect oldFrame = self.frame; - [super setFrame:frame]; - [delegate_ frameDidChangeFrame:frame fromFrame:oldFrame]; +- (void)layoutSubviews { + [super layoutSubviews]; + [delegate_ toolbarDidLayout]; } - (void)didMoveToWindow {
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h b/ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h new file mode 100644 index 0000000..e7e85d2 --- /dev/null +++ b/ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_VIEW_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_VIEW_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +// A delegate protocol to pass UIView information about the toolbar. +// TODO(crbug.com/683793): Remove this protocol when toolbars are presented via +// UIViewControllers, as this can already be accomplished through that API. +@protocol ToolbarViewDelegate<NSObject> + +// Called when the toolbar view performs a layout pass. +- (void)toolbarDidLayout; + +// Called when the toolbar view is transferred to a new parent window. +- (void)windowDidChange; + +// Called when the toolbar view's trait collection changes. +- (void)traitCollectionDidChange; + +@end + +#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_VIEW_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h index bc518aa..ecaacf6 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
@@ -19,7 +19,6 @@ @protocol ApplicationCommands; @protocol BrowserCommands; @class Tab; -@protocol ToolbarFrameDelegate; @protocol UrlLoader; @protocol WebToolbarDelegate;
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm index 5c6efbbd..364fac9 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -59,9 +59,9 @@ #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h" #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h" #import "ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h" -#import "ios/chrome/browser/ui/toolbar/toolbar_frame_delegate.h" #import "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h" #include "ios/chrome/browser/ui/toolbar/toolbar_resource_macros.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h" #import "ios/chrome/browser/ui/toolbar/web_toolbar_delegate.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" @@ -102,7 +102,7 @@ LocationBarDelegate, OmniboxPopupPositioner, ToolbarAssistiveKeyboardDelegate, - ToolbarFrameDelegate> { + ToolbarViewDelegate> { // Top-level view for web content. UIView* _webToolbar; UIButton* _backButton; @@ -140,6 +140,9 @@ // reversed. ToolbarButtonMode _forwardButtonMode; + // Keeps track of the last known toolbar frame. + CGRect _lastKnownToolbarFrame; + // Keeps track of last known trait collection used by the subviews. UITraitCollection* _lastKnownTraitCollection; @@ -1201,12 +1204,14 @@ } #pragma mark - -#pragma mark ToolbarFrameDelegate methods. +#pragma mark ToolbarViewDelegate methods. -- (void)frameDidChangeFrame:(CGRect)newFrame fromFrame:(CGRect)oldFrame { - if (oldFrame.origin.y == newFrame.origin.y) +- (void)toolbarDidLayout { + CGRect frame = self.view.frame; + if (CGRectEqualToRect(_lastKnownToolbarFrame, frame)) return; - [self updateToolbarAlphaForFrame:newFrame]; + [self updateToolbarAlphaForFrame:frame]; + _lastKnownToolbarFrame = frame; } - (void)windowDidChange {
diff --git a/ios/chrome/browser/ui/util/BUILD.gn b/ios/chrome/browser/ui/util/BUILD.gn index b60dc1e..8b46d82d 100644 --- a/ios/chrome/browser/ui/util/BUILD.gn +++ b/ios/chrome/browser/ui/util/BUILD.gn
@@ -9,6 +9,8 @@ "CRUILabel+AttributeUtils.mm", "core_text_util.h", "core_text_util.mm", + "form_sheet_navigation_controller.h", + "form_sheet_navigation_controller.mm", "i18n_string.h", "i18n_string.mm", "label_link_controller.h",
diff --git a/ios/chrome/browser/ui/util/form_sheet_navigation_controller.h b/ios/chrome/browser/ui/util/form_sheet_navigation_controller.h new file mode 100644 index 0000000..c1315c2 --- /dev/null +++ b/ios/chrome/browser/ui/util/form_sheet_navigation_controller.h
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_UTIL_FORM_SHEET_NAVIGATION_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_UTIL_FORM_SHEET_NAVIGATION_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +// A navigation controller subclass that respects the +// disablesAutomaticKeyboardDismissal of its top view controller. This is useful +// when presenting some view controllers in a navigation controller with +// UIModalPresentationFormSheet. +@interface FormSheetNavigationController : UINavigationController +@end + +#endif // IOS_CHROME_BROWSER_UI_UTIL_FORM_SHEET_NAVIGATION_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/util/form_sheet_navigation_controller.mm b/ios/chrome/browser/ui/util/form_sheet_navigation_controller.mm new file mode 100644 index 0000000..ceb16e7 --- /dev/null +++ b/ios/chrome/browser/ui/util/form_sheet_navigation_controller.mm
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/util/form_sheet_navigation_controller.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation FormSheetNavigationController + +- (BOOL)disablesAutomaticKeyboardDismissal { + return self.topViewController.disablesAutomaticKeyboardDismissal; +} + +@end
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h index bf69cfb..a69879d5 100644 --- a/ios/web/public/test/fakes/test_web_state.h +++ b/ios/web/public/test/fakes/test_web_state.h
@@ -87,6 +87,7 @@ // Setters for test data. void SetBrowserState(BrowserState* browser_state); + void SetJSInjectionReceiver(CRWJSInjectionReceiver* injection_receiver); void SetContentIsHTML(bool content_is_html); void SetLoading(bool is_loading); void SetCurrentURL(const GURL& url); @@ -109,6 +110,7 @@ private: BrowserState* browser_state_; + CRWJSInjectionReceiver* injection_receiver_; bool web_usage_enabled_; bool is_loading_; bool is_visible_;
diff --git a/ios/web/public/test/fakes/test_web_state.mm b/ios/web/public/test/fakes/test_web_state.mm index 56266da..47d4b4e 100644 --- a/ios/web/public/test/fakes/test_web_state.mm +++ b/ios/web/public/test/fakes/test_web_state.mm
@@ -128,7 +128,7 @@ } CRWJSInjectionReceiver* TestWebState::GetJSInjectionReceiver() const { - return nullptr; + return injection_receiver_; } void TestWebState::ExecuteJavaScript(const base::string16& javascript) {} @@ -173,6 +173,11 @@ browser_state_ = browser_state; } +void TestWebState::SetJSInjectionReceiver( + CRWJSInjectionReceiver* injection_receiver) { + injection_receiver_ = injection_receiver; +} + void TestWebState::SetContentIsHTML(bool content_is_html) { content_is_html_ = content_is_html; }
diff --git a/ios/web/public/test/web_view_interaction_test_util.mm b/ios/web/public/test/web_view_interaction_test_util.mm index 31fe8d2..44f75d1 100644 --- a/ios/web/public/test/web_view_interaction_test_util.mm +++ b/ios/web/public/test/web_view_interaction_test_util.mm
@@ -19,6 +19,9 @@ #endif using web::NavigationManager; +using testing::WaitUntilConditionOrTimeout; +using testing::kWaitForUIElementTimeout; +using testing::kWaitForJSCompletionTimeout; namespace web { namespace test { @@ -40,10 +43,9 @@ did_finish = true; })); - bool completed = testing::WaitUntilConditionOrTimeout( - testing::kWaitForJSCompletionTimeout, ^{ - return did_finish; - }); + bool completed = WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return did_finish; + }); if (!completed) { return nullptr; } @@ -86,22 +88,21 @@ __block base::DictionaryValue const* rect = nullptr; - bool found = - testing::WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ - std::unique_ptr<base::Value> value = - ExecuteJavaScript(web_state, kGetBoundsScript); - base::DictionaryValue* dictionary = nullptr; - if (value && value->GetAsDictionary(&dictionary)) { - std::string error; - if (dictionary->GetString("error", &error)) { - DLOG(ERROR) << "Error getting rect: " << error << ", retrying.."; - } else { - rect = dictionary->DeepCopy(); - return true; - } - } - return false; - }); + bool found = WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ + std::unique_ptr<base::Value> value = + ExecuteJavaScript(web_state, kGetBoundsScript); + base::DictionaryValue* dictionary = nullptr; + if (value && value->GetAsDictionary(&dictionary)) { + std::string error; + if (dictionary->GetString("error", &error)) { + DLOG(ERROR) << "Error getting rect: " << error << ", retrying.."; + } else { + rect = dictionary->DeepCopy(); + return true; + } + } + return false; + }); if (!found) return CGRectNull; @@ -159,11 +160,11 @@ element_found = [result boolValue]; }]; - testing::WaitUntilConditionOrTimeout(testing::kWaitForJSCompletionTimeout, ^{ + bool js_finished = WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return did_complete; }); - return element_found; + return js_finished && element_found; } bool TapWebViewElementWithId(web::WebState* web_state,
diff --git a/ios/web/web_state/js/resources/common.js b/ios/web/web_state/js/resources/common.js index f003ecb3..3b4f7275 100644 --- a/ios/web/web_state/js/resources/common.js +++ b/ios/web/web_state/js/resources/common.js
@@ -426,7 +426,10 @@ }; /** - * Returns the name that should be used for the specified |element| when + * Returns the form's |name| attribute if not space only; otherwise the + * form's |id| attribute. + * + * It is the name that should be used for the specified |element| when * storing Autofill data. Various attributes are used to attempt to identify * the element, beginning with 'name' and 'id' attributes. Providing a * uniquely reversible identifier for any element is a non-trivial problem; @@ -441,7 +444,7 @@ * returned. * @return {string} the name for Autofill. */ - __gCrWeb.common.nameForAutofill = function(element) { + __gCrWeb.common.getFieldIdentifier = function(element) { if (!element) { return ''; } @@ -452,7 +455,7 @@ return trimmedName; } } - trimmedName = element.getAttribute('id'); + trimmedName = element.id; if (trimmedName) { return __gCrWeb.common.trim(trimmedName); }
diff --git a/ios/web/web_state/js/resources/form.js b/ios/web/web_state/js/resources/form.js index c18d3da..2f28de2 100644 --- a/ios/web/web_state/js/resources/form.js +++ b/ios/web/web_state/js/resources/form.js
@@ -25,13 +25,12 @@ */ var formActivity_ = function(evt) { var srcElement = evt.srcElement; - var fieldName = srcElement.name || ''; var value = srcElement.value || ''; var msg = { 'command': 'form.activity', 'formName': __gCrWeb.common.getFormIdentifier(evt.srcElement.form), - 'fieldName': fieldName, + 'fieldName': __gCrWeb.common.getFieldIdentifier(srcElement), 'type': evt.type, 'value': value };
diff --git a/ios/web/web_state/session_certificate_policy_cache_impl_unittest.mm b/ios/web/web_state/session_certificate_policy_cache_impl_unittest.mm index 8ad205f..458248cb 100644 --- a/ios/web/web_state/session_certificate_policy_cache_impl_unittest.mm +++ b/ios/web/web_state/session_certificate_policy_cache_impl_unittest.mm
@@ -21,6 +21,9 @@ #error "This file requires ARC support." #endif +using testing::WaitUntilConditionOrTimeout; +using testing::kWaitForJSCompletionTimeout; + namespace { // Synchronously checks |cache| for the specified cert and returns the judgment. web::CertPolicy::Judgment GetJudgmenet( @@ -31,17 +34,15 @@ // Post a task to the IO thread and wait for a reply __block web::CertPolicy::Judgment judgement = web::CertPolicy::Judgment::UNKNOWN; - __block bool io_thread_has_run = false; - web::WebThread::PostTaskAndReply( - web::WebThread::IO, FROM_HERE, base::BindBlockArc(^{ - judgement = cache->QueryPolicy(cert.get(), host, status); - }), - base::BindBlockArc(^{ - io_thread_has_run = true; - })); - testing::WaitUntilConditionOrTimeout(testing::kWaitForJSCompletionTimeout, ^{ - return io_thread_has_run; - }); + __block bool completed = false; + web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlockArc(^{ + completed = true; + judgement = + cache->QueryPolicy(cert.get(), host, status); + })); + EXPECT_TRUE(WaitUntilConditionOrTimeout(1.0, ^{ + return completed; + })); return judgement; }
diff --git a/media/base/audio_renderer_mixer_unittest.cc b/media/base/audio_renderer_mixer_unittest.cc index fb34254..a6d54e8 100644 --- a/media/base/audio_renderer_mixer_unittest.cc +++ b/media/base/audio_renderer_mixer_unittest.cc
@@ -97,7 +97,9 @@ return mixer_.get(); }; - MOCK_METHOD1(ReturnMixer, void(AudioRendererMixer*)); + void ReturnMixer(AudioRendererMixer* mixer) { + EXPECT_EQ(mixer_.get(), mixer); + } MOCK_METHOD4( GetOutputDeviceInfo, @@ -515,7 +517,7 @@ } INSTANTIATE_TEST_CASE_P( - AudioRendererMixerTest, + /* no prefix */, AudioRendererMixerTest, testing::Values( // No resampling, 1 input sample rate.
diff --git a/media/blink/webmediaplayer_delegate.h b/media/blink/webmediaplayer_delegate.h index 1dd0b7a..b5a502e 100644 --- a/media/blink/webmediaplayer_delegate.h +++ b/media/blink/webmediaplayer_delegate.h
@@ -52,6 +52,8 @@ // Called when external controls are activated. virtual void OnPlay() = 0; virtual void OnPause() = 0; + virtual void OnSeekForward(double seconds) = 0; + virtual void OnSeekBackward(double seconds) = 0; // Called to control audio ducking. Output volume should be set to // |player_volume| * |multiplier|. The range of |multiplier| is [0, 1],
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 1a4337a7..0782a78 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1864,6 +1864,16 @@ client_->PlaybackStateChanged(); } +void WebMediaPlayerImpl::OnSeekForward(double seconds) { + DCHECK_GE(seconds, 0) << "Attempted to seek by a negative number of seconds"; + client_->RequestSeek(CurrentTime() + seconds); +} + +void WebMediaPlayerImpl::OnSeekBackward(double seconds) { + DCHECK_GE(seconds, 0) << "Attempted to seek by a negative number of seconds"; + client_->RequestSeek(CurrentTime() - seconds); +} + void WebMediaPlayerImpl::OnVolumeMultiplierUpdate(double multiplier) { volume_multiplier_ = multiplier; SetVolume(volume_);
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 11231cc..26630e1 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -219,6 +219,8 @@ void OnIdleTimeout() override; void OnPlay() override; void OnPause() override; + void OnSeekForward(double seconds) override; + void OnSeekBackward(double seconds) override; void OnVolumeMultiplierUpdate(double multiplier) override; void OnBecamePersistentVideo(bool value) override;
diff --git a/media/filters/source_buffer_state.cc b/media/filters/source_buffer_state.cc index 1b4f773d..aa7d625 100644 --- a/media/filters/source_buffer_state.cc +++ b/media/filters/source_buffer_state.cc
@@ -8,7 +8,6 @@ #include "base/callback_helpers.h" #include "base/command_line.h" -#include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "media/base/media_switches.h" #include "media/base/media_track.h" @@ -228,23 +227,6 @@ << __func__ << ": stream parsing failed. Data size=" << length << " append_window_start=" << append_window_start.InSecondsF() << " append_window_end=" << append_window_end.InSecondsF(); - - // Crash with a 1/10 chance to investigate https://crbug.com/778363. - // CHECK on different conditions so we can more easily distinguish between - // different cases. - // TODO(crbug.com/778363): Remove after investigation is done. - int n = base::RandInt(1, 10); - if (state_ == PARSER_INITIALIZED) { - if (encrypted_media_init_data_reported_) - CHECK(n != 1); - else - CHECK(n != 2); - } else { - if (encrypted_media_init_data_reported_) - CHECK(n != 3); - else - CHECK(n != 4); - } } timestamp_offset_during_append_ = NULL;
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index c6cf6304..d5bffd3 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -27,7 +27,7 @@ if (use_vaapi) { action("libva_generate_stubs") { - extra_header = "va_stub_header.fragment" + extra_header = "vaapi/va_stub_header.fragment" script = "../../tools/generate_stubs/generate_stubs.py" sources = [ @@ -132,8 +132,6 @@ "fake_jpeg_decode_accelerator.h", "fake_video_decode_accelerator.cc", "fake_video_decode_accelerator.h", - "format_utils.cc", - "format_utils.h", "gles2_decoder_helper.cc", "gles2_decoder_helper.h", "gpu_video_accelerator_util.cc",
diff --git a/media/gpu/format_utils.cc b/media/gpu/format_utils.cc deleted file mode 100644 index 70745366b..0000000 --- a/media/gpu/format_utils.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/gpu/format_utils.h" -#include "base/logging.h" - -namespace media { - -VideoPixelFormat GfxBufferFormatToVideoPixelFormat(gfx::BufferFormat format) { - switch (format) { - case gfx::BufferFormat::BGRX_8888: - return PIXEL_FORMAT_XRGB; - - case gfx::BufferFormat::BGRA_8888: - return PIXEL_FORMAT_ARGB; - - case gfx::BufferFormat::YVU_420: - return PIXEL_FORMAT_YV12; - - case gfx::BufferFormat::YUV_420_BIPLANAR: - return PIXEL_FORMAT_NV12; - - default: - LOG(FATAL) << "Add more cases as needed"; - return PIXEL_FORMAT_UNKNOWN; - } -} - -gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( - VideoPixelFormat pixel_format) { - switch (pixel_format) { - case PIXEL_FORMAT_ARGB: - return gfx::BufferFormat::BGRA_8888; - - case PIXEL_FORMAT_XRGB: - return gfx::BufferFormat::BGRX_8888; - - case PIXEL_FORMAT_YV12: - return gfx::BufferFormat::YVU_420; - - case PIXEL_FORMAT_NV12: - return gfx::BufferFormat::YUV_420_BIPLANAR; - - default: - LOG(FATAL) << "Add more cases as needed"; - return gfx::BufferFormat::BGRX_8888; - } -} - -} // namespace media
diff --git a/media/gpu/format_utils.h b/media/gpu/format_utils.h deleted file mode 100644 index 69457614..0000000 --- a/media/gpu/format_utils.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_GPU_FORMAT_UTILS_H_ -#define MEDIA_GPU_FORMAT_UTILS_H_ - -#include "media/base/video_types.h" -#include "ui/gfx/buffer_types.h" - -namespace media { - -VideoPixelFormat GfxBufferFormatToVideoPixelFormat(gfx::BufferFormat format); - -gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( - VideoPixelFormat pixel_format); - -} // namespace media - -#endif // MEDIA_GPU_FORMAT_UTILS_H_
diff --git a/media/gpu/va_stub_header.fragment b/media/gpu/vaapi/va_stub_header.fragment similarity index 100% rename from media/gpu/va_stub_header.fragment rename to media/gpu/vaapi/va_stub_header.fragment
diff --git a/media/gpu/vaapi_drm_picture.cc b/media/gpu/vaapi_drm_picture.cc index 8894f37..0a8dc27b 100644 --- a/media/gpu/vaapi_drm_picture.cc +++ b/media/gpu/vaapi_drm_picture.cc
@@ -17,28 +17,7 @@ namespace media { -VaapiDrmPicture::VaapiDrmPicture( - const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - int32_t picture_buffer_id, - const gfx::Size& size, - uint32_t texture_id, - uint32_t client_texture_id) - : VaapiPicture(vaapi_wrapper, - make_context_current_cb, - bind_image_cb, - picture_buffer_id, - size, - texture_id, - client_texture_id) {} - -VaapiDrmPicture::~VaapiDrmPicture() { - if (gl_image_ && make_context_current_cb_.Run()) { - gl_image_->ReleaseTexImage(GL_TEXTURE_EXTERNAL_OES); - DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR)); - } -} +namespace { static unsigned BufferFormatToInternalFormat(gfx::BufferFormat format) { switch (format) { @@ -57,7 +36,36 @@ } } +} // anonymous namespace + +VaapiDrmPicture::VaapiDrmPicture( + const scoped_refptr<VaapiWrapper>& vaapi_wrapper, + const MakeGLContextCurrentCallback& make_context_current_cb, + const BindGLImageCallback& bind_image_cb, + int32_t picture_buffer_id, + const gfx::Size& size, + uint32_t texture_id, + uint32_t client_texture_id) + : VaapiPicture(vaapi_wrapper, + make_context_current_cb, + bind_image_cb, + picture_buffer_id, + size, + texture_id, + client_texture_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +VaapiDrmPicture::~VaapiDrmPicture() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (gl_image_ && make_context_current_cb_.Run()) { + gl_image_->ReleaseTexImage(GL_TEXTURE_EXTERNAL_OES); + DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR)); + } +} + bool VaapiDrmPicture::Initialize() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(pixmap_); va_surface_ = vaapi_wrapper_->CreateVASurfaceForPixmap(pixmap_); @@ -100,6 +108,7 @@ } bool VaapiDrmPicture::Allocate(gfx::BufferFormat format) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); pixmap_ = factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size_, @@ -115,6 +124,7 @@ bool VaapiDrmPicture::ImportGpuMemoryBufferHandle( gfx::BufferFormat format, const gfx::GpuMemoryBufferHandle& gpu_memory_buffer_handle) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); // CreateNativePixmapFromHandle() will take ownership of the handle. @@ -131,10 +141,12 @@ bool VaapiDrmPicture::DownloadFromSurface( const scoped_refptr<VASurface>& va_surface) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return vaapi_wrapper_->BlitSurface(va_surface, va_surface_); } bool VaapiDrmPicture::AllowOverlay() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return true; }
diff --git a/media/gpu/vaapi_picture.h b/media/gpu/vaapi_picture.h index 11ebf80..62c3dcb 100644 --- a/media/gpu/vaapi_picture.h +++ b/media/gpu/vaapi_picture.h
@@ -84,11 +84,11 @@ const uint32_t texture_id_; const uint32_t client_texture_id_; + SEQUENCE_CHECKER(sequence_checker_); + private: const int32_t picture_buffer_id_; - SEQUENCE_CHECKER(sequence_checker_); - DISALLOW_COPY_AND_ASSIGN(VaapiPicture); };
diff --git a/media/gpu/vaapi_tfp_picture.cc b/media/gpu/vaapi_tfp_picture.cc index 261c908..1b52489 100644 --- a/media/gpu/vaapi_tfp_picture.cc +++ b/media/gpu/vaapi_tfp_picture.cc
@@ -31,9 +31,12 @@ texture_id, client_texture_id), x_display_(gfx::GetXDisplay()), - x_pixmap_(0) {} + x_pixmap_(0) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} VaapiTFPPicture::~VaapiTFPPicture() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (glx_image_.get() && make_context_current_cb_.Run()) { glx_image_->ReleaseTexImage(GL_TEXTURE_2D); DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR)); @@ -44,6 +47,7 @@ } bool VaapiTFPPicture::Initialize() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(x_pixmap_); if (texture_id_ != 0 && !make_context_current_cb_.is_null()) { @@ -68,6 +72,7 @@ } bool VaapiTFPPicture::Allocate(gfx::BufferFormat format) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (format != gfx::BufferFormat::BGRX_8888 && format != gfx::BufferFormat::BGRA_8888) { DLOG(ERROR) << "Unsupported format"; @@ -92,12 +97,14 @@ bool VaapiTFPPicture::ImportGpuMemoryBufferHandle( gfx::BufferFormat format, const gfx::GpuMemoryBufferHandle& gpu_memory_buffer_handle) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); NOTIMPLEMENTED() << "GpuMemoryBufferHandle import not implemented"; return false; } bool VaapiTFPPicture::DownloadFromSurface( const scoped_refptr<VASurface>& va_surface) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return vaapi_wrapper_->PutSurfaceIntoPixmap(va_surface->id(), x_pixmap_, va_surface->size()); }
diff --git a/media/gpu/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi_video_decode_accelerator.cc index 608959e..10bcbde 100644 --- a/media/gpu/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi_video_decode_accelerator.cc
@@ -23,7 +23,6 @@ #include "gpu/ipc/service/gpu_channel.h" #include "media/base/bind_to_current_loop.h" #include "media/gpu/accelerated_video_decoder.h" -#include "media/gpu/format_utils.h" #include "media/gpu/h264_decoder.h" #include "media/gpu/vaapi_picture.h" #include "media/gpu/vp8_decoder.h" @@ -707,6 +706,24 @@ TryFinishSurfaceSetChange(); } +static VideoPixelFormat BufferFormatToVideoPixelFormat( + gfx::BufferFormat format) { + switch (format) { + case gfx::BufferFormat::BGRX_8888: + return PIXEL_FORMAT_XRGB; + + case gfx::BufferFormat::BGRA_8888: + return PIXEL_FORMAT_ARGB; + + case gfx::BufferFormat::YVU_420: + return PIXEL_FORMAT_YV12; + + default: + LOG(FATAL) << "Add more cases as needed"; + return PIXEL_FORMAT_UNKNOWN; + } +} + void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() { DCHECK(task_runner_->BelongsToCurrentThread()); @@ -746,7 +763,7 @@ VLOGF(2) << "Requesting " << requested_num_pics_ << " pictures of size: " << requested_pic_size_.ToString(); - VideoPixelFormat format = GfxBufferFormatToVideoPixelFormat(output_format_); + VideoPixelFormat format = BufferFormatToVideoPixelFormat(output_format_); task_runner_->PostTask( FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, requested_num_pics_, format, 1, requested_pic_size_,
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index 8cf966aa..4fd451b 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -61,7 +61,6 @@ #include "media/base/test_data_util.h" #include "media/gpu/fake_video_decode_accelerator.h" #include "media/gpu/features.h" -#include "media/gpu/format_utils.h" #include "media/gpu/gpu_video_decode_accelerator_factory.h" #include "media/gpu/rendering_helper.h" #include "media/gpu/video_accelerator_unittest_helpers.h" @@ -341,6 +340,23 @@ return base::WrapRefCounted(new TextureRef(texture_id, no_longer_needed_cb)); } +#if defined(OS_CHROMEOS) +gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( + VideoPixelFormat pixel_format) { + switch (pixel_format) { + case VideoPixelFormat::PIXEL_FORMAT_ARGB: + return gfx::BufferFormat::BGRA_8888; + case VideoPixelFormat::PIXEL_FORMAT_XRGB: + return gfx::BufferFormat::BGRX_8888; + case VideoPixelFormat::PIXEL_FORMAT_NV12: + return gfx::BufferFormat::YUV_420_BIPLANAR; + default: + LOG_ASSERT(false) << "Unknown VideoPixelFormat"; + return gfx::BufferFormat::BGRX_8888; + } +} +#endif + // static scoped_refptr<TextureRef> TextureRef::CreatePreallocated( uint32_t texture_id,
diff --git a/net/BUILD.gn b/net/BUILD.gn index 68a1209..4f70084 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -698,6 +698,8 @@ "disk_cache/simple/simple_entry_operation.h", "disk_cache/simple/simple_experiment.cc", "disk_cache/simple/simple_experiment.h", + "disk_cache/simple/simple_file_tracker.cc", + "disk_cache/simple/simple_file_tracker.h", "disk_cache/simple/simple_histogram_macros.h", "disk_cache/simple/simple_index.cc", "disk_cache/simple/simple_index.h", @@ -4718,6 +4720,7 @@ "disk_cache/cache_util_unittest.cc", "disk_cache/entry_unittest.cc", "disk_cache/simple/simple_experiment_unittest.cc", + "disk_cache/simple/simple_file_tracker_unittest.cc", "disk_cache/simple/simple_index_file_unittest.cc", "disk_cache/simple/simple_index_unittest.cc", "disk_cache/simple/simple_test_util.cc",
diff --git a/net/cert/OWNERS b/net/cert/OWNERS index c7144676..c5d05bc8 100644 --- a/net/cert/OWNERS +++ b/net/cert/OWNERS
@@ -1 +1,7 @@ +davidben@chromium.org +eroman@chromium.org +mattm@chromium.org +rsleevi@chromium.org +svaldez@chromium.org + # COMPONENT: Internals>Network>Certificate
diff --git a/net/cert_net/OWNERS b/net/cert_net/OWNERS index c7144676..b7d227e 100644 --- a/net/cert_net/OWNERS +++ b/net/cert_net/OWNERS
@@ -1 +1,5 @@ +eroman@chromium.org +mattm@chromium.org +rsleevi@chromium.org + # COMPONENT: Internals>Network>Certificate
diff --git a/net/cookies/OWNERS b/net/cookies/OWNERS index ff5707f..db28c8e 100644 --- a/net/cookies/OWNERS +++ b/net/cookies/OWNERS
@@ -1,4 +1,6 @@ estark@chromium.org mkwst@chromium.org +mmenke@chromium.org +rdsmith@chromium.org # COMPONENT: Internals>Network>Cookies
diff --git a/net/der/OWNERS b/net/der/OWNERS new file mode 100644 index 0000000..4a621d5 --- /dev/null +++ b/net/der/OWNERS
@@ -0,0 +1,6 @@ +davidben@chromium.org +mattm@chromium.org +nharper@chromium.org +svaldez@chromium.org + +# COMPONENT: Internals>Network>Certificate
diff --git a/net/disk_cache/OWNERS b/net/disk_cache/OWNERS index b11ae2ed..854e7d8f 100644 --- a/net/disk_cache/OWNERS +++ b/net/disk_cache/OWNERS
@@ -1 +1,4 @@ +morlovich@chromium.org +jkarlin@chromium.org + # COMPONENT: Internals>Network>Cache
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index a300edf..147d6f6 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc
@@ -3907,7 +3907,7 @@ // Check that the |SimpleBackendImpl| does not favor this structure. disk_cache::SimpleBackendImpl* simple_cache = - new disk_cache::SimpleBackendImpl(cache_path_, nullptr, 0, + new disk_cache::SimpleBackendImpl(cache_path_, nullptr, nullptr, 0, net::DISK_CACHE, nullptr, nullptr); net::TestCompletionCallback cb; int rv = simple_cache->Init(cb.callback());
diff --git a/net/disk_cache/disk_cache.cc b/net/disk_cache/disk_cache.cc index da40ac6e..fe7a2fa 100644 --- a/net/disk_cache/disk_cache.cc +++ b/net/disk_cache/disk_cache.cc
@@ -107,8 +107,8 @@ kSimpleBackendIsDefault)) { disk_cache::SimpleBackendImpl* simple_cache = new disk_cache::SimpleBackendImpl( - path_, cleanup_tracker_.get(), max_bytes_, type_, - /* cache_thread = */ nullptr, net_log_); + path_, cleanup_tracker_.get(), /* file_tracker = */ nullptr, + max_bytes_, type_, /* cache_thread = */ nullptr, net_log_); created_cache_.reset(simple_cache); return simple_cache->Init( base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
diff --git a/net/disk_cache/disk_cache_test_base.cc b/net/disk_cache/disk_cache_test_base.cc index e762101..5ca7545 100644 --- a/net/disk_cache/disk_cache_test_base.cc +++ b/net/disk_cache/disk_cache_test_base.cc
@@ -24,6 +24,7 @@ #include "net/disk_cache/disk_cache_test_util.h" #include "net/disk_cache/memory/mem_backend_impl.h" #include "net/disk_cache/simple/simple_backend_impl.h" +#include "net/disk_cache/simple/simple_file_tracker.h" #include "net/disk_cache/simple/simple_index.h" #include "net/test/gtest_util.h" #include "net/test/net_test_suite.h" @@ -285,6 +286,9 @@ EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_)); } NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle(); + if (simple_cache_mode_ && simple_file_tracker_) + EXPECT_TRUE(simple_file_tracker_->IsEmptyForTesting()); + DiskCacheTest::TearDown(); } @@ -315,10 +319,13 @@ if (simple_cache_mode_) { net::TestCompletionCallback cb; - std::unique_ptr<disk_cache::SimpleBackendImpl> simple_backend( - new disk_cache::SimpleBackendImpl( - cache_path_, /* cleanup_tracker = */ nullptr, size_, type_, runner, - /*net_log = */ nullptr)); + if (!simple_file_tracker_) + simple_file_tracker_ = std::make_unique<disk_cache::SimpleFileTracker>(); + std::unique_ptr<disk_cache::SimpleBackendImpl> simple_backend = + std::make_unique<disk_cache::SimpleBackendImpl>( + cache_path_, /* cleanup_tracker = */ nullptr, + simple_file_tracker_.get(), size_, type_, runner, + /*net_log = */ nullptr); int rv = simple_backend->Init(cb.callback()); ASSERT_THAT(cb.GetResult(rv), IsOk()); simple_cache_impl_ = simple_backend.get();
diff --git a/net/disk_cache/disk_cache_test_base.h b/net/disk_cache/disk_cache_test_base.h index d73095a..66b3cfc3 100644 --- a/net/disk_cache/disk_cache_test_base.h +++ b/net/disk_cache/disk_cache_test_base.h
@@ -31,6 +31,7 @@ class Entry; class MemBackendImpl; class SimpleBackendImpl; +class SimpleFileTracker; } // namespace disk_cache @@ -168,6 +169,7 @@ // initialized. The implementation pointers can be NULL. std::unique_ptr<disk_cache::Backend> cache_; disk_cache::BackendImpl* cache_impl_; + std::unique_ptr<disk_cache::SimpleFileTracker> simple_file_tracker_; disk_cache::SimpleBackendImpl* simple_cache_impl_; disk_cache::MemBackendImpl* mem_cache_;
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc index 0729ae62..5a182054 100644 --- a/net/disk_cache/entry_unittest.cc +++ b/net/disk_cache/entry_unittest.cc
@@ -4377,11 +4377,13 @@ std::string key("a key"); - uint64_t hash = disk_cache::simple_util::GetEntryHashKey(key); + disk_cache::SimpleFileTracker::EntryFileKey num_key( + disk_cache::simple_util::GetEntryHashKey(key)); base::FilePath path_0 = cache_path_.AppendASCII( - disk_cache::simple_util::GetFilenameFromEntryHashAndFileIndex(hash, 0)); + disk_cache::simple_util::GetFilenameFromEntryFileKeyAndFileIndex(num_key, + 0)); base::FilePath path_s = cache_path_.AppendASCII( - disk_cache::simple_util::GetSparseFilenameFromEntryHash(hash)); + disk_cache::simple_util::GetSparseFilenameFromEntryFileKey(num_key)); disk_cache::Entry* entry = nullptr; ASSERT_THAT(CreateEntry(key, &entry), IsOk());
diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc index 922df1ad..c59268e8 100644 --- a/net/disk_cache/simple/simple_backend_impl.cc +++ b/net/disk_cache/simple/simple_backend_impl.cc
@@ -37,6 +37,7 @@ #include "net/disk_cache/simple/simple_entry_format.h" #include "net/disk_cache/simple/simple_entry_impl.h" #include "net/disk_cache/simple/simple_experiment.h" +#include "net/disk_cache/simple/simple_file_tracker.h" #include "net/disk_cache/simple/simple_histogram_macros.h" #include "net/disk_cache/simple/simple_index.h" #include "net/disk_cache/simple/simple_index_file.h" @@ -108,6 +109,11 @@ g_fd_limit_histogram_has_been_populated = true; } +// Global context of all the files we have open --- this permits some to be +// closed on demand if too many FDs are being used, to avoid running out. +base::LazyInstance<SimpleFileTracker>::Leaky g_simple_file_tracker = + LAZY_INSTANCE_INITIALIZER; + // Detects if the files in the cache directory match the current disk cache // backend type and version. If the directory contains no cache, occupies it // with the fresh structure. @@ -221,11 +227,14 @@ SimpleBackendImpl::SimpleBackendImpl( const FilePath& path, scoped_refptr<BackendCleanupTracker> cleanup_tracker, + SimpleFileTracker* file_tracker, int max_bytes, net::CacheType cache_type, const scoped_refptr<base::SequencedTaskRunner>& cache_runner, net::NetLog* net_log) : cleanup_tracker_(std::move(cleanup_tracker)), + file_tracker_(file_tracker ? file_tracker + : g_simple_file_tracker.Pointer()), path_(path), cache_type_(cache_type), cache_runner_(FallbackToInternalIfNull(cache_runner)), @@ -410,7 +419,7 @@ entry_operations_mode_ == SimpleEntryImpl::OPTIMISTIC_OPERATIONS) { simple_entry = new SimpleEntryImpl( cache_type_, path_, cleanup_tracker_.get(), entry_hash, - entry_operations_mode_, this, net_log_); + entry_operations_mode_, this, file_tracker_, net_log_); simple_entry->SetKey(key); simple_entry->SetActiveEntryProxy( ActiveEntryProxy::Create(entry_hash, this)); @@ -697,9 +706,9 @@ EntryMap::iterator& it = insert_result.first; const bool did_insert = insert_result.second; if (did_insert) { - SimpleEntryImpl* entry = it->second = - new SimpleEntryImpl(cache_type_, path_, cleanup_tracker_.get(), - entry_hash, entry_operations_mode_, this, net_log_); + SimpleEntryImpl* entry = it->second = new SimpleEntryImpl( + cache_type_, path_, cleanup_tracker_.get(), entry_hash, + entry_operations_mode_, this, file_tracker_, net_log_); entry->SetKey(key); entry->SetActiveEntryProxy(ActiveEntryProxy::Create(entry_hash, this)); } @@ -736,9 +745,9 @@ return OpenEntry(has_active->second->key(), entry, callback); } - scoped_refptr<SimpleEntryImpl> simple_entry = - new SimpleEntryImpl(cache_type_, path_, cleanup_tracker_.get(), - entry_hash, entry_operations_mode_, this, net_log_); + scoped_refptr<SimpleEntryImpl> simple_entry = new SimpleEntryImpl( + cache_type_, path_, cleanup_tracker_.get(), entry_hash, + entry_operations_mode_, this, file_tracker_, net_log_); CompletionCallback backend_callback = base::Bind(&SimpleBackendImpl::OnEntryOpenedFromHash, AsWeakPtr(), entry_hash, entry, simple_entry, callback);
diff --git a/net/disk_cache/simple/simple_backend_impl.h b/net/disk_cache/simple/simple_backend_impl.h index 7427d26..b54afc1 100644 --- a/net/disk_cache/simple/simple_backend_impl.h +++ b/net/disk_cache/simple/simple_backend_impl.h
@@ -49,15 +49,20 @@ class BackendCleanupTracker; class SimpleEntryImpl; +class SimpleFileTracker; class SimpleIndex; class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, public SimpleIndexDelegate, public base::SupportsWeakPtr<SimpleBackendImpl> { public: + // Note: only pass non-nullptr for |file_tracker| if you don't want the global + // one (which things other than tests would want). |file_tracker| must outlive + // the backend and all the entries, including their asynchronous close. SimpleBackendImpl( const base::FilePath& path, scoped_refptr<BackendCleanupTracker> cleanup_tracker, + SimpleFileTracker* file_tracker, int max_bytes, net::CacheType cache_type, const scoped_refptr<base::SequencedTaskRunner>& cache_runner, @@ -225,6 +230,8 @@ // We want this destroyed after every other field. scoped_refptr<BackendCleanupTracker> cleanup_tracker_; + SimpleFileTracker* const file_tracker_; + const base::FilePath path_; const net::CacheType cache_type_; std::unique_ptr<SimpleIndex> index_;
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc index a43e86e..66e72ef 100644 --- a/net/disk_cache/simple/simple_entry_impl.cc +++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -185,9 +185,11 @@ const uint64_t entry_hash, OperationsMode operations_mode, SimpleBackendImpl* backend, + SimpleFileTracker* file_tracker, net::NetLog* net_log) : cleanup_tracker_(std::move(cleanup_tracker)), backend_(backend->AsWeakPtr()), + file_tracker_(file_tracker), cache_type_(cache_type), worker_pool_(backend->worker_pool()), path_(path), @@ -762,9 +764,9 @@ std::unique_ptr<SimpleEntryCreationResults> results( new SimpleEntryCreationResults(SimpleEntryStat( last_used_, last_modified_, data_size_, sparse_data_size_))); - Closure task = - base::Bind(&SimpleSynchronousEntry::OpenEntry, cache_type_, path_, key_, - entry_hash_, have_index, start_time, results.get()); + Closure task = base::Bind(&SimpleSynchronousEntry::OpenEntry, cache_type_, + path_, key_, entry_hash_, have_index, start_time, + file_tracker_, results.get()); Closure reply = base::Bind(&SimpleEntryImpl::CreationOperationComplete, this, callback, start_time, base::Passed(&results), out_entry, @@ -804,9 +806,9 @@ std::unique_ptr<SimpleEntryCreationResults> results( new SimpleEntryCreationResults(SimpleEntryStat( last_used_, last_modified_, data_size_, sparse_data_size_))); - Closure task = - base::Bind(&SimpleSynchronousEntry::CreateEntry, cache_type_, path_, key_, - entry_hash_, have_index, start_time, results.get()); + Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, cache_type_, + path_, key_, entry_hash_, have_index, start_time, + file_tracker_, results.get()); Closure reply = base::Bind(&SimpleEntryImpl::CreationOperationComplete, this, callback, start_time, base::Passed(&results), out_entry,
diff --git a/net/disk_cache/simple/simple_entry_impl.h b/net/disk_cache/simple/simple_entry_impl.h index 45a3f9a..a80f00f 100644 --- a/net/disk_cache/simple/simple_entry_impl.h +++ b/net/disk_cache/simple/simple_entry_impl.h
@@ -37,8 +37,9 @@ class BackendCleanupTracker; class SimpleBackendImpl; -class SimpleSynchronousEntry; class SimpleEntryStat; +class SimpleFileTracker; +class SimpleSynchronousEntry; struct SimpleEntryCreationResults; // SimpleEntryImpl is the IO thread interface to an entry in the very simple @@ -67,6 +68,7 @@ uint64_t entry_hash, OperationsMode operations_mode, SimpleBackendImpl* backend, + SimpleFileTracker* file_tracker, net::NetLog* net_log); void SetActiveEntryProxy( @@ -344,6 +346,7 @@ base::ThreadCheckerImpl io_thread_checker_; const base::WeakPtr<SimpleBackendImpl> backend_; + SimpleFileTracker* const file_tracker_; const net::CacheType cache_type_; const scoped_refptr<base::TaskRunner> worker_pool_; const base::FilePath path_;
diff --git a/net/disk_cache/simple/simple_file_tracker.cc b/net/disk_cache/simple/simple_file_tracker.cc new file mode 100644 index 0000000..5672bb76 --- /dev/null +++ b/net/disk_cache/simple/simple_file_tracker.cc
@@ -0,0 +1,205 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/disk_cache/simple/simple_file_tracker.h" + +#include <memory> +#include <utility> + +#include "base/files/file.h" +#include "base/synchronization/lock.h" +#include "net/disk_cache/simple/simple_synchronous_entry.h" + +namespace disk_cache { + +SimpleFileTracker::SimpleFileTracker() {} + +SimpleFileTracker::~SimpleFileTracker() { + DCHECK(tracked_files_.empty()); +} + +void SimpleFileTracker::Register(const SimpleSynchronousEntry* owner, + SubFile subfile, + std::unique_ptr<base::File> file) { + base::AutoLock hold_lock(lock_); + + // Make sure the list exists. + auto insert_status = tracked_files_.insert(std::make_pair( + owner->entry_file_key().entry_hash, std::vector<TrackedFiles>())); + + std::vector<TrackedFiles>& candidates = insert_status.first->second; + + // See if entry already exists, if not append. + TrackedFiles* owners_files = nullptr; + for (TrackedFiles& candidate : candidates) { + if (candidate.owner == owner) { + owners_files = &candidate; + break; + } + } + + if (!owners_files) { + candidates.emplace_back(); + owners_files = &candidates.back(); + owners_files->owner = owner; + owners_files->key = owner->entry_file_key(); + } + + int file_index = static_cast<int>(subfile); + DCHECK_EQ(TrackedFiles::TF_NO_REGISTRATION, owners_files->state[file_index]); + owners_files->files[file_index] = std::move(file); + owners_files->state[file_index] = TrackedFiles::TF_REGISTERED; +} + +SimpleFileTracker::FileHandle SimpleFileTracker::Acquire( + const SimpleSynchronousEntry* owner, + SubFile subfile) { + base::AutoLock hold_lock(lock_); + std::vector<TrackedFiles>::iterator owners_files = Find(owner); + int file_index = static_cast<int>(subfile); + + DCHECK_EQ(TrackedFiles::TF_REGISTERED, owners_files->state[file_index]); + owners_files->state[file_index] = TrackedFiles::TF_ACQUIRED; + return FileHandle(this, owner, subfile, + owners_files->files[file_index].get()); +} + +bool SimpleFileTracker::TrackedFiles::Empty() const { + for (State s : state) + if (s != TF_NO_REGISTRATION) + return false; + return true; +} + +void SimpleFileTracker::Release(const SimpleSynchronousEntry* owner, + SubFile subfile) { + std::unique_ptr<base::File> file_to_close; + + { + base::AutoLock hold_lock(lock_); + std::vector<TrackedFiles>::iterator owners_files = Find(owner); + int file_index = static_cast<int>(subfile); + + DCHECK(owners_files->state[file_index] == TrackedFiles::TF_ACQUIRED || + owners_files->state[file_index] == + TrackedFiles::TF_ACQUIRED_PENDING_CLOSE); + + // Prepare to executed deferred close, if any. + if (owners_files->state[file_index] == + TrackedFiles::TF_ACQUIRED_PENDING_CLOSE) { + file_to_close = PrepareClose(owners_files, file_index); + } else { + owners_files->state[file_index] = TrackedFiles::TF_REGISTERED; + } + } + + // The destructor of file_to_close will close it if needed. +} + +void SimpleFileTracker::Close(const SimpleSynchronousEntry* owner, + SubFile subfile) { + std::unique_ptr<base::File> file_to_close; + + { + base::AutoLock hold_lock(lock_); + std::vector<TrackedFiles>::iterator owners_files = Find(owner); + int file_index = static_cast<int>(subfile); + + DCHECK(owners_files->state[file_index] == TrackedFiles::TF_ACQUIRED || + owners_files->state[file_index] == TrackedFiles::TF_REGISTERED); + + if (owners_files->state[file_index] == TrackedFiles::TF_ACQUIRED) { + // The FD is currently acquired, so we can't clean up the TrackedFiles, + // just yet; even if this is the last close, so delay the close until it + // gets released. + owners_files->state[file_index] = TrackedFiles::TF_ACQUIRED_PENDING_CLOSE; + } else { + file_to_close = PrepareClose(owners_files, file_index); + } + } + + // The destructor of file_to_close will close it if needed. Thing to watch + // for impl with stealing: race between bookkeeping above and actual + // close --- the FD is still alive for it. +} + +bool SimpleFileTracker::IsEmptyForTesting() { + base::AutoLock hold_lock(lock_); + return tracked_files_.empty(); +} + +std::vector<SimpleFileTracker::TrackedFiles>::iterator SimpleFileTracker::Find( + const SimpleSynchronousEntry* owner) { + auto candidates = tracked_files_.find(owner->entry_file_key().entry_hash); + for (std::vector<TrackedFiles>::iterator i = candidates->second.begin(); + i != candidates->second.end(); ++i) { + if (i->owner == owner) { + return i; + } + } + LOG(DFATAL) << "SimpleFileTracker operation on non-found entry"; + return candidates->second.end(); +} + +std::unique_ptr<base::File> SimpleFileTracker::PrepareClose( + std::vector<TrackedFiles>::iterator owners_files, + int file_index) { + std::unique_ptr<base::File> file_out = + std::move(owners_files->files[file_index]); + owners_files->state[file_index] = TrackedFiles::TF_NO_REGISTRATION; + if (owners_files->Empty()) { + auto iter = tracked_files_.find(owners_files->key.entry_hash); + iter->second.erase(owners_files); + if (iter->second.empty()) + tracked_files_.erase(iter); + } + return file_out; +} + +SimpleFileTracker::FileHandle::FileHandle() + : file_tracker_(nullptr), entry_(nullptr), file_(nullptr) {} + +SimpleFileTracker::FileHandle::FileHandle(SimpleFileTracker* file_tracker, + const SimpleSynchronousEntry* entry, + SimpleFileTracker::SubFile subfile, + base::File* file) + : file_tracker_(file_tracker), + entry_(entry), + subfile_(subfile), + file_(file) {} + +SimpleFileTracker::FileHandle::FileHandle(FileHandle&& other) { + *this = std::move(other); +} + +SimpleFileTracker::FileHandle::~FileHandle() { + if (entry_) + file_tracker_->Release(entry_, subfile_); +} + +SimpleFileTracker::FileHandle& SimpleFileTracker::FileHandle::operator=( + FileHandle&& other) { + file_tracker_ = other.file_tracker_; + entry_ = other.entry_; + subfile_ = other.subfile_; + file_ = other.file_; + other.file_tracker_ = nullptr; + other.entry_ = nullptr; + other.file_ = nullptr; + return *this; +} + +base::File* SimpleFileTracker::FileHandle::operator->() const { + return file_; +} + +base::File* SimpleFileTracker::FileHandle::get() const { + return file_; +} + +bool SimpleFileTracker::FileHandle::IsOK() const { + return file_ && file_->IsValid(); +} + +} // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_file_tracker.h b/net/disk_cache/simple/simple_file_tracker.h new file mode 100644 index 0000000..a438825 --- /dev/null +++ b/net/disk_cache/simple/simple_file_tracker.h
@@ -0,0 +1,183 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_TRACKER_H_ +#define NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_TRACKER_H_ + +#include <stdint.h> +#include <algorithm> +#include <memory> +#include <unordered_map> +#include <vector> + +#include "base/files/file.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "net/base/net_export.h" +#include "net/disk_cache/simple/simple_entry_format.h" + +namespace disk_cache { + +class SimpleSynchronousEntry; + +// This keeps track of all the files SimpleCache has open, across all the +// backend instancess, in order to prevent us from running out of file +// descriptors. +// TODO(morlovich): Actually implement closing and re-opening of things if we +// run out. +// +// This class is thread-safe. +class NET_EXPORT_PRIVATE SimpleFileTracker { + public: + enum class SubFile { FILE_0, FILE_1, FILE_SPARSE }; + + // A RAII helper that guards access to a file grabbed for use from + // SimpleFileTracker::Acquire(). While it's still alive, if IsOK() is true, + // then using the underlying base::File via get() or the -> operator will be + // safe. + // + // This class is movable but not copyable. It should only be used from a + // single logical sequence of execution, and should not outlive the + // corresponding SimpleSynchronousEntry. + class NET_EXPORT_PRIVATE FileHandle { + public: + FileHandle(); + FileHandle(FileHandle&& other); + ~FileHandle(); + FileHandle& operator=(FileHandle&& other); + base::File* operator->() const; + base::File* get() const; + // Returns true if this handle points to a valid file. This should normally + // be the first thing called on the object, after getting it from + // SimpleFileTracker::Acquire. + bool IsOK() const; + + private: + friend class SimpleFileTracker; + FileHandle(SimpleFileTracker* file_tracker, + const SimpleSynchronousEntry* entry, + SimpleFileTracker::SubFile subfile, + base::File* file); + + // All the pointer fields are nullptr in the default/moved away from form. + SimpleFileTracker* file_tracker_; + const SimpleSynchronousEntry* entry_; + SimpleFileTracker::SubFile subfile_; + base::File* file_; + DISALLOW_COPY_AND_ASSIGN(FileHandle); + }; + + struct EntryFileKey { + EntryFileKey() : entry_hash(0), doom_generation(0) {} + explicit EntryFileKey(uint64_t hash) + : entry_hash(hash), doom_generation(0) {} + + uint64_t entry_hash; + + // In case of a hash collision, there may be multiple SimpleEntryImpl's + // around which have the same entry_hash but different key. In that case, + // we doom all but the most recent one and this number will eventually be + // used to name the files for the doomed ones. + // 0 here means the entry is the active one, and is the only value that's + // presently in use here. + uint32_t doom_generation; + }; + + SimpleFileTracker(); + ~SimpleFileTracker(); + + // Established |file| as what's backing |subfile| for |owner|. This is + // intended to be called when SimpleSynchronousEntry first sets up the file to + // transfer its ownership to SimpleFileTracker. Any Register() call must be + // eventually followed by a corresponding Close() call before the |owner| is + // destroyed. + void Register(const SimpleSynchronousEntry* owner, + SubFile subfile, + std::unique_ptr<base::File> file); + + // Lends out a file to SimpleSynchronousEntry for use. SimpleFileTracker + // will ensure that it doesn't close the file until the handle is destroyed. + // The caller should check .IsOK() on the returned value before using it, as + // it's possible that the file had to be closed and re-opened due to FD + // pressure, and that open may have failed. This should not be called twice + // with the exact same arguments until the handle returned from the previous + // such call is destroyed. + FileHandle Acquire(const SimpleSynchronousEntry* owner, SubFile subfile); + + // Tells SimpleFileTracker that SimpleSynchronousEntry will not be interested + // in the file further, so it can be closed and forgotten about. It's OK to + // call this while a handle to the file is alive, in which case the effect + // takes place after the handle is destroyed. + // If Close() has been called and the handle to the file is no longer alive, + // a new backing file can be established by calling Register() again. + void Close(const SimpleSynchronousEntry* owner, SubFile file); + + // Returns true if there is no in-memory state around, e.g. everything got + // cleaned up. This is a test-only method since this object is expected to be + // shared between multiple threads, in which case its return value may be + // outdated the moment it's returned. + bool IsEmptyForTesting(); + + private: + struct TrackedFiles { + // We can potentially run through this state machine multiple times for + // FILE_1, as that's often missing, so SimpleSynchronousEntry can sometimes + // close and remove the file for an empty stream, then re-open it on actual + // data. + enum State { + TF_NO_REGISTRATION = 0, + TF_REGISTERED = 1, + TF_ACQUIRED = 2, + TF_ACQUIRED_PENDING_CLOSE = 3, + }; + + TrackedFiles() { + std::fill(state, state + kSimpleEntryTotalFileCount, TF_NO_REGISTRATION); + } + + bool Empty() const; + + // We use pointers to SimpleSynchronousEntry two ways: + // 1) As opaque keys. This is handy as it avoids having to compare paths in + // case multiple backends use the same key. Since we access the + // bookkeeping under |lock_| + // + // 2) To get info on the caller of our operation. + // Accessing |owner| from any other TrackedFiles would be unsafe (as it + // may be doing its own thing in a different thread). + const SimpleSynchronousEntry* owner; + EntryFileKey key; + + // Some of these may be !IsValid(), if they are not open. + // Note that these are stored indirect since we hand out pointers to these, + // and we don't want those to become invalid if some other thread appends + // things here. + std::unique_ptr<base::File> files[kSimpleEntryTotalFileCount]; + + State state[kSimpleEntryTotalFileCount]; + }; + + // Marks the file that was previously returned by Acquire as eligible for + // closing again. Called by ~FileHandle. + void Release(const SimpleSynchronousEntry* owner, SubFile subfile); + + // |*found| will be set to whether the entry was found or not. + std::vector<TrackedFiles>::iterator Find(const SimpleSynchronousEntry* owner); + + // Handles state transition of closing file (when we are not deferring it), + // and moves the file out. Note that this may invalidate |owners_files|. + std::unique_ptr<base::File> PrepareClose( + std::vector<TrackedFiles>::iterator owners_files, + int file_index); + + base::Lock lock_; + std::unordered_map<uint64_t, std::vector<TrackedFiles>> tracked_files_; + + DISALLOW_COPY_AND_ASSIGN(SimpleFileTracker); +}; + +} // namespace disk_cache + +#endif // NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_TRACKER_H_
diff --git a/net/disk_cache/simple/simple_file_tracker_unittest.cc b/net/disk_cache/simple/simple_file_tracker_unittest.cc new file mode 100644 index 0000000..b09c5a1 --- /dev/null +++ b/net/disk_cache/simple/simple_file_tracker_unittest.cc
@@ -0,0 +1,221 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" +#include "net/base/cache_type.h" +#include "net/disk_cache/disk_cache_test_base.h" +#include "net/disk_cache/simple/simple_file_tracker.h" +#include "net/disk_cache/simple/simple_synchronous_entry.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace disk_cache { + +class SimpleFileTrackerTest : public DiskCacheTest { + public: + void DeleteSyncEntry(SimpleSynchronousEntry* entry) { delete entry; } + + protected: + // A bit of messiness since we rely on friendship of the fixture to be able to + // create/delete SimpleSynchronousEntry objects. + class SyncEntryDeleter { + public: + SyncEntryDeleter(SimpleFileTrackerTest* fixture) : fixture_(fixture) {} + void operator()(SimpleSynchronousEntry* entry) { + fixture_->DeleteSyncEntry(entry); + } + + private: + SimpleFileTrackerTest* fixture_; + }; + + using SyncEntryPointer = + std::unique_ptr<SimpleSynchronousEntry, SyncEntryDeleter>; + + SyncEntryPointer MakeSyncEntry(uint64_t hash) { + return SyncEntryPointer( + new SimpleSynchronousEntry(net::DISK_CACHE, cache_path_, "dummy", hash, + /* had_index=*/true, &file_tracker_), + SyncEntryDeleter(this)); + } + + SimpleFileTracker file_tracker_; +}; + +TEST_F(SimpleFileTrackerTest, Basic) { + SyncEntryPointer entry = MakeSyncEntry(1); + + // Just transfer some files to the tracker, and then do some I/O on getting + // them back. + base::FilePath path_0 = cache_path_.AppendASCII("file_0"); + base::FilePath path_1 = cache_path_.AppendASCII("file_1"); + + std::unique_ptr<base::File> file_0 = std::make_unique<base::File>( + path_0, base::File::FLAG_CREATE | base::File::FLAG_WRITE); + std::unique_ptr<base::File> file_1 = std::make_unique<base::File>( + path_1, base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file_0->IsValid()); + ASSERT_TRUE(file_1->IsValid()); + + file_tracker_.Register(entry.get(), SimpleFileTracker::SubFile::FILE_0, + std::move(file_0)); + file_tracker_.Register(entry.get(), SimpleFileTracker::SubFile::FILE_1, + std::move(file_1)); + + base::StringPiece msg_0 = "Hello"; + base::StringPiece msg_1 = "Worldish Place"; + + { + SimpleFileTracker::FileHandle borrow_0 = + file_tracker_.Acquire(entry.get(), SimpleFileTracker::SubFile::FILE_0); + SimpleFileTracker::FileHandle borrow_1 = + file_tracker_.Acquire(entry.get(), SimpleFileTracker::SubFile::FILE_1); + + EXPECT_EQ(static_cast<int>(msg_0.size()), + borrow_0->Write(0, msg_0.data(), msg_0.size())); + EXPECT_EQ(static_cast<int>(msg_1.size()), + borrow_1->Write(0, msg_1.data(), msg_1.size())); + + // For stream 0 do release/close, for stream 1 do close/release --- where + // release happens when borrow_{0,1} go out of scope + file_tracker_.Close(entry.get(), SimpleFileTracker::SubFile::FILE_1); + } + file_tracker_.Close(entry.get(), SimpleFileTracker::SubFile::FILE_0); + + // Verify contents. + std::string verify_0, verify_1; + EXPECT_TRUE(ReadFileToString(path_0, &verify_0)); + EXPECT_TRUE(ReadFileToString(path_1, &verify_1)); + EXPECT_EQ(msg_0, verify_0); + EXPECT_EQ(msg_1, verify_1); + EXPECT_TRUE(file_tracker_.IsEmptyForTesting()); +} + +TEST_F(SimpleFileTrackerTest, Collision) { + // Two entries with same key. + SyncEntryPointer entry = MakeSyncEntry(1); + SyncEntryPointer entry2 = MakeSyncEntry(1); + + base::FilePath path = cache_path_.AppendASCII("file"); + base::FilePath path2 = cache_path_.AppendASCII("file2"); + + std::unique_ptr<base::File> file = std::make_unique<base::File>( + path, base::File::FLAG_CREATE | base::File::FLAG_WRITE); + std::unique_ptr<base::File> file2 = std::make_unique<base::File>( + path2, base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file->IsValid()); + ASSERT_TRUE(file2->IsValid()); + + file_tracker_.Register(entry.get(), SimpleFileTracker::SubFile::FILE_0, + std::move(file)); + file_tracker_.Register(entry2.get(), SimpleFileTracker::SubFile::FILE_0, + std::move(file2)); + + base::StringPiece msg = "Alpha"; + base::StringPiece msg2 = "Beta"; + + { + SimpleFileTracker::FileHandle borrow = + file_tracker_.Acquire(entry.get(), SimpleFileTracker::SubFile::FILE_0); + SimpleFileTracker::FileHandle borrow2 = + file_tracker_.Acquire(entry2.get(), SimpleFileTracker::SubFile::FILE_0); + + EXPECT_EQ(static_cast<int>(msg.size()), + borrow->Write(0, msg.data(), msg.size())); + EXPECT_EQ(static_cast<int>(msg2.size()), + borrow2->Write(0, msg2.data(), msg2.size())); + } + file_tracker_.Close(entry.get(), SimpleFileTracker::SubFile::FILE_0); + file_tracker_.Close(entry2.get(), SimpleFileTracker::SubFile::FILE_0); + + // Verify contents. + std::string verify, verify2; + EXPECT_TRUE(ReadFileToString(path, &verify)); + EXPECT_TRUE(ReadFileToString(path2, &verify2)); + EXPECT_EQ(msg, verify); + EXPECT_EQ(msg2, verify2); + EXPECT_TRUE(file_tracker_.IsEmptyForTesting()); +} + +TEST_F(SimpleFileTrackerTest, Reopen) { + // We may sometimes go Register -> Close -> Register, with info still + // alive. + SyncEntryPointer entry = MakeSyncEntry(1); + + base::FilePath path_0 = cache_path_.AppendASCII("file_0"); + base::FilePath path_1 = cache_path_.AppendASCII("file_1"); + + std::unique_ptr<base::File> file_0 = std::make_unique<base::File>( + path_0, base::File::FLAG_CREATE | base::File::FLAG_WRITE); + std::unique_ptr<base::File> file_1 = std::make_unique<base::File>( + path_1, base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file_0->IsValid()); + ASSERT_TRUE(file_1->IsValid()); + + file_tracker_.Register(entry.get(), SimpleFileTracker::SubFile::FILE_0, + std::move(file_0)); + file_tracker_.Register(entry.get(), SimpleFileTracker::SubFile::FILE_1, + std::move(file_1)); + + file_tracker_.Close(entry.get(), SimpleFileTracker::SubFile::FILE_1); + base::File file_1b(path_1, base::File::FLAG_OPEN | base::File::FLAG_WRITE); + ASSERT_TRUE(file_1b.IsValid()); + file_tracker_.Register(entry.get(), SimpleFileTracker::SubFile::FILE_1, + std::move(file_1)); + file_tracker_.Close(entry.get(), SimpleFileTracker::SubFile::FILE_0); + file_tracker_.Close(entry.get(), SimpleFileTracker::SubFile::FILE_1); + EXPECT_TRUE(file_tracker_.IsEmptyForTesting()); +} + +TEST_F(SimpleFileTrackerTest, PointerStability) { + // Make sure the FileHandle lent out doesn't get screwed up as we update + // the state (and potentially move the underlying base::File object around). + const int kEntries = 8; + SyncEntryPointer entries[kEntries] = { + MakeSyncEntry(1), MakeSyncEntry(1), MakeSyncEntry(1), MakeSyncEntry(1), + MakeSyncEntry(1), MakeSyncEntry(1), MakeSyncEntry(1), MakeSyncEntry(1), + }; + std::unique_ptr<base::File> file_0 = std::make_unique<base::File>( + cache_path_.AppendASCII("0"), + base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file_0->IsValid()); + file_tracker_.Register(entries[0].get(), SimpleFileTracker::SubFile::FILE_0, + std::move(file_0)); + + base::StringPiece msg = "Message to write"; + { + SimpleFileTracker::FileHandle borrow = file_tracker_.Acquire( + entries[0].get(), SimpleFileTracker::SubFile::FILE_0); + for (int i = 1; i < kEntries; ++i) { + std::unique_ptr<base::File> file_n = std::make_unique<base::File>( + cache_path_.AppendASCII(base::IntToString(i)), + base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file_n->IsValid()); + file_tracker_.Register(entries[i].get(), + SimpleFileTracker::SubFile::FILE_0, + std::move(file_n)); + } + + EXPECT_EQ(static_cast<int>(msg.size()), + borrow->Write(0, msg.data(), msg.size())); + } + + for (int i = 0; i < kEntries; ++i) + file_tracker_.Close(entries[i].get(), SimpleFileTracker::SubFile::FILE_0); + + // Verify the file. + std::string verify; + EXPECT_TRUE(ReadFileToString(cache_path_.AppendASCII("0"), &verify)); + EXPECT_EQ(msg, verify); + EXPECT_TRUE(file_tracker_.IsEmptyForTesting()); +} + +} // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_index_file_unittest.cc b/net/disk_cache/simple/simple_index_file_unittest.cc index 16e420e3..d3d6cbf 100644 --- a/net/disk_cache/simple/simple_index_file_unittest.cc +++ b/net/disk_cache/simple/simple_index_file_unittest.cc
@@ -402,7 +402,8 @@ base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); disk_cache::SimpleBackendImpl* simple_cache = new disk_cache::SimpleBackendImpl( - cache_path, /* cleanup_tracker = */ nullptr, 0, net::DISK_CACHE, + cache_path, /* cleanup_tracker = */ nullptr, + /* file_tracker = */ nullptr, 0, net::DISK_CACHE, cache_thread.task_runner(), /* net_log = */ nullptr); net::TestCompletionCallback cb; int rv = simple_cache->Init(cb.callback());
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc index 455f00d..87f77118 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.cc +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -107,11 +107,17 @@ hash->Finish(out_hash_value, sizeof(*out_hash_value)); } +SimpleFileTracker::SubFile SubFileForFileIndex(int file_index) { + DCHECK_GT(kSimpleEntryNormalFileCount, file_index); + return file_index == 0 ? SimpleFileTracker::SubFile::FILE_0 + : SimpleFileTracker::SubFile::FILE_1; +} + } // namespace using simple_util::GetEntryHashKey; -using simple_util::GetFilenameFromEntryHashAndFileIndex; -using simple_util::GetSparseFilenameFromEntryHash; +using simple_util::GetFilenameFromEntryFileKeyAndFileIndex; +using simple_util::GetSparseFilenameFromEntryFileKey; using simple_util::GetHeaderSize; using simple_util::GetDataSizeFromFileSize; using simple_util::GetFileSizeFromDataSize; @@ -231,13 +237,14 @@ const uint64_t entry_hash, const bool had_index, const base::TimeTicks& time_enqueued, + SimpleFileTracker* file_tracker, SimpleEntryCreationResults* out_results) { base::TimeTicks start_sync_open_entry = base::TimeTicks::Now(); SIMPLE_CACHE_UMA(TIMES, "QueueLatency.OpenEntry", cache_type, (start_sync_open_entry - time_enqueued)); - SimpleSynchronousEntry* sync_entry = - new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index); + SimpleSynchronousEntry* sync_entry = new SimpleSynchronousEntry( + cache_type, path, key, entry_hash, had_index, file_tracker); out_results->result = sync_entry->InitializeForOpen( &out_results->entry_stat, out_results->stream_prefetch_data); if (out_results->result != net::OK) { @@ -261,14 +268,15 @@ const uint64_t entry_hash, const bool had_index, const base::TimeTicks& time_enqueued, + SimpleFileTracker* file_tracker, SimpleEntryCreationResults* out_results) { DCHECK_EQ(entry_hash, GetEntryHashKey(key)); base::TimeTicks start_sync_create_entry = base::TimeTicks::Now(); SIMPLE_CACHE_UMA(TIMES, "QueueLatency.CreateEntry", cache_type, (start_sync_create_entry - time_enqueued)); - SimpleSynchronousEntry* sync_entry = - new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index); + SimpleSynchronousEntry* sync_entry = new SimpleSynchronousEntry( + cache_type, path, key, entry_hash, had_index, file_tracker); out_results->result = sync_entry->InitializeForCreate(&out_results->entry_stat); if (out_results->result != net::OK) { @@ -317,8 +325,11 @@ DCHECK(initialized_); DCHECK_NE(0, in_entry_op.index); int file_index = GetFileIndexFromStreamIndex(in_entry_op.index); - if (header_and_key_check_needed_[file_index] && - !CheckHeaderAndKey(file_index)) { + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(file_index)); + + if (!file.IsOK() || (header_and_key_check_needed_[file_index] && + !CheckHeaderAndKey(file.get(), file_index))) { *out_result = net::ERR_FAILED; Doom(); return; @@ -329,8 +340,8 @@ // be handled in the SimpleEntryImpl. DCHECK_GT(in_entry_op.buf_len, 0); DCHECK(!empty_file_omitted_[file_index]); - int bytes_read = files_[file_index].Read(file_offset, out_buf->data(), - in_entry_op.buf_len); + int bytes_read = + file->Read(file_offset, out_buf->data(), in_entry_op.buf_len); if (bytes_read > 0) { entry_stat->set_last_used(Time::Now()); if (crc_request != nullptr) { @@ -341,8 +352,9 @@ in_entry_op.offset + bytes_read == entry_stat->data_size(in_entry_op.index)) { crc_request->performed_verify = true; - int checksum_result = CheckEOFRecord(in_entry_op.index, *entry_stat, - crc_request->data_crc32); + int checksum_result = + CheckEOFRecord(file.get(), in_entry_op.index, *entry_stat, + crc_request->data_crc32); if (checksum_result < 0) { crc_request->verify_ok = false; *out_result = checksum_result; @@ -371,10 +383,14 @@ int index = in_entry_op.index; int file_index = GetFileIndexFromStreamIndex(index); if (header_and_key_check_needed_[file_index] && - !empty_file_omitted_[file_index] && !CheckHeaderAndKey(file_index)) { - *out_result = net::ERR_FAILED; - Doom(); - return; + !empty_file_omitted_[file_index]) { + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(file_index)); + if (!file.IsOK() || !CheckHeaderAndKey(file.get(), file_index)) { + *out_result = net::ERR_FAILED; + Doom(); + return; + } } int offset = in_entry_op.offset; int buf_len = in_entry_op.buf_len; @@ -412,11 +428,21 @@ } DCHECK(!empty_file_omitted_[file_index]); + // This needs to be grabbed after the above block, since that's what may + // create the file (for stream 2/file 1). + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(file_index)); + if (!file.IsOK()) { + *out_result = net::ERR_FAILED; + Doom(); + return; + } + if (extending_by_write) { // The EOF record and the eventual stream afterward need to be zeroed out. const int64_t file_eof_offset = out_entry_stat->GetEOFOffsetInFile(key_.size(), index); - if (!files_[file_index].SetLength(file_eof_offset)) { + if (!file->SetLength(file_eof_offset)) { RecordWriteResult(cache_type_, SYNC_WRITE_RESULT_PRETRUNCATE_FAILURE); Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; @@ -424,8 +450,7 @@ } } if (buf_len > 0) { - if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) != - buf_len) { + if (file->Write(file_offset, in_buf->data(), buf_len) != buf_len) { RecordWriteResult(cache_type_, SYNC_WRITE_RESULT_WRITE_FAILURE); Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; @@ -439,7 +464,7 @@ out_entry_stat->set_data_size(index, offset + buf_len); int file_eof_offset = out_entry_stat->GetLastEOFOffsetInFile(key_.size(), index); - if (!files_[file_index].SetLength(file_eof_offset)) { + if (!file->SetLength(file_eof_offset)) { RecordWriteResult(cache_type_, SYNC_WRITE_RESULT_TRUNCATE_FAILURE); Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; @@ -468,6 +493,19 @@ char* buf = out_buf->data(); int read_so_far = 0; + if (!sparse_file_open()) { + *out_result = 0; + return; + } + + SimpleFileTracker::FileHandle sparse_file = + file_tracker_->Acquire(this, SimpleFileTracker::SubFile::FILE_SPARSE); + if (!sparse_file.IsOK()) { + Doom(); + *out_result = net::ERR_CACHE_READ_FAILURE; + return; + } + // Find the first sparse range at or after the requested offset. SparseRangeIterator it = sparse_ranges_.lower_bound(offset); @@ -488,7 +526,8 @@ DCHECK_GE(range_len_after_offset, 0); int len_to_read = std::min(buf_len, range_len_after_offset); - if (!ReadSparseRange(found_range, net_offset, len_to_read, buf)) { + if (!ReadSparseRange(sparse_file.get(), found_range, net_offset, + len_to_read, buf)) { Doom(); *out_result = net::ERR_CACHE_READ_FAILURE; return; @@ -507,7 +546,8 @@ DCHECK_EQ(it->first, found_range->offset); int range_len = base::saturated_cast<int>(found_range->length); int len_to_read = std::min(buf_len - read_so_far, range_len); - if (!ReadSparseRange(found_range, 0, len_to_read, buf + read_so_far)) { + if (!ReadSparseRange(sparse_file.get(), found_range, 0, len_to_read, + buf + read_so_far)) { Doom(); *out_result = net::ERR_CACHE_READ_FAILURE; return; @@ -538,6 +578,13 @@ *out_result = net::ERR_CACHE_WRITE_FAILURE; return; } + SimpleFileTracker::FileHandle sparse_file = + file_tracker_->Acquire(this, SimpleFileTracker::SubFile::FILE_SPARSE); + if (!sparse_file.IsOK()) { + Doom(); + *out_result = net::ERR_CACHE_WRITE_FAILURE; + return; + } uint64_t sparse_data_size = out_entry_stat->sparse_data_size(); // This is a pessimistic estimate; it assumes the entire buffer is going to @@ -545,7 +592,7 @@ if (sparse_data_size + buf_len > max_sparse_data_size) { DVLOG(1) << "Truncating sparse data file (" << sparse_data_size << " + " << buf_len << " > " << max_sparse_data_size << ")"; - TruncateSparseFile(); + TruncateSparseFile(sparse_file.get()); out_entry_stat->set_sparse_data_size(0); } @@ -566,7 +613,8 @@ DCHECK_GE(range_len_after_offset, 0); int len_to_write = std::min(buf_len, range_len_after_offset); - if (!WriteSparseRange(found_range, net_offset, len_to_write, buf)) { + if (!WriteSparseRange(sparse_file.get(), found_range, net_offset, + len_to_write, buf)) { Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; return; @@ -583,9 +631,8 @@ if (offset + written_so_far < found_range->offset) { int len_to_append = static_cast<int>(found_range->offset - (offset + written_so_far)); - if (!AppendSparseRange(offset + written_so_far, - len_to_append, - buf + written_so_far)) { + if (!AppendSparseRange(sparse_file.get(), offset + written_so_far, + len_to_append, buf + written_so_far)) { Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; return; @@ -595,9 +642,7 @@ } int range_len = base::saturated_cast<int>(found_range->length); int len_to_write = std::min(buf_len - written_so_far, range_len); - if (!WriteSparseRange(found_range, - 0, - len_to_write, + if (!WriteSparseRange(sparse_file.get(), found_range, 0, len_to_write, buf + written_so_far)) { Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; @@ -609,9 +654,8 @@ if (written_so_far < buf_len) { int len_to_append = buf_len - written_so_far; - if (!AppendSparseRange(offset + written_so_far, - len_to_append, - buf + written_so_far)) { + if (!AppendSparseRange(sparse_file.get(), offset + written_so_far, + len_to_append, buf + written_so_far)) { Doom(); *out_result = net::ERR_CACHE_WRITE_FAILURE; return; @@ -668,14 +712,15 @@ *out_result = static_cast<int>(std::min(avail_so_far, len_from_start)); } -int SimpleSynchronousEntry::CheckEOFRecord(int stream_index, +int SimpleSynchronousEntry::CheckEOFRecord(base::File* file, + int stream_index, const SimpleEntryStat& entry_stat, uint32_t expected_crc32) { DCHECK(initialized_); SimpleFileEOF eof_record; int file_offset = entry_stat.GetEOFOffsetInFile(key_.size(), stream_index); int file_index = GetFileIndexFromStreamIndex(stream_index); - int rv = GetEOFRecordData(base::StringPiece(), file_index, file_offset, + int rv = GetEOFRecordData(file, base::StringPiece(), file_index, file_offset, &eof_record); if (rv != net::OK) { @@ -694,6 +739,7 @@ } int SimpleSynchronousEntry::PreReadStreamPayload( + base::File* file, base::StringPiece file_0_prefetch, int stream_index, int extra_size, @@ -707,8 +753,8 @@ out->data = new net::GrowableIOBuffer(); out->data->SetCapacity(read_size); int file_offset = entry_stat.GetOffsetInFile(key_.size(), 0, stream_index); - if (!ReadFromFileOrPrefetched(file_0_prefetch, 0, file_offset, read_size, - out->data->data())) + if (!ReadFromFileOrPrefetched(file, file_0_prefetch, 0, file_offset, + read_size, out->data->data())) return net::ERR_FAILED; // Check the CRC32. @@ -738,20 +784,28 @@ if (empty_file_omitted_[file_index]) continue; + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(file_index)); + if (!file.IsOK()) { + RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); + Doom(); + break; + } + if (stream_index == 0) { // Write stream 0 data. int stream_0_offset = entry_stat.GetOffsetInFile(key_.size(), 0, 0); - if (files_[0].Write(stream_0_offset, stream_0_data->data(), - entry_stat.data_size(0)) != entry_stat.data_size(0)) { + if (file->Write(stream_0_offset, stream_0_data->data(), + entry_stat.data_size(0)) != entry_stat.data_size(0)) { RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); DVLOG(1) << "Could not write stream 0 data."; Doom(); } net::SHA256HashValue hash_value; CalculateSHA256OfKey(key_, &hash_value); - if (files_[0].Write(stream_0_offset + entry_stat.data_size(0), - reinterpret_cast<char*>(hash_value.data), - sizeof(hash_value)) != sizeof(hash_value)) { + if (file->Write(stream_0_offset + entry_stat.data_size(0), + reinterpret_cast<char*>(hash_value.data), + sizeof(hash_value)) != sizeof(hash_value)) { RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); DVLOG(1) << "Could not write stream 0 data."; Doom(); @@ -771,17 +825,14 @@ // If stream 0 changed size, the file needs to be resized, otherwise the // next open will yield wrong stream sizes. On stream 1 and stream 2 proper // resizing of the file is handled in SimpleSynchronousEntry::WriteData(). - if (stream_index == 0 && - !files_[file_index].SetLength(eof_offset)) { + if (stream_index == 0 && !file->SetLength(eof_offset)) { RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); DVLOG(1) << "Could not truncate stream 0 file."; Doom(); break; } - if (files_[file_index].Write(eof_offset, - reinterpret_cast<const char*>(&eof_record), - sizeof(eof_record)) != - sizeof(eof_record)) { + if (file->Write(eof_offset, reinterpret_cast<const char*>(&eof_record), + sizeof(eof_record)) != sizeof(eof_record)) { RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); DVLOG(1) << "Could not write eof record."; Doom(); @@ -792,10 +843,13 @@ if (empty_file_omitted_[i]) continue; - if (header_and_key_check_needed_[i] && !CheckHeaderAndKey(i)) { - Doom(); + if (header_and_key_check_needed_[i]) { + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(i)); + if (!file.IsOK() || !CheckHeaderAndKey(file.get(), i)) + Doom(); } - files_[i].Close(); + file_tracker_->Close(this, SubFileForFileIndex(i)); const int64_t file_size = entry_stat.GetFileSize(key_.size(), i); SIMPLE_CACHE_UMA(CUSTOM_COUNTS, "LastClusterSize", cache_type_, @@ -807,8 +861,9 @@ cluster_loss * 100 / (cluster_loss + file_size))); } - if (sparse_file_open()) - sparse_file_.Close(); + if (sparse_file_open()) { + CloseSparseFile(); + } if (files_created_) { const int stream2_file_index = GetFileIndexFromStreamIndex(2); @@ -826,14 +881,17 @@ const FilePath& path, const std::string& key, const uint64_t entry_hash, - const bool had_index) + const bool had_index, + SimpleFileTracker* file_tracker) : cache_type_(cache_type), path_(path), - entry_hash_(entry_hash), + entry_file_key_(entry_hash), had_index_(had_index), key_(key), have_open_files_(false), - initialized_(false) { + initialized_(false), + file_tracker_(file_tracker), + sparse_file_open_(false) { for (int i = 0; i < kSimpleEntryNormalFileCount; ++i) empty_file_omitted_[i] = false; } @@ -852,16 +910,22 @@ FilePath filename = GetFilenameFromFileIndex(file_index); int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE | File::FLAG_SHARE_DELETE; - files_[file_index].Initialize(filename, flags); - *out_error = files_[file_index].error_details(); + std::unique_ptr<base::File> file = + std::make_unique<base::File>(filename, flags); + *out_error = file->error_details(); - if (CanOmitEmptyFile(file_index) && !files_[file_index].IsValid() && + if (CanOmitEmptyFile(file_index) && !file->IsValid() && *out_error == File::FILE_ERROR_NOT_FOUND) { empty_file_omitted_[file_index] = true; return true; } - return files_[file_index].IsValid(); + if (file->IsValid()) { + file_tracker_->Register(this, SubFileForFileIndex(file_index), + std::move(file)); + return true; + } + return false; } bool SimpleSynchronousEntry::MaybeCreateFile( @@ -878,23 +942,27 @@ FilePath filename = GetFilenameFromFileIndex(file_index); int flags = File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE | File::FLAG_SHARE_DELETE; - files_[file_index].Initialize(filename, flags); + std::unique_ptr<base::File> file = + std::make_unique<base::File>(filename, flags); // It's possible that the creation failed because someone deleted the // directory (e.g. because someone pressed "clear cache" on Android). // If so, we would keep failing for a while until periodic index snapshot // re-creates the cache dir, so try to recover from it quickly here. - if (!files_[file_index].IsValid() && - files_[file_index].error_details() == File::FILE_ERROR_NOT_FOUND && + if (!file->IsValid() && file->error_details() == File::FILE_ERROR_NOT_FOUND && !base::DirectoryExists(path_)) { if (base::CreateDirectory(path_)) - files_[file_index].Initialize(filename, flags); + file->Initialize(filename, flags); } - *out_error = files_[file_index].error_details(); + *out_error = file->error_details(); empty_file_omitted_[file_index] = false; - - return files_[file_index].IsValid(); + if (file->IsValid()) { + file_tracker_->Register(this, SubFileForFileIndex(file_index), + std::move(file)); + return true; + } + return false; } bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) { @@ -935,7 +1003,9 @@ } File::Info file_info; - bool success = files_[i].GetInfo(&file_info); + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(i)); + bool success = file.IsOK() && file->GetInfo(&file_info); base::Time file_last_modified; if (!success) { DLOG(WARNING) << "Could not get platform file info."; @@ -1022,8 +1092,7 @@ if (empty_file_omitted_[index]) { empty_file_omitted_[index] = false; } else { - DCHECK(files_[index].IsValid()); - files_[index].Close(); + file_tracker_->Close(this, SubFileForFileIndex(index)); } } @@ -1034,7 +1103,8 @@ CloseSparseFile(); } -bool SimpleSynchronousEntry::CheckHeaderAndKey(int file_index) { +bool SimpleSynchronousEntry::CheckHeaderAndKey(base::File* file, + int file_index) { // TODO(gavinp): Frequently we are doing this at the same time as we read from // the beginning of an entry. It might improve performance to make a single // read(2) call rather than two separate reads. On the other hand, it would @@ -1043,8 +1113,7 @@ // actually already reading stream 1 data here, and tossing it out. std::vector<char> header_data(key_.empty() ? kInitialHeaderRead : GetHeaderSize(key_.size())); - int bytes_read = - files_[file_index].Read(0, header_data.data(), header_data.size()); + int bytes_read = file->Read(0, header_data.data(), header_data.size()); const SimpleFileHeader* header = reinterpret_cast<const SimpleFileHeader*>(header_data.data()); @@ -1073,8 +1142,8 @@ int bytes_to_read = expected_header_size - old_size; // This resize will invalidate iterators, since it is enlarging header_data. header_data.resize(expected_header_size); - int bytes_read = files_[file_index].Read( - old_size, header_data.data() + old_size, bytes_to_read); + int bytes_read = + file->Read(old_size, header_data.data() + old_size, bytes_to_read); if (bytes_read != bytes_to_read) { RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index_); return false; @@ -1115,11 +1184,13 @@ continue; if (key_.empty()) { + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(i)); // If |key_| is empty, we were opened via the iterator interface, without // knowing what our key is. We must therefore read the header immediately // to discover it, so SimpleEntryImpl can make it available to // disk_cache::Entry::GetKey(). - if (!CheckHeaderAndKey(i)) + if (!file.IsOK() || !CheckHeaderAndKey(file.get(), i)) return net::ERR_FAILED; } else { // If we do know which key were are looking for, we still need to @@ -1162,7 +1233,8 @@ out_entry_stat->data_size(2) == 0) { DVLOG(1) << "Removing empty stream 2 file."; CloseFile(stream2_file_index); - DeleteFileForEntryHash(path_, entry_hash_, stream2_file_index); + DeleteFileForEntryHash(path_, entry_file_key_.entry_hash, + stream2_file_index); empty_file_omitted_[stream2_file_index] = true; removed_stream2 = true; } @@ -1178,6 +1250,13 @@ bool SimpleSynchronousEntry::InitializeCreatedFile( int file_index, CreateEntryResult* out_result) { + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(file_index)); + if (!file.IsOK()) { + *out_result = CREATE_ENTRY_CANT_WRITE_HEADER; + return false; + } + SimpleFileHeader header; header.initial_magic_number = kSimpleInitialMagicNumber; header.version = kSimpleEntryVersionOnDisk; @@ -1185,15 +1264,14 @@ header.key_length = key_.size(); header.key_hash = base::Hash(key_); - int bytes_written = files_[file_index].Write( - 0, reinterpret_cast<char*>(&header), sizeof(header)); + int bytes_written = + file->Write(0, reinterpret_cast<char*>(&header), sizeof(header)); if (bytes_written != sizeof(header)) { *out_result = CREATE_ENTRY_CANT_WRITE_HEADER; return false; } - bytes_written = files_[file_index].Write(sizeof(header), key_.data(), - key_.size()); + bytes_written = file->Write(sizeof(header), key_.data(), key_.size()); if (bytes_written != base::checked_cast<int>(key_.size())) { *out_result = CREATE_ENTRY_CANT_WRITE_KEY; return false; @@ -1228,6 +1306,11 @@ int file_size, SimpleEntryStat* out_entry_stat, SimpleStreamPrefetchData stream_prefetch_data[2]) { + SimpleFileTracker::FileHandle file = + file_tracker_->Acquire(this, SubFileForFileIndex(0)); + if (!file.IsOK()) + return net::ERR_FAILED; + // If the file is sufficiently small, we will prefetch everything -- // in which case |prefetch_buf| will be non-null, and we should look at it // rather than call ::Read for the bits. @@ -1239,7 +1322,7 @@ } else { RecordWhetherOpenDidPrefetch(cache_type_, true); prefetch_buf = std::make_unique<char[]>(file_size); - if (files_[0].Read(0, prefetch_buf.get(), file_size) != file_size) + if (file->Read(0, prefetch_buf.get(), file_size) != file_size) return net::ERR_FAILED; file_0_prefetch.set(prefetch_buf.get(), file_size); } @@ -1248,7 +1331,7 @@ // out file 0's layout. SimpleFileEOF stream_0_eof; int rv = GetEOFRecordData( - file_0_prefetch, /* file_index = */ 0, + file.get(), file_0_prefetch, /* file_index = */ 0, /* file_offset = */ file_size - sizeof(SimpleFileEOF), &stream_0_eof); if (rv != net::OK) return rv; @@ -1276,7 +1359,7 @@ out_entry_stat->set_data_size(1, stream1_size); // Put stream 0 data in memory --- plus maybe the sha256(key) footer. - rv = PreReadStreamPayload(file_0_prefetch, /* stream_index = */ 0, + rv = PreReadStreamPayload(file.get(), file_0_prefetch, /* stream_index = */ 0, extra_post_stream_0_read, *out_entry_stat, stream_0_eof, &stream_prefetch_data[0]); if (rv != net::OK) @@ -1287,13 +1370,14 @@ if (prefetch_buf && has_key_sha256) { SimpleFileEOF stream_1_eof; rv = GetEOFRecordData( - file_0_prefetch, /* file_index = */ 0, + file.get(), file_0_prefetch, /* file_index = */ 0, out_entry_stat->GetEOFOffsetInFile(key_.size(), /* stream_index = */ 1), &stream_1_eof); if (rv != net::OK) return rv; - rv = PreReadStreamPayload(file_0_prefetch, /* stream_index = */ 1, + rv = PreReadStreamPayload(file.get(), file_0_prefetch, + /* stream_index = */ 1, /* extra_size = */ 0, *out_entry_stat, stream_1_eof, &stream_prefetch_data[1]); if (rv != net::OK) @@ -1321,19 +1405,20 @@ // Ensure the key is validated before completion. if (!has_key_sha256 && header_and_key_check_needed_[0]) - CheckHeaderAndKey(0); + CheckHeaderAndKey(file.get(), 0); return net::OK; } bool SimpleSynchronousEntry::ReadFromFileOrPrefetched( + base::File* file, base::StringPiece file_0_prefetch, int file_index, int offset, int size, char* dest) { if (file_0_prefetch.empty() || file_index != 0) { - return files_[file_index].Read(offset, dest, size) == size; + return file->Read(offset, dest, size) == size; } else { if (offset < 0 || size < 0) return false; @@ -1357,11 +1442,12 @@ } } -int SimpleSynchronousEntry::GetEOFRecordData(base::StringPiece file_0_prefetch, +int SimpleSynchronousEntry::GetEOFRecordData(base::File* file, + base::StringPiece file_0_prefetch, int file_index, int file_offset, SimpleFileEOF* eof_record) { - if (!ReadFromFileOrPrefetched(file_0_prefetch, file_index, file_offset, + if (!ReadFromFileOrPrefetched(file, file_0_prefetch, file_index, file_offset, sizeof(SimpleFileEOF), reinterpret_cast<char*>(eof_record))) { RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE); @@ -1383,15 +1469,16 @@ } void SimpleSynchronousEntry::Doom() const { - DeleteFilesForEntryHash(path_, entry_hash_); + DCHECK_EQ(0u, entry_file_key_.doom_generation); + DeleteFilesForEntryHash(path_, entry_file_key_.entry_hash); } // static bool SimpleSynchronousEntry::DeleteFileForEntryHash(const FilePath& path, const uint64_t entry_hash, const int file_index) { - FilePath to_delete = path.AppendASCII( - GetFilenameFromEntryHashAndFileIndex(entry_hash, file_index)); + FilePath to_delete = path.AppendASCII(GetFilenameFromEntryFileKeyAndFileIndex( + SimpleFileTracker::EntryFileKey(entry_hash), file_index)); return simple_util::SimpleCacheDeleteFile(to_delete); } @@ -1404,8 +1491,8 @@ if (!DeleteFileForEntryHash(path, entry_hash, i) && !CanOmitEmptyFile(i)) result = false; } - FilePath to_delete = path.AppendASCII( - GetSparseFilenameFromEntryHash(entry_hash)); + FilePath to_delete = path.AppendASCII(GetSparseFilenameFromEntryFileKey( + SimpleFileTracker::EntryFileKey(entry_hash))); simple_util::SimpleCacheDeleteFile(to_delete); return result; } @@ -1414,15 +1501,16 @@ bool SimpleSynchronousEntry::TruncateFilesForEntryHash( const FilePath& path, const uint64_t entry_hash) { + SimpleFileTracker::EntryFileKey file_key(entry_hash); bool result = true; for (int i = 0; i < kSimpleEntryNormalFileCount; ++i) { FilePath filename_to_truncate = - path.AppendASCII(GetFilenameFromEntryHashAndFileIndex(entry_hash, i)); + path.AppendASCII(GetFilenameFromEntryFileKeyAndFileIndex(file_key, i)); if (!TruncatePath(filename_to_truncate)) result = false; } FilePath to_delete = - path.AppendASCII(GetSparseFilenameFromEntryHash(entry_hash)); + path.AppendASCII(GetSparseFilenameFromEntryFileKey(file_key)); TruncatePath(to_delete); return result; } @@ -1445,48 +1533,62 @@ FilePath SimpleSynchronousEntry::GetFilenameFromFileIndex(int file_index) { return path_.AppendASCII( - GetFilenameFromEntryHashAndFileIndex(entry_hash_, file_index)); + GetFilenameFromEntryFileKeyAndFileIndex(entry_file_key_, file_index)); } bool SimpleSynchronousEntry::OpenSparseFileIfExists( int32_t* out_sparse_data_size) { DCHECK(!sparse_file_open()); - FilePath filename = path_.AppendASCII( - GetSparseFilenameFromEntryHash(entry_hash_)); + FilePath filename = + path_.AppendASCII(GetSparseFilenameFromEntryFileKey(entry_file_key_)); int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE | File::FLAG_SHARE_DELETE; - sparse_file_.Initialize(filename, flags); - if (sparse_file_.IsValid()) - return ScanSparseFile(out_sparse_data_size); + std::unique_ptr<base::File> sparse_file = + std::make_unique<base::File>(filename, flags); + if (!sparse_file->IsValid()) + // No file -> OK, file open error -> trouble. + return sparse_file->error_details() == File::FILE_ERROR_NOT_FOUND; - return sparse_file_.error_details() == File::FILE_ERROR_NOT_FOUND; + if (!ScanSparseFile(sparse_file.get(), out_sparse_data_size)) + return false; + + file_tracker_->Register(this, SimpleFileTracker::SubFile::FILE_SPARSE, + std::move(sparse_file)); + sparse_file_open_ = true; + return true; } bool SimpleSynchronousEntry::CreateSparseFile() { DCHECK(!sparse_file_open()); - FilePath filename = path_.AppendASCII( - GetSparseFilenameFromEntryHash(entry_hash_)); + FilePath filename = + path_.AppendASCII(GetSparseFilenameFromEntryFileKey(entry_file_key_)); int flags = File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE | File::FLAG_SHARE_DELETE; - sparse_file_.Initialize(filename, flags); - if (!sparse_file_.IsValid()) + std::unique_ptr<base::File> sparse_file = + std::make_unique<base::File>(filename, flags); + if (!sparse_file->IsValid()) return false; - - return InitializeSparseFile(); + if (!InitializeSparseFile(sparse_file.get())) + return false; + file_tracker_->Register(this, SimpleFileTracker::SubFile::FILE_SPARSE, + std::move(sparse_file)); + sparse_file_open_ = true; + return true; } void SimpleSynchronousEntry::CloseSparseFile() { DCHECK(sparse_file_open()); - sparse_file_.Close(); + file_tracker_->Close(this, SimpleFileTracker::SubFile::FILE_SPARSE); + sparse_file_open_ = false; } -bool SimpleSynchronousEntry::TruncateSparseFile() { +bool SimpleSynchronousEntry::TruncateSparseFile(base::File* sparse_file) { DCHECK(sparse_file_open()); int64_t header_and_key_length = sizeof(SimpleFileHeader) + key_.size(); - if (!sparse_file_.SetLength(header_and_key_length)) { + if (!sparse_file->SetLength(header_and_key_length)) { DLOG(WARNING) << "Could not truncate sparse file"; return false; } @@ -1497,9 +1599,7 @@ return true; } -bool SimpleSynchronousEntry::InitializeSparseFile() { - DCHECK(sparse_file_open()); - +bool SimpleSynchronousEntry::InitializeSparseFile(base::File* sparse_file) { SimpleFileHeader header; header.initial_magic_number = kSimpleInitialMagicNumber; header.version = kSimpleVersion; @@ -1507,14 +1607,14 @@ header.key_hash = base::Hash(key_); int header_write_result = - sparse_file_.Write(0, reinterpret_cast<char*>(&header), sizeof(header)); + sparse_file->Write(0, reinterpret_cast<char*>(&header), sizeof(header)); if (header_write_result != sizeof(header)) { DLOG(WARNING) << "Could not write sparse file header"; return false; } - int key_write_result = sparse_file_.Write(sizeof(header), key_.data(), - key_.size()); + int key_write_result = + sparse_file->Write(sizeof(header), key_.data(), key_.size()); if (key_write_result != base::checked_cast<int>(key_.size())) { DLOG(WARNING) << "Could not write sparse file key"; return false; @@ -1526,14 +1626,13 @@ return true; } -bool SimpleSynchronousEntry::ScanSparseFile(int32_t* out_sparse_data_size) { - DCHECK(sparse_file_open()); - +bool SimpleSynchronousEntry::ScanSparseFile(base::File* sparse_file, + int32_t* out_sparse_data_size) { int64_t sparse_data_size = 0; SimpleFileHeader header; int header_read_result = - sparse_file_.Read(0, reinterpret_cast<char*>(&header), sizeof(header)); + sparse_file->Read(0, reinterpret_cast<char*>(&header), sizeof(header)); if (header_read_result != sizeof(header)) { DLOG(WARNING) << "Could not read header from sparse file."; return false; @@ -1555,10 +1654,9 @@ int64_t range_header_offset = sizeof(header) + key_.size(); while (1) { SimpleFileSparseRangeHeader range_header; - int range_header_read_result = - sparse_file_.Read(range_header_offset, - reinterpret_cast<char*>(&range_header), - sizeof(range_header)); + int range_header_read_result = sparse_file->Read( + range_header_offset, reinterpret_cast<char*>(&range_header), + sizeof(range_header)); if (range_header_read_result == 0) break; if (range_header_read_result != sizeof(range_header)) { @@ -1591,14 +1689,17 @@ return true; } -bool SimpleSynchronousEntry::ReadSparseRange(const SparseRange* range, - int offset, int len, char* buf) { +bool SimpleSynchronousEntry::ReadSparseRange(base::File* sparse_file, + const SparseRange* range, + int offset, + int len, + char* buf) { DCHECK(range); DCHECK(buf); DCHECK_LE(offset, range->length); DCHECK_LE(offset + len, range->length); - int bytes_read = sparse_file_.Read(range->file_offset + offset, buf, len); + int bytes_read = sparse_file->Read(range->file_offset + offset, buf, len); if (bytes_read < len) { DLOG(WARNING) << "Could not read sparse range."; return false; @@ -1616,8 +1717,10 @@ return true; } -bool SimpleSynchronousEntry::WriteSparseRange(SparseRange* range, - int offset, int len, +bool SimpleSynchronousEntry::WriteSparseRange(base::File* sparse_file, + SparseRange* range, + int offset, + int len, const char* buf) { DCHECK(range); DCHECK(buf); @@ -1638,16 +1741,16 @@ header.length = range->length; header.data_crc32 = range->data_crc32; - int bytes_written = sparse_file_.Write(range->file_offset - sizeof(header), - reinterpret_cast<char*>(&header), - sizeof(header)); + int bytes_written = + sparse_file->Write(range->file_offset - sizeof(header), + reinterpret_cast<char*>(&header), sizeof(header)); if (bytes_written != base::checked_cast<int>(sizeof(header))) { DLOG(WARNING) << "Could not rewrite sparse range header."; return false; } } - int bytes_written = sparse_file_.Write(range->file_offset + offset, buf, len); + int bytes_written = sparse_file->Write(range->file_offset + offset, buf, len); if (bytes_written < len) { DLOG(WARNING) << "Could not write sparse range."; return false; @@ -1656,7 +1759,8 @@ return true; } -bool SimpleSynchronousEntry::AppendSparseRange(int64_t offset, +bool SimpleSynchronousEntry::AppendSparseRange(base::File* sparse_file, + int64_t offset, int len, const char* buf) { DCHECK_GE(offset, 0); @@ -1671,16 +1775,15 @@ header.length = len; header.data_crc32 = data_crc32; - int bytes_written = sparse_file_.Write(sparse_tail_offset_, - reinterpret_cast<char*>(&header), - sizeof(header)); + int bytes_written = sparse_file->Write( + sparse_tail_offset_, reinterpret_cast<char*>(&header), sizeof(header)); if (bytes_written != base::checked_cast<int>(sizeof(header))) { DLOG(WARNING) << "Could not append sparse range header."; return false; } sparse_tail_offset_ += bytes_written; - bytes_written = sparse_file_.Write(sparse_tail_offset_, buf, len); + bytes_written = sparse_file->Write(sparse_tail_offset_, buf, len); if (bytes_written < len) { DLOG(WARNING) << "Could not append sparse range data."; return false;
diff --git a/net/disk_cache/simple/simple_synchronous_entry.h b/net/disk_cache/simple/simple_synchronous_entry.h index 1ddda90..38779a7e 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.h +++ b/net/disk_cache/simple/simple_synchronous_entry.h
@@ -24,6 +24,7 @@ #include "net/base/cache_type.h" #include "net/base/net_export.h" #include "net/disk_cache/simple/simple_entry_format.h" +#include "net/disk_cache/simple/simple_file_tracker.h" namespace net { class GrowableIOBuffer; @@ -163,6 +164,7 @@ uint64_t entry_hash, bool had_index, const base::TimeTicks& time_enqueued, + SimpleFileTracker* file_tracker, SimpleEntryCreationResults* out_results); static void CreateEntry(net::CacheType cache_type, @@ -171,6 +173,7 @@ uint64_t entry_hash, bool had_index, const base::TimeTicks& time_enqueued, + SimpleFileTracker* file_tracker, SimpleEntryCreationResults* out_results); // Deletes an entry from the file system without affecting the state of the @@ -207,7 +210,8 @@ net::IOBuffer* in_buf, SimpleEntryStat* out_entry_stat, int* out_result); - int CheckEOFRecord(int stream_index, + int CheckEOFRecord(base::File* file, + int stream_index, const SimpleEntryStat& entry_stat, uint32_t expected_crc32); @@ -232,10 +236,14 @@ const base::FilePath& path() const { return path_; } std::string key() const { return key_; } + const SimpleFileTracker::EntryFileKey& entry_file_key() const { + return entry_file_key_; + } private: FRIEND_TEST_ALL_PREFIXES(::DiskCacheBackendTest, SimpleCacheEnumerationLongKeys); + friend class SimpleFileTrackerTest; enum CreateEntryResult { CREATE_ENTRY_SUCCESS = 0, @@ -266,15 +274,17 @@ // make it likely the entire key is read. static const size_t kInitialHeaderRead = 64 * 1024; - SimpleSynchronousEntry(net::CacheType cache_type, - const base::FilePath& path, - const std::string& key, - uint64_t entry_hash, - bool had_index); + NET_EXPORT_PRIVATE SimpleSynchronousEntry( + net::CacheType cache_type, + const base::FilePath& path, + const std::string& key, + uint64_t entry_hash, + bool had_index, + SimpleFileTracker* simple_file_tracker); // Like Entry, the SimpleSynchronousEntry self releases when Close() is // called. - ~SimpleSynchronousEntry(); + NET_EXPORT_PRIVATE ~SimpleSynchronousEntry(); // Tries to open one of the cache entry files. Succeeds if the open succeeds // or if the file was not found and is allowed to be omitted if the @@ -296,7 +306,7 @@ // they are correct. If this entry was opened with a key, the key is checked // for a match. If not, then the |key_| member is set based on the value in // this header. Records histograms if any check is failed. - bool CheckHeaderAndKey(int file_index); + bool CheckHeaderAndKey(base::File* file, int file_index); // Returns a net error, i.e. net::OK on success. int InitializeForOpen(SimpleEntryStat* out_entry_stat, @@ -320,31 +330,34 @@ SimpleStreamPrefetchData stream_prefetch_data[2]); // Reads the EOF record located at |file_offset| in file |file_index|, - // with |file_0_prefetch| ptentially having prefetched file 0 content. + // with |file_0_prefetch| potentially having prefetched file 0 content. // Puts the result into |*eof_record| and sanity-checks it. // Returns net status, and records any failures to UMA. - int GetEOFRecordData(base::StringPiece file_0_prefetch, + int GetEOFRecordData(base::File* file, + base::StringPiece file_0_prefetch, int file_index, int file_offset, SimpleFileEOF* eof_record); - // Reads either from |file_0_prefetch| or files_[file_index]. + // Reads either from |file_0_prefetch| or |file|. // Range-checks all the in-memory reads. - bool ReadFromFileOrPrefetched(base::StringPiece file_0_prefetch, + bool ReadFromFileOrPrefetched(base::File* file, + base::StringPiece file_0_prefetch, int file_index, int offset, int size, char* dest); // Extracts out the payload of stream |stream_index|, reading either from - // |file_0_prefetch|, if available, or the file. |entry_stat| will be used to + // |file_0_prefetch|, if available, or |file|. |entry_stat| will be used to // determine file layout, though |extra_size| additional bytes will be read // past the stream payload end. // // |*stream_data| will be pointed to a fresh buffer with the results, // and |*out_crc32| will get the checksum, which will be verified against // |eof_record|. - int PreReadStreamPayload(base::StringPiece file_0_prefetch, + int PreReadStreamPayload(base::File* file, + base::StringPiece file_0_prefetch, int stream_index, int extra_size, const SimpleEntryStat& entry_stat, @@ -363,28 +376,37 @@ void CloseSparseFile(); // Writes the header to the (newly-created) sparse file. - bool InitializeSparseFile(); + bool InitializeSparseFile(base::File* file); // Removes all but the header of the sparse file. - bool TruncateSparseFile(); + bool TruncateSparseFile(base::File* sparse_file); // Scans the existing ranges in the sparse file. Populates |sparse_ranges_| // and sets |*out_sparse_data_size| to the total size of all the ranges (not // including headers). - bool ScanSparseFile(int32_t* out_sparse_data_size); + bool ScanSparseFile(base::File* sparse_file, int32_t* out_sparse_data_size); // Reads from a single sparse range. If asked to read the entire range, also // verifies the CRC32. - bool ReadSparseRange(const SparseRange* range, - int offset, int len, char* buf); + bool ReadSparseRange(base::File* sparse_file, + const SparseRange* range, + int offset, + int len, + char* buf); // Writes to a single (existing) sparse range. If asked to write the entire // range, also updates the CRC32; otherwise, invalidates it. - bool WriteSparseRange(SparseRange* range, - int offset, int len, const char* buf); + bool WriteSparseRange(base::File* sparse_file, + SparseRange* range, + int offset, + int len, + const char* buf); // Appends a new sparse range to the sparse data file. - bool AppendSparseRange(int64_t offset, int len, const char* buf); + bool AppendSparseRange(base::File* sparse_file, + int64_t offset, + int len, + const char* buf); static bool DeleteFileForEntryHash(const base::FilePath& path, uint64_t entry_hash, @@ -398,13 +420,11 @@ base::FilePath GetFilenameFromFileIndex(int file_index); - bool sparse_file_open() const { - return sparse_file_.IsValid(); - } + bool sparse_file_open() const { return sparse_file_open_; } const net::CacheType cache_type_; const base::FilePath path_; - const uint64_t entry_hash_; + SimpleFileTracker::EntryFileKey entry_file_key_; const bool had_index_; std::string key_; @@ -418,7 +438,7 @@ false, }; - base::File files_[kSimpleEntryNormalFileCount]; + SimpleFileTracker* file_tracker_; // True if the corresponding stream is empty and therefore no on-disk file // was created to store it. @@ -427,7 +447,8 @@ typedef std::map<int64_t, SparseRange> SparseRangeOffsetMap; typedef SparseRangeOffsetMap::iterator SparseRangeIterator; SparseRangeOffsetMap sparse_ranges_; - base::File sparse_file_; + bool sparse_file_open_; + // Offset of the end of the sparse file (where the next sparse range will be // written). int64_t sparse_tail_offset_;
diff --git a/net/disk_cache/simple/simple_util.cc b/net/disk_cache/simple/simple_util.cc index 4e0869f..ea56edf 100644 --- a/net/disk_cache/simple/simple_util.cc +++ b/net/disk_cache/simple/simple_util.cc
@@ -60,13 +60,21 @@ return u.key_hash; } -std::string GetFilenameFromEntryHashAndFileIndex(uint64_t entry_hash, - int file_index) { - return base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, file_index); +std::string GetFilenameFromEntryFileKeyAndFileIndex( + const SimpleFileTracker::EntryFileKey& key, + int file_index) { + // TODO(morlovich): create a todelete_..._ file for a non-zero + // doom_generation. + DCHECK_EQ(0u, key.doom_generation); + return base::StringPrintf("%016" PRIx64 "_%1d", key.entry_hash, file_index); } -std::string GetSparseFilenameFromEntryHash(uint64_t entry_hash) { - return base::StringPrintf("%016" PRIx64 "_s", entry_hash); +std::string GetSparseFilenameFromEntryFileKey( + const SimpleFileTracker::EntryFileKey& key) { + // TODO(morlovich): create a todelete_..._ file for a non-zero + // doom_generation. + DCHECK_EQ(0u, key.doom_generation); + return base::StringPrintf("%016" PRIx64 "_s", key.entry_hash); } std::string GetFilenameFromKeyAndFileIndex(const std::string& key,
diff --git a/net/disk_cache/simple/simple_util.h b/net/disk_cache/simple/simple_util.h index 9ea7548..e40dd26 100644 --- a/net/disk_cache/simple/simple_util.h +++ b/net/disk_cache/simple/simple_util.h
@@ -11,6 +11,7 @@ #include "base/strings/string_piece.h" #include "net/base/net_export.h" +#include "net/disk_cache/simple/simple_file_tracker.h" namespace base { class FilePath; @@ -46,14 +47,14 @@ const std::string& key, int file_index); -// Same as |GetFilenameFromKeyAndIndex| above, but using a hex string. -NET_EXPORT_PRIVATE std::string GetFilenameFromEntryHashAndFileIndex( - uint64_t entry_hash, +// Same as |GetFilenameFromKeyAndIndex| above, but using a numeric key. +NET_EXPORT_PRIVATE std::string GetFilenameFromEntryFileKeyAndFileIndex( + const SimpleFileTracker::EntryFileKey& key, int file_index); // Given a |key| for an entry, returns the name of the sparse data file. -NET_EXPORT_PRIVATE std::string GetSparseFilenameFromEntryHash( - uint64_t entry_hash); +NET_EXPORT_PRIVATE std::string GetSparseFilenameFromEntryFileKey( + const SimpleFileTracker::EntryFileKey& key); // Given the size of a key, the size in bytes of the header at the beginning // of a simple cache file.
diff --git a/net/dns/OWNERS b/net/dns/OWNERS index 52b51f2..4be0e48 100644 --- a/net/dns/OWNERS +++ b/net/dns/OWNERS
@@ -1,3 +1,5 @@ +mgersh@chromium.org + per-file *_struct_traits*.*=set noparent per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc index 899493b..9c0e0d8 100644 --- a/net/dns/dns_transaction.cc +++ b/net/dns/dns_transaction.cc
@@ -670,8 +670,13 @@ } void DoCallback(AttemptResult result) { - DCHECK(!callback_.is_null()); DCHECK_NE(ERR_IO_PENDING, result.rv); + + // TODO(mgersh): consider changing back to a DCHECK once + // https://crbug.com/779589 is fixed. + if (callback_.is_null()) + return; + const DnsResponse* response = result.attempt ? result.attempt->GetResponse() : NULL; CHECK(result.rv != OK || response != NULL); @@ -883,8 +888,12 @@ session_->RecordServerSuccess(result.attempt->server_index()); net_log_.EndEventWithNetErrorCode( NetLogEventType::DNS_TRANSACTION_QUERY, result.rv); - // Try next suffix. - qnames_.pop_front(); + // Try next suffix. Check that qnames_ isn't already empty first, + // which can happen when there are two attempts running at once. + // TODO(mgersh): remove this workaround for https://crbug.com/774846 + // when https://crbug.com/779589 is fixed. + if (!qnames_.empty()) + qnames_.pop_front(); if (qnames_.empty()) { return AttemptResult(ERR_NAME_NOT_RESOLVED, NULL); } else {
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc index 886d17f..53328d7 100644 --- a/net/dns/dns_transaction_unittest.cc +++ b/net/dns/dns_transaction_unittest.cc
@@ -643,6 +643,26 @@ EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); } +TEST_F(DnsTransactionTest, MismatchedResponseNxdomain) { + config_.attempts = 2; + config_.timeout = TestTimeouts::tiny_timeout(); + ConfigureFactory(); + + // First attempt receives mismatched response followed by valid NXDOMAIN + // response. + // Second attempt receives valid NXDOMAIN response. + std::unique_ptr<DnsSocketData> data( + new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false)); + data->AddResponseData(kT1ResponseDatagram, arraysize(kT1ResponseDatagram), + SYNCHRONOUS); + data->AddRcode(dns_protocol::kRcodeNXDOMAIN, ASYNC); + AddSocketData(std::move(data)); + AddSyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN); + + TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED); + EXPECT_TRUE(helper0.Run(transaction_factory_.get())); +} + TEST_F(DnsTransactionTest, ServerFail) { AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc index 1ecc71b..669509e 100644 --- a/net/dns/host_resolver_impl.cc +++ b/net/dns/host_resolver_impl.cc
@@ -2490,8 +2490,9 @@ // the newly started jobs use the new config. if (dns_client_.get()) { // Make sure that if the update is an initial read, not a change, there - // wasn't already a DnsConfig. - DCHECK(config_changed || !dns_client_->GetConfig()); + // wasn't already a DnsConfig or it's the same one. + DCHECK(config_changed || !dns_client_->GetConfig() || + dns_client_->GetConfig()->Equals(dns_config)); dns_client_->SetConfig(dns_config); if (dns_client_->GetConfig()) UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
diff --git a/net/filter/OWNERS b/net/filter/OWNERS index 9f6f061..c0aa5db 100644 --- a/net/filter/OWNERS +++ b/net/filter/OWNERS
@@ -1 +1,4 @@ +rdsmith@chromium.org +xunjieli@chromium.org + # COMPONENT: Internals>Network>Filters
diff --git a/net/ftp/OWNERS b/net/ftp/OWNERS index 9d7fb31..71184cb 100644 --- a/net/ftp/OWNERS +++ b/net/ftp/OWNERS
@@ -1 +1,4 @@ +eroman@chromium.org +mmenke@chromium.org + # COMPONENT: Internals>Network>FTP
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index d539e41..abacb5f 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -1796,7 +1796,7 @@ } else if (entry_ && !handling_206_) { DCHECK_EQ(READ_WRITE, mode_); if ((!partial_ && !cache_->IsWritingInProgress(entry_)) || - partial_->IsLastRange()) { + (partial_ && partial_->IsLastRange())) { mode_ = READ; } // We no longer need the network transaction, so destroy it.
diff --git a/net/http2/OWNERS b/net/http2/OWNERS index 25d7b80..b608e73 100644 --- a/net/http2/OWNERS +++ b/net/http2/OWNERS
@@ -1 +1,8 @@ +birenroy@chromium.org +bnc@chromium.org +dahollings@chromium.org +diannahu@chromium.org +rch@chromium.org +yasong@chromium.org + # COMPONENT: Internals>Network>HTTP2
diff --git a/net/log/OWNERS b/net/log/OWNERS index 8cc34f7..529249d6 100644 --- a/net/log/OWNERS +++ b/net/log/OWNERS
@@ -1 +1,5 @@ +eroman@chromium.org +mmenke@chormium.org +xunjieli@chromium.org + # COMPONENT: Internals>Network>Logging
diff --git a/net/proxy/OWNERS b/net/proxy/OWNERS index d896072..b03baf3a 100644 --- a/net/proxy/OWNERS +++ b/net/proxy/OWNERS
@@ -1,5 +1,5 @@ -per-file *_struct_traits*.*=set noparent -per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +eroman@chromium.org +mmenke@chromium.org per-file *_v8*=jochen@chromium.org
diff --git a/net/quic/OWNERS b/net/quic/OWNERS index 4612afd..9cd4df79 100644 --- a/net/quic/OWNERS +++ b/net/quic/OWNERS
@@ -1 +1,6 @@ +ckrasic@chromium.org +jri@chromium.org +rch@chromium.org +zhongyi@chromium.org + # COMPONENT: Internals>Network>QUIC
diff --git a/net/reporting/OWNERS b/net/reporting/OWNERS new file mode 100644 index 0000000..5ad5dc9 --- /dev/null +++ b/net/reporting/OWNERS
@@ -0,0 +1 @@ +juliatuttle@chromium.org
diff --git a/net/spdy/OWNERS b/net/spdy/OWNERS index 47a6bae9..4969fc1 100644 --- a/net/spdy/OWNERS +++ b/net/spdy/OWNERS
@@ -1,6 +1,3 @@ -birenroy@chromium.org -dahollings@chromium.org -diannahu@chromium.org -yasong@chromium.org +file://net/http2/OWNERS # COMPONENT: Internals>Network>HTTP2
diff --git a/net/spdy/chromium/http2_push_promise_index.cc b/net/spdy/chromium/http2_push_promise_index.cc index dc41ccbc..7eb6383 100644 --- a/net/spdy/chromium/http2_push_promise_index.cc +++ b/net/spdy/chromium/http2_push_promise_index.cc
@@ -29,11 +29,6 @@ for (WeakSessionList::iterator it = url_it->second.begin(); it != url_it->second.end();) { base::WeakPtr<SpdySession> spdy_session = *it; - // Lazy deletion of destroyed SpdySessions. - if (!spdy_session) { - it = url_it->second.erase(it); - continue; - } ++it; const SpdySessionKey& spdy_session_key = spdy_session->spdy_session_key(); if (spdy_session_key.proxy_server() != key.proxy_server() || @@ -85,11 +80,6 @@ size_t removed = 0; for (WeakSessionList::iterator it = url_it->second.begin(); it != url_it->second.end();) { - // Lazy deletion of destroyed SpdySessions. - if (!*it) { - it = url_it->second.erase(it); - continue; - } if (it->get() == spdy_session) { it = url_it->second.erase(it); ++removed;
diff --git a/net/spdy/chromium/http2_push_promise_index.h b/net/spdy/chromium/http2_push_promise_index.h index 61ce6e3..990c27e 100644 --- a/net/spdy/chromium/http2_push_promise_index.h +++ b/net/spdy/chromium/http2_push_promise_index.h
@@ -45,7 +45,8 @@ typedef std::map<GURL, WeakSessionList> UnclaimedPushedStreamMap; // A map of all SpdySessions owned by |this| that have an unclaimed pushed - // streams for a GURL. Might contain invalid WeakPtr's. + // streams for a GURL. SpdySession must unregister its streams before + // destruction, therefore all weak pointers must be valid. // A single SpdySession can only have at most one pushed stream for each GURL, // but it is possible that multiple SpdySessions have pushed streams for the // same GURL.
diff --git a/net/spdy/core/spdy_alt_svc_wire_format.cc b/net/spdy/core/spdy_alt_svc_wire_format.cc index 72e95fd..a0a3783 100644 --- a/net/spdy/core/spdy_alt_svc_wire_format.cc +++ b/net/spdy/core/spdy_alt_svc_wire_format.cc
@@ -78,7 +78,7 @@ } // Check for IETF format for advertising QUIC: // hq=":443";quic=51303338;quic=51303334 - const bool is_ietf_format_quic = (protocol_id.compare("hq") == 0); + const bool is_ietf_format_quic = (protocol_id == "hq"); c = percent_encoded_protocol_id_end; if (c == value.end()) { return false; @@ -145,11 +145,11 @@ if (c == parameter_value_begin) { return false; } - if (parameter_name.compare("ma") == 0) { + if (parameter_name == "ma") { if (!ParsePositiveInteger32(parameter_value_begin, c, &max_age)) { return false; } - } else if (!is_ietf_format_quic && parameter_name.compare("v") == 0) { + } else if (!is_ietf_format_quic && parameter_name == "v") { // Version is a comma separated list of positive integers enclosed in // quotation marks. Since it can contain commas, which are not // delineating alternative service entries, |parameters_end| and |c| can @@ -180,7 +180,7 @@ return false; } } - } else if (is_ietf_format_quic && parameter_name.compare("quic") == 0) { + } else if (is_ietf_format_quic && parameter_name == "quic") { // IETF format for advertising QUIC. Version is hex encoding of QUIC // version tag. Hex-encoded string should not include leading "0x" or // leading zeros. @@ -223,7 +223,7 @@ value.push_back(','); } // Check for IETF format for advertising QUIC. - const bool is_ietf_format_quic = (altsvc.protocol_id.compare("hq") == 0); + const bool is_ietf_format_quic = (altsvc.protocol_id == "hq"); // Percent escape protocol id according to // http://tools.ietf.org/html/rfc7230#section-3.2.6. for (char c : altsvc.protocol_id) {
diff --git a/net/ssl/OWNERS b/net/ssl/OWNERS index 44be2c5..0d1ddab3 100644 --- a/net/ssl/OWNERS +++ b/net/ssl/OWNERS
@@ -1 +1,5 @@ +davidben@chromium.org +mattm@chromium.org +svaldez@chromium.org + # COMPONENT: Internals>Network>SSL
diff --git a/remoting/ios/client_keyboard.mm b/remoting/ios/client_keyboard.mm index 1f545c1..518b57b2 100644 --- a/remoting/ios/client_keyboard.mm +++ b/remoting/ios/client_keyboard.mm
@@ -37,7 +37,7 @@ if (self) { _autocapitalizationType = UITextAutocapitalizationTypeNone; _autocorrectionType = UITextAutocorrectionTypeNo; - _autocorrectionType = UITextAutocorrectionTypeNo; + _keyboardAppearance = UIKeyboardAppearanceDefault; _keyboardType = UIKeyboardTypeDefault; _spellCheckingType = UITextSpellCheckingTypeNo;
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.cc b/remoting/protocol/webrtc_frame_scheduler_simple.cc index 08f78874..c96b2d8 100644 --- a/remoting/protocol/webrtc_frame_scheduler_simple.cc +++ b/remoting/protocol/webrtc_frame_scheduler_simple.cc
@@ -151,7 +151,7 @@ void WebrtcFrameSchedulerSimple::OnTargetBitrateChanged(int bandwidth_kbps) { DCHECK(thread_checker_.CalledOnValidThread()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = Now(); processing_time_estimator_.SetBandwidthKbps(bandwidth_kbps); pacing_bucket_.UpdateRate(bandwidth_kbps * 1000 / 8, now); encoder_bitrate_.SetBandwidthEstimate(bandwidth_kbps, now); @@ -183,7 +183,7 @@ WebrtcVideoEncoder::FrameParams* params_out) { DCHECK(thread_checker_.CalledOnValidThread()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = Now(); // Null |frame| indicates a capturer error. if (!frame) { @@ -259,7 +259,7 @@ DCHECK(frame_pending_); frame_pending_ = false; - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = Now(); if (frame_stats) { // Calculate |send_pending_delay| before refilling |pacing_bucket_|. @@ -289,9 +289,13 @@ } } +void WebrtcFrameSchedulerSimple::SetCurrentTimeForTest(base::TimeTicks now) { + fake_now_for_test_ = now; +} + void WebrtcFrameSchedulerSimple::ScheduleNextFrame() { DCHECK(thread_checker_.CalledOnValidThread()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = Now(); if (!encoder_ready_ || paused_ || pacing_bucket_.rate() == 0 || capture_callback_.is_null() || frame_pending_) { @@ -332,11 +336,16 @@ void WebrtcFrameSchedulerSimple::CaptureNextFrame() { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!frame_pending_); - last_capture_started_time_ = base::TimeTicks::Now(); + last_capture_started_time_ = Now(); processing_time_estimator_.StartFrame(); frame_pending_ = true; capture_callback_.Run(); } +base::TimeTicks WebrtcFrameSchedulerSimple::Now() { + return fake_now_for_test_.is_null() ? base::TimeTicks::Now() + : fake_now_for_test_; +} + } // namespace protocol } // namespace remoting
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.h b/remoting/protocol/webrtc_frame_scheduler_simple.h index 531dc37..04dbbc3 100644 --- a/remoting/protocol/webrtc_frame_scheduler_simple.h +++ b/remoting/protocol/webrtc_frame_scheduler_simple.h
@@ -42,6 +42,9 @@ void OnFrameEncoded(const WebrtcVideoEncoder::EncodedFrame* encoded_frame, HostFrameStats* frame_stats) override; + // Allows unit-tests to fake the current time. + void SetCurrentTimeForTest(base::TimeTicks now); + private: // Helper class used to calculate target encoder bitrate. class EncoderBitrateFilter { @@ -66,6 +69,13 @@ void ScheduleNextFrame(); void CaptureNextFrame(); + // Returns the current time according to base::TimeTicks::Now(), + // or a fake time provided by a unit-test. + base::TimeTicks Now(); + + // Non-null if a fake current time is set by unit-test. + base::TimeTicks fake_now_for_test_; + base::Closure capture_callback_; bool paused_ = false;
diff --git a/remoting/protocol/webrtc_frame_scheduler_unittest.cc b/remoting/protocol/webrtc_frame_scheduler_unittest.cc index 3a578e34..41a780e1 100644 --- a/remoting/protocol/webrtc_frame_scheduler_unittest.cc +++ b/remoting/protocol/webrtc_frame_scheduler_unittest.cc
@@ -9,6 +9,11 @@ #include "remoting/protocol/webrtc_dummy_video_encoder.h" #include "remoting/protocol/webrtc_frame_scheduler_simple.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" + +using webrtc::BasicDesktopFrame; +using webrtc::DesktopRect; +using webrtc::DesktopSize; namespace remoting { namespace protocol { @@ -17,9 +22,11 @@ public: WebrtcFrameSchedulerTest() : task_runner_(new base::TestSimpleTaskRunner()), - task_runner_handle_(task_runner_.get()) { + task_runner_handle_(task_runner_.get()), + now_(base::TimeTicks::Now()) { video_encoder_factory_.reset(new WebrtcDummyVideoEncoderFactory()); scheduler_.reset(new WebrtcFrameSchedulerSimple()); + scheduler_->SetCurrentTimeForTest(now_); scheduler_->Start(video_encoder_factory_.get(), base::Bind(&WebrtcFrameSchedulerTest::CaptureCallback, base::Unretained(this))); @@ -38,9 +45,11 @@ base::ThreadTaskRunnerHandle task_runner_handle_; std::unique_ptr<WebrtcDummyVideoEncoderFactory> video_encoder_factory_; - std::unique_ptr<WebrtcFrameScheduler> scheduler_; + std::unique_ptr<WebrtcFrameSchedulerSimple> scheduler_; bool capture_callback_called_ = false; + + base::TimeTicks now_; }; TEST_F(WebrtcFrameSchedulerTest, UpdateBitrateWhenPending) { @@ -62,6 +71,48 @@ EXPECT_FALSE(task_runner_->HasPendingTask()); } +TEST_F(WebrtcFrameSchedulerTest, EmptyFrameUpdate_ShouldNotBeSentImmediately) { + auto video_channel_observer = + video_encoder_factory_->get_video_channel_state_observer_for_tests(); + // Needed to avoid DCHECK in OnFrameCaptured(). + video_channel_observer->OnTargetBitrateChanged(100); + + WebrtcVideoEncoder::FrameParams outParams; + BasicDesktopFrame frame(DesktopSize(1, 1)); + // Initial capture, full frame. + frame.mutable_updated_region()->SetRect(DesktopRect::MakeWH(1, 1)); + scheduler_->OnFrameCaptured(&frame, &outParams); + // Empty frame. + frame.mutable_updated_region()->Clear(); + bool result = scheduler_->OnFrameCaptured(&frame, &outParams); + + // Should not be sent, because of throttling of empty frames. + EXPECT_FALSE(result); +}; + +TEST_F(WebrtcFrameSchedulerTest, EmptyFrameUpdate_ShouldBeSentAfter200ms) { + // Identical to the previous test, except it waits a short amount of time + // before the empty frame update. + auto video_channel_observer = + video_encoder_factory_->get_video_channel_state_observer_for_tests(); + video_channel_observer->OnTargetBitrateChanged(100); + + WebrtcVideoEncoder::FrameParams outParams; + BasicDesktopFrame frame(DesktopSize(1, 1)); + // Initial capture, full frame. + frame.mutable_updated_region()->SetRect(DesktopRect::MakeWH(1, 1)); + scheduler_->OnFrameCaptured(&frame, &outParams); + // Wait more than 200ms. + scheduler_->SetCurrentTimeForTest(now_ + + base::TimeDelta::FromMilliseconds(300)); + // Empty frame. + frame.mutable_updated_region()->Clear(); + bool result = scheduler_->OnFrameCaptured(&frame, &outParams); + + // Empty frames should be sent at the throttled rate. + EXPECT_TRUE(result); +}; + // TODO(sergeyu): Add more unittests. } // namespace protocol
diff --git a/services/resource_coordinator/memory_instrumentation/graph.cc b/services/resource_coordinator/memory_instrumentation/graph.cc index 509d0e4..6f9a68c3 100644 --- a/services/resource_coordinator/memory_instrumentation/graph.cc +++ b/services/resource_coordinator/memory_instrumentation/graph.cc
@@ -76,8 +76,10 @@ current->set_weak(weak); current->set_explicit(true); - // Add to the global guid map as well. - global_graph_->nodes_by_guid_.emplace(guid, current); + // Add to the global guid map as well if it exists. + if (!guid.empty()) + global_graph_->nodes_by_guid_.emplace(guid, current); + return current; }
diff --git a/services/resource_coordinator/memory_instrumentation/graph_processor.cc b/services/resource_coordinator/memory_instrumentation/graph_processor.cc index cb1defbe..96ba83d 100644 --- a/services/resource_coordinator/memory_instrumentation/graph_processor.cc +++ b/services/resource_coordinator/memory_instrumentation/graph_processor.cc
@@ -89,6 +89,18 @@ RemoveWeakNodesRecursively(pid_to_process.second->root()); } + // Sixth pass: account for tracing overhead in system memory allocators. + for (auto& pid_to_process : global_graph->process_dump_graphs()) { + Process* process = pid_to_process.second.get(); + if (process->FindNode("winheap")) { + AssignTracingOverhead("winheap", global_graph.get(), + pid_to_process.second.get()); + } else if (process->FindNode("malloc")) { + AssignTracingOverhead("malloc", global_graph.get(), + pid_to_process.second.get()); + } + } + return global_graph; } @@ -263,4 +275,31 @@ } } +// static +void GraphProcessor::AssignTracingOverhead(base::StringPiece allocator, + GlobalDumpGraph* global_graph, + Process* process) { + // This method should only be called if the allocator node exists. + DCHECK(process->FindNode(allocator)); + + // Check that the tracing dump exists and isn't already owning another node. + Node* tracing_node = process->FindNode("tracing"); + if (!tracing_node) + return; + + // This should be first edge associated with the tracing node. + DCHECK(!tracing_node->owns_edge()); + + // Create the node under the allocator to which tracing overhead can be + // assigned. + std::string child_name = + allocator.as_string() + "/allocated_objects/tracing_overhead"; + Node* child_node = process->CreateNode(MemoryAllocatorDumpGuid(), child_name, + false /* weak */); + + // Assign the overhead of tracing to the tracing node. + global_graph->AddNodeOwnershipEdge(tracing_node, child_node, + 0 /* importance */); +} + } // namespace memory_instrumentation \ No newline at end of file
diff --git a/services/resource_coordinator/memory_instrumentation/graph_processor.h b/services/resource_coordinator/memory_instrumentation/graph_processor.h index aa96435..3c47e69 100644 --- a/services/resource_coordinator/memory_instrumentation/graph_processor.h +++ b/services/resource_coordinator/memory_instrumentation/graph_processor.h
@@ -39,6 +39,10 @@ std::set<const GlobalDumpGraph::Node*>* nodes); static void RemoveWeakNodesRecursively(GlobalDumpGraph::Node* parent); + + static void AssignTracingOverhead(base::StringPiece allocator, + GlobalDumpGraph* global_graph, + GlobalDumpGraph::Process* process); }; } // namespace memory_instrumentation
diff --git a/services/resource_coordinator/memory_instrumentation/graph_processor_unittest.cc b/services/resource_coordinator/memory_instrumentation/graph_processor_unittest.cc index a9ebaee..08f7959 100644 --- a/services/resource_coordinator/memory_instrumentation/graph_processor_unittest.cc +++ b/services/resource_coordinator/memory_instrumentation/graph_processor_unittest.cc
@@ -17,6 +17,7 @@ using base::trace_event::ProcessMemoryDump; using Edge = GlobalDumpGraph::Edge; using Node = GlobalDumpGraph::Node; +using Process = GlobalDumpGraph::Process; class GraphProcessorTest : public testing::Test { public: @@ -34,6 +35,12 @@ void RemoveWeakNodesRecursively(Node* node) { GraphProcessor::RemoveWeakNodesRecursively(node); } + + void AssignTracingOverhead(base::StringPiece allocator, + GlobalDumpGraph* global_graph, + GlobalDumpGraph::Process* process) { + GraphProcessor::AssignTracingOverhead(allocator, global_graph, process); + } }; TEST_F(GraphProcessorTest, SmokeComputeMemoryGraph) { @@ -312,4 +319,26 @@ ASSERT_TRUE(owned.owned_by_edges()->empty()); } +TEST_F(GraphProcessorTest, AssignTracingOverhead) { + GlobalDumpGraph graph; + Process process(&graph); + + // Now add an allocator node. + Node allocator(&process, process.root()); + process.root()->InsertChild("malloc", &allocator); + + // If the tracing node does not exist, this should do nothing. + AssignTracingOverhead("malloc", &graph, &process); + ASSERT_TRUE(process.root()->GetChild("malloc")->children()->empty()); + + // Now add a tracing node. + Node tracing(&process, process.root()); + process.root()->InsertChild("tracing", &tracing); + + // This should now add a node with the allocator. + AssignTracingOverhead("malloc", &graph, &process); + ASSERT_NE(process.FindNode("malloc/allocated_objects/tracing_overhead"), + nullptr); +} + } // namespace memory_instrumentation \ No newline at end of file
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc index 0dc289e..53df25e 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc
@@ -4,6 +4,7 @@ #include "services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h" +#include "base/files/file_path.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/memory_dump_manager.h" @@ -152,7 +153,7 @@ if (memory_maps->size()) { traced_value->BeginDictionary("process_mmaps"); - MemoryMapsAsValueInto(*memory_maps, traced_value.get()); + MemoryMapsAsValueInto(*memory_maps, traced_value.get(), false); traced_value->EndDictionary(); } @@ -163,7 +164,8 @@ // static void TracingObserver::MemoryMapsAsValueInto( const std::vector<mojom::VmRegionPtr>& memory_maps, - TracedValue* value) { + TracedValue* value, + bool is_argument_filtering_enabled) { static const char kHexFmt[] = "%" PRIx64; // Refer to the design doc goo.gl/sxfFY8 for the semantics of these fields. @@ -177,7 +179,19 @@ value->SetString("ts", base::StringPrintf(kHexFmt, region->module_timestamp)); value->SetInteger("pf", region->protection_flags); - value->SetString("mf", region->mapped_file); + + // The module path will be the basename when argument filtering is + // activated. The whitelisting implemented for filtering string values + // doesn't allow rewriting. Therefore, a different path is produced here + // when argument filtering is activated. + if (is_argument_filtering_enabled) { + base::FilePath::StringType module_path(region->mapped_file.begin(), + region->mapped_file.end()); + value->SetString("mf", + base::FilePath(module_path).BaseName().AsUTF8Unsafe()); + } else { + value->SetString("mf", region->mapped_file); + } value->BeginDictionary("bs"); // byte stats value->SetString(
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h index 9252de5..8abbb575 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h
@@ -39,7 +39,8 @@ static void MemoryMapsAsValueInto( const std::vector<mojom::VmRegionPtr>& memory_maps, - base::trace_event::TracedValue* value); + base::trace_event::TracedValue* value, + bool is_argument_filtering_enabled); private: // Returns true if the dump mode is allowed for current tracing session.
diff --git a/services/video_capture/BUILD.gn b/services/video_capture/BUILD.gn index c4bde501..8e06e0b 100644 --- a/services/video_capture/BUILD.gn +++ b/services/video_capture/BUILD.gn
@@ -60,6 +60,7 @@ testonly = true sources = [ + "test/device_factory_provider_connectortest.cc", "test/device_factory_provider_test.cc", "test/device_factory_provider_test.h", "test/device_factory_provider_unittest.cc", @@ -85,6 +86,7 @@ "//media/capture/mojo:capture_types", "//services/service_manager/public/cpp", "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", "//testing/gmock", "//testing/gtest", "//ui/gfx:test_support",
diff --git a/services/video_capture/service_impl.cc b/services/video_capture/service_impl.cc index 4ac4eac1..55db691 100644 --- a/services/video_capture/service_impl.cc +++ b/services/video_capture/service_impl.cc
@@ -38,6 +38,9 @@ // Unretained |this| is safe because |registry_| is owned by |this|. base::Bind(&ServiceImpl::OnTestingControlsRequest, base::Unretained(this))); + + factory_provider_bindings_.set_connection_error_handler(base::BindRepeating( + &ServiceImpl::OnProviderClientDisconnected, base::Unretained(this))); } void ServiceImpl::OnBindInterface( @@ -54,18 +57,17 @@ return true; } +void ServiceImpl::SetFactoryProviderClientDisconnectedObserver( + const base::RepeatingClosure& observer_cb) { + factory_provider_client_disconnected_cb_ = observer_cb; +} + void ServiceImpl::OnDeviceFactoryProviderRequest( mojom::DeviceFactoryProviderRequest request) { DCHECK(thread_checker_.CalledOnValidThread()); - mojo::MakeStrongBinding( - base::MakeUnique<DeviceFactoryProviderImpl>( - ref_factory_->CreateRef(), - // Use of unretained |this| is safe, because the - // VideoCaptureServiceImpl has shared ownership of |this| via the - // reference created by ref_factory->CreateRef(). - base::Bind(&ServiceImpl::SetShutdownDelayInSeconds, - base::Unretained(this))), - std::move(request)); + LazyInitializeDeviceFactoryProvider(); + factory_provider_bindings_.AddBinding(device_factory_provider_.get(), + std::move(request)); } void ServiceImpl::OnTestingControlsRequest( @@ -102,4 +104,28 @@ } } +void ServiceImpl::LazyInitializeDeviceFactoryProvider() { + if (device_factory_provider_) + return; + + device_factory_provider_ = std::make_unique<DeviceFactoryProviderImpl>( + ref_factory_->CreateRef(), + // Use of unretained |this| is safe, because the + // VideoCaptureServiceImpl has shared ownership of |this| via the + // reference created by ref_factory->CreateRef(). + base::Bind(&ServiceImpl::SetShutdownDelayInSeconds, + base::Unretained(this))); +} + +void ServiceImpl::OnProviderClientDisconnected() { + // Reset factory provider if no client is connected. + if (factory_provider_bindings_.empty()) { + device_factory_provider_.reset(); + } + + if (!factory_provider_client_disconnected_cb_.is_null()) { + factory_provider_client_disconnected_cb_.Run(); + } +} + } // namespace video_capture
diff --git a/services/video_capture/service_impl.h b/services/video_capture/service_impl.h index b9249939..011a5e9 100644 --- a/services/video_capture/service_impl.h +++ b/services/video_capture/service_impl.h
@@ -12,6 +12,7 @@ #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context_ref.h" +#include "services/video_capture/device_factory_provider_impl.h" #include "services/video_capture/public/interfaces/device_factory_provider.mojom.h" #include "services/video_capture/public/interfaces/testing_controls.mojom.h" @@ -33,6 +34,9 @@ mojo::ScopedMessagePipeHandle interface_pipe) override; bool OnServiceManagerConnectionLost() override; + void SetFactoryProviderClientDisconnectedObserver( + const base::RepeatingClosure& observer_cb); + private: void OnDeviceFactoryProviderRequest( mojom::DeviceFactoryProviderRequest request); @@ -40,6 +44,8 @@ void SetShutdownDelayInSeconds(float seconds); void MaybeRequestQuitDelayed(); void MaybeRequestQuit(); + void LazyInitializeDeviceFactoryProvider(); + void OnProviderClientDisconnected(); #if defined(OS_WIN) // COM must be initialized in order to access the video capture devices. @@ -47,7 +53,12 @@ #endif float shutdown_delay_in_seconds_; service_manager::BinderRegistry registry_; + mojo::BindingSet<mojom::DeviceFactoryProvider> factory_provider_bindings_; + std::unique_ptr<DeviceFactoryProviderImpl> device_factory_provider_; std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; + // Callback to be invoked when a provider client is disconnected. Mainly used + // for testing. + base::RepeatingClosure factory_provider_client_disconnected_cb_; base::ThreadChecker thread_checker_; base::WeakPtrFactory<ServiceImpl> weak_factory_;
diff --git a/services/video_capture/test/device_factory_provider_connectortest.cc b/services/video_capture/test/device_factory_provider_connectortest.cc new file mode 100644 index 0000000..61b6264 --- /dev/null +++ b/services/video_capture/test/device_factory_provider_connectortest.cc
@@ -0,0 +1,77 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/run_loop.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" +#include "media/base/media_switches.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" +#include "services/video_capture/public/interfaces/constants.mojom.h" +#include "services/video_capture/public/interfaces/device_factory_provider.mojom.h" +#include "services/video_capture/service_impl.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace video_capture { + +using testing::Exactly; +using testing::_; +using testing::Invoke; +using testing::InvokeWithoutArgs; + +// Test fixture that creates a video_capture::ServiceImpl and sets up a +// local service_manager::Connector through which client code can connect to +// it. +class DeviceFactoryProviderConnectorTest : public ::testing::Test { + public: + DeviceFactoryProviderConnectorTest() {} + ~DeviceFactoryProviderConnectorTest() override {} + + void SetUp() override { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kUseFakeDeviceForMediaStream); + std::unique_ptr<ServiceImpl> service_impl = std::make_unique<ServiceImpl>(); + service_impl_ = service_impl.get(); + connector_factory_ = + base::MakeUnique<service_manager::TestConnectorFactory>( + std::move(service_impl)); + connector_ = connector_factory_->CreateConnector(); + connector_->BindInterface(mojom::kServiceName, &factory_provider_); + factory_provider_->SetShutdownDelayInSeconds(0.0f); + factory_provider_->ConnectToDeviceFactory(mojo::MakeRequest(&factory_)); + } + + protected: + ServiceImpl* service_impl_; + mojom::DeviceFactoryProviderPtr factory_provider_; + mojom::DeviceFactoryPtr factory_; + base::MockCallback<mojom::DeviceFactory::GetDeviceInfosCallback> + device_info_receiver_; + std::unique_ptr<service_manager::Connector> connector_; + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + std::unique_ptr<service_manager::TestConnectorFactory> connector_factory_; +}; + +TEST_F(DeviceFactoryProviderConnectorTest, ServiceNotQuitWhenClientConnected) { + base::RunLoop wait_loop; + + mojom::DeviceFactoryProviderPtr leftover_provider_; + connector_->BindInterface(mojom::kServiceName, &leftover_provider_); + service_impl_->SetFactoryProviderClientDisconnectedObserver( + wait_loop.QuitClosure()); + + factory_.reset(); + factory_provider_.reset(); + + wait_loop.Run(); + + // Verify that the original provider is not bound while the + // |leftover_provider| is still bound. + EXPECT_FALSE(factory_provider_.is_bound()); + EXPECT_TRUE(leftover_provider_.is_bound()); +} + +} // namespace video_capture
diff --git a/services/video_capture/test/device_factory_provider_unittest.cc b/services/video_capture/test/device_factory_provider_unittest.cc index 743512a..8aa3b36b 100644 --- a/services/video_capture/test/device_factory_provider_unittest.cc +++ b/services/video_capture/test/device_factory_provider_unittest.cc
@@ -71,11 +71,11 @@ wait_loop.Run(); } -// Tests that the service requests to be closed when the last client disconnects +// Tests that the service requests to be closed when the only client disconnects // after not having done anything other than obtaining a connection to the // fake device factory. TEST_F(VideoCaptureServiceDeviceFactoryProviderTest, - ServiceQuitsWhenNoClientConnected) { + ServiceQuitsWhenSingleClientDisconnected) { base::RunLoop wait_loop; EXPECT_CALL(*service_state_observer_, OnServiceStopped(_)) .WillOnce(Invoke([&wait_loop](const service_manager::Identity& identity) { @@ -90,4 +90,28 @@ wait_loop.Run(); } +// Tests that the service requests to be closed when the all clients disconnect +// after not having done anything other than obtaining a connection to the +// fake device factory. +TEST_F(VideoCaptureServiceDeviceFactoryProviderTest, + ServiceQuitsWhenAllClientsDisconnected) { + // Bind another client to the DeviceFactoryProvider interface. + mojom::DeviceFactoryProviderPtr unused_provider; + connector()->BindInterface(mojom::kServiceName, &unused_provider); + + base::RunLoop wait_loop; + EXPECT_CALL(*service_state_observer_, OnServiceStopped(_)) + .WillOnce(Invoke([&wait_loop](const service_manager::Identity& identity) { + if (identity.name() == mojom::kServiceName) + wait_loop.Quit(); + })); + + // Exercise: Disconnect from service by discarding our references to it. + factory_.reset(); + factory_provider_.reset(); + unused_provider.reset(); + + wait_loop.Run(); +} + } // namespace video_capture
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 85dc544..ce6f291 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -204,10 +204,6 @@ #define SK_USE_LEGACY_DISTANCE_FIELDS #endif -#ifndef SK_DISABLE_DEFERRED_PROXIES -#define SK_DISABLE_DEFERRED_PROXIES -#endif - #ifndef SK_SUPPORT_LEGACY_BLUR_IMAGE #define SK_SUPPORT_LEGACY_BLUR_IMAGE #endif @@ -228,10 +224,6 @@ #define SK_COLOR_SPACE_XFORM_LEGACY_PIPELINE #endif -#ifndef SK_LEGACY_LOWP_STAGES -#define SK_LEGACY_LOWP_STAGES -#endif - ///////////////////////// Imported from BUILD.gn and skia_common.gypi /* In some places Skia can use static initializers for global initialization,
diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc index c9254d7b..19d890a 100644 --- a/storage/browser/blob/blob_storage_context.cc +++ b/storage/browser/blob/blob_storage_context.cc
@@ -169,7 +169,10 @@ } // Validate our reference has good offset & length. - if (input_element.offset() + length > ref_entry->total_size()) { + uint64_t end_byte; + if (!base::CheckAdd(input_element.offset(), length) + .AssignIfValid(&end_byte) || + end_byte > ref_entry->total_size()) { status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; return; }
diff --git a/storage/browser/blob/blob_storage_context_unittest.cc b/storage/browser/blob/blob_storage_context_unittest.cc index a0b699f4..8d11c70 100644 --- a/storage/browser/blob/blob_storage_context_unittest.cc +++ b/storage/browser/blob/blob_storage_context_unittest.cc
@@ -889,6 +889,24 @@ EXPECT_EQ(0lu, context_->memory_controller().disk_usage()); } +TEST_F(BlobStorageContextTest, NegativeSlice) { + const std::string kId1("id1"); + const std::string kId2("id2"); + + std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kId1); + + EXPECT_EQ(1lu, context_->memory_controller().memory_usage()); + + BlobDataBuilder builder(kId2); + builder.AppendBlob(kId1, static_cast<uint64_t>(-10), 11); + std::unique_ptr<BlobDataHandle> handle2 = context_->BuildBlob( + builder, BlobStorageContext::TransportAllowedCallback()); + + EXPECT_TRUE(handle2->IsBroken()); + EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, + handle2->GetBlobStatus()); +} + // TODO(michaeln): tests for the deprecated url stuff } // namespace storage
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html index 26e2e50..a1e47d13 100644 --- a/styleguide/c++/c++11.html +++ b/styleguide/c++/c++11.html
@@ -609,6 +609,14 @@ </tr> <tr> +<td>Heterogeneous lookup in associative containers</td> +<td><code><i>// Does not construct an std::string to use as the lookup key.</i><br>std::map<std::string, int, std::less<>> map;<br>auto it = map.find("answer");</code></td> +<td>Allows searching associative containers without converting the key to exactly match the stored key type, assuming a suitable comparator exists.</td> +<td><a href="http://en.cppreference.com/w/cpp/utility/functional/less">std::less</a></td> +<td><a href="https://groups.google.com/a/chromium.org/d/msg/cxx/ow7hmdDm4yw/EDEvBRi_BQAJ">Discussion thread</a></td> +</tr> + +<tr> <td><code>std::integer_sequence</code></td> <td><code>template <size_t... I><br>void CallFooImpl(std::index_sequence<I...>) {<br> Foo(I...);<br>}<br><br>template <size_t N><br>void CallFoo() {<br> CallFooImpl(std::make_index_sequence<N>());<br>}</code></td> <td>Template metaprogramming utility for representing a sequence of integers as a type.</td> @@ -1193,14 +1201,6 @@ </tr> <tr> -<td>Heterogeneous lookup in associative containers</td> -<td><code><i>// Does not construct an std::string to use as the lookup key.</i><br>std::map<std::string, int, std::less<>> map;<br>auto it = map.find("answer");</code></td> -<td>Allows searching associative containers without converting the key to exactly match the stored key type, assuming a suitable comparator exists.</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/functional/less">std::less</a></td> -<td></td> -</tr> - -<tr> <td><code>std::complex</code> literals</td> <td><code>using namespace std::complex_literals;<br>std::complex<double> c = 2.0 + 0.5i;</code></td> <td>Allows <code>std::complex</code> objects to be more easily constructed.</td>
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index fa943c7..754c66f1 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -3578,6 +3578,46 @@ "shards": 5 }, "test": "chrome_public_test_apk" + }, + { + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "webview_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "OPR6.170623.012", + "device_type": "marlin" + } + ], + "expiration": 10800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "shards": 5 + }, + "test": "webview_instrumentation_test_apk" } ] },
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 0b3e658..2be015e4 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -3820,9 +3820,6 @@ "test": "media_unittests" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_common_unittests.filter" - ], "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4130,13 +4127,7 @@ "content_unittests", "gl_unittests", "headless_shell", - "ipc_tests", "media_unittests", - "mojo_common_unittests", - "mojo_js_unittests", - "mojo_public_bindings_unittests", - "mojo_public_system_unittests", - "mojo_system_unittests", "net_unittests", "skia_unittests", "service_manager_unittests", @@ -4157,6 +4148,51 @@ "can_use_on_swarming_builders": true }, "test": "crypto_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ipc_tests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ipc_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "mojo_common_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_js_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "mojo_js_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "mojo_public_bindings_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "mojo_public_system_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_system_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "mojo_system_unittests" } ] },
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 1669fc7..a451dc5d 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -4117,11 +4117,12 @@ "--test-launcher-retry-limit=0" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4135,11 +4136,12 @@ "--no-xvfb" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4151,11 +4153,12 @@ "--use-gpu-in-tests" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4165,13 +4168,21 @@ { "args": [ "--enable-gpu", - "--no-xvfb", + "--test-launcher-bot-mode", "--test-launcher-jobs=1", - "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*" + "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*", + "--no-xvfb" ], "name": "tab_capture_end2end_tests", "swarming": { - "can_use_on_swarming_builders": false + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ] }, "test": "browser_tests", "use_xvfb": false @@ -4182,11 +4193,12 @@ "--use-cmd-decoder=validating" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4199,11 +4211,12 @@ "--no-xvfb" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4215,11 +4228,12 @@ "--use-gpu-in-tests" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4228,11 +4242,12 @@ }, { "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] }, @@ -4243,6 +4258,24 @@ "isolated_scripts": [ { "args": [ + "-v", + "--one-frame-only" + ], + "isolate_name": "angle_perftests", + "name": "angle_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=release", @@ -4256,11 +4289,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4280,11 +4314,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4304,11 +4339,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4328,11 +4364,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4356,11 +4393,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4386,11 +4424,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4424,11 +4463,12 @@ "--download-refimg-from-cloud-storage" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4448,11 +4488,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4472,11 +4513,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ] } @@ -4488,6 +4530,34 @@ "--browser=release", "--passthrough", "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl2_conformance_gl_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ], + "shards": 20 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", "--webgl-conformance-version=2.0.1", "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" @@ -4498,11 +4568,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ], "shards": 20 @@ -4523,11 +4594,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ], "shards": 2 @@ -4548,11 +4620,12 @@ "telemetry_gpu_integration_test" ], "swarming": { - "can_use_on_swarming_builders": false, + "can_use_on_swarming_builders": true, "dimension_sets": [ { - "gpu": "10de:1cb3", - "os": "Ubuntu" + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" } ], "shards": 2 @@ -17956,6 +18029,708 @@ } ] }, + "Win7 Release (NVIDIA Quadro P400)": { + "gtest_tests": [ + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_end2end_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_unittests", + "use_xvfb": false + }, + { + "args": [ + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_white_box_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "audio_unittests", + "use_xvfb": false + }, + { + "args": [ + "--enable-gpu", + "--test-launcher-bot-mode", + "--test-launcher-jobs=1", + "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*" + ], + "name": "tab_capture_end2end_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "browser_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-cmd-decoder=validating" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gl_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-cmd-decoder=passthrough" + ], + "name": "gl_tests_passthrough", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gl_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gl_unittests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-angle=d3d9" + ], + "name": "gles2_conform_d3d9_test", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-angle=gl", + "--disable-gpu-sandbox" + ], + "name": "gles2_conform_gl_test", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gpu_unittests", + "use_xvfb": false + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "swiftshader_unittests", + "use_xvfb": false + }, + { + "args": [ + "--use-angle=d3d11", + "--use-test-data-path", + "--test_video_data=test-25fps.h264:320:240:250:258:::1" + ], + "name": "video_decode_accelerator_d3d11_unittest", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "video_decode_accelerator_unittest", + "use_xvfb": false + }, + { + "args": [ + "--use-angle=d3d9", + "--use-test-data-path", + "--test_video_data=test-25fps.h264:320:240:250:258:::1" + ], + "name": "video_decode_accelerator_d3d9_unittest", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "video_decode_accelerator_unittest", + "use_xvfb": false + }, + { + "args": [ + "--use-angle=gl", + "--use-test-data-path", + "--test_video_data=test-25fps.h264:320:240:250:258:::1" + ], + "name": "video_decode_accelerator_gl_unittest", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + }, + "test": "video_decode_accelerator_unittest", + "use_xvfb": false + } + ], + "isolated_scripts": [ + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "context_lost_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "depth_capture", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "depth_capture_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "gpu_process_launch_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "hardware_accelerated_feature_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--expected-vendor-id", + "10de", + "--expected-device-id", + "1cb3" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "info_collection_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--os-type", + "win", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "maps_pixel_test", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "win", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "pixel_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "screenshot_sync_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "trace_test", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "trace_test", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl2_conformance_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 20 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_d3d11_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_d3d9_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=validating" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_d3d9_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_gl_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8792", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + } + ] + }, "Win7 Release (NVIDIA)": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index b30955f1..678a877 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -83,8 +83,6 @@ "isolated_scripts": [ { "args": [ - "--bot", - "swarm823-c4", "--builder", "One Buildbot Step Test Builder", "-v", @@ -102,7 +100,6 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "swarm823-c4", "pool": "Chrome-perf-fyi" } ], @@ -110,6 +107,17 @@ "hard_timeout": 10800, "ignore_task_failure": false, "io_timeout": 3600 + }, + "trigger_script": { + "args": [ + "--bot-id", + "swarm823-c4", + "--bot-id", + "swarm846-c4", + "--bot-id", + "swarm847-c4" + ], + "script": "//tools/perf/perf_device_trigger.py" } } ]
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 7236cb4..898edc25 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -78,7 +78,6 @@ "//testing/buildbot/filters/fuchsia.base_unittests.filter", "//testing/buildbot/filters/fuchsia.content_unittests.filter", "//testing/buildbot/filters/fuchsia.ipc_tests.filter", - "//testing/buildbot/filters/fuchsia.mojo_common_unittests.filter", "//testing/buildbot/filters/fuchsia.mojo_js_unittests.filter", "//testing/buildbot/filters/fuchsia.mojo_system_unittests.filter", "//testing/buildbot/filters/fuchsia.net_unittests.filter",
diff --git a/testing/buildbot/filters/ash_unittests_mash.filter b/testing/buildbot/filters/ash_unittests_mash.filter index 9d775e1..b4f4ee6 100644 --- a/testing/buildbot/filters/ash_unittests_mash.filter +++ b/testing/buildbot/filters/ash_unittests_mash.filter
@@ -144,6 +144,12 @@ # TODO: Needs virtual keyboard. http://crbug.com/616909 -TrayIMETest.HidesOnA11yEnabled -TrayIMETest.PerformActionOnDetailedView +# TODO: wire up mirroring and unified display. +# http://crbug.com/770243. +-UnifiedMouseWarpControllerTest.BoundaryTest +-UnifiedMouseWarpControllerTest.BoundaryAndWarpSimpleTest +-UnifiedMouseWarpControllerTest.BoundaryTestGrid +-UnifiedMouseWarpControllerTest.WarpMouse # TODO: Needs virtual keyboard. http://crbug.com/616909 -VirtualKeyboardAlwaysOnTopControllerTest.NotifyKeyboardBoundsChanged -VirtualKeyboardControllerAlwaysEnabledTest.DoesNotSuppressKeyboard
diff --git a/testing/buildbot/filters/ash_unittests_mus.filter b/testing/buildbot/filters/ash_unittests_mus.filter index 43c2af0f..21f7742f 100644 --- a/testing/buildbot/filters/ash_unittests_mus.filter +++ b/testing/buildbot/filters/ash_unittests_mus.filter
@@ -7,10 +7,15 @@ -TouchCalibratorControllerTest.CustomCalibration -TouchCalibratorControllerTest.CustomCalibrationInvalidTouchId -TouchCalibratorControllerTest.TouchDeviceIdIsSet - # TODO: fix this. It fails because GL_OES_texture_npot is not supported. # http://crbug.com/775067. -WorkspaceLayoutManagerBackdropTest.BackdropTest +# TODO: wire up mirroring and unified display. +# http://crbug.com/770243. +-UnifiedMouseWarpControllerTest.BoundaryTestGrid +-UnifiedMouseWarpControllerTest.WarpMouse +-UnifiedMouseWarpControllerTest.BoundaryAndWarpSimpleTest + # When adding new exclusions be sure to file bug with reason. Group with the # above if applicable.
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter index 524604c..beb12a61 100644 --- a/testing/buildbot/filters/fuchsia.base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -62,6 +62,3 @@ # https://crbug.com/779645 - requires ability to set address-space limits. -PartitionAllocTest.RepeatedReturnNull -PartitionAllocTest.RepeatedReturnNullDirect - -# https://crbug.com/779668 - fails under Fuchsia/ARM64 due to Time::Now issue. --BuildTime.InThePast
diff --git a/testing/buildbot/filters/fuchsia.mojo_common_unittests.filter b/testing/buildbot/filters/fuchsia.mojo_common_unittests.filter deleted file mode 100644 index dbab0f3e..0000000 --- a/testing/buildbot/filters/fuchsia.mojo_common_unittests.filter +++ /dev/null
@@ -1,5 +0,0 @@ -# TODO(fuchsia): Fix the tests and delete this file. crbug.com/740791 - -# These tests depend upon support for passing file-descriptors over IPC. -# See crbug.com/754029. --CommonCustomTypesTest.File
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index 62d1327..fd345df3 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -2,58 +2,6 @@ # See https://crbug.com/769401 # Crashed tests that haven't been categorized. --AdsPageLoadMetricsObserverBrowserTest.DocOverwritesNavigation --AdsPageLoadMetricsObserverBrowserTest.SubresourceFilter --CrExtensionsCodeSectionTest.Layout --CrExtensionsDetailViewTest.ClickableElements --CrExtensionsDetailViewTest.IndicatorTest --CrExtensionsDetailViewTest.Layout --CrExtensionsDetailViewTest.Warnings --CrExtensionsErrorPageTest.CodeSection --CrExtensionsErrorPageTest.ErrorSelection --CrExtensionsErrorPageTest.Layout --CrExtensionsItemListTest.NoItems --CrExtensionsItemListTest.NoSearchResults --CrExtensionsItemsTest.ClickableItems --CrExtensionsItemsTest.DeveloperState --CrExtensionsItemsTest.EnableToggle --CrExtensionsItemsTest.NormalState --CrExtensionsItemsTest.RemoveButton --CrExtensionsItemsTest.SourceIndicator --CrExtensionsItemsTest.Warnings --CrExtensionsLoadErrorTest.CodeSection --CrExtensionsLoadErrorTest.Interaction --CrExtensionsManagerTestWithIdQueryParam.NavigationToDetails --CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.ChangePages --CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.ItemListVisibility --CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.SplitItems --CrExtensionsManagerTest.ItemOrder --CrExtensionsManagerTest.UpdateItemData --CrExtensionsNavigationHelperTest.Basic --CrExtensionsNavigationHelperTest.Conversion --CrExtensionsNavigationHelperTest.PushAndReplaceState --CrExtensionsNavigationHelperTest.SupportedRoutes --CrExtensionsOptionsDialogTest.Layout --CrExtensionsPackDialogTest.Interaction --CrExtensionsPackDialogTest.PackError --CrExtensionsPackDialogTest.PackSuccess --CrExtensionsPackDialogTest.PackWarning --CrExtensionsServiceTest.ProfileSettings --CrExtensionsServiceTest.ToggleEnable --CrExtensionsServiceTest.ToggleIncognito --CrExtensionsServiceTest.Uninstall --CrExtensionsSidebarTest.LayoutAndClickHandlers --CrExtensionsSidebarTest.SetSelected --CrExtensionsShortcutTest.Basic --CrExtensionsShortcutTest.Layout --CrExtensionsToggleRowTest.ToggleRowTest --CrExtensionsToolbarTest.ClickHandlers --CrExtensionsToolbarTest.Layout --CrExtensionsViewManagerTest.EventFiringTest --CrExtensionsViewManagerTest.VisibilityTest --CredentialManagerBrowserTest.StoreInUnloadHandler_SameSite_OnDemandMojoPipe --DiceMigrationBrowserTest.Signin --DiceMigrationBrowserTest.Signout -ExtensionsA11yTestFixture.BASIC_EXTENSIONS_region -LocalNTPDoodleTest.ShouldAnimateLogoWhenClicked -LocalNTPJavascriptTest.SimpleJavascriptTests @@ -84,9 +32,6 @@ -MSE_ExternalClearKey_Mojo/EncryptedMediaTest.Playback_VP9Video_WebM_Fullsample/0 -MSE_ExternalClearKey_Mojo/EncryptedMediaTest.Playback_VP9Video_WebM_Subsample/0 -MSE_ExternalClearKey_Mojo/EncryptedMediaTest.PolicyCheck/0 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchHistograms/1 --PolicyTest.BookmarkBarEnabled --PolicyTest.HomepageLocation -PredictorBrowserTest.CrossSiteNoReferrerNoPredictionAfterOneNavigation -PredictorBrowserTest.CrossSiteRedirectNoPredictionWithPath -PredictorBrowserTest.CrossSiteSimplePredictionAfterOneNavigationNoInterceptor @@ -114,23 +59,6 @@ -ResourcePrefetchPredictorBrowserTest.TabIdBehavingAsExpected -ResourcePrefetchPredictorPrefetchingBrowserTest.Redirect -ResourcePrefetchPredictorPrefetchingBrowserTest.Simple --SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/2 --SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/3 --SSLUITestCommittedInterstitials.ErrorPageType --SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/0 --SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/1 --SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/2 --SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/3 --SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/4 --SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/5 --SafeBrowsingTriggeredInterceptingBrowserTest.AbusiveMetadata --SafeBrowsingTriggeredPopupBlockerBrowserTest.BlockCreatingNewWindows --SafeBrowsingTriggeredPopupBlockerBrowserTest.BlockOpenURLFromTab --SafeBrowsingTriggeredPopupBlockerBrowserTest.BlockOpenURLFromTabInIframe --SafeBrowsingTriggeredPopupBlockerBrowserTest.MultipleNavigations --SafeBrowsingTriggeredPopupBlockerBrowserTest.WarningAllowCreatingNewWindows_LogsToConsole --SafeBrowsingTriggeredPopupBlockerBrowserTest.WarningDoNotBlockCreatingNewWindows_LogsToConsole --SafeBrowsingTriggeredInterceptingBrowserTest.AbusiveMetadata -SavePageBrowserTest.SaveUnauthorizedResource -ServiceWorkerPaymentAppFactoryBrowserTest.AllOringsSupported -ServiceWorkerPaymentAppFactoryBrowserTest.SupportedOrigin @@ -391,6 +319,8 @@ -DiceFixAuthErrorsBrowserTest.SigninAccountMismatch -DiceFixAuthErrorsBrowserTest.SigninNoAuthError -DiceFixAuthErrorsBrowserTest.Signout +-DiceMigrationBrowserTest.Signin +-DiceMigrationBrowserTest.Signout -DidChangeVisibleSecurityStateTest.DidChangeVisibleSecurityStateObserver -DidChangeVisibleSecurityStateTest.DidChangeVisibleSecurityStateObserverGoBack -DisabledSignInIsolationBrowserTest.SyntheticTrial @@ -2070,6 +2000,8 @@ -WindowOpenApiTest.WindowOpenSized # Failed tests that haven't been categorized. +-AdsPageLoadMetricsObserverBrowserTest.DocOverwritesNavigation +-AdsPageLoadMetricsObserverBrowserTest.SubresourceFilter -BitmapFetcherBrowserTest.StartTest -BrowserNavigatorTest.CloseSingletonTab -BrowserNavigatorTest.Disposition_CurrentTab @@ -2102,7 +2034,55 @@ -ContentFaviconDriverTest.ReloadBypassingCache -CookiePolicyBrowserTest.AllowFirstPartyCookies -CookiePolicyBrowserTest.AllowFirstPartyCookiesRedirect +-CrExtensionsCodeSectionTest.Layout +-CrExtensionsDetailViewTest.ClickableElements +-CrExtensionsDetailViewTest.IndicatorTest +-CrExtensionsDetailViewTest.Layout +-CrExtensionsDetailViewTest.Warnings +-CrExtensionsErrorPageTest.CodeSection +-CrExtensionsErrorPageTest.ErrorSelection +-CrExtensionsErrorPageTest.Layout -CrExtensionsItemListTest.Filtering +-CrExtensionsItemListTest.NoItems +-CrExtensionsItemListTest.NoSearchResults +-CrExtensionsItemsTest.ClickableItems +-CrExtensionsItemsTest.DeveloperState +-CrExtensionsItemsTest.EnableToggle +-CrExtensionsItemsTest.NormalState +-CrExtensionsItemsTest.RemoveButton +-CrExtensionsItemsTest.SourceIndicator +-CrExtensionsItemsTest.Warnings +-CrExtensionsLoadErrorTest.CodeSection +-CrExtensionsLoadErrorTest.Interaction +-CrExtensionsManagerTestWithIdQueryParam.NavigationToDetails +-CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.ChangePages +-CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.ItemListVisibility +-CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.SplitItems +-CrExtensionsManagerTest.ItemOrder +-CrExtensionsManagerTest.UpdateItemData +-CrExtensionsNavigationHelperTest.Basic +-CrExtensionsNavigationHelperTest.Conversion +-CrExtensionsNavigationHelperTest.PushAndReplaceState +-CrExtensionsNavigationHelperTest.SupportedRoutes +-CrExtensionsOptionsDialogTest.Layout +-CrExtensionsPackDialogTest.Interaction +-CrExtensionsPackDialogTest.PackError +-CrExtensionsPackDialogTest.PackSuccess +-CrExtensionsPackDialogTest.PackWarning +-CrExtensionsServiceTest.ProfileSettings +-CrExtensionsServiceTest.ToggleEnable +-CrExtensionsServiceTest.ToggleIncognito +-CrExtensionsServiceTest.Uninstall +-CrExtensionsSidebarTest.LayoutAndClickHandlers +-CrExtensionsSidebarTest.SetSelected +-CrExtensionsShortcutTest.Basic +-CrExtensionsShortcutTest.Layout +-CrExtensionsToggleRowTest.ToggleRowTest +-CrExtensionsToolbarTest.ClickHandlers +-CrExtensionsToolbarTest.Layout +-CrExtensionsViewManagerTest.EventFiringTest +-CrExtensionsViewManagerTest.VisibilityTest +-CredentialManagerBrowserTest.StoreInUnloadHandler_SameSite_OnDemandMojoPipe -DataProxyScriptBrowserTest.Verify -DeclarativeContentApiTest.RulesAddedFromManifest -DevToolsExperimentalExtensionTest.TestDevToolsExperimentalExtensionAPI @@ -2225,6 +2205,7 @@ -NewTabPageInterceptorTest.FailedRequestInterception -NewTabPageInterceptorTest.NoInterception -NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchHistograms/0 +-NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchHistograms/1 -OutOfProcessPPAPITest.FileRef1 -OutOfProcessPPAPITest.FileRef2 -OutOfProcessPPAPITest.URLLoader1 @@ -2247,6 +2228,8 @@ -PaymentRequestWebContentsManagerTest.MultipleRequests -PlatformAppBrowserTest.Isolation -PlatformAppBrowserTest.RunningAppsAreRecorded +-PolicyTest.BookmarkBarEnabled +-PolicyTest.HomepageLocation -PolicyUITest.SendPolicyValues -ProcessManagerBrowserTest.ExtensionFrameNavigatesToParentSiteInstance -ProcessManagerBrowserTest.ExtensionHostCreation @@ -2296,6 +2279,7 @@ -SSLUITest.TestRefNavigation -SSLUITest.TestUnsafeContentsWithUserException -SSLUITest.TestUnsafeImageWithUserException +-SSLUITestCommittedInterstitials.ErrorPageType -SSLUITestIgnoreCertErrorsBySPKIHTTPS.TestHTTPS -SSLUITestIgnoreCertErrorsBySPKIHTTPS.TestInsecureSubresource -SSLUITestIgnoreLocalhostCertErrors.TestNoInterstitialOnLocalhost @@ -2307,7 +2291,22 @@ -SSLUITestWithExtendedReporting.TestBrokenHTTPSProceedReportingWithNoOptIn -SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/0 -SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/1 +-SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/2 +-SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/3 +-SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/0 +-SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/1 +-SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/2 +-SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/3 +-SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/4 +-SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.SecurityStateGoBackOnSubresourceInterstitial/5 -SafeBrowsingServiceTest.Prefetch +-SafeBrowsingTriggeredInterceptingBrowserTest.AbusiveMetadata +-SafeBrowsingTriggeredPopupBlockerBrowserTest.BlockCreatingNewWindows +-SafeBrowsingTriggeredPopupBlockerBrowserTest.BlockOpenURLFromTab +-SafeBrowsingTriggeredPopupBlockerBrowserTest.BlockOpenURLFromTabInIframe +-SafeBrowsingTriggeredPopupBlockerBrowserTest.MultipleNavigations +-SafeBrowsingTriggeredPopupBlockerBrowserTest.WarningAllowCreatingNewWindows_LogsToConsole +-SafeBrowsingTriggeredPopupBlockerBrowserTest.WarningDoNotBlockCreatingNewWindows_LogsToConsole -SafeJsonParserTest.Parse -SecurityStateTabHelperTest.BrokenHTTPS -SecurityStateTabHelperTest.MixedContentWithSHA1Cert
diff --git a/testing/libfuzzer/proto/BUILD.gn b/testing/libfuzzer/proto/BUILD.gn new file mode 100644 index 0000000..e4addeda --- /dev/null +++ b/testing/libfuzzer/proto/BUILD.gn
@@ -0,0 +1,37 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/protobuf/proto_library.gni") + +copy("json_proto_copy") { + sources = [ + "json.proto", + ] + outputs = [ + "$root_gen_dir" + "/testing/libfuzzer/proto/json.proto", + ] +} + +proto_library("json_proto") { + sources = [ + "json.proto", + ] + + # This way json.pb.h header goes into "$root_gen_dir" directory precisely, + # otherwise it goes into "$root_gen_dir" + "/testing/libfuzzer/proto/". + proto_out_dir = "" + deps = [ + ":json_proto_copy", + ] +} + +source_set("json_proto_converter") { + sources = [ + "json_proto_converter.cc", + "json_proto_converter.h", + ] + deps = [ + ":json_proto", + ] +}
diff --git a/testing/libfuzzer/proto/json.proto b/testing/libfuzzer/proto/json.proto new file mode 100644 index 0000000..004e9ee --- /dev/null +++ b/testing/libfuzzer/proto/json.proto
@@ -0,0 +1,81 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The proto definition for JSON format has been written based on +// http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf + +syntax = "proto2"; + +package json_proto; + +message JsonObject { + required string name = 1; + required JsonValue value = 2; +} + +message JsonValue { + oneof value { + // Json value types: + + // null: null, will be used when 'oneof' contains nothing + + // object: another json object of any type + JsonObject object_value = 1; + + // array: an array of values + ArrayValue array_value = 2; + + // number: can be an integer, a float, an exponent + NumberValue number_value = 3; + + // string: unicode string + StringValue string_value = 4; + + // boolean: true or talse + BooleanValue boolean_value = 5; + } +} + +message ArrayValue { + repeated JsonValue value = 1; +} + +message NumberInteger { + required int64 value = 1; +} + +message NumberFloat { + required double value = 1; +} + +message NumberExponent { + required int32 base = 1; + required int32 exponent = 2; + required bool use_uppercase = 3; +} + +message NumberExponentFrac { + required float base = 1; + required int32 exponent = 2; + required bool use_uppercase = 3; +} + +message NumberValue { + required NumberInteger integer_value = 1; + + // integer_value is used when oneof field below has nothing. + oneof value { + NumberFloat float_value = 2; + NumberExponent exponent_value = 3; + NumberExponentFrac exponent_frac_value = 4; + } +} + +message StringValue { + required string value = 1; +} + +message BooleanValue { + required bool value = 1; +}
diff --git a/testing/libfuzzer/proto/json_proto_converter.cc b/testing/libfuzzer/proto/json_proto_converter.cc new file mode 100644 index 0000000..79b321b --- /dev/null +++ b/testing/libfuzzer/proto/json_proto_converter.cc
@@ -0,0 +1,67 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "testing/libfuzzer/proto/json_proto_converter.h" + +using namespace json_proto; + +void JsonProtoConverter::AppendArray(const ArrayValue& array_value) { + data_ << '['; + bool need_comma = false; + for (const auto& value : array_value.value()) { + // Trailing comma inside of an array makes JSON invalid, avoid adding that. + if (need_comma) + data_ << ','; + else + need_comma = true; + + AppendValue(value); + } + data_ << ']'; +} + +void JsonProtoConverter::AppendNumber(const NumberValue& number_value) { + if (number_value.has_float_value()) { + data_ << number_value.float_value().value(); + } else if (number_value.has_exponent_value()) { + auto value = number_value.exponent_value(); + data_ << value.base(); + data_ << (value.use_uppercase() ? 'E' : 'e'); + data_ << value.exponent(); + } else if (number_value.has_exponent_frac_value()) { + auto value = number_value.exponent_value(); + data_ << value.base(); + data_ << (value.use_uppercase() ? 'E' : 'e'); + data_ << value.exponent(); + } else { + data_ << number_value.integer_value().value(); + } +} + +void JsonProtoConverter::AppendObject(const JsonObject& json_object) { + data_ << '{' << '"' << json_object.name() << '"' << ':'; + AppendValue(json_object.value()); + data_ << '}'; +} + +void JsonProtoConverter::AppendValue(const JsonValue& json_value) { + if (json_value.has_object_value()) { + AppendObject(json_value.object_value()); + } else if (json_value.has_array_value()) { + AppendArray(json_value.array_value()); + } else if (json_value.has_number_value()) { + AppendNumber(json_value.number_value()); + } else if (json_value.has_string_value()) { + data_ << '"' << json_value.string_value().value() << '"'; + } else if (json_value.has_boolean_value()) { + data_ << (json_value.boolean_value().value() ? "true" : "false"); + } else { + data_ << "null"; + } +} + +std::string JsonProtoConverter::Convert(const JsonObject& json_object) { + AppendObject(json_object); + return data_.str(); +}
diff --git a/testing/libfuzzer/proto/json_proto_converter.h b/testing/libfuzzer/proto/json_proto_converter.h new file mode 100644 index 0000000..cbe95fe2 --- /dev/null +++ b/testing/libfuzzer/proto/json_proto_converter.h
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TESTING_LIBFUZZER_PROTO_JSON_PROTO_CONVERTER_H +#define TESTING_LIBFUZZER_PROTO_JSON_PROTO_CONVERTER_H + +#include "testing/libfuzzer/proto/json.pb.h" + +#include <sstream> +#include <string> + +namespace json_proto { + +class JsonProtoConverter { + public: + std::string Convert(const json_proto::JsonObject&); + + private: + std::stringstream data_; + + void AppendArray(const json_proto::ArrayValue&); + void AppendNumber(const json_proto::NumberValue&); + void AppendObject(const json_proto::JsonObject&); + void AppendValue(const json_proto::JsonValue&); +}; + +} // namespace json_proto + +#endif // TESTING_LIBFUZZER_PROTO_JSON_PROTO_CONVERTER_H
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 9b9e982..63be8fb 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1023,26 +1023,6 @@ ] } ], - "DataReductionProxyUseQuic": [ - { - "platforms": [ - "android", - "chromeos", - "linux", - "mac", - "win" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "enable_quic_non_core_proxies": "true", - "enable_warmup": "true" - } - } - ] - } - ], "DecoupleTranslateLanguage": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index dc1a099f..fc237619 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -9,7 +9,6 @@ Bug(none) external/wpt/clear-site-data/storage.https.html [ Failure ] Bug(none) external/wpt/XMLHttpRequest/overridemimetype-blob.html [ Failure ] -Bug(none) external/wpt/beacon/headers/header-content-type.html [ Timeout ] Bug(none) external/wpt/clear-site-data/navigation.https.html [ Timeout ] Bug(none) external/wpt/content-security-policy/generic/filesystem-urls-match-filesystem.sub.html [ Failure ] Bug(none) external/wpt/content-security-policy/inside-worker/dedicated-inheritance.html [ Failure Timeout ] @@ -190,35 +189,35 @@ crbug.com/764474 plugins/plugin-document-back-forward.html [ Crash Failure Timeout ] # http/tests/fetch -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/auth-base-https-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cookie-nocors-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cookie.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cors-preflight.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cors-preflight2.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/nocors-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect-nocors-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect-nocors.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect-password.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/scheme-blob.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/block-mixed-content-base-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/stream-reader.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/thorough/cors-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-credentials.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-loop-base-https-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-nocors.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-password-base-https-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-password-other-https.html [ Failure Timeout ] -crbug.com/778721 http/tests/fetch/workers/stream-reader.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/access-control.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/auth-nocors-base-https-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/auth-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/cookie.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/cors-preflight-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/cors-preflight2-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/redirect-credentials-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/redirect-credentials.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/redirect-nocors-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/redirect-password-other-https.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/redirect-password.html [ Failure ] -crbug.com/778721 http/tests/fetch/workers/thorough/scheme-blob.html [ Failure ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/auth-base-https-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cookie-nocors-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cookie.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cors-preflight.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/cors-preflight2.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/nocors-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect-nocors-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect-nocors.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect-password.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/redirect.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/scheme-blob.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/block-mixed-content-base-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/stream-reader.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/thorough/cors-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-credentials.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-loop-base-https-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-nocors.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-password-base-https-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/serviceworker/thorough/redirect-password-other-https.html [ Pass Failure Timeout ] +crbug.com/778721 http/tests/fetch/workers/stream-reader.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/access-control.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/auth-nocors-base-https-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/auth-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/cookie.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/cors-preflight-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/cors-preflight2-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/redirect-credentials-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/redirect-credentials.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/redirect-nocors-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/redirect-password-other-https.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/redirect-password.html [ Pass Failure ] +crbug.com/778721 http/tests/fetch/workers/thorough/scheme-blob.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 3b7c9213..a50a4891 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -493,3 +493,5 @@ # This test continues to fail as timeout on Win7(dbg) crbug.com/757292 [ Win Debug ] external/wpt/encoding/legacy-mb-korean/euc-kr/euckr-encode-form-errors-han.html [ Slow ] + +crbug.com/779965 external/wpt/beacon/headers/header-content-type.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a30b35a..688c022 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1783,7 +1783,6 @@ crbug.com/626703 external/wpt/beacon/beacon-cors.sub.window.html [ Timeout ] crbug.com/626703 external/wpt/beacon/beacon-navigate.html [ Timeout ] crbug.com/626703 external/wpt/beacon/beacon-redirect.window.html [ Timeout ] -crbug.com/626703 external/wpt/beacon/headers/header-content-type.html [ Pass Timeout ] crbug.com/626703 external/wpt/compat/webkit-text-fill-color-property-005.html [ Failure ] crbug.com/626703 external/wpt/css/CSS2/text/text-align-white-space-003.xht [ Failure ] crbug.com/626703 external/wpt/css/CSS2/text/text-align-white-space-007.xht [ Failure ] @@ -2746,8 +2745,6 @@ # Sheriff failures 2017-02-27 crbug.com/696407 [ Linux ] external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-with-colon.sub.html [ Failure Pass ] -crbug.com/698520 external/wpt/preload/fetch-destination.https.html [ Failure Pass ] - # Sheriff failures 2017-03-10 crbug.com/741210 [ Mac ] inspector-protocol/emulation/device-emulation-restore.js [ Failure ] crbug.com/700374 [ Win ] virtual/mojo-loading/http/tests/devtools/workers-on-navigation.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-into-videos-expected.txt b/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-into-videos-expected.txt index 65498a7a..e91ba30 100644 --- a/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-into-videos-expected.txt +++ b/third_party/WebKit/LayoutTests/compositing/squashing/dont-squash-into-videos-expected.txt
@@ -13,7 +13,7 @@ "backgroundColor": "#ADD8E6" }, { - "name": "LayoutFlexibleBox (relative positioned) DIV class='phase-pre-ready state-no-source'", + "name": "LayoutFlexibleBox (relative positioned) DIV class='phase-pre-ready state-no-source use-default-poster'", "bounds": [100, 100] }, {
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 9794f2e2..92c5eec5 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -111749,11 +111749,6 @@ {} ] ], - "html/semantics/scripting-1/the-script-element/module/integrity-expected.txt": [ - [ - {} - ] - ], "html/semantics/scripting-1/the-script-element/module/integrity-matches-inner.js": [ [ {} @@ -125839,6 +125834,16 @@ {} ] ], + "worklets/resources/credentials-tests.js": [ + [ + {} + ] + ], + "worklets/resources/credentials.py": [ + [ + {} + ] + ], "worklets/resources/empty-worklet-script.js": [ [ {} @@ -125879,6 +125884,11 @@ {} ] ], + "worklets/resources/set-cookie.py": [ + [ + {} + ] + ], "worklets/resources/throwing-worklet-script.js": [ [ {} @@ -188547,6 +188557,12 @@ {} ] ], + "worklets/animation-worklet-credentials.html": [ + [ + "/worklets/animation-worklet-credentials.html", + {} + ] + ], "worklets/animation-worklet-import.html": [ [ "/worklets/animation-worklet-import.html", @@ -188559,6 +188575,12 @@ {} ] ], + "worklets/paint-worklet-credentials.html": [ + [ + "/worklets/paint-worklet-credentials.html", + {} + ] + ], "worklets/paint-worklet-import.html": [ [ "/worklets/paint-worklet-import.html", @@ -272318,10 +272340,6 @@ "62b71ff7d3d3a74337a3c782fe75fdbcd37b1b27", "testharness" ], - "html/semantics/scripting-1/the-script-element/module/integrity-expected.txt": [ - "4c940d29eb7dff8175263cec755c951689d9713f", - "support" - ], "html/semantics/scripting-1/the-script-element/module/integrity-matches-inner.js": [ "bf1734923e4507555842710515c20288532fd995", "support" @@ -284747,11 +284765,11 @@ "testharness" ], "payment-request/payment-request-canmakepayment-method.https-expected.txt": [ - "99d0a55e579791ebea66931adae60cc9bcc60979", + "edf4b9aedbdc74041e2aa49d77eaa177954f0f80", "support" ], "payment-request/payment-request-canmakepayment-method.https.html": [ - "44a75a5b40fc80970bb629dd4d98722849d862f7", + "0d863558b996df81a36207201bbf8c649688845d", "testharness" ], "payment-request/payment-request-constructor-crash.https.html": [ @@ -306326,6 +306344,10 @@ "33a3530260a18e74dd96470d9890bbdb4ecdb08d", "support" ], + "worklets/animation-worklet-credentials.html": [ + "4519b0a79879ead03e03fbd280699120ed17f06f", + "testharness" + ], "worklets/animation-worklet-import.html": [ "6e92613e720ac1fa1cdec91665cc1ca68a6e0bc8", "testharness" @@ -306334,6 +306356,10 @@ "7c6e4a94815093e9353d184b877046ad7627bae9", "testharness" ], + "worklets/paint-worklet-credentials.html": [ + "fd0d5e0e34454755ddd693916476af809dfd9bb1", + "testharness" + ], "worklets/paint-worklet-import.html": [ "a1a5fe53abb00fe37c7688032038110a67f988ee", "testharness" @@ -306342,6 +306368,14 @@ "86e7c0fe4de0764a7064ed22eef2b66ab09d4a62", "testharness" ], + "worklets/resources/credentials-tests.js": [ + "0b88679b6ff0d94c0a7e6cc1100ba6f1864913ca", + "support" + ], + "worklets/resources/credentials.py": [ + "6ce932e1cdc3626efc85ba0fe4a517b6308c67bd", + "support" + ], "worklets/resources/empty-worklet-script.js": [ "84b3339c3419e318803e51f46d7252d9e8ac183b", "support" @@ -306374,6 +306408,10 @@ "ed296faa934f89efcca9a116f6a2e931cafd831e", "support" ], + "worklets/resources/set-cookie.py": [ + "3152f5d79b6f362f5aaf738d7d2454de94a6159d", + "support" + ], "worklets/resources/throwing-worklet-script.js": [ "a7164f899afec387321c7737aa1006aa5f225669", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted-expected.txt index 774fd0c7..9293745 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted-expected.txt
@@ -7,18 +7,18 @@ PASS setting video.muted (parser-created) FAIL getting video.muted with muted="" (parser-created) assert_true: expected true got false FAIL setting video.muted with muted="" (parser-created) assert_equals: expected true but got false -FAIL getting video.muted with muted="" after load (parser-created) assert_true: expected true got false +PASS getting video.muted with muted="" after load (parser-created) PASS getting audio.muted (script-created) PASS setting audio.muted (script-created) PASS getting audio.muted with muted="" (script-created) PASS setting audio.muted with muted="" (script-created) -FAIL getting audio.muted with muted="" (innerHTML-created) assert_true: expected true got false +PASS getting audio.muted with muted="" (innerHTML-created) FAIL getting audio.muted with muted="" (document.write-created) assert_true: expected true got false PASS getting video.muted (script-created) PASS setting video.muted (script-created) PASS getting video.muted with muted="" (script-created) PASS setting video.muted with muted="" (script-created) -FAIL getting video.muted with muted="" (innerHTML-created) assert_true: expected true got false +PASS getting video.muted with muted="" (innerHTML-created) FAIL getting video.muted with muted="" (document.write-created) assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt index 47b95f2..9269b3a3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt
@@ -4,7 +4,7 @@ FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "UnknownError: Request failed" FAIL If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "UnknownError: Request failed" FAIL If payment method identifier and serialized parts are supported, resolve promise with true. promise_test: Unhandled rejection with value: object "UnknownError: Request failed" -FAIL If payment method identifier is unknown, resolve promise with false. assert_true: Unexpected exception testing method this-is-not-supported, expected false. See error console. expected true got false +FAIL If payment method identifier is unknown, resolve promise with false. assert_equals: if it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "UnknownError" FAIL Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException. assert_equals: if it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "UnknownError" Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html index c85c7f7..9fe0c4a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-canmakepayment-method.https.html
@@ -123,9 +123,10 @@ `method "${method}" must not be supported` ); } catch (err) { - assert_true( - false, - `Unexpected exception testing method ${method}, expected false. See error console.` + assert_equals( + err.name, + "NotAllowedError", + "if it throws, then it must be a NotAllowedError." ); } }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html index 22256c05..2b043b99 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html
@@ -90,6 +90,12 @@ assert_equals(length.valueInSpecifiedUnits, 2); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PX); + assert_throws("SyntaxError", function() { length.valueAsString = ''; }); + assert_equals(length.valueAsString, "2px"); + assert_equals(length.value, 2); + assert_equals(length.valueInSpecifiedUnits, 2); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PX); + // Check setting invalid 'value' arguments. assert_throws(new TypeError(), function() { length.value = NaN; }); assert_throws(new TypeError(), function() { length.value = Infinity; }); @@ -104,4 +110,4 @@ assert_equals(length.valueInSpecifiedUnits, 2); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PX); }); -</script> \ No newline at end of file +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset-expected.txt b/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset-expected.txt index 3992c4ac..67f0deb 100644 --- a/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset-expected.txt
@@ -1,8 +1,8 @@ layer at (0,0) size 800x600 LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 +layer at (0,0) size 800x357 + LayoutBlockFlow {HTML} at (0,0) size 800x357 + LayoutBlockFlow {BODY} at (8,8) size 784x341 LayoutText {#text} at (0,0) size 0x0 layer at (28,28) size 335x296 LayoutImage {IMG} at (20,20) size 335x296
diff --git a/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset.html b/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset.html index 074bd86e..9c6acbe 100644 --- a/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset.html +++ b/third_party/WebKit/LayoutTests/fast/reflections/reflection-masks-outset.html
@@ -1 +1,15 @@ -<img src="resources/kate.png" style="margin:20px; outline:20px solid green; -webkit-box-reflect:below 2px url(resources/vignette-mask.png) 75 / auto / 25px stretch"> +<!DOCTYPE html> +<img id="target" src="resources/kate.png" + style="margin:20px; outline:20px solid green; + -webkit-box-reflect: below 2px url(resources/vignette-mask.png) 75 / auto / 25px stretch"> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +if (window.testRunner) + testRunner.waitUntilDone(); +// Ensure the reflect mask image is loaded before ending the test. +var imageLoader = new Image(); +imageLoader.onload = function() { + runAfterLayoutAndPaint(function() {}, true); +}; +imageLoader.src = 'resources/vignette-mask.png'; +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/components/object-properties-section-onchange-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/components/object-properties-section-onchange-expected.txt new file mode 100644 index 0000000..0e9447b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/components/object-properties-section-onchange-expected.txt
@@ -0,0 +1,21 @@ +Tests that ObjectPropertiesSection fires callback upon DOM changes. + + +Running: expand +6 change calls fired + +Running: expandArrayWithRanges +6 change calls fired + +Running: expandArrayRange +102 change calls fired + +Running: clickAccessorProperty +2 change calls fired + +Running: applyExpression +5 change calls fired + +Running: collapse +1 change calls fired +
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/components/object-properties-section-onchange.js b/third_party/WebKit/LayoutTests/http/tests/devtools/components/object-properties-section-onchange.js new file mode 100644 index 0000000..1a603ec --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/components/object-properties-section-onchange.js
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that ObjectPropertiesSection fires callback upon DOM changes.\n`); + + await TestRunner.loadModule('object_ui'); + await TestRunner.showPanel('console'); + + TestRunner.addSniffer(Console.ConsoleViewMessage.prototype, '_onObjectChange', onChange, true /* sticky */); + await TestRunner.evaluateInPagePromise(` + var arrayWithRanges = new Array(101).fill(1); + var localObject = {a: arrayWithRanges, get b() { return 'myGetterValue'; } }; + console.log(localObject); + `); + + var messageElement = Console.ConsoleView._instance._visibleViewMessages[0].element(); + var section = messageElement.querySelector('.console-view-object-properties-section')._section; + var rootElement = section.objectTreeElement(); + + var expectedChangeCount; + var actualChangeCount = 0; + var waitForConditionCallback; + var continueCondition = () => false; + + TestRunner.runTestSuite([ + function expand(next) { + waitForCondition(() => (rootElement.children().length === 4), next); + section.expand(); + }, + function expandArrayWithRanges(next) { + var arrayPropertyTreeElement = rootElement.childAt(0); + waitForCondition(() => (arrayPropertyTreeElement.children().length === 4), next); + arrayPropertyTreeElement.expand(); + }, + function expandArrayRange(next) { + var arrayRangeTreeElement = rootElement.childAt(0).childAt(0); + waitForCondition(() => (arrayRangeTreeElement.children().length === 100), next); + arrayRangeTreeElement.expand(); + }, + function clickAccessorProperty(next) { + var getterTreeElement = rootElement.childAt(1); + waitForCondition(() => (getterTreeElement.valueElement.textContent !== '(...)'), next); + getterTreeElement.listItemElement.querySelector('.object-value-calculate-value-button').click(); + }, + function applyExpression(next) { + var getterTreeElement = rootElement.childAt(1); + waitForCondition(() => (getterTreeElement.valueElement.textContent !== 'myGetterValue'), next); + getterTreeElement._applyExpression('1 + 1'); + }, + function collapse(next) { + waitForCondition(() => (!rootElement.treeOutline.element.classList.contains('expanded')), next); + rootElement.collapse(); + } + ]); + + /** + * @param {function():boolean} condition + * @param {function()} next + */ + function waitForCondition(condition, next) { + continueCondition = condition; + waitForConditionCallback = next; + } + + function onChange() { + actualChangeCount++; + if (waitForConditionCallback && continueCondition()) { + var callback = waitForConditionCallback; + // Flush any pending synchronous onChange calls before proceeding. + waitForConditionCallback = null; + setTimeout(() => { + TestRunner.addResult(actualChangeCount + ' change calls fired'); + actualChangeCount = 0; + callback(); + }); + } + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt index 5c52d87..c9db3d9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt
@@ -5,8 +5,8 @@ { data : { cacheProduceOptions : "code" - columnNumber : <number> - lineNumber : <number> + columnNumber : 0 + lineNumber : 0 producedCacheSize : <number> streamed : <boolean> url : .../devtools/service-workers/resources/v8-cache-script.js @@ -21,9 +21,9 @@ data : { cacheConsumeOptions : "code" cacheRejected : false - columnNumber : <number> + columnNumber : 0 consumedCacheSize : <number> - lineNumber : <number> + lineNumber : 0 streamed : <boolean> url : .../devtools/service-workers/resources/v8-cache-script.js }
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt index f388308..962aab5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt
@@ -4,8 +4,8 @@ v8.compile Properties: { data : { - columnNumber : <number> - lineNumber : <number> + columnNumber : 0 + lineNumber : 0 streamed : <boolean> url : } @@ -17,8 +17,8 @@ v8.compile Properties: { data : { - columnNumber : <number> - lineNumber : <number> + columnNumber : 0 + lineNumber : 0 streamed : <boolean> url : .../devtools/tracing/timeline-js/resources/timeline-script-tag-2.js }
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-1-expected.txt index a8390a4..ed82d81 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-1-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-1-expected.txt
@@ -13,9 +13,9 @@ EvaluateScript Properties: { data : { - columnNumber : <number> + columnNumber : 8 frame : <string> - lineNumber : <number> + lineNumber : 2 url : .../devtools/tracing/resources/timeline-iframe-data.html } endTime : <number>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-2-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-2-expected.txt index 3392589..a287ed3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-2-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-js/timeline-script-tag-2-expected.txt
@@ -12,9 +12,9 @@ EvaluateScript Properties: { data : { - columnNumber : <number> + columnNumber : 0 frame : <string> - lineNumber : <number> + lineNumber : 0 url : .../devtools/tracing/timeline-js/resources/timeline-script-tag-2.js } endTime : <number>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-expected.txt index 1f446bc..1eadd16e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-expected.txt
@@ -27,7 +27,7 @@ frame : <string> fromCache : false fromServiceWorker : false - mimeType : <string> + mimeType : "application/x-javascript" requestId : <string> statusCode : 200 timing : <object>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt index b398d191..0b76a62 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt
@@ -85,10 +85,10 @@ FunctionCall Properties: { data : { - columnNumber : <number> + columnNumber : 30 frame : <string> functionName : "intervalTimerWork" - lineNumber : <number> + lineNumber : 14 scriptId : <string> url : .../devtools/tracing/timeline-time/timeline-timer.html } @@ -100,10 +100,10 @@ FunctionCall Properties: { data : { - columnNumber : <number> + columnNumber : 30 frame : <string> functionName : "intervalTimerWork" - lineNumber : <number> + lineNumber : 14 scriptId : <string> url : .../devtools/tracing/timeline-time/timeline-timer.html } @@ -124,9 +124,9 @@ EvaluateScript Properties: { data : { - columnNumber : <number> + columnNumber : 0 frame : <string> - lineNumber : <number> + lineNumber : 0 url : } endTime : <number>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source-buffer.html b/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source-buffer.html index f5618587..e175b8c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source-buffer.html +++ b/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source-buffer.html
@@ -9,7 +9,7 @@ <script> async_test(t => { const video = document.querySelector('video'); - checkControlsClassName(video, "phase-pre-ready state-no-source"); + checkControlsClassName(video, "phase-pre-ready state-no-source use-default-poster"); video.onstalled = t.step_func_done(() => { checkControlsClassName(video, "phase-ready state-buffering");
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source.html b/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source.html index 6216b5a..947da096 100644 --- a/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source.html +++ b/third_party/WebKit/LayoutTests/http/tests/media/controls/toggle-class-with-state-source.html
@@ -11,7 +11,7 @@ const video = document.querySelector('video'); let was_paused = false; - checkControlsClassName(video, "phase-pre-ready state-no-source"); + checkControlsClassName(video, "phase-pre-ready state-no-source use-default-poster"); video.onstalled = t.step_func(() => { checkControlsClassName(video, "state-loading-metadata");
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-expected.txt index dcf7f46..eeb68b0 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-expected.txt
@@ -1219,8 +1219,8 @@ { "domNodeIndex": 35, "boundingBox": { - "x": 10, - "y": 634, + "x": 0, + "y": 0, "width": 400, "height": 200 }, @@ -1229,8 +1229,8 @@ { "domNodeIndex": 42, "boundingBox": { - "x": 18, - "y": 642, + "x": 8, + "y": 8, "width": 384, "height": 184 }, @@ -1239,8 +1239,8 @@ { "domNodeIndex": 44, "boundingBox": { - "x": 18, - "y": 642, + "x": 8, + "y": 8, "width": 384, "height": 16 },
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport-expected.txt new file mode 100644 index 0000000..0f527db --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport-expected.txt
@@ -0,0 +1,246 @@ +Tests DOMSnapshot.getSnapshot method on a mobile page. +Emulating device: 600x600x1 +{ + "domNodes": [ + { + "nodeType": 9, + "nodeName": "#document", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 1, + 2, + 3 + ], + "layoutNodeIndex": 0, + "documentURL": "<string>", + "baseURL": "<string>", + "documentEncoding": "windows-1252", + "frameId": "<string>" + }, + { + "nodeType": 10, + "nodeName": "html", + "nodeValue": "", + "backendNodeId": "<number>", + "publicId": "", + "systemId": "" + }, + { + "nodeType": 8, + "nodeName": "#comment", + "nodeValue": " domSnapshot test for a document with a viewport. ", + "backendNodeId": "<number>" + }, + { + "nodeType": 1, + "nodeName": "HTML", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 4, + 15 + ], + "layoutNodeIndex": 1, + "frameId": "<string>" + }, + { + "nodeType": 1, + "nodeName": "HEAD", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 5, + 6, + 7, + 9, + 10, + 12, + 13, + 14 + ] + }, + { + "nodeType": 1, + "nodeName": "META", + "nodeValue": "", + "backendNodeId": "<number>", + "attributes": [ + { + "name": "name", + "value": "viewport" + }, + { + "name": "content", + "value": "width=300" + } + ] + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n", + "backendNodeId": "<number>" + }, + { + "nodeType": 1, + "nodeName": "STYLE", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 8 + ] + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n@font-face {\n font-family: 'ahem';\n src: url(../../resources/Ahem.ttf);\n}\n", + "backendNodeId": "<number>" + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n", + "backendNodeId": "<number>" + }, + { + "nodeType": 1, + "nodeName": "STYLE", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 11 + ] + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n* {\n margin: 0;\n padding: 0;\n}\ndiv {\n position: absolute;\n top: 100px;\n left: 100px;\n width: 100px;\n height: 100px;\n background-color: green;\n}\n", + "backendNodeId": "<number>" + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n", + "backendNodeId": "<number>" + }, + { + "nodeType": 8, + "nodeName": "#comment", + "nodeValue": " The div's box should have size and position of 100x100 to match the\n computed style, even though it's visually scaled by the viewport. The\n text's box should also be inside the div's box, not outside it. ", + "backendNodeId": "<number>" + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n", + "backendNodeId": "<number>" + }, + { + "nodeType": 1, + "nodeName": "BODY", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 16, + 18 + ], + "layoutNodeIndex": 2 + }, + { + "nodeType": 1, + "nodeName": "DIV", + "nodeValue": "", + "backendNodeId": "<number>", + "childNodeIndexes": [ + 17 + ], + "attributes": [ + { + "name": "style", + "value": "font-family: ahem;" + }, + { + "name": "id", + "value": "100x100" + } + ], + "layoutNodeIndex": 3 + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "Boxes!", + "backendNodeId": "<number>", + "layoutNodeIndex": 4 + }, + { + "nodeType": 3, + "nodeName": "#text", + "nodeValue": "\n\n", + "backendNodeId": "<number>" + } + ], + "layoutTreeNodes": [ + { + "domNodeIndex": 0, + "boundingBox": { + "x": 0, + "y": 0, + "width": 300, + "height": 300 + } + }, + { + "domNodeIndex": 3, + "boundingBox": { + "x": 0, + "y": 0, + "width": 300, + "height": 0 + } + }, + { + "domNodeIndex": 15, + "boundingBox": { + "x": 0, + "y": 0, + "width": 300, + "height": 0 + } + }, + { + "domNodeIndex": 16, + "boundingBox": { + "x": 100, + "y": 100, + "width": 100, + "height": 100 + } + }, + { + "domNodeIndex": 17, + "boundingBox": { + "x": 100, + "y": 100, + "width": 96, + "height": 16 + }, + "layoutText": "Boxes!", + "inlineTextNodes": [ + { + "boundingBox": { + "x": 100, + "y": 100, + "width": 96, + "height": 16 + }, + "startCharacterIndex": 0, + "numCharacters": 6 + } + ] + } + ], + "computedStyles": [] +} +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js new file mode 100644 index 0000000..fa5eb4b --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js
@@ -0,0 +1,26 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank('Tests DOMSnapshot.getSnapshot method on a mobile page.'); + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(600, 600, 1); + + // The viewport width is 300px, half the device width. + await session.navigate('../resources/dom-snapshot-viewport.html'); + + function stabilize(key, value) { + var unstableKeys = ['documentURL', 'baseURL', 'frameId', 'backendNodeId']; + if (unstableKeys.indexOf(key) !== -1) + return '<' + typeof(value) + '>'; + if (typeof value === 'string' && value.indexOf('/dom-snapshot/') !== -1) + value = '<value>'; + return value; + } + + var whitelist = []; + var response = await dp.DOMSnapshot.getSnapshot({'computedStyleWhitelist': whitelist}); + if (response.error) + testRunner.log(response); + else + testRunner.log(JSON.stringify(response.result, stabilize, 2)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/getFrameTree-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/page/getFrameTree-expected.txt new file mode 100644 index 0000000..fdb32c9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/getFrameTree-expected.txt
@@ -0,0 +1,6 @@ +Tests Page.getFrameTree protocol method. +frame: undefined + frame: a + frame: b + frame: d +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/getFrameTree.js b/third_party/WebKit/LayoutTests/inspector-protocol/page/getFrameTree.js new file mode 100644 index 0000000..10826f5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/getFrameTree.js
@@ -0,0 +1,24 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank('Tests Page.getFrameTree protocol method.'); + + await dp.Page.enable(); + dp.Page.onFrameNavigated(async result => { + var name = result.params.frame.name; + if (name !== 'd') + return; + var frameTreeResponse = await dp.Page.getFrameTree(); + printFrameTree('', frameTreeResponse.result.frameTree); + testRunner.completeTest(); + }); + + page.loadHTML( + `<iframe name='a' src='about:blank'></iframe> + <iframe name='b' src='data:text/html,%3Ciframe%20name=%22d%22%20src=%22about:blank%22%3E%3C/iframe%3E'></iframe>`); + + function printFrameTree(indent, frameTree) { + testRunner.log(`${indent}frame: ${frameTree.frame.name}`); + if (frameTree.childFrames) + frameTree.childFrames.forEach(printFrameTree.bind(null, `${indent} `)); + } + +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/dom-snapshot-viewport.html b/third_party/WebKit/LayoutTests/inspector-protocol/resources/dom-snapshot-viewport.html new file mode 100644 index 0000000..375cad7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/dom-snapshot-viewport.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<!-- domSnapshot test for a document with a viewport. --> +<meta name=viewport content='width=300'> +<style> +@font-face { + font-family: 'ahem'; + src: url(../../resources/Ahem.ttf); +} +</style> +<style> +* { + margin: 0; + padding: 0; +} +div { + position: absolute; + top: 100px; + left: 100px; + width: 100px; + height: 100px; + background-color: green; +} +</style> +<!-- The div's box should have size and position of 100x100 to match the + computed style, even though it's visually scaled by the viewport. The + text's box should also be inside the div's box, not outside it. --> +<div style='font-family: ahem;' id='100x100'>Boxes!</div> +
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-poster-frame.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-poster-frame.html new file mode 100644 index 0000000..535d2117 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-poster-frame.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<title>Test that poster availability is reflected in CSS classes.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../media-controls.js"></script> +<script src="../media-file.js"></script> +<video controls width=400 preload=auto></video> +<script> +async_test(t => { + const video = document.querySelector('video'); + + checkControlsClassName(video, 'phase-pre-ready state-no-source use-default-poster'); + + video.oncanplay = t.step_func_done(() => { + checkControlsClassName(video, 'phase-ready state-stopped'); + }); + + video.src = findMediaFile('video', '../content/counting'); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-poster-image.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-poster-image.html new file mode 100644 index 0000000..a9cee03 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-poster-image.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<title>Test that poster availability is reflected in CSS classes.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../media-controls.js"></script> +<script src="../media-file.js"></script> +<video controls width=400 preload=auto poster="../content/greenbox.png"></video> +<script> +async_test(t => { + const video = document.querySelector('video'); + + checkControlsClassName(video, 'phase-pre-ready state-no-source'); + + video.oncanplay = t.step_func_done(() => { + checkControlsClassName(video, 'phase-ready state-stopped'); + }); + + video.src = findMediaFile('video', '../content/counting'); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-error.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-error.html index 65b234d..f92347d8 100644 --- a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-error.html +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-error.html
@@ -9,10 +9,10 @@ <script> async_test(t => { const video = document.querySelector('video'); - checkControlsClassName(video, "phase-pre-ready state-no-source"); + checkControlsClassName(video, "phase-pre-ready state-no-source use-default-poster"); video.onerror = t.step_func_done(() => { - checkControlsClassName(video, "phase-pre-ready state-no-source"); + checkControlsClassName(video, "phase-pre-ready state-no-source use-default-poster"); }); video.src = findMediaFile("video", "../content/missing");
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-reset.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-reset.html index c499a49..30020bd 100644 --- a/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-reset.html +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-state-source-reset.html
@@ -11,7 +11,7 @@ const video = document.querySelector('video'); let count = 0; - checkControlsClassName(video, "phase-pre-ready state-no-source"); + checkControlsClassName(video, "phase-pre-ready state-no-source use-default-poster"); video.onplaying = t.step_func(() => { checkControlsClassName(video, "phase-ready state-playing");
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html new file mode 100644 index 0000000..5c3e123 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<title>Test that poster availability is reflected in CSS classes.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../media-controls.js"></script> +<script src="../media-file.js"></script> +<video controls width=400 preload=metadata></video> +<script> +async_test(t => { + const video = document.querySelector('video'); + let count = 0; + + checkControlsClassName(video, 'phase-pre-ready state-no-source use-default-poster'); + + video.onloadedmetadata = t.step_func_done(() => { + checkControlsClassName(video, 'phase-ready state-stopped use-default-poster'); + }); + + video.src = findMediaFile('video', '../content/counting'); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/volumechange-muted-attribute.html b/third_party/WebKit/LayoutTests/media/controls/volumechange-muted-attribute.html index e86ac1c..157aad88 100644 --- a/third_party/WebKit/LayoutTests/media/controls/volumechange-muted-attribute.html +++ b/third_party/WebKit/LayoutTests/media/controls/volumechange-muted-attribute.html
@@ -2,17 +2,13 @@ <html> <title>This tests that controls are properly updated when muted content attribute is changed.</title> <script src="../media-file.js"></script> -<audio controls></audio> -<video controls></video> +<audio controls muted></audio> +<video controls muted></video> <script> var audio = document.querySelector('audio'); - // TODO(mlamouri): per spec, this should do nothing but Blink will mute the - // media in this case, see https://crbug.com/350303 - audio.setAttribute('muted', true); audio.src = findMediaFile('audio', '../content/test'); var video = document.querySelector('video'); - video.setAttribute('muted', true); video.src = findMediaFile('video', '../content/test'); </script> </html>
diff --git a/third_party/WebKit/LayoutTests/media/video-defaultmuted.html b/third_party/WebKit/LayoutTests/media/video-defaultmuted.html index 67623dd..db62a01 100644 --- a/third_party/WebKit/LayoutTests/media/video-defaultmuted.html +++ b/third_party/WebKit/LayoutTests/media/video-defaultmuted.html
@@ -24,13 +24,12 @@ async_test(function(t) { var video = document.createElement("video"); - // Set "muted" content attribute and it should set "muted" IDL attribute on video load. - // This is wrong per spec. See https://crbug.com/350303 for details. + // Set "muted" content attribute and test that it doesn't affect "muted" IDL attribute. video.setAttribute("muted", "muted"); video.onloadedmetadata = t.step_func_done(function() { - // "muted" IDL attribute should have been set. - assert_true(video.muted); + // "muted" IDL attribute shouldn't be affected by muted content attribute. + assert_false(video.muted); }); video.src = findMediaFile("audio", "content/test");
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.png index 19bf27e..802519d 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.png +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.png index 19bf27e..802519d 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.png +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/mask-child-changes-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/svg/mask-child-changes-expected.png index 19bf27e..802519d 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/mask-child-changes-expected.png +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/mask-child-changes-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png index d001569..763a61a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png index 58ce5607c..6f119de9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png index 299a088..37b1dc5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/as-background-image/svg-as-background-6-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/as-background-image/svg-as-background-6-expected.png index 7bde4b82..5925f125 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/as-background-image/svg-as-background-6-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/as-background-image/svg-as-background-6-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/masking/maskRegions-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/masking/maskRegions-expected.png index 252954e..b54d6a530 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/masking/maskRegions-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/masking/maskRegions-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-mask-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-mask-with-svg-transform-expected.png index ea368b2..8ae53364 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-mask-with-svg-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-mask-with-svg-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png index c8e1cd4..a94a2ed 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png index 3a82b908..c5ea4d1 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-with-transform-layer-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-with-transform-layer-expected.png index e59d3a3..ddc33d6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-with-transform-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-with-transform-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png index 8a85564..28124c2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png index cbb16c0..5a7be6eb 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png index 7ffb6ff..41574fe8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/svg-as-background-6-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/svg-as-background-6-expected.png index effa5807..5ff5cde7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/svg-as-background-6-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/svg-as-background-6-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png index 3c60b1c..4e65f79 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png index 4a9ce99..56b3d5b8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png index 33dd0a4..c39a65b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png index cca1da5..fba88ab 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png index 919770f..e519e09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png index 919770f..e519e09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png index 7f068ce..589b7dd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png index 02bd0dd..2cabbc5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png index 463b625..1d281c5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png index 109f33ebc..95b87be 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png index fdb3483..e40d803 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/as-background-image/svg-as-background-6-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/as-background-image/svg-as-background-6-expected.png index a099696..2a12638 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/as-background-image/svg-as-background-6-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/as-background-image/svg-as-background-6-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/masking/maskRegions-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/masking/maskRegions-expected.png index 70aa14f..6663a5af 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/masking/maskRegions-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/masking/maskRegions-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-mask-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-mask-with-svg-transform-expected.png index 3508b80..1f911845 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-mask-with-svg-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-mask-with-svg-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png index 2473737..5e81e861 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png index 3880ae0..1210490f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png index 02bd0dd..2cabbc5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png index 2c30ef4..4211633 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png index 2c30ef4..4211633 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png index 02bd0dd..2cabbc5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png index 6e8176f70..fffa76b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/fill-url-percent-encoding-expected.html b/third_party/WebKit/LayoutTests/svg/custom/fill-url-percent-encoding-expected.html new file mode 100644 index 0000000..f718ea6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/fill-url-percent-encoding-expected.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/fill-url-percent-encoding.html b/third_party/WebKit/LayoutTests/svg/custom/fill-url-percent-encoding.html new file mode 100644 index 0000000..2fc1814 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/fill-url-percent-encoding.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<svg> + <defs> + <linearGradient id="foo"> + <stop stop-color="green"/> + </linearGradient> + </defs> + <rect width="100" height="100" fill="url(#%66%6f%6f) red"/> +</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-2-expected.png b/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-2-expected.png index b751232b..47529e8 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-2-expected.png +++ b/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-expected.png b/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-expected.png index 2bb60b3c..3e0bf3a 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-expected.png +++ b/third_party/WebKit/LayoutTests/svg/custom/grayscale-gradient-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units-expected.txt b/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units-expected.txt deleted file mode 100644 index 432a96b2..0000000 --- a/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units-expected.txt +++ /dev/null
@@ -1,37 +0,0 @@ -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, " ". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "foo". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "10foo". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "px". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "10 % ". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "10 %". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "10 px ". -CONSOLE ERROR: line 1: Error: <rect> attribute x: Expected length, "10 px". -Tests handling of invalid SVG length units. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS rect.setAttribute('x', ''); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', ' '); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', 'foo'); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', '10foo'); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', 'px'); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', '10px '); rect.x.baseVal.valueAsString is '10px' -PASS rect.setAttribute('x', '10% '); rect.x.baseVal.valueAsString is '10%' -PASS rect.setAttribute('x', '10 % '); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', '10 %'); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', '10 px '); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', '10 px'); rect.x.baseVal.valueAsString is '0' -PASS rect.setAttribute('x', '10'); rect.x.baseVal.valueAsString is '10' -PASS rect.setAttribute('x', '10%'); rect.x.baseVal.valueAsString is '10%' -PASS rect.setAttribute('x', '10em'); rect.x.baseVal.valueAsString is '10em' -PASS rect.setAttribute('x', '10ex'); rect.x.baseVal.valueAsString is '10ex' -PASS rect.setAttribute('x', '10px'); rect.x.baseVal.valueAsString is '10px' -PASS rect.setAttribute('x', '10cm'); rect.x.baseVal.valueAsString is '10cm' -PASS rect.setAttribute('x', '10mm'); rect.x.baseVal.valueAsString is '10mm' -PASS rect.setAttribute('x', '10pt'); rect.x.baseVal.valueAsString is '10pt' -PASS rect.setAttribute('x', '10pc'); rect.x.baseVal.valueAsString is '10pc' -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units.html b/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units.html index 32ac54a..09c695f 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units.html +++ b/third_party/WebKit/LayoutTests/svg/custom/invalid-length-units.html
@@ -1,9 +1,39 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<script src="script-tests/invalid-length-units.js"></script> -</body> -</html> +<!DOCTYPE html> +<title>Invalid SVG length units</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<svg height="0"><rect/></svg> +<script> +function test_length_value(lengthString, expectedString) { + test(function() { + let rect = document.querySelector('rect'); + rect.setAttribute('x', "1234"); + rect.setAttribute('x', lengthString); + assert_equals(rect.x.baseVal.valueAsString, expectedString); + }, document.title + ', "' + lengthString + '"'); +} + +// Invalid +test_length_value("", "0"); +test_length_value(" ", "0"); +test_length_value("foo", "0"); +test_length_value("10foo", "0"); +test_length_value("px", "0"); +test_length_value("10 % ", "0"); +test_length_value("10 %", "0"); +test_length_value("10 px ", "0"); +test_length_value("10 px", "0"); + +// Valid +test_length_value("10px ", "10px"); +test_length_value("10% ", "10%"); +test_length_value("10", "10"); +test_length_value("10%", "10%"); +test_length_value("10em", "10em"); +test_length_value("10ex", "10ex"); +test_length_value("10px", "10px"); +test_length_value("10cm", "10cm"); +test_length_value("10mm", "10mm"); +test_length_value("10pt", "10pt"); +test_length_value("10pc", "10pc"); +</script>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/mask-changes-expected.png b/third_party/WebKit/LayoutTests/svg/custom/mask-changes-expected.png index 19bf27e..802519d 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/mask-changes-expected.png +++ b/third_party/WebKit/LayoutTests/svg/custom/mask-changes-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/mask-colorspace-expected.png b/third_party/WebKit/LayoutTests/svg/custom/mask-colorspace-expected.png index de56749..b848911 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/mask-colorspace-expected.png +++ b/third_party/WebKit/LayoutTests/svg/custom/mask-colorspace-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/script-tests/invalid-length-units.js b/third_party/WebKit/LayoutTests/svg/custom/script-tests/invalid-length-units.js deleted file mode 100644 index a89a248e..0000000 --- a/third_party/WebKit/LayoutTests/svg/custom/script-tests/invalid-length-units.js +++ /dev/null
@@ -1,40 +0,0 @@ -description("Tests handling of invalid SVG length units."); - -var svgNS = "http://www.w3.org/2000/svg"; - -var svgRoot = document.createElementNS(svgNS, "svg"); -document.documentElement.appendChild(svgRoot); - -rect = document.createElementNS(svgNS, "rect"); -svgRoot.appendChild(rect); - -function trySettingLength(length, expected) -{ - rect.setAttribute('x', "1234"); - shouldBe("rect.setAttribute('x', '" + length + "'); rect.x.baseVal.valueAsString", expected); -} - -trySettingLength("", "'0'"); -trySettingLength(" ", "'0'"); -trySettingLength("foo", "'0'"); -trySettingLength("10foo", "'0'"); -trySettingLength("px", "'0'"); -trySettingLength("10px ", "'10px'"); -trySettingLength("10% ", "'10%'"); -trySettingLength("10 % ", "'0'"); -trySettingLength("10 %", "'0'"); -trySettingLength("10 px ", "'0'"); -trySettingLength("10 px", "'0'"); -trySettingLength("10", "'10'"); -trySettingLength("10%", "'10%'"); -trySettingLength("10em", "'10em'"); -trySettingLength("10ex", "'10ex'"); -trySettingLength("10px", "'10px'"); -trySettingLength("10cm", "'10cm'"); -trySettingLength("10mm", "'10mm'"); -trySettingLength("10pt", "'10pt'"); -trySettingLength("10pc", "'10pc'"); - -document.documentElement.removeChild(svgRoot); - -var successfullyParsed = true;
diff --git a/third_party/WebKit/LayoutTests/svg/custom/svg-length-empty-string.html b/third_party/WebKit/LayoutTests/svg/custom/svg-length-empty-string.html new file mode 100644 index 0000000..63ddfa1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/svg-length-empty-string.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title>Empty string length value</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<svg width="" height=""> + <rect width="100" height="100" fill="green"/> +</svg> +<script> +test(function() { + let bounds = document.querySelector('svg').getBoundingClientRect(); + assert_greater_than(bounds.width, 0); + assert_greater_than(bounds.height, 0); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/use-href-percent-encoding-expected.html b/third_party/WebKit/LayoutTests/svg/custom/use-href-percent-encoding-expected.html new file mode 100644 index 0000000..f718ea6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/use-href-percent-encoding-expected.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/use-href-percent-encoding.html b/third_party/WebKit/LayoutTests/svg/custom/use-href-percent-encoding.html new file mode 100644 index 0000000..f085948 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/use-href-percent-encoding.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<svg xmlns="http://www.w3.org/2000/svg"> + <symbol id="желтый"> + <rect width="50" height="100" fill="green"/> + </symbol> + <symbol id="зеленый"> + <rect width="50" height="100" fill="green"/> + </symbol> + <use href="#желтый"/> + <use href="#%D0%B7%D0%B5%D0%BB%D0%B5%D0%BD%D1%8B%D0%B9" x="50"/> +</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/filters/filter-clip-expected.png b/third_party/WebKit/LayoutTests/svg/filters/filter-clip-expected.png index 8d66f12..76482fb 100644 --- a/third_party/WebKit/LayoutTests/svg/filters/filter-clip-expected.png +++ b/third_party/WebKit/LayoutTests/svg/filters/filter-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js b/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js index aaaf3f5..4764c7b3 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js +++ b/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
@@ -19,3 +19,10 @@ assert_style_value_equals(a[i], b[i]); } } + +// Creates a new div element with specified inline style. +function newDivWithStyle(style) { + let target = document.createElement('div'); + target.style = style; + return target; +}
diff --git a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssKeywordValue-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssKeywordValue-expected.txt deleted file mode 100644 index 079e41a..0000000 --- a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssKeywordValue-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a testharness.js-based test. -PASS Constructing CSSKeywordValue with an empty string throws a TypeError -FAIL Updating CSSKeywordValue.value with an empty string throws a TypeError assert_throws: function "() => result.value = value" did not throw -PASS Constructing CSSKeywordValue with an object that serializes to empty string throws a TypeError -FAIL Updating CSSKeywordValue.value with an object that serializes to empty string throws a TypeError assert_throws: function "() => result.value = value" did not throw -PASS CSSKeywordValue can be constructed from a CSS keyword -PASS CSSKeywordValue can be constructed from an unsupported CSS keyword -PASS CSSKeywordValue can be constructed from a string containing multiple tokens -PASS CSSKeywordValue can be constructed from a unicode string -PASS CSSKeywordValue can be constructed from an object that serializes to a nonempty string -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/computed-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/computed-expected.txt new file mode 100644 index 0000000..49af982 --- /dev/null +++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/computed-expected.txt
@@ -0,0 +1,10 @@ +This is a testharness.js-based test. +FAIL Computed StylePropertyMap contains every CSS property assert_equals: expected 298 but got 296 +PASS Computed StylePropertyMap contains CSS property declarations in style rules +FAIL Computed StylePropertyMap contains custom property declarations in style rules Illegal constructor +PASS Computed StylePropertyMap contains CSS property declarations in inline styles +FAIL Computed StylePropertyMap contains custom property declarations in inline rules Illegal constructor +PASS Computed StylePropertyMap contains computed values and not resolved values +PASS Computed StylePropertyMap is live +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/computed.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/computed.html new file mode 100644 index 0000000..ba776de6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/computed.html
@@ -0,0 +1,70 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Computed StylePropertyMap tests</title> +<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#computed-stylepropertymapreadonly-objects"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../resources/testhelper.js"></script> +<style>#target { height: 10px; --foo: auto; }</style> +<div style="width: 50px"> + <div id="target" style="top: 5px; --bar: 5; width: 50%;"></div> +</div> +<script> +'use strict'; + +const target = document.getElementById('target'); +// FIXME(774933): change this to Element.computedStyleMap +const styleMap = getComputedStyleMap(target); + +test(() => { + const computedStyle = getComputedStyle(target); + const properties = styleMap.getProperties(); + + // Two extra entries for custom properties + assert_equals(properties.length, computedStyle.length + 2); + for (let i = 0; i < computedStyle.length; i++) { + assert_equals(properties[i], computedStyle[i]); + assert_not_equals(styleMap.get(computedStyle[i]), null); + assert_not_equals(styleMap.getAll(computedStyle[i]).length, 0); + assert_true(styleMap.has(computedStyle[i])); + } +}, 'Computed StylePropertyMap contains every CSS property'); + +test(() => { + const result = styleMap.get('height'); + assert_style_value_equals(result, CSS.px(10)); +}, 'Computed StylePropertyMap contains CSS property declarations in style rules'); + +test(() => { + const result = styleMap.get('--foo'); + assert_style_value_equals(result, new CSSUnparsedValue('auto')); +}, 'Computed StylePropertyMap contains custom property declarations in style rules'); + +test(() => { + const result = styleMap.get('top'); + assert_style_value_equals(result, CSS.px(5)); +}, 'Computed StylePropertyMap contains CSS property declarations in inline styles'); + +test(() => { + const result = styleMap.get('--bar'); + assert_style_value_equals(result, new CSSUnparsedValue("5")); +}, 'Computed StylePropertyMap contains custom property declarations in inline rules'); + +test(() => { + const computedStyle = getComputedStyle(target); + assert_equals(computedStyle.width, '25px'); + + const result = styleMap.get('width'); + assert_style_value_equals(result, CSS.percent(50)); +}, 'Computed StylePropertyMap contains computed values and not resolved values'); + +test(() => { + let target = newDivWithStyle('width: 10px'); + const styleMap = target.styleMap; + assert_style_value_equals(styleMap.get('width'), CSS.px(10)); + + target.style.width = '20px'; + assert_style_value_equals(styleMap.get('width'), CSS.px(20)); +}, 'Computed StylePropertyMap is live'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-detune-modulation.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-detune-modulation.html index d02bfc2..3eeda40 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-detune-modulation.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-detune-modulation.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/audiobuffersource-testing.js"></script> <script src="../resources/buffer-loader.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-playbackrate-modulation.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-playbackrate-modulation.html index 6e9a440..87ac19e0 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-playbackrate-modulation.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-playbackrate-modulation.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/audiobuffersource-testing.js"></script> <script src="../resources/buffer-loader.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-custom.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-custom.html index 219fa990..e75a10a3 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-custom.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-custom.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/buffer-loader.js"></script> <script src="../resources/oscillator-testing.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sawtooth.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sawtooth.html index 1f97750..d8890f0c 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sawtooth.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sawtooth.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/buffer-loader.js"></script> <script src="../resources/oscillator-testing.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sine.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sine.html index fd2d3c2..12f3c319 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sine.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-sine.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/buffer-loader.js"></script> <script src="../resources/oscillator-testing.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-square.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-square.html index 1faf1a0..d38f2ac 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-square.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-square.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/buffer-loader.js"></script> <script src="../resources/oscillator-testing.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-triangle.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-triangle.html index ff2e44a..d893ebea 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-triangle.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-sweep-snr-triangle.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/buffer-loader.js"></script> <script src="../resources/oscillator-testing.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/PeriodicWave/periodicwave-contexts.html b/third_party/WebKit/LayoutTests/webaudio/PeriodicWave/periodicwave-contexts.html index c250d60..8f642fe 100644 --- a/third_party/WebKit/LayoutTests/webaudio/PeriodicWave/periodicwave-contexts.html +++ b/third_party/WebKit/LayoutTests/webaudio/PeriodicWave/periodicwave-contexts.html
@@ -10,6 +10,7 @@ <script src="../resources/audit.js"></script> <script src="../resources/buffer-loader.js"></script> <script src="../resources/oscillator-testing.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz.html index 76b670b..fed6668b 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz.html
@@ -5,6 +5,7 @@ <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> <script src="../../resources/audio-codec-test.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/vbr-128kbps-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/vbr-128kbps-44khz.html index af2d879..bfb8aa6 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/vbr-128kbps-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/vbr-128kbps-44khz.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/flac/flac-decode.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/flac/flac-decode.html index 8bbd63e0..b06d99a 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/flac/flac-decode.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/flac/flac-decode.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/mp3/128kbps-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/mp3/128kbps-44khz.html index 4dcd30c..c7a859d5 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/mp3/128kbps-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/mp3/128kbps-44khz.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/opus/opus-decode.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/opus/opus-decode.html index 99db9e3..50176c8 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/opus/opus-decode.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/opus/opus-decode.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html index 5954bf74..527a0a6 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-70kbps-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-70kbps-44khz.html index f43678d..aec480e 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-70kbps-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-70kbps-44khz.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-96kbps-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-96kbps-44khz.html index 0f8ebba..467228a 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-96kbps-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/vorbis/vbr-96kbps-44khz.html
@@ -6,6 +6,7 @@ </title> <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> + <script src="../../resources/audio-file-utils.js"></script> <script src="../../resources/buffer-loader.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-22khz-resample.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-22khz-resample.html index fd602dfb..a309080 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-22khz-resample.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-22khz-resample.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-44khz.html index 60f6178..74c750a 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/24bit-44khz.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/f32-44khz.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/f32-44khz.html index ff73a64..7a31fcb 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/f32-44khz.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/wav/f32-44khz.html
@@ -7,6 +7,7 @@ <script src="../../resources/audio-codec-test.js"></script> <script src="../../resources/audit-util.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/webm/webm-decode.html b/third_party/WebKit/LayoutTests/webaudio/codec-tests/webm/webm-decode.html index 2c57da3..e3da5e38 100644 --- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/webm/webm-decode.html +++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/webm/webm-decode.html
@@ -9,6 +9,7 @@ <script src="../../resources/audit-util.js"></script> <script src="../../resources/audit.js"></script> <script src="../../resources/buffer-loader.js"></script> + <script src="../../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/internals/audiobuffersource.html b/third_party/WebKit/LayoutTests/webaudio/internals/audiobuffersource.html index f11c6ca5..e66e43c 100644 --- a/third_party/WebKit/LayoutTests/webaudio/internals/audiobuffersource.html +++ b/third_party/WebKit/LayoutTests/webaudio/internals/audiobuffersource.html
@@ -10,6 +10,7 @@ <script src="../../resources/js-test.js"></script> <script src="../resources/audit-util.js"></script> <script src="../resources/buffer-loader.js"></script> + <script src="../resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audio-file-utils.js b/third_party/WebKit/LayoutTests/webaudio/resources/audio-file-utils.js new file mode 100644 index 0000000..b477e33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/resources/audio-file-utils.js
@@ -0,0 +1,157 @@ +// Utilities for creating a 16-bit PCM WAV file from an AudioBuffer +// when using Chrome testRunner, and for downloading an AudioBuffer as +// a float WAV file when running in a browser. + +function writeString(s, a, offset) { + for (let i = 0; i < s.length; ++i) { + a[offset + i] = s.charCodeAt(i); + } +} + +function writeInt16(n, a, offset) { + n = Math.floor(n); + + let b1 = n & 255; + let b2 = (n >> 8) & 255; + + a[offset + 0] = b1; + a[offset + 1] = b2; +} + +function writeInt32(n, a, offset) { + n = Math.floor(n); + let b1 = n & 255; + let b2 = (n >> 8) & 255; + let b3 = (n >> 16) & 255; + let b4 = (n >> 24) & 255; + + a[offset + 0] = b1; + a[offset + 1] = b2; + a[offset + 2] = b3; + a[offset + 3] = b4; +} + +// Return the bits of the float as a 32-bit integer value. This +// produces the raw bits; no intepretation of the value is done. +function floatBits(f) { + let buf = new ArrayBuffer(4); + (new Float32Array(buf))[0] = f; + let bits = (new Uint32Array(buf))[0]; + // Return as a signed integer. + return bits | 0; +} + +function writeAudioBuffer(audioBuffer, a, offset, asFloat) { + let n = audioBuffer.length; + let channels = audioBuffer.numberOfChannels; + + for (let i = 0; i < n; ++i) { + for (let k = 0; k < channels; ++k) { + let buffer = audioBuffer.getChannelData(k); + if (asFloat) { + let sample = floatBits(buffer[i]); + writeInt32(sample, a, offset); + offset += 4; + } else { + let sample = buffer[i] * 32768.0; + + // Clip samples to the limitations of 16-bit. + // If we don't do this then we'll get nasty wrap-around distortion. + if (sample < -32768) + sample = -32768; + if (sample > 32767) + sample = 32767; + + writeInt16(sample, a, offset); + offset += 2; + } + } + } +} + +// See http://soundfile.sapp.org/doc/WaveFormat/ and +// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html +// for a quick introduction to the WAVE PCM format. +function createWaveFileData(audioBuffer, asFloat) { + let bytesPerSample = asFloat ? 4 : 2; + let frameLength = audioBuffer.length; + let numberOfChannels = audioBuffer.numberOfChannels; + let sampleRate = audioBuffer.sampleRate; + let bitsPerSample = 8 * bytesPerSample; + let byteRate = sampleRate * numberOfChannels * bitsPerSample / 8; + let blockAlign = numberOfChannels * bitsPerSample / 8; + let wavDataByteLength = frameLength * numberOfChannels * bytesPerSample; + let headerByteLength = 44; + let totalLength = headerByteLength + wavDataByteLength; + + let waveFileData = new Uint8Array(totalLength); + + let subChunk1Size = 16; // for linear PCM + let subChunk2Size = wavDataByteLength; + let chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); + + writeString('RIFF', waveFileData, 0); + writeInt32(chunkSize, waveFileData, 4); + writeString('WAVE', waveFileData, 8); + writeString('fmt ', waveFileData, 12); + + writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4) + // The format tag value is 1 for integer PCM data and 3 for IEEE + // float data. + writeInt16(asFloat ? 3 : 1, waveFileData, 20); // AudioFormat (2) + writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2) + writeInt32(sampleRate, waveFileData, 24); // SampleRate (4) + writeInt32(byteRate, waveFileData, 28); // ByteRate (4) + writeInt16(blockAlign, waveFileData, 32); // BlockAlign (2) + writeInt32(bitsPerSample, waveFileData, 34); // BitsPerSample (4) + + writeString('data', waveFileData, 36); + writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4) + + // Write actual audio data starting at offset 44. + writeAudioBuffer(audioBuffer, waveFileData, 44, asFloat); + + return waveFileData; +} + +function createAudioData(audioBuffer, asFloat) { + return createWaveFileData(audioBuffer, asFloat); +} + +function finishAudioTest(event) { + let audioData = createAudioData(event.renderedBuffer); + testRunner.setAudioData(audioData); + testRunner.notifyDone(); +} + +// Save the given |audioBuffer| to a WAV file using the name given by +// |filename|. This is intended to be run from a browser. The +// developer is expected to use the console to run downloadAudioBuffer +// when necessary to create a new reference file for a test. If +// |asFloat| is given and is true, the WAV file produced uses 32-bit +// float format (full WebAudio resolution). Otherwise a 16-bit PCM +// WAV file is produced. +function downloadAudioBuffer(audioBuffer, filename, asFloat) { + // Don't download if testRunner is defined; we're running a layout + // test where this won't be useful in general. + if (window.testRunner) + return false; + // Convert the audio buffer to an array containing the WAV file + // contents. Then convert it to a blob that can be saved as a WAV + // file. + let wavData = createAudioData(audioBuffer, asFloat); + let blob = new Blob([wavData], {type: 'audio/wav'}); + // Manually create html tags for downloading, and simulate a click + // to download the file to the given file name. + let a = document.createElement('a'); + a.style.display = 'none'; + a.download = filename; + let audioURL = window.URL.createObjectURL(blob); + let audio = new Audio(); + audio.src = audioURL; + a.href = audioURL; + document.body.appendChild(a); + a.click(); + return true; +} +
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js b/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js index 1e39c87..4213fda5 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js
@@ -11,159 +11,6 @@ // How many frames in a WebAudio render quantum. let RENDER_QUANTUM_FRAMES = 128; -function writeString(s, a, offset) { - for (let i = 0; i < s.length; ++i) { - a[offset + i] = s.charCodeAt(i); - } -} - -function writeInt16(n, a, offset) { - n = Math.floor(n); - - let b1 = n & 255; - let b2 = (n >> 8) & 255; - - a[offset + 0] = b1; - a[offset + 1] = b2; -} - -function writeInt32(n, a, offset) { - n = Math.floor(n); - let b1 = n & 255; - let b2 = (n >> 8) & 255; - let b3 = (n >> 16) & 255; - let b4 = (n >> 24) & 255; - - a[offset + 0] = b1; - a[offset + 1] = b2; - a[offset + 2] = b3; - a[offset + 3] = b4; -} - -// Return the bits of the float as a 32-bit integer value. This -// produces the raw bits; no intepretation of the value is done. -function floatBits(f) { - let buf = new ArrayBuffer(4); - (new Float32Array(buf))[0] = f; - let bits = (new Uint32Array(buf))[0]; - // Return as a signed integer. - return bits | 0; -} - -function writeAudioBuffer(audioBuffer, a, offset, asFloat) { - let n = audioBuffer.length; - let channels = audioBuffer.numberOfChannels; - - for (let i = 0; i < n; ++i) { - for (let k = 0; k < channels; ++k) { - let buffer = audioBuffer.getChannelData(k); - if (asFloat) { - let sample = floatBits(buffer[i]); - writeInt32(sample, a, offset); - offset += 4; - } else { - let sample = buffer[i] * 32768.0; - - // Clip samples to the limitations of 16-bit. - // If we don't do this then we'll get nasty wrap-around distortion. - if (sample < -32768) - sample = -32768; - if (sample > 32767) - sample = 32767; - - writeInt16(sample, a, offset); - offset += 2; - } - } - } -} - -// See http://soundfile.sapp.org/doc/WaveFormat/ and -// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html -// for a quick introduction to the WAVE PCM format. -function createWaveFileData(audioBuffer, asFloat) { - let bytesPerSample = asFloat ? 4 : 2; - let frameLength = audioBuffer.length; - let numberOfChannels = audioBuffer.numberOfChannels; - let sampleRate = audioBuffer.sampleRate; - let bitsPerSample = 8 * bytesPerSample; - let byteRate = sampleRate * numberOfChannels * bitsPerSample / 8; - let blockAlign = numberOfChannels * bitsPerSample / 8; - let wavDataByteLength = frameLength * numberOfChannels * bytesPerSample; - let headerByteLength = 44; - let totalLength = headerByteLength + wavDataByteLength; - - let waveFileData = new Uint8Array(totalLength); - - let subChunk1Size = 16; // for linear PCM - let subChunk2Size = wavDataByteLength; - let chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); - - writeString('RIFF', waveFileData, 0); - writeInt32(chunkSize, waveFileData, 4); - writeString('WAVE', waveFileData, 8); - writeString('fmt ', waveFileData, 12); - - writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4) - // The format tag value is 1 for integer PCM data and 3 for IEEE - // float data. - writeInt16(asFloat ? 3 : 1, waveFileData, 20); // AudioFormat (2) - writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2) - writeInt32(sampleRate, waveFileData, 24); // SampleRate (4) - writeInt32(byteRate, waveFileData, 28); // ByteRate (4) - writeInt16(blockAlign, waveFileData, 32); // BlockAlign (2) - writeInt32(bitsPerSample, waveFileData, 34); // BitsPerSample (4) - - writeString('data', waveFileData, 36); - writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4) - - // Write actual audio data starting at offset 44. - writeAudioBuffer(audioBuffer, waveFileData, 44, asFloat); - - return waveFileData; -} - -function createAudioData(audioBuffer, asFloat) { - return createWaveFileData(audioBuffer, asFloat); -} - -function finishAudioTest(event) { - let audioData = createAudioData(event.renderedBuffer); - testRunner.setAudioData(audioData); - testRunner.notifyDone(); -} - -// Save the given |audioBuffer| to a WAV file using the name given by -// |filename|. This is intended to be run from a browser. The -// developer is expected to use the console to run downloadAudioBuffer -// when necessary to create a new reference file for a test. If -// |asFloat| is given and is true, the WAV file produced uses 32-bit -// float format (full WebAudio resolution). Otherwise a 16-bit PCM -// WAV file is produced. -function downloadAudioBuffer(audioBuffer, filename, asFloat) { - // Don't download if testRunner is defined; we're running a layout - // test where this won't be useful in general. - if (window.testRunner) - return false; - // Convert the audio buffer to an array containing the WAV file - // contents. Then convert it to a blob that can be saved as a WAV - // file. - let wavData = createAudioData(audioBuffer, asFloat); - let blob = new Blob([wavData], {type: 'audio/wav'}); - // Manually create html tags for downloading, and simulate a click - // to download the file to the given file name. - let a = document.createElement('a'); - a.style.display = 'none'; - a.download = filename; - let audioURL = window.URL.createObjectURL(blob); - let audio = new Audio(); - audio.src = audioURL; - a.href = audioURL; - document.body.appendChild(a); - a.click(); - return true; -} - // Compare two arrays (commonly extracted from buffer.getChannelData()) with // constraints: // options.thresholdSNR: Minimum allowed SNR between the actual and expected
diff --git a/third_party/WebKit/LayoutTests/webaudio/test-basic.html b/third_party/WebKit/LayoutTests/webaudio/test-basic.html index 3ccda25..dea2708 100644 --- a/third_party/WebKit/LayoutTests/webaudio/test-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/test-basic.html
@@ -13,6 +13,7 @@ <script src="../resources/testharnessreport.js"></script> <script src="resources/audit-util.js"></script> <script src="resources/audit.js"></script> + <script src="resources/audio-file-utils.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp index 0bf153f..7e0df3b4 100644 --- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
@@ -37,9 +37,18 @@ DummyExceptionStateForTesting exception_state; v8::Local<v8::Function> function = v8::Function::New(scope.GetContext(), nullptr).ToLocalChecked(); +#if defined(OFFICIAL_BUILD) + // crbug.com/779820 + // Official builds have an issue that stripts the CHECK strings despite that + // the strings are referenced in tests. + ASSERT_DEATH(NativeValueTraits<V8TestSequenceCallback>::NativeValue( + scope.GetIsolate(), function, exception_state), + ""); +#else ASSERT_DEATH(NativeValueTraits<V8TestSequenceCallback>::NativeValue( scope.GetIsolate(), function, exception_state), "NativeValueTraits<CallbackFunctionBase>::NativeValue"); +#endif } void ThrowException(v8::Local<v8::Name>,
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp index 148d465..2173a2f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp
@@ -5,8 +5,8 @@ #include "bindings/core/v8/ScriptPromiseResolver.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/probe/CoreProbes.h" +#include "public/platform/TaskType.h" namespace blink { @@ -14,7 +14,7 @@ : SuspendableObject(ExecutionContext::From(script_state)), state_(kPending), script_state_(script_state), - timer_(TaskRunnerHelper::Get(TaskType::kMicrotask, GetExecutionContext()), + timer_(GetExecutionContext()->GetTaskRunner(TaskType::kMicrotask), this, &ScriptPromiseResolver::OnTimerFired), resolver_(script_state) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxyTest.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxyTest.cpp index 96145cc..bba38a3 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WindowProxyTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxyTest.cpp
@@ -18,26 +18,27 @@ SimRequest main_resource("https://example.com/index.html", "text/html"); LoadURL("https://example.com/index.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head><script>" - "var childWindow;" - "function runTest() {" - " childWindow = window[0];" - " document.querySelector('iframe').onload = runTest2;" - " childWindow.location = 'data:text/plain,Initial.';" - "}" - "function runTest2() {" - " try {" - " childWindow.location = 'data:text/plain,Final.';" - " console.log('PASSED');" - " } catch (e) {" - " console.log('FAILED');" - " }" - " document.querySelector('iframe').onload = null;" - "}" - "</script></head><body onload='runTest()'>" - "<iframe></iframe></body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head><script> + var childWindow; + function runTest() { + childWindow = window[0]; + document.querySelector('iframe').onload = runTest2; + childWindow.location = 'data:text/plain,Initial.'; + } + function runTest2() { + try { + childWindow.location = 'data:text/plain,Final.'; + console.log('PASSED'); + } catch (e) { + console.log('FAILED'); + } + document.querySelector('iframe').onload = null; + } + </script></head><body onload='runTest()'> + <iframe></iframe></body></html> + )HTML"); // Wait for the first data: URL to load testing::RunPendingTasks();
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.cpp index b4de22d..16ec2ee4f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.cpp
@@ -7,16 +7,13 @@ namespace blink { SerializedColorParams::SerializedColorParams() - : color_space_(SerializedColorSpace::kLegacy), + : color_space_(SerializedColorSpace::kSRGB), pixel_format_(SerializedPixelFormat::kRGBA8), opacity_mode_(SerializedOpacityMode::kNonOpaque), storage_format_(SerializedImageDataStorageFormat::kUint8Clamped) {} SerializedColorParams::SerializedColorParams(CanvasColorParams color_params) { switch (color_params.ColorSpace()) { - case kLegacyCanvasColorSpace: - color_space_ = SerializedColorSpace::kLegacy; - break; case kSRGBCanvasColorSpace: color_space_ = SerializedColorSpace::kSRGB; break; @@ -74,11 +71,9 @@ } CanvasColorParams SerializedColorParams::GetCanvasColorParams() const { - CanvasColorSpace color_space = kLegacyCanvasColorSpace; + CanvasColorSpace color_space = kSRGBCanvasColorSpace; switch (color_space_) { - case SerializedColorSpace::kLegacy: - color_space = kLegacyCanvasColorSpace; - break; + case SerializedColorSpace::kLegacyObsolete: case SerializedColorSpace::kSRGB: color_space = kSRGBCanvasColorSpace; break;
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.h b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.h index 75892f7..16199c7d 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.h +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedColorParams.h
@@ -33,7 +33,11 @@ // This enumeration specifies the values used to serialize CanvasColorSpace. enum class SerializedColorSpace : uint32_t { - kLegacy = 0, + // Legacy sRGB color space is deprecated as of M65. Objects in legacy color + // space will be serialized as sRGB since the legacy behavior is now merged + // with sRGB color space. Deserialized objects with legacy color space also + // will be interpreted as sRGB. + kLegacyObsolete = 0, kSRGB = 1, kRec2020 = 2, kP3 = 3,
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp index 33f8e0b..bb8c226 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp
@@ -266,7 +266,7 @@ return file_list; } case kImageBitmapTag: { - SerializedColorSpace canvas_color_space = SerializedColorSpace::kLegacy; + SerializedColorSpace canvas_color_space = SerializedColorSpace::kSRGB; SerializedPixelFormat canvas_pixel_format = SerializedPixelFormat::kRGBA8; SerializedOpacityMode canvas_opacity_mode = SerializedOpacityMode::kOpaque; @@ -339,7 +339,7 @@ return transferred_image_bitmaps[index].Get(); } case kImageDataTag: { - SerializedColorSpace canvas_color_space = SerializedColorSpace::kLegacy; + SerializedColorSpace canvas_color_space = SerializedColorSpace::kSRGB; SerializedImageDataStorageFormat image_data_storage_format = SerializedImageDataStorageFormat::kUint8Clamped; uint32_t width = 0, height = 0, byte_length = 0;
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp b/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp index 9d5eda2..96aa299 100644 --- a/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp +++ b/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp
@@ -35,11 +35,12 @@ INSTANTIATE_TEST_CASE_P(All, DataTransferTest, ::testing::Bool()); TEST_P(DataTransferTest, NodeImage) { - SetBodyInnerHTML( - "<style>" - " #sample { width: 100px; height: 100px; }" - "</style>" - "<div id=sample></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #sample { width: 100px; height: 100px; } + </style> + <div id=sample></div> + )HTML"); Element* sample = GetDocument().getElementById("sample"); const std::unique_ptr<DragImage> image = DataTransfer::NodeImage(GetFrame(), *sample); @@ -47,12 +48,13 @@ } TEST_P(DataTransferTest, NodeImageWithNestedElement) { - SetBodyInnerHTML( - "<style>" - " div { -webkit-user-drag: element }" - " span:-webkit-drag { color: #0F0 }" - "</style>" - "<div id=sample><span>Green when dragged</span></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { -webkit-user-drag: element } + span:-webkit-drag { color: #0F0 } + </style> + <div id=sample><span>Green when dragged</span></div> + )HTML"); Element* sample = GetDocument().getElementById("sample"); const std::unique_ptr<DragImage> image = DataTransfer::NodeImage(GetFrame(), *sample); @@ -63,12 +65,13 @@ } TEST_P(DataTransferTest, NodeImageWithPsuedoClassWebKitDrag) { - SetBodyInnerHTML( - "<style>" - " #sample { width: 100px; height: 100px; }" - " #sample:-webkit-drag { width: 200px; height: 200px; }" - "</style>" - "<div id=sample></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #sample { width: 100px; height: 100px; } + #sample:-webkit-drag { width: 200px; height: 200px; } + </style> + <div id=sample></div> + )HTML"); Element* sample = GetDocument().getElementById("sample"); const std::unique_ptr<DragImage> image = DataTransfer::NodeImage(GetFrame(), *sample); @@ -77,12 +80,13 @@ } TEST_P(DataTransferTest, NodeImageWithoutDraggedLayoutObject) { - SetBodyInnerHTML( - "<style>" - " #sample { width: 100px; height: 100px; }" - " #sample:-webkit-drag { display:none }" - "</style>" - "<div id=sample></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #sample { width: 100px; height: 100px; } + #sample:-webkit-drag { display:none } + </style> + <div id=sample></div> + )HTML"); Element* sample = GetDocument().getElementById("sample"); const std::unique_ptr<DragImage> image = DataTransfer::NodeImage(GetFrame(), *sample); @@ -90,12 +94,13 @@ } TEST_P(DataTransferTest, NodeImageWithChangingLayoutObject) { - SetBodyInnerHTML( - "<style>" - " #sample { color: blue; }" - " #sample:-webkit-drag { display: inline-block; color: red; }" - "</style>" - "<span id=sample>foo</span>"); + SetBodyInnerHTML(R"HTML( + <style> + #sample { color: blue; } + #sample:-webkit-drag { display: inline-block; color: red; } + </style> + <span id=sample>foo</span> + )HTML"); Element* sample = GetDocument().getElementById("sample"); UpdateAllLifecyclePhases(); LayoutObject* before_layout_object = sample->GetLayoutObject(); @@ -117,26 +122,28 @@ } TEST_P(DataTransferTest, NodeImageExceedsViewportBounds) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " #node { width: 2000px; height: 2000px; }" - "</style>" - "<div id='node'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #node { width: 2000px; height: 2000px; } + </style> + <div id='node'></div> + )HTML"); Element& node = *GetDocument().getElementById("node"); const auto image = DataTransfer::NodeImage(GetFrame(), node); EXPECT_EQ(IntSize(800, 600), image->Size()); } TEST_P(DataTransferTest, NodeImageUnderScrollOffset) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " #first { width: 500px; height: 500px; }" - " #second { width: 300px; height: 200px; }" - "</style>" - "<div id='first'></div>" - "<div id='second'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #first { width: 500px; height: 500px; } + #second { width: 300px; height: 200px; } + </style> + <div id='first'></div> + <div id='second'></div> + )HTML"); const int scroll_amount = 10; LocalFrameView* frame_view = GetDocument().View(); @@ -159,13 +166,14 @@ } TEST_P(DataTransferTest, NodeImageSizeWithPageScaleFactor) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " html, body { height: 2000px; }" - " #node { width: 200px; height: 141px; }" - "</style>" - "<div id='node'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + html, body { height: 2000px; } + #node { width: 200px; height: 141px; } + </style> + <div id='node'></div> + )HTML"); const int page_scale_factor = 2; GetPage().SetPageScaleFactor(page_scale_factor); Element& node = *GetDocument().getElementById("node"); @@ -191,18 +199,19 @@ TEST_P(DataTransferTest, NodeImageWithPageScaleFactor) { // #bluegreen is a 2x1 rectangle where the left pixel is blue and the right // pixel is green. The element is offset by a margin of 1px. - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " #bluegreen {" - " width: 1px;" - " height: 1px;" - " background: #0f0;" - " border-left: 1px solid #00f;" - " margin: 1px;" - " }" - "</style>" - "<div id='bluegreen'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #bluegreen { + width: 1px; + height: 1px; + background: #0f0; + border-left: 1px solid #00f; + margin: 1px; + } + </style> + <div id='bluegreen'></div> + )HTML"); const int page_scale_factor = 2; GetPage().SetPageScaleFactor(page_scale_factor); Element& blue_green = *GetDocument().getElementById("bluegreen");
diff --git a/third_party/WebKit/Source/core/css/AffectedByPseudoTest.cpp b/third_party/WebKit/Source/core/css/AffectedByPseudoTest.cpp index 5079f46..d4983209 100644 --- a/third_party/WebKit/Source/core/css/AffectedByPseudoTest.cpp +++ b/third_party/WebKit/Source/core/css/AffectedByPseudoTest.cpp
@@ -78,14 +78,15 @@ {divTag, false}, {spanTag, false}}; - SetHtmlInnerHTML( - "<head>" - "<style>:focus div { background-color: pink }</style>" - "</head>" - "<body>" - "<div><div></div></div>" - "<div><span></span></div>" - "</body>"); + SetHtmlInnerHTML(R"HTML( + <head> + <style>:focus div { background-color: pink }</style> + </head> + <body> + <div><div></div></div> + <div><span></span></div> + </body> + )HTML"); CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); } @@ -99,14 +100,15 @@ {divTag, false}, {spanTag, false}}; - SetHtmlInnerHTML( - "<head>" - "<style>body:focus div { background-color: pink }</style>" - "</head>" - "<body>" - "<div><div></div></div>" - "<div><span></span></div>" - "</body>"); + SetHtmlInnerHTML(R"HTML( + <head> + <style>body:focus div { background-color: pink }</style> + </head> + <body> + <div><div></div></div> + <div><span></span></div> + </body> + )HTML"); CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); } @@ -123,14 +125,15 @@ {divTag, false}, {spanTag, false}}; - SetHtmlInnerHTML( - "<head>" - "<style>:not(body):focus div { background-color: pink }</style>" - "</head>" - "<body>" - "<div><div></div></div>" - "<div><span></span></div>" - "</body>"); + SetHtmlInnerHTML(R"HTML( + <head> + <style>:not(body):focus div { background-color: pink }</style> + </head> + <body> + <div><div></div></div> + <div><span></span></div> + </body> + )HTML"); CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); } @@ -145,16 +148,17 @@ ElementResult expected[] = { {bodyTag, false}, {divTag, true}, {spanTag, false}, {divTag, false}}; - SetHtmlInnerHTML( - "<head>" - "<style>:focus + div { background-color: pink }</style>" - "</head>" - "<body>" - "<div>" - " <span></span>" - "</div>" - "<div></div>" - "</body>"); + SetHtmlInnerHTML(R"HTML( + <head> + <style>:focus + div { background-color: pink }</style> + </head> + <body> + <div> + <span></span> + </div> + <div></div> + </body> + )HTML"); CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); } @@ -163,20 +167,21 @@ // Check that when focussing the outer div in the document below, you only // get a single element style recalc. - SetHtmlInnerHTML( - "<style>:focus { border: 1px solid lime; }</style>" - "<div id=d tabIndex=1>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "</div>"); + SetHtmlInnerHTML(R"HTML( + <style>:focus { border: 1px solid lime; }</style> + <div id=d tabIndex=1> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -195,20 +200,21 @@ // Check that when focussing the outer div in the document below, you get a // style recalc for the whole subtree. - SetHtmlInnerHTML( - "<style>:focus div { border: 1px solid lime; }</style>" - "<div id=d tabIndex=1>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "</div>"); + SetHtmlInnerHTML(R"HTML( + <style>:focus div { border: 1px solid lime; }</style> + <div id=d tabIndex=1> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -227,20 +233,21 @@ // Check that when focussing the outer div in the document below, you get a // style recalc for the outer div and the class=a div only. - SetHtmlInnerHTML( - "<style>:focus .a { border: 1px solid lime; }</style>" - "<div id=d tabIndex=1>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div class='a'></div>" - "</div>"); + SetHtmlInnerHTML(R"HTML( + <style>:focus .a { border: 1px solid lime; }</style> + <div id=d tabIndex=1> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div class='a'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -261,20 +268,21 @@ // include 'a', but the id=d div should be affectedByFocus, not // childrenOrSiblingsAffectedByFocus. - SetHtmlInnerHTML( - "<style>#nomatch:focus .a { border: 1px solid lime; }</style>" - "<div id=d tabIndex=1>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div></div>" - "<div class='a'></div>" - "</div>"); + SetHtmlInnerHTML(R"HTML( + <style>#nomatch:focus .a { border: 1px solid lime; }</style> + <div id=d tabIndex=1> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div class='a'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -293,14 +301,15 @@ // Check that when changing the focus between 2 elements we don't need a style // recalc for all the ancestors affected by ":focus-within". - SetHtmlInnerHTML( - "<style>div:focus-within { background-color: lime; }</style>" - "<div>" - " <div>" - " <div id=focusme1 tabIndex=1></div>" - " <div id=focusme2 tabIndex=2></div>" - " <div>" - "</div>"); + SetHtmlInnerHTML(R"HTML( + <style>div:focus-within { background-color: lime; }</style> + <div> + <div> + <div id=focusme1 tabIndex=1></div> + <div id=focusme2 tabIndex=2></div> + <div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index eb94729..339c08c 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -198,6 +198,8 @@ "FontFaceSetDocument.h", "FontFaceSetLoadEvent.cpp", "FontFaceSetLoadEvent.h", + "FontFaceSetWorker.cpp", + "FontFaceSetWorker.h", "FontFaceSource.cpp", "FontFaceSource.h", "FontSize.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSFontFace.cpp b/third_party/WebKit/Source/core/css/CSSFontFace.cpp index e3daf75a..76de3a9 100644 --- a/third_party/WebKit/Source/core/css/CSSFontFace.cpp +++ b/third_party/WebKit/Source/core/css/CSSFontFace.cpp
@@ -30,8 +30,10 @@ #include "core/css/CSSFontSelector.h" #include "core/css/CSSSegmentedFontFace.h" #include "core/css/FontFaceSetDocument.h" +#include "core/css/FontFaceSetWorker.h" #include "core/css/RemoteFontFaceSource.h" #include "core/frame/UseCounter.h" +#include "core/workers/WorkerGlobalScope.h" #include "platform/fonts/FontDescription.h" #include "platform/fonts/SimpleFontData.h" @@ -185,12 +187,20 @@ else font_face_->SetLoadStatus(new_status); - if (!segmented_font_face_ || !font_face_->GetExecutionContext() || - !font_face_->GetExecutionContext()->IsDocument()) + if (!segmented_font_face_ || !font_face_->GetExecutionContext()) return; - Document* document = ToDocument(font_face_->GetExecutionContext()); - if (document && new_status == FontFace::kLoading) - FontFaceSetDocument::From(*document)->BeginFontLoading(font_face_); + + if (font_face_->GetExecutionContext()->IsDocument()) { + Document* document = ToDocument(font_face_->GetExecutionContext()); + if (new_status == FontFace::kLoading) + FontFaceSetDocument::From(*document)->BeginFontLoading(font_face_); + } + if (font_face_->GetExecutionContext()->IsWorkerGlobalScope()) { + WorkerGlobalScope* scope = + ToWorkerGlobalScope(font_face_->GetExecutionContext()); + if (new_status == FontFace::kLoading) + FontFaceSetWorker::From(*scope)->BeginFontLoading(font_face_); + } } void CSSFontFace::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/css/CSSFontSelector.h b/third_party/WebKit/Source/core/css/CSSFontSelector.h index 41e1c7c9..9146fbf 100644 --- a/third_party/WebKit/Source/core/css/CSSFontSelector.h +++ b/third_party/WebKit/Source/core/css/CSSFontSelector.h
@@ -60,7 +60,7 @@ const AtomicString& family_name, const FontDataForRangeSet&) override; bool IsPlatformFamilyMatchAvailable(const FontDescription&, - const AtomicString& family); + const AtomicString& family) override; void FontFaceInvalidated() override; @@ -71,7 +71,7 @@ void UnregisterForInvalidationCallbacks(FontSelectorClient*) override; ExecutionContext* GetExecutionContext() const override { return document_; } - FontFaceCache* GetFontFaceCache() { return &font_face_cache_; } + FontFaceCache* GetFontFaceCache() override { return &font_face_cache_; } const GenericFontFamilySettings& GetGenericFontFamilySettings() const { return generic_font_family_settings_;
diff --git a/third_party/WebKit/Source/core/css/CSSSelectorWatchTest.cpp b/third_party/WebKit/Source/core/css/CSSSelectorWatchTest.cpp index c5b3944..ecdee88 100644 --- a/third_party/WebKit/Source/core/css/CSSSelectorWatchTest.cpp +++ b/third_party/WebKit/Source/core/css/CSSSelectorWatchTest.cpp
@@ -43,12 +43,13 @@ } TEST_F(CSSSelectorWatchTest, RecalcOnDocumentChange) { - GetDocument().body()->SetInnerHTMLFromString( - "<div>" - " <span id='x' class='a'></span>" - " <span id='y' class='b'><span></span></span>" - " <span id='z'><span></span></span>" - "</div>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <div> + <span id='x' class='a'></span> + <span id='y' class='b'><span></span></span> + <span id='z'><span></span></span> + </div> + )HTML"); CSSSelectorWatch& watch = CSSSelectorWatch::From(GetDocument());
diff --git a/third_party/WebKit/Source/core/css/DragUpdateTest.cpp b/third_party/WebKit/Source/core/css/DragUpdateTest.cpp index ea85584..ab2a5a2 100644 --- a/third_party/WebKit/Source/core/css/DragUpdateTest.cpp +++ b/third_party/WebKit/Source/core/css/DragUpdateTest.cpp
@@ -19,15 +19,16 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = DummyPageHolder::Create(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); - document.documentElement()->SetInnerHTMLFromString( - "<style>div {width:100px;height:100px} div:-webkit-drag { " - "background-color: green }</style>" - "<div id='div'>" - "<span></span>" - "<span></span>" - "<span></span>" - "<span></span>" - "</div>"); + document.documentElement()->SetInnerHTMLFromString(R"HTML( + <style>div {width:100px;height:100px} div:-webkit-drag { + background-color: green }</style> + <div id='div'> + <span></span> + <span></span> + <span></span> + <span></span> + </div> + )HTML"); document.View()->UpdateAllLifecyclePhases(); unsigned start_count = document.GetStyleEngine().StyleForElementCount(); @@ -48,15 +49,16 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = DummyPageHolder::Create(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); - document.documentElement()->SetInnerHTMLFromString( - "<style>div {width:100px;height:100px} div:-webkit-drag .drag { " - "background-color: green }</style>" - "<div id='div'>" - "<span></span>" - "<span></span>" - "<span class='drag'></span>" - "<span></span>" - "</div>"); + document.documentElement()->SetInnerHTMLFromString(R"HTML( + <style>div {width:100px;height:100px} div:-webkit-drag .drag { + background-color: green }</style> + <div id='div'> + <span></span> + <span></span> + <span class='drag'></span> + <span></span> + </div> + )HTML"); document.UpdateStyleAndLayout(); unsigned start_count = document.GetStyleEngine().StyleForElementCount(); @@ -77,16 +79,17 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = DummyPageHolder::Create(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); - document.documentElement()->SetInnerHTMLFromString( - "<style>div {width:100px;height:100px} div:-webkit-drag + .drag { " - "background-color: green }</style>" - "<div id='div'>" - "<span></span>" - "<span></span>" - "<span></span>" - "<span></span>" - "</div>" - "<span class='drag'></span>"); + document.documentElement()->SetInnerHTMLFromString(R"HTML( + <style>div {width:100px;height:100px} div:-webkit-drag + .drag { + background-color: green }</style> + <div id='div'> + <span></span> + <span></span> + <span></span> + <span></span> + </div> + <span class='drag'></span> + )HTML"); document.UpdateStyleAndLayout(); unsigned start_count = document.GetStyleEngine().StyleForElementCount();
diff --git a/third_party/WebKit/Source/core/css/FontFaceSet.cpp b/third_party/WebKit/Source/core/css/FontFaceSet.cpp index 2246f61..517843d3 100644 --- a/third_party/WebKit/Source/core/css/FontFaceSet.cpp +++ b/third_party/WebKit/Source/core/css/FontFaceSet.cpp
@@ -4,8 +4,309 @@ #include "core/css/FontFaceSet.h" +#include "core/css/FontFaceCache.h" +#include "core/css/FontFaceSetLoadEvent.h" +#include "platform/fonts/Font.h" + namespace blink { +const int FontFaceSet::kDefaultFontSize = 10; +const char FontFaceSet::kDefaultFontFamily[] = "sans-serif"; +void FontFaceSet::Suspend() { + async_runner_->Suspend(); +} + +void FontFaceSet::Resume() { + async_runner_->Resume(); +} + +void FontFaceSet::ContextDestroyed(ExecutionContext*) { + async_runner_->Stop(); +} + +void FontFaceSet::HandlePendingEventsAndPromisesSoon() { + // async_runner_ will be automatically stopped on destruction. + async_runner_->RunAsync(); +} + +void FontFaceSet::HandlePendingEventsAndPromises() { + FireLoadingEvent(); + FireDoneEventIfPossible(); +} + +void FontFaceSet::FireLoadingEvent() { + if (should_fire_loading_event_) { + should_fire_loading_event_ = false; + DispatchEvent( + FontFaceSetLoadEvent::CreateForFontFaces(EventTypeNames::loading)); + } +} + +FontFaceSet* FontFaceSet::addForBinding(ScriptState*, + FontFace* font_face, + ExceptionState&) { + DCHECK(font_face); + if (!InActiveContext()) + return this; + if (non_css_connected_faces_.Contains(font_face)) + return this; + if (IsCSSConnectedFontFace(font_face)) + return this; + FontSelector* font_selector = GetFontSelector(); + non_css_connected_faces_.insert(font_face); + font_selector->GetFontFaceCache()->AddFontFace(font_face, false); + if (font_face->LoadStatus() == FontFace::kLoading) + AddToLoadingFonts(font_face); + font_selector->FontFaceInvalidated(); + return this; +} + +void FontFaceSet::clearForBinding(ScriptState*, ExceptionState&) { + if (!InActiveContext() || non_css_connected_faces_.IsEmpty()) + return; + FontSelector* font_selector = GetFontSelector(); + FontFaceCache* font_face_cache = font_selector->GetFontFaceCache(); + for (const auto& font_face : non_css_connected_faces_) { + font_face_cache->RemoveFontFace(font_face.Get(), false); + if (font_face->LoadStatus() == FontFace::kLoading) + RemoveFromLoadingFonts(font_face); + } + non_css_connected_faces_.clear(); + font_selector->FontFaceInvalidated(); +} + +bool FontFaceSet::deleteForBinding(ScriptState*, + FontFace* font_face, + ExceptionState&) { + DCHECK(font_face); + if (!InActiveContext()) + return false; + HeapListHashSet<Member<FontFace>>::iterator it = + non_css_connected_faces_.find(font_face); + if (it != non_css_connected_faces_.end()) { + non_css_connected_faces_.erase(it); + FontSelector* font_selector = GetFontSelector(); + font_selector->GetFontFaceCache()->RemoveFontFace(font_face, false); + if (font_face->LoadStatus() == FontFace::kLoading) + RemoveFromLoadingFonts(font_face); + font_selector->FontFaceInvalidated(); + return true; + } + return false; +} + +bool FontFaceSet::hasForBinding(ScriptState*, + FontFace* font_face, + ExceptionState&) const { + DCHECK(font_face); + if (!InActiveContext()) + return false; + return non_css_connected_faces_.Contains(font_face) || + IsCSSConnectedFontFace(font_face); +} + +void FontFaceSet::Trace(blink::Visitor* visitor) { + visitor->Trace(non_css_connected_faces_); + visitor->Trace(loading_fonts_); + visitor->Trace(loaded_fonts_); + visitor->Trace(failed_fonts_); + visitor->Trace(ready_); + visitor->Trace(async_runner_); + SuspendableObject::Trace(visitor); + EventTargetWithInlineData::Trace(visitor); + FontFace::LoadFontCallback::Trace(visitor); +} + +size_t FontFaceSet::size() const { + if (!InActiveContext()) + return non_css_connected_faces_.size(); + return CSSConnectedFontFaceList().size() + non_css_connected_faces_.size(); +} + +void FontFaceSet::AddFontFacesToFontFaceCache(FontFaceCache* font_face_cache) { + for (const auto& font_face : non_css_connected_faces_) + font_face_cache->AddFontFace(font_face, false); +} + +void FontFaceSet::AddToLoadingFonts(FontFace* font_face) { + if (!is_loading_) { + is_loading_ = true; + should_fire_loading_event_ = true; + if (ready_->GetState() != ReadyProperty::kPending) + ready_->Reset(); + HandlePendingEventsAndPromisesSoon(); + } + loading_fonts_.insert(font_face); + font_face->AddCallback(this); +} + +void FontFaceSet::RemoveFromLoadingFonts(FontFace* font_face) { + loading_fonts_.erase(font_face); + if (loading_fonts_.IsEmpty()) + HandlePendingEventsAndPromisesSoon(); +} + +void FontFaceSet::LoadFontPromiseResolver::LoadFonts() { + if (!num_loading_) { + resolver_->Resolve(font_faces_); + return; + } + + for (size_t i = 0; i < font_faces_.size(); i++) + font_faces_[i]->LoadWithCallback(this); +} + +ScriptPromise FontFaceSet::load(ScriptState* script_state, + const String& font_string, + const String& text) { + if (!InActiveContext()) + return ScriptPromise(); + + Font font; + if (!ResolveFontStyle(font_string, font)) { + ScriptPromiseResolver* resolver = + ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + resolver->Reject(DOMException::Create( + kSyntaxError, "Could not resolve '" + font_string + "' as a font.")); + return promise; + } + + FontFaceCache* font_face_cache = GetFontSelector()->GetFontFaceCache(); + FontFaceArray faces; + for (const FontFamily* f = &font.GetFontDescription().Family(); f; + f = f->Next()) { + CSSSegmentedFontFace* segmented_font_face = + font_face_cache->Get(font.GetFontDescription(), f->Family()); + if (segmented_font_face) + segmented_font_face->Match(text, faces); + } + + LoadFontPromiseResolver* resolver = + LoadFontPromiseResolver::Create(faces, script_state); + ScriptPromise promise = resolver->Promise(); + // After this, resolver->promise() may return null. + resolver->LoadFonts(); + return promise; +} + +bool FontFaceSet::check(const String& font_string, + const String& text, + ExceptionState& exception_state) { + if (!InActiveContext()) + return false; + + Font font; + if (!ResolveFontStyle(font_string, font)) { + exception_state.ThrowDOMException( + kSyntaxError, "Could not resolve '" + font_string + "' as a font."); + return false; + } + + FontSelector* font_selector = GetFontSelector(); + FontFaceCache* font_face_cache = font_selector->GetFontFaceCache(); + + bool has_loaded_faces = false; + for (const FontFamily* f = &font.GetFontDescription().Family(); f; + f = f->Next()) { + CSSSegmentedFontFace* face = + font_face_cache->Get(font.GetFontDescription(), f->Family()); + if (face) { + if (!face->CheckFont(text)) + return false; + has_loaded_faces = true; + } + } + if (has_loaded_faces) + return true; + for (const FontFamily* f = &font.GetFontDescription().Family(); f; + f = f->Next()) { + if (font_selector->IsPlatformFamilyMatchAvailable(font.GetFontDescription(), + f->Family())) + return true; + } + return false; +} + +void FontFaceSet::FireDoneEvent() { + if (is_loading_) { + FontFaceSetLoadEvent* done_event = nullptr; + FontFaceSetLoadEvent* error_event = nullptr; + done_event = FontFaceSetLoadEvent::CreateForFontFaces( + EventTypeNames::loadingdone, loaded_fonts_); + loaded_fonts_.clear(); + if (!failed_fonts_.IsEmpty()) { + error_event = FontFaceSetLoadEvent::CreateForFontFaces( + EventTypeNames::loadingerror, failed_fonts_); + failed_fonts_.clear(); + } + is_loading_ = false; + DispatchEvent(done_event); + if (error_event) + DispatchEvent(error_event); + } + + if (ready_->GetState() == ReadyProperty::kPending) + ready_->Resolve(this); +} + +bool FontFaceSet::ShouldSignalReady() const { + if (!loading_fonts_.IsEmpty()) + return false; + return is_loading_ || ready_->GetState() == ReadyProperty::kPending; +} + +void FontFaceSet::LoadFontPromiseResolver::NotifyLoaded(FontFace* font_face) { + num_loading_--; + if (num_loading_ || error_occured_) + return; + + resolver_->Resolve(font_faces_); +} + +void FontFaceSet::LoadFontPromiseResolver::NotifyError(FontFace* font_face) { + num_loading_--; + if (!error_occured_) { + error_occured_ = true; + resolver_->Reject(font_face->GetError()); + } +} + +void FontFaceSet::LoadFontPromiseResolver::Trace(blink::Visitor* visitor) { + visitor->Trace(font_faces_); + visitor->Trace(resolver_); + LoadFontCallback::Trace(visitor); +} + +bool FontFaceSet::IterationSource::Next(ScriptState*, + Member<FontFace>& key, + Member<FontFace>& value, + ExceptionState&) { + if (font_faces_.size() <= index_) + return false; + key = value = font_faces_[index_++]; + return true; +} + +FontFaceSetIterable::IterationSource* FontFaceSet::StartIteration( + ScriptState*, + ExceptionState&) { + // Setlike should iterate each item in insertion order, and items should + // be keep on up to date. But since blink does not have a way to hook up CSS + // modification, take a snapshot here, and make it ordered as follows. + HeapVector<Member<FontFace>> font_faces; + if (InActiveContext()) { + const HeapListHashSet<Member<FontFace>>& css_connected_faces = + CSSConnectedFontFaceList(); + font_faces.ReserveInitialCapacity(css_connected_faces.size() + + non_css_connected_faces_.size()); + for (const auto& font_face : css_connected_faces) + font_faces.push_back(font_face); + for (const auto& font_face : non_css_connected_faces_) + font_faces.push_back(font_face); + } + return new IterationSource(font_faces); +} } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/FontFaceSet.h b/third_party/WebKit/Source/core/css/FontFaceSet.h index 624325b0..f1f93b9 100644 --- a/third_party/WebKit/Source/core/css/FontFaceSet.h +++ b/third_party/WebKit/Source/core/css/FontFaceSet.h
@@ -1,3 +1,4 @@ + // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,10 +8,14 @@ #include "bindings/core/v8/Iterable.h" #include "bindings/core/v8/ScriptPromise.h" +#include "bindings/core/v8/ScriptPromiseResolver.h" #include "core/css/FontFace.h" +#include "core/dom/SuspendableObject.h" #include "core/dom/events/EventListener.h" #include "core/dom/events/EventTarget.h" +#include "platform/AsyncMethodRunner.h" #include "platform/bindings/ScriptWrappable.h" +#include "platform/fonts/FontSelector.h" // Mac OS X 10.6 SDK defines check() macro that interferes with our check() // method @@ -20,55 +25,97 @@ namespace blink { +class FontFaceCache; + using FontFaceSetIterable = SetlikeIterable<Member<FontFace>>; class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData, - public FontFaceSetIterable { + public SuspendableObject, + public FontFaceSetIterable, + public FontFace::LoadFontCallback { DEFINE_WRAPPERTYPEINFO(); WTF_MAKE_NONCOPYABLE(FontFaceSet); public: - FontFaceSet() {} + FontFaceSet(ExecutionContext& context) + : SuspendableObject(&context), + is_loading_(false), + should_fire_loading_event_(false), + ready_(new ReadyProperty(GetExecutionContext(), + this, + ReadyProperty::kReady)), + async_runner_(AsyncMethodRunner<FontFaceSet>::Create( + this, + &FontFaceSet::HandlePendingEventsAndPromises)) {} ~FontFaceSet() {} DEFINE_ATTRIBUTE_EVENT_LISTENER(loading); DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone); DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror); - virtual bool check(const String& font, - const String& text, - ExceptionState&) = 0; - virtual ScriptPromise load(ScriptState*, - const String& font, - const String& text) = 0; + bool check(const String& font, const String& text, ExceptionState&); + ScriptPromise load(ScriptState*, const String& font, const String& text); virtual ScriptPromise ready(ScriptState*) = 0; - virtual ExecutionContext* GetExecutionContext() const = 0; + ExecutionContext* GetExecutionContext() const { + return SuspendableObject::GetExecutionContext(); + } + const AtomicString& InterfaceName() const { return EventTargetNames::FontFaceSet; } - virtual FontFaceSet* addForBinding(ScriptState*, - FontFace*, - ExceptionState&) = 0; - virtual void clearForBinding(ScriptState*, ExceptionState&) = 0; - virtual bool deleteForBinding(ScriptState*, FontFace*, ExceptionState&) = 0; - virtual bool hasForBinding(ScriptState*, - FontFace*, - ExceptionState&) const = 0; + FontFaceSet* addForBinding(ScriptState*, FontFace*, ExceptionState&); + void clearForBinding(ScriptState*, ExceptionState&); + bool deleteForBinding(ScriptState*, FontFace*, ExceptionState&); + bool hasForBinding(ScriptState*, FontFace*, ExceptionState&) const; - virtual size_t size() const = 0; + void AddFontFacesToFontFaceCache(FontFaceCache*); + + // SuspendableObject + void Suspend() override; + void Resume() override; + void ContextDestroyed(ExecutionContext*) override; + + size_t size() const; virtual AtomicString status() const = 0; - virtual void Trace(blink::Visitor* visitor) { - EventTargetWithInlineData::Trace(visitor); - } + virtual void Trace(blink::Visitor*); protected: - // Iterable overrides. - virtual FontFaceSetIterable::IterationSource* StartIteration( - ScriptState*, - ExceptionState&) = 0; + static const int kDefaultFontSize; + static const char kDefaultFontFamily[]; + + virtual bool ResolveFontStyle(const String&, Font&) = 0; + virtual bool InActiveContext() const = 0; + virtual FontSelector* GetFontSelector() const = 0; + virtual const HeapListHashSet<Member<FontFace>>& CSSConnectedFontFaceList() + const = 0; + bool IsCSSConnectedFontFace(FontFace* font_face) const { + return CSSConnectedFontFaceList().Contains(font_face); + } + + virtual void FireDoneEventIfPossible() = 0; + + void AddToLoadingFonts(FontFace*); + void RemoveFromLoadingFonts(FontFace*); + void HandlePendingEventsAndPromisesSoon(); + bool ShouldSignalReady() const; + void FireDoneEvent(); + + using ReadyProperty = ScriptPromiseProperty<Member<FontFaceSet>, + Member<FontFaceSet>, + Member<DOMException>>; + + bool is_loading_; + bool should_fire_loading_event_; + HeapListHashSet<Member<FontFace>> non_css_connected_faces_; + HeapHashSet<Member<FontFace>> loading_fonts_; + FontFaceArray loaded_fonts_; + FontFaceArray failed_fonts_; + Member<ReadyProperty> ready_; + + Member<AsyncMethodRunner<FontFaceSet>> async_runner_; class IterationSource final : public FontFaceSetIterable::IterationSource { public: @@ -88,6 +135,47 @@ size_t index_; HeapVector<Member<FontFace>> font_faces_; }; + + class LoadFontPromiseResolver final + : public GarbageCollectedFinalized<LoadFontPromiseResolver>, + public FontFace::LoadFontCallback { + USING_GARBAGE_COLLECTED_MIXIN(LoadFontPromiseResolver); + + public: + static LoadFontPromiseResolver* Create(FontFaceArray faces, + ScriptState* script_state) { + return new LoadFontPromiseResolver(faces, script_state); + } + + void LoadFonts(); + ScriptPromise Promise() { return resolver_->Promise(); } + + void NotifyLoaded(FontFace*) override; + void NotifyError(FontFace*) override; + + void Trace(blink::Visitor*); + + private: + LoadFontPromiseResolver(FontFaceArray faces, ScriptState* script_state) + : num_loading_(faces.size()), + error_occured_(false), + resolver_(ScriptPromiseResolver::Create(script_state)) { + font_faces_.swap(faces); + } + + HeapVector<Member<FontFace>> font_faces_; + int num_loading_; + bool error_occured_; + Member<ScriptPromiseResolver> resolver_; + }; + + private: + FontFaceSetIterable::IterationSource* StartIteration( + ScriptState*, + ExceptionState&) override; + + void HandlePendingEventsAndPromises(); + void FireLoadingEvent(); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/FontFaceSet.idl b/third_party/WebKit/Source/core/css/FontFaceSet.idl index 2e8622d..06ca463 100644 --- a/third_party/WebKit/Source/core/css/FontFaceSet.idl +++ b/third_party/WebKit/Source/core/css/FontFaceSet.idl
@@ -32,11 +32,12 @@ enum FontFaceSetLoadStatus { "loading", "loaded" }; -// TODO(foolip): This interface should be [Exposed=Window,Worker] and should -// have a constructor, and thus not have [NoInterfaceObject]. +// TODO(foolip): This interface should have a constructor and thos not have +// [NoInterfaceObject] [ DependentLifetime, - NoInterfaceObject + NoInterfaceObject, + Exposed(Window StableBlinkFeatures, Worker ExperimentalCanvasFeatures) ] interface FontFaceSet : EventTarget { setlike<FontFace>;
diff --git a/third_party/WebKit/Source/core/css/FontFaceSetDocument.cpp b/third_party/WebKit/Source/core/css/FontFaceSetDocument.cpp index 6f73179..e0c341b 100644 --- a/third_party/WebKit/Source/core/css/FontFaceSetDocument.cpp +++ b/third_party/WebKit/Source/core/css/FontFaceSetDocument.cpp
@@ -26,7 +26,6 @@ #include "core/css/FontFaceSetDocument.h" #include "bindings/core/v8/Dictionary.h" -#include "bindings/core/v8/ScriptPromiseResolver.h" #include "core/css/CSSFontSelector.h" #include "core/css/CSSSegmentedFontFace.h" #include "core/css/FontFaceCache.h" @@ -44,85 +43,8 @@ namespace blink { -static const int kDefaultFontSize = 10; -static const char kDefaultFontFamily[] = "sans-serif"; - -class LoadFontPromiseResolver final - : public GarbageCollectedFinalized<LoadFontPromiseResolver>, - public FontFace::LoadFontCallback { - USING_GARBAGE_COLLECTED_MIXIN(LoadFontPromiseResolver); - - public: - static LoadFontPromiseResolver* Create(FontFaceArray faces, - ScriptState* script_state) { - return new LoadFontPromiseResolver(faces, script_state); - } - - void LoadFonts(); - ScriptPromise Promise() { return resolver_->Promise(); } - - void NotifyLoaded(FontFace*) override; - void NotifyError(FontFace*) override; - - virtual void Trace(blink::Visitor*); - - private: - LoadFontPromiseResolver(FontFaceArray faces, ScriptState* script_state) - : num_loading_(faces.size()), - error_occured_(false), - resolver_(ScriptPromiseResolver::Create(script_state)) { - font_faces_.swap(faces); - } - - HeapVector<Member<FontFace>> font_faces_; - int num_loading_; - bool error_occured_; - Member<ScriptPromiseResolver> resolver_; -}; - -void LoadFontPromiseResolver::LoadFonts() { - if (!num_loading_) { - resolver_->Resolve(font_faces_); - return; - } - - for (size_t i = 0; i < font_faces_.size(); i++) - font_faces_[i]->LoadWithCallback(this); -} - -void LoadFontPromiseResolver::NotifyLoaded(FontFace* font_face) { - num_loading_--; - if (num_loading_ || error_occured_) - return; - - resolver_->Resolve(font_faces_); -} - -void LoadFontPromiseResolver::NotifyError(FontFace* font_face) { - num_loading_--; - if (!error_occured_) { - error_occured_ = true; - resolver_->Reject(font_face->GetError()); - } -} - -void LoadFontPromiseResolver::Trace(blink::Visitor* visitor) { - visitor->Trace(font_faces_); - visitor->Trace(resolver_); - LoadFontCallback::Trace(visitor); -} - FontFaceSetDocument::FontFaceSetDocument(Document& document) - : Supplement<Document>(document), - SuspendableObject(&document), - should_fire_loading_event_(false), - is_loading_(false), - ready_(new ReadyProperty(GetExecutionContext(), - this, - ReadyProperty::kReady)), - async_runner_(AsyncMethodRunner<FontFaceSetDocument>::Create( - this, - &FontFaceSetDocument::HandlePendingEventsAndPromises)) { + : FontFaceSet(document), Supplement<Document>(document) { SuspendIfNeeded(); } @@ -132,20 +54,11 @@ return ToDocument(GetExecutionContext()); } -bool FontFaceSetDocument::InActiveDocumentContext() const { +bool FontFaceSetDocument::InActiveContext() const { ExecutionContext* context = GetExecutionContext(); return context && ToDocument(context)->IsActive(); } -void FontFaceSetDocument::AddFontFacesToFontFaceCache( - FontFaceCache* font_face_cache) { - for (const auto& font_face : non_css_connected_faces_) - font_face_cache->AddFontFace(font_face, false); -} - -ExecutionContext* FontFaceSetDocument::GetExecutionContext() const { - return SuspendableObject::GetExecutionContext(); -} AtomicString FontFaceSetDocument::status() const { DEFINE_STATIC_LOCAL(AtomicString, loading, ("loading")); @@ -153,11 +66,6 @@ return is_loading_ ? loading : loaded; } -void FontFaceSetDocument::HandlePendingEventsAndPromisesSoon() { - // async_runner_ will be automatically stopped on destruction. - async_runner_->RunAsync(); -} - void FontFaceSetDocument::DidLayout() { if (GetDocument()->GetFrame()->IsMainFrame() && loading_fonts_.IsEmpty()) histogram_.Record(); @@ -166,37 +74,6 @@ HandlePendingEventsAndPromisesSoon(); } -bool FontFaceSetDocument::ShouldSignalReady() const { - if (!loading_fonts_.IsEmpty()) - return false; - return is_loading_ || ready_->GetState() == ReadyProperty::kPending; -} - -void FontFaceSetDocument::HandlePendingEventsAndPromises() { - FireLoadingEvent(); - FireDoneEventIfPossible(); -} - -void FontFaceSetDocument::FireLoadingEvent() { - if (should_fire_loading_event_) { - should_fire_loading_event_ = false; - DispatchEvent( - FontFaceSetLoadEvent::CreateForFontFaces(EventTypeNames::loading)); - } -} - -void FontFaceSetDocument::Suspend() { - async_runner_->Suspend(); -} - -void FontFaceSetDocument::Resume() { - async_runner_->Resume(); -} - -void FontFaceSetDocument::ContextDestroyed(ExecutionContext*) { - async_runner_->Stop(); -} - void FontFaceSetDocument::BeginFontLoading(FontFace* font_face) { histogram_.IncrementCount(); AddToLoadingFonts(font_face); @@ -221,27 +98,8 @@ return count; } -void FontFaceSetDocument::AddToLoadingFonts(FontFace* font_face) { - if (!is_loading_) { - is_loading_ = true; - should_fire_loading_event_ = true; - if (ready_->GetState() != ReadyProperty::kPending) - ready_->Reset(); - HandlePendingEventsAndPromisesSoon(); - } - loading_fonts_.insert(font_face); - font_face->AddCallback(this); -} - -void FontFaceSetDocument::RemoveFromLoadingFonts(FontFace* font_face) { - loading_fonts_.erase(font_face); - if (loading_fonts_.IsEmpty()) - HandlePendingEventsAndPromisesSoon(); -} - ScriptPromise FontFaceSetDocument::ready(ScriptState* script_state) { - if (ready_->GetState() != ReadyProperty::kPending && - InActiveDocumentContext()) { + if (ready_->GetState() != ReadyProperty::kPending && InActiveContext()) { // |ready_| is already resolved, but there may be pending stylesheet // changes and/or layout operations that may cause another font loads. // So synchronously update style and layout here. @@ -251,90 +109,11 @@ return ready_->Promise(script_state->World()); } -FontFaceSet* FontFaceSetDocument::addForBinding(ScriptState*, - FontFace* font_face, - ExceptionState&) { - DCHECK(font_face); - if (!InActiveDocumentContext()) - return this; - if (non_css_connected_faces_.Contains(font_face)) - return this; - if (IsCSSConnectedFontFace(font_face)) - return this; - CSSFontSelector* font_selector = - GetDocument()->GetStyleEngine().GetFontSelector(); - non_css_connected_faces_.insert(font_face); - font_selector->GetFontFaceCache()->AddFontFace(font_face, false); - if (font_face->LoadStatus() == FontFace::kLoading) - AddToLoadingFonts(font_face); - font_selector->FontFaceInvalidated(); - return this; -} - -void FontFaceSetDocument::clearForBinding(ScriptState*, ExceptionState&) { - if (!InActiveDocumentContext() || non_css_connected_faces_.IsEmpty()) - return; - CSSFontSelector* font_selector = - GetDocument()->GetStyleEngine().GetFontSelector(); - FontFaceCache* font_face_cache = font_selector->GetFontFaceCache(); - for (const auto& font_face : non_css_connected_faces_) { - font_face_cache->RemoveFontFace(font_face.Get(), false); - if (font_face->LoadStatus() == FontFace::kLoading) - RemoveFromLoadingFonts(font_face); - } - non_css_connected_faces_.clear(); - font_selector->FontFaceInvalidated(); -} - -bool FontFaceSetDocument::deleteForBinding(ScriptState*, - FontFace* font_face, - ExceptionState&) { - DCHECK(font_face); - if (!InActiveDocumentContext()) - return false; - HeapListHashSet<Member<FontFace>>::iterator it = - non_css_connected_faces_.find(font_face); - if (it != non_css_connected_faces_.end()) { - non_css_connected_faces_.erase(it); - CSSFontSelector* font_selector = - GetDocument()->GetStyleEngine().GetFontSelector(); - font_selector->GetFontFaceCache()->RemoveFontFace(font_face, false); - if (font_face->LoadStatus() == FontFace::kLoading) - RemoveFromLoadingFonts(font_face); - font_selector->FontFaceInvalidated(); - return true; - } - return false; -} - -bool FontFaceSetDocument::hasForBinding(ScriptState*, - FontFace* font_face, - ExceptionState&) const { - DCHECK(font_face); - if (!InActiveDocumentContext()) - return false; - return non_css_connected_faces_.Contains(font_face) || - IsCSSConnectedFontFace(font_face); -} - const HeapListHashSet<Member<FontFace>>& -FontFaceSetDocument::CssConnectedFontFaceList() const { +FontFaceSetDocument::CSSConnectedFontFaceList() const { Document* document = this->GetDocument(); document->UpdateActiveStyle(); - return document->GetStyleEngine() - .GetFontSelector() - ->GetFontFaceCache() - ->CssConnectedFontFaces(); -} - -bool FontFaceSetDocument::IsCSSConnectedFontFace(FontFace* font_face) const { - return CssConnectedFontFaceList().Contains(font_face); -} - -size_t FontFaceSetDocument::size() const { - if (!InActiveDocumentContext()) - return non_css_connected_faces_.size(); - return CssConnectedFontFaceList().size() + non_css_connected_faces_.size(); + return GetFontSelector()->GetFontFaceCache()->CssConnectedFontFaces(); } void FontFaceSetDocument::FireDoneEventIfPossible() { @@ -352,100 +131,9 @@ if (!d->View() || d->View()->NeedsLayout()) return; - if (is_loading_) { - FontFaceSetLoadEvent* done_event = nullptr; - FontFaceSetLoadEvent* error_event = nullptr; - done_event = FontFaceSetLoadEvent::CreateForFontFaces( - EventTypeNames::loadingdone, loaded_fonts_); - loaded_fonts_.clear(); - if (!failed_fonts_.IsEmpty()) { - error_event = FontFaceSetLoadEvent::CreateForFontFaces( - EventTypeNames::loadingerror, failed_fonts_); - failed_fonts_.clear(); - } - is_loading_ = false; - DispatchEvent(done_event); - if (error_event) - DispatchEvent(error_event); - } - - if (ready_->GetState() == ReadyProperty::kPending) - ready_->Resolve(this); + FireDoneEvent(); } -ScriptPromise FontFaceSetDocument::load(ScriptState* script_state, - const String& font_string, - const String& text) { - if (!InActiveDocumentContext()) - return ScriptPromise(); - - Font font; - if (!ResolveFontStyle(font_string, font)) { - ScriptPromiseResolver* resolver = - ScriptPromiseResolver::Create(script_state); - ScriptPromise promise = resolver->Promise(); - resolver->Reject(DOMException::Create( - kSyntaxError, "Could not resolve '" + font_string + "' as a font.")); - return promise; - } - - FontFaceCache* font_face_cache = - GetDocument()->GetStyleEngine().GetFontSelector()->GetFontFaceCache(); - FontFaceArray faces; - for (const FontFamily* f = &font.GetFontDescription().Family(); f; - f = f->Next()) { - CSSSegmentedFontFace* segmented_font_face = - font_face_cache->Get(font.GetFontDescription(), f->Family()); - if (segmented_font_face) - segmented_font_face->Match(text, faces); - } - - LoadFontPromiseResolver* resolver = - LoadFontPromiseResolver::Create(faces, script_state); - ScriptPromise promise = resolver->Promise(); - // After this, resolver->promise() may return null. - resolver->LoadFonts(); - return promise; -} - -bool FontFaceSetDocument::check(const String& font_string, - const String& text, - ExceptionState& exception_state) { - if (!InActiveDocumentContext()) - return false; - - Font font; - if (!ResolveFontStyle(font_string, font)) { - exception_state.ThrowDOMException( - kSyntaxError, "Could not resolve '" + font_string + "' as a font."); - return false; - } - - CSSFontSelector* font_selector = - GetDocument()->GetStyleEngine().GetFontSelector(); - FontFaceCache* font_face_cache = font_selector->GetFontFaceCache(); - - bool has_loaded_faces = false; - for (const FontFamily* f = &font.GetFontDescription().Family(); f; - f = f->Next()) { - CSSSegmentedFontFace* face = - font_face_cache->Get(font.GetFontDescription(), f->Family()); - if (face) { - if (!face->CheckFont(text)) - return false; - has_loaded_faces = true; - } - } - if (has_loaded_faces) - return true; - for (const FontFamily* f = &font.GetFontDescription().Family(); f; - f = f->Next()) { - if (font_selector->IsPlatformFamilyMatchAvailable(font.GetFontDescription(), - f->Family())) - return true; - } - return false; -} bool FontFaceSetDocument::ResolveFontStyle(const String& font_string, Font& font) { @@ -467,12 +155,12 @@ scoped_refptr<ComputedStyle> style = ComputedStyle::Create(); FontFamily font_family; - font_family.SetFamily(kDefaultFontFamily); + font_family.SetFamily(FontFaceSet::kDefaultFontFamily); FontDescription default_font_description; default_font_description.SetFamily(font_family); - default_font_description.SetSpecifiedSize(kDefaultFontSize); - default_font_description.SetComputedSize(kDefaultFontSize); + default_font_description.SetSpecifiedSize(FontFaceSet::kDefaultFontSize); + default_font_description.SetComputedSize(FontFaceSet::kDefaultFontSize); style->SetFontDescription(default_font_description); @@ -482,34 +170,10 @@ GetDocument()->EnsureStyleResolver().ComputeFont(style.get(), *parsed_style); font = style->GetFont(); - font.Update(GetDocument()->GetStyleEngine().GetFontSelector()); + font.Update(GetFontSelector()); return true; } -void FontFaceSetDocument::FontLoadHistogram::UpdateStatus(FontFace* font_face) { - if (status_ == kReported) - return; - if (font_face->HadBlankText()) - status_ = kHadBlankText; - else if (status_ == kNoWebFonts) - status_ = kDidNotHaveBlankText; -} - -void FontFaceSetDocument::FontLoadHistogram::Record() { - if (!recorded_) { - recorded_ = true; - DEFINE_STATIC_LOCAL(CustomCountHistogram, web_fonts_in_page_histogram, - ("WebFont.WebFontsInPage", 1, 100, 50)); - web_fonts_in_page_histogram.Count(count_); - } - if (status_ == kHadBlankText || status_ == kDidNotHaveBlankText) { - DEFINE_STATIC_LOCAL(EnumerationHistogram, had_blank_text_histogram, - ("WebFont.HadBlankText", 2)); - had_blank_text_histogram.Count(status_ == kHadBlankText ? 1 : 0); - status_ = kReported; - } -} - FontFaceSetDocument* FontFaceSetDocument::From(Document& document) { FontFaceSetDocument* fonts = static_cast<FontFaceSetDocument*>( Supplement<Document>::From(document, SupplementName())); @@ -534,46 +198,8 @@ return 0; } -FontFaceSetIterable::IterationSource* FontFaceSetDocument::StartIteration( - ScriptState*, - ExceptionState&) { - // Setlike should iterate each item in insertion order, and items should - // be keep on up to date. But since blink does not have a way to hook up CSS - // modification, take a snapshot here, and make it ordered as follows. - HeapVector<Member<FontFace>> font_faces; - if (InActiveDocumentContext()) { - const HeapListHashSet<Member<FontFace>>& css_connected_faces = - CssConnectedFontFaceList(); - font_faces.ReserveInitialCapacity(css_connected_faces.size() + - non_css_connected_faces_.size()); - for (const auto& font_face : css_connected_faces) - font_faces.push_back(font_face); - for (const auto& font_face : non_css_connected_faces_) - font_faces.push_back(font_face); - } - return new IterationSource(font_faces); -} - -bool FontFaceSetDocument::IterationSource::Next(ScriptState*, - Member<FontFace>& key, - Member<FontFace>& value, - ExceptionState&) { - if (font_faces_.size() <= index_) - return false; - key = value = font_faces_[index_++]; - return true; -} - void FontFaceSetDocument::Trace(blink::Visitor* visitor) { - visitor->Trace(ready_); - visitor->Trace(loading_fonts_); - visitor->Trace(loaded_fonts_); - visitor->Trace(failed_fonts_); - visitor->Trace(non_css_connected_faces_); - visitor->Trace(async_runner_); Supplement<Document>::Trace(visitor); - SuspendableObject::Trace(visitor); - FontFace::LoadFontCallback::Trace(visitor); FontFaceSet::Trace(visitor); } @@ -583,4 +209,28 @@ Supplement<Document>::TraceWrappers(visitor); } +void FontFaceSetDocument::FontLoadHistogram::UpdateStatus(FontFace* font_face) { + if (status_ == kReported) + return; + if (font_face->HadBlankText()) + status_ = kHadBlankText; + else if (status_ == kNoWebFonts) + status_ = kDidNotHaveBlankText; +} + +void FontFaceSetDocument::FontLoadHistogram::Record() { + if (!recorded_) { + recorded_ = true; + DEFINE_STATIC_LOCAL(CustomCountHistogram, web_fonts_in_page_histogram, + ("WebFont.WebFontsInPage", 1, 100, 50)); + web_fonts_in_page_histogram.Count(count_); + } + if (status_ == kHadBlankText || status_ == kDidNotHaveBlankText) { + DEFINE_STATIC_LOCAL(EnumerationHistogram, had_blank_text_histogram, + ("WebFont.HadBlankText", 2)); + had_blank_text_histogram.Count(status_ == kHadBlankText ? 1 : 0); + status_ = kReported; + } +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/FontFaceSetDocument.h b/third_party/WebKit/Source/core/css/FontFaceSetDocument.h index e60d79d..80d03e7 100644 --- a/third_party/WebKit/Source/core/css/FontFaceSetDocument.h +++ b/third_party/WebKit/Source/core/css/FontFaceSetDocument.h
@@ -28,8 +28,10 @@ #include "bindings/core/v8/Iterable.h" #include "bindings/core/v8/ScriptPromise.h" +#include "core/css/CSSFontSelector.h" #include "core/css/FontFace.h" #include "core/css/FontFaceSet.h" +#include "core/css/StyleEngine.h" #include "core/dom/Document.h" #include "core/dom/SuspendableObject.h" #include "core/dom/events/EventListener.h" @@ -39,46 +41,22 @@ #include "platform/wtf/Allocator.h" #include "platform/wtf/Vector.h" -// Mac OS X 10.6 SDK defines check() macro that interferes with our check() -// method -#ifdef check -#undef check -#endif - namespace blink { -class ExceptionState; class Font; -class FontFaceCache; -class ExecutionContext; -class CORE_EXPORT FontFaceSetDocument final - : public FontFaceSet, - public Supplement<Document>, - public SuspendableObject, - public FontFace::LoadFontCallback { +class CORE_EXPORT FontFaceSetDocument final : public FontFaceSet, + public Supplement<Document> { USING_GARBAGE_COLLECTED_MIXIN(FontFaceSetDocument); WTF_MAKE_NONCOPYABLE(FontFaceSetDocument); public: ~FontFaceSetDocument() override; - bool check(const String& font, const String& text, ExceptionState&) override; - ScriptPromise load(ScriptState*, - const String& font, - const String& text) override; ScriptPromise ready(ScriptState*) override; - FontFaceSet* addForBinding(ScriptState*, FontFace*, ExceptionState&) override; - void clearForBinding(ScriptState*, ExceptionState&) override; - bool deleteForBinding(ScriptState*, FontFace*, ExceptionState&) override; - bool hasForBinding(ScriptState*, FontFace*, ExceptionState&) const override; - - size_t size() const override; AtomicString status() const override; - ExecutionContext* GetExecutionContext() const override; - Document* GetDocument() const; void DidLayout(); @@ -90,31 +68,34 @@ size_t ApproximateBlankCharacterCount() const; - // SuspendableObject - void Suspend() override; - void Resume() override; - void ContextDestroyed(ExecutionContext*) override; - static FontFaceSetDocument* From(Document&); static void DidLayout(Document&); static size_t ApproximateBlankCharacterCount(Document&); static const char* SupplementName() { return "FontFaceSetDocument"; } - void AddFontFacesToFontFaceCache(FontFaceCache*); - virtual void Trace(blink::Visitor*); virtual void TraceWrappers(const ScriptWrappableVisitor*) const; - private: - FontFaceSetIterable::IterationSource* StartIteration( - ScriptState*, - ExceptionState&) override; + protected: + bool InActiveContext() const override; + FontSelector* GetFontSelector() const override { + return GetDocument()->GetStyleEngine().GetFontSelector(); + } + bool ResolveFontStyle(const String&, Font&) override; + + private: static FontFaceSetDocument* Create(Document& document) { return new FontFaceSetDocument(document); } + explicit FontFaceSetDocument(Document&); + + void FireDoneEventIfPossible() override; + const HeapListHashSet<Member<FontFace>>& CSSConnectedFontFaceList() + const override; + class FontLoadHistogram { DISALLOW_NEW(); @@ -130,35 +111,6 @@ int count_; bool recorded_; }; - - explicit FontFaceSetDocument(Document&); - - bool InActiveDocumentContext() const; - void AddToLoadingFonts(FontFace*); - void RemoveFromLoadingFonts(FontFace*); - void FireLoadingEvent(); - void FireDoneEventIfPossible(); - bool ResolveFontStyle(const String&, Font&); - void HandlePendingEventsAndPromisesSoon(); - void HandlePendingEventsAndPromises(); - const HeapListHashSet<Member<FontFace>>& CssConnectedFontFaceList() const; - bool IsCSSConnectedFontFace(FontFace*) const; - bool ShouldSignalReady() const; - - using ReadyProperty = ScriptPromiseProperty<Member<FontFaceSetDocument>, - Member<FontFaceSetDocument>, - Member<DOMException>>; - - HeapHashSet<Member<FontFace>> loading_fonts_; - bool should_fire_loading_event_; - bool is_loading_; - Member<ReadyProperty> ready_; - FontFaceArray loaded_fonts_; - FontFaceArray failed_fonts_; - HeapListHashSet<Member<FontFace>> non_css_connected_faces_; - - Member<AsyncMethodRunner<FontFaceSetDocument>> async_runner_; - FontLoadHistogram histogram_; };
diff --git a/third_party/WebKit/Source/core/css/FontFaceSetWorker.cpp b/third_party/WebKit/Source/core/css/FontFaceSetWorker.cpp new file mode 100644 index 0000000..ddeaf6b --- /dev/null +++ b/third_party/WebKit/Source/core/css/FontFaceSetWorker.cpp
@@ -0,0 +1,118 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/FontFaceSetWorker.h" + +#include "bindings/core/v8/Dictionary.h" +#include "bindings/core/v8/ScriptPromiseResolver.h" +#include "core/css/CSSSegmentedFontFace.h" +#include "core/css/FontFaceCache.h" +#include "core/css/FontFaceSetLoadEvent.h" +#include "core/css/OffscreenFontSelector.h" +#include "core/css/StylePropertySet.h" +#include "core/css/parser/CSSParser.h" +#include "core/css/resolver/FontStyleResolver.h" +#include "core/css/resolver/StyleResolver.h" +#include "core/frame/LocalFrame.h" +#include "core/frame/LocalFrameView.h" +#include "core/style/ComputedStyle.h" +#include "platform/bindings/ScriptState.h" + +namespace blink { + +FontFaceSetWorker::FontFaceSetWorker(WorkerGlobalScope& worker) + : FontFaceSet(worker), Supplement<WorkerGlobalScope>(worker) { + SuspendIfNeeded(); +} + +FontFaceSetWorker::~FontFaceSetWorker() {} + +WorkerGlobalScope* FontFaceSetWorker::GetWorker() const { + return ToWorkerGlobalScope(GetExecutionContext()); +} + +AtomicString FontFaceSetWorker::status() const { + DEFINE_STATIC_LOCAL(AtomicString, loading, ("loading")); + DEFINE_STATIC_LOCAL(AtomicString, loaded, ("loaded")); + return is_loading_ ? loading : loaded; +} + +void FontFaceSetWorker::BeginFontLoading(FontFace* font_face) { + AddToLoadingFonts(font_face); +} + +void FontFaceSetWorker::NotifyLoaded(FontFace* font_face) { + loaded_fonts_.push_back(font_face); + RemoveFromLoadingFonts(font_face); +} + +void FontFaceSetWorker::NotifyError(FontFace* font_face) { + failed_fonts_.push_back(font_face); + RemoveFromLoadingFonts(font_face); +} + +ScriptPromise FontFaceSetWorker::ready(ScriptState* script_state) { + return ready_->Promise(script_state->World()); +} + +void FontFaceSetWorker::FireDoneEventIfPossible() { + if (should_fire_loading_event_) + return; + if (!ShouldSignalReady()) + return; + + FireDoneEvent(); +} + +bool FontFaceSetWorker::ResolveFontStyle(const String& font_string, + Font& font) { + if (font_string.IsEmpty()) + return false; + + // Interpret fontString in the same way as the 'font' attribute of + // CanvasRenderingContext2D. + MutableStylePropertySet* parsed_style = + MutableStylePropertySet::Create(kHTMLStandardMode); + CSSParser::ParseValue(parsed_style, CSSPropertyFont, font_string, true); + if (parsed_style->IsEmpty()) + return false; + + String font_value = parsed_style->GetPropertyValue(CSSPropertyFont); + if (font_value == "inherit" || font_value == "initial") + return false; + + FontFamily font_family; + font_family.SetFamily(FontFaceSet::kDefaultFontFamily); + + FontDescription default_font_description; + default_font_description.SetFamily(font_family); + default_font_description.SetSpecifiedSize(FontFaceSet::kDefaultFontSize); + default_font_description.SetComputedSize(FontFaceSet::kDefaultFontSize); + + FontDescription description = FontStyleResolver::ComputeFont( + *parsed_style, GetWorker()->GetFontSelector()); + + font = Font(description); + font.Update(GetWorker()->GetFontSelector()); + + return true; +} + +FontFaceSetWorker* FontFaceSetWorker::From(WorkerGlobalScope& worker) { + FontFaceSetWorker* fonts = static_cast<FontFaceSetWorker*>( + Supplement<WorkerGlobalScope>::From(worker, SupplementName())); + if (!fonts) { + fonts = FontFaceSetWorker::Create(worker); + Supplement<WorkerGlobalScope>::ProvideTo(worker, SupplementName(), fonts); + } + + return fonts; +} + +void FontFaceSetWorker::Trace(Visitor* visitor) { + Supplement<WorkerGlobalScope>::Trace(visitor); + FontFaceSet::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/FontFaceSetWorker.h b/third_party/WebKit/Source/core/css/FontFaceSetWorker.h new file mode 100644 index 0000000..5b03107 --- /dev/null +++ b/third_party/WebKit/Source/core/css/FontFaceSetWorker.h
@@ -0,0 +1,79 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FontFaceSetWorker_h +#define FontFaceSetWorker_h + +#include "bindings/core/v8/Iterable.h" +#include "bindings/core/v8/ScriptPromise.h" +#include "core/css/FontFace.h" +#include "core/css/FontFaceSet.h" +#include "core/css/OffscreenFontSelector.h" +#include "core/dom/SuspendableObject.h" +#include "core/workers/WorkerGlobalScope.h" +#include "platform/AsyncMethodRunner.h" +#include "platform/heap/Handle.h" +#include "platform/wtf/Allocator.h" +#include "platform/wtf/Vector.h" + +namespace blink { + +class Font; + +class CORE_EXPORT FontFaceSetWorker final + : public FontFaceSet, + public Supplement<WorkerGlobalScope> { + USING_GARBAGE_COLLECTED_MIXIN(FontFaceSetWorker); + WTF_MAKE_NONCOPYABLE(FontFaceSetWorker); + + public: + ~FontFaceSetWorker() override; + + ScriptPromise ready(ScriptState*) override; + + AtomicString status() const override; + + WorkerGlobalScope* GetWorker() const; + + // FontFace::LoadFontCallback + void NotifyLoaded(FontFace*) override; + void NotifyError(FontFace*) override; + + void BeginFontLoading(FontFace*); + + static FontFaceSetWorker* From(WorkerGlobalScope&); + + static const char* SupplementName() { return "FontFaceSetWorker"; } + + void Trace(Visitor*) override; + + protected: + bool InActiveContext() const override { return true; } + FontSelector* GetFontSelector() const override { + return GetWorker()->GetFontSelector(); + } + // For workers, this is always an empty list. + const HeapListHashSet<Member<FontFace>>& CSSConnectedFontFaceList() + const override { + DCHECK( + GetFontSelector()->GetFontFaceCache()->CssConnectedFontFaces().size() == + 0); + return GetFontSelector()->GetFontFaceCache()->CssConnectedFontFaces(); + } + + bool ResolveFontStyle(const String&, Font&) override; + + private: + static FontFaceSetWorker* Create(WorkerGlobalScope& worker) { + return new FontFaceSetWorker(worker); + } + + explicit FontFaceSetWorker(WorkerGlobalScope&); + + void FireDoneEventIfPossible() override; +}; + +} // namespace blink + +#endif // FontFaceSetWorker_h
diff --git a/third_party/WebKit/Source/core/css/OffscreenFontSelector.h b/third_party/WebKit/Source/core/css/OffscreenFontSelector.h index f006c7b..7e22ed84 100644 --- a/third_party/WebKit/Source/core/css/OffscreenFontSelector.h +++ b/third_party/WebKit/Source/core/css/OffscreenFontSelector.h
@@ -51,10 +51,11 @@ void UpdateGenericFontFamilySettings(const GenericFontFamilySettings&); - FontFaceCache* GetFontFaceCache() { return &font_face_cache_; } + FontFaceCache* GetFontFaceCache() override { return &font_face_cache_; } - bool IsPlatformFamilyMatchAvailable(const FontDescription&, - const AtomicString& passed_family); + bool IsPlatformFamilyMatchAvailable( + const FontDescription&, + const AtomicString& passed_family) override; ExecutionContext* GetExecutionContext() const override { return execution_context_;
diff --git a/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp b/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp index 63d1531..287fbc5 100644 --- a/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp +++ b/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp
@@ -110,27 +110,28 @@ TEST(SelectorQueryTest, StandardsModeFastPaths) { Document* document = HTMLDocument::CreateForTest(); - document->write( - "<!DOCTYPE html>" - "<html>" - " <head></head>" - " <body>" - " <span id=first class=A>" - " <span id=a class=one></span>" - " <span id=b class=two></span>" - " <span id=c class=one></span>" - " <div id=multiple class=two></div>" - " </span>" - " <div>" - " <span id=second class=B>" - " <span id=A class=one></span>" - " <span id=B class=two></span>" - " <span id=C class=one></span>" - " <span id=multiple class=two></span>" - " </span>" - " </div>" - " </body>" - "</html>"); + document->write(R"HTML( + <!DOCTYPE html> + <html> + <head></head> + <body> + <span id=first class=A> + <span id=a class=one></span> + <span id=b class=two></span> + <span id=c class=one></span> + <div id=multiple class=two></div> + </span> + <div> + <span id=second class=B> + <span id=A class=one></span> + <span id=B class=two></span> + <span id=C class=one></span> + <span id=multiple class=two></span> + </span> + </div> + </body> + </html> + )HTML"); static const struct QueryTest kTestCases[] = { // Id in right most selector fast path. {"#A", false, 1, {1, 1, 0, 0, 0, 0, 0}}, @@ -221,23 +222,24 @@ TEST(SelectorQueryTest, FastPathScoped) { Document* document = HTMLDocument::CreateForTest(); - document->write( - "<!DOCTYPE html>" - "<html id=root-id class=root-class>" - " <head></head>" - " <body>" - " <span id=first>" - " <span id=A class='a child'></span>" - " <span id=B class='a child'>" - " <a class=first></a>" - " <a class=second></a>" - " <a class=third></a>" - " </span>" - " <span id=multiple class='b child'></span>" - " <span id=multiple class='c child'></span>" - " </span>" - " </body>" - "</html>"); + document->write(R"HTML( + <!DOCTYPE html> + <html id=root-id class=root-class> + <head></head> + <body> + <span id=first> + <span id=A class='a child'></span> + <span id=B class='a child'> + <a class=first></a> + <a class=second></a> + <a class=third></a> + </span> + <span id=multiple class='b child'></span> + <span id=multiple class='c child'></span> + </span> + </body> + </html> + )HTML"); // TODO(esprehn): Element::attachShadow() should not require a ScriptState, // it should handle the use counting in the bindings layer instead of in the // C++. @@ -290,16 +292,17 @@ TEST(SelectorQueryTest, QuirksModeSlowPath) { Document* document = HTMLDocument::CreateForTest(); - document->write( - "<html>" - " <head></head>" - " <body>" - " <span id=first>" - " <span id=One class=Two></span>" - " <span id=one class=tWo></span>" - " </span>" - " </body>" - "</html>"); + document->write(R"HTML( + <html> + <head></head> + <body> + <span id=first> + <span id=One class=Two></span> + <span id=one class=tWo></span> + </span> + </body> + </html> + )HTML"); static const struct QueryTest kTestCases[] = { // Quirks mode can't use the id fast path due to being case-insensitive. {"#one", false, 1, {5, 0, 0, 0, 5, 0, 0}}, @@ -326,15 +329,16 @@ TEST(SelectorQueryTest, DisconnectedSubtree) { Document* document = HTMLDocument::CreateForTest(); Element* scope = document->createElement("div"); - scope->SetInnerHTMLFromString( - "<section>" - " <span id=first>" - " <span id=A class=A></span>" - " <span id=B class=child></span>" - " <span id=multiple class=child></span>" - " <span id=multiple class=B></span>" - " </span>" - "</section>"); + scope->SetInnerHTMLFromString(R"HTML( + <section> + <span id=first> + <span id=A class=A></span> + <span id=B class=child></span> + <span id=multiple class=child></span> + <span id=multiple class=B></span> + </span> + </section> + )HTML"); static const struct QueryTest kTestCases[] = { {"#A", false, 1, {3, 0, 0, 0, 3, 0, 0}}, {"#B", false, 1, {4, 0, 0, 0, 4, 0, 0}}, @@ -357,15 +361,16 @@ // C++. ShadowRoot& shadowRoot = host->EnsureShadow().AddShadowRoot(*host, ShadowRootType::kOpen); - shadowRoot.SetInnerHTMLFromString( - "<section>" - " <span id=first>" - " <span id=A class=A></span>" - " <span id=B class=child></span>" - " <span id=multiple class=child></span>" - " <span id=multiple class=B></span>" - " </span>" - "</section>"); + shadowRoot.SetInnerHTMLFromString(R"HTML( + <section> + <span id=first> + <span id=A class=A></span> + <span id=B class=child></span> + <span id=multiple class=child></span> + <span id=multiple class=B></span> + </span> + </section> + )HTML"); static const struct QueryTest kTestCases[] = { {"#A", false, 1, {1, 1, 0, 0, 0, 0, 0}}, {"#B", false, 1, {1, 1, 0, 0, 0, 0, 0}},
diff --git a/third_party/WebKit/Source/core/css/StyleEngineTest.cpp b/third_party/WebKit/Source/core/css/StyleEngineTest.cpp index 919e9ae..a8e13e61 100644 --- a/third_party/WebKit/Source/core/css/StyleEngineTest.cpp +++ b/third_party/WebKit/Source/core/css/StyleEngineTest.cpp
@@ -80,17 +80,18 @@ } TEST_F(StyleEngineTest, AnalyzedInject) { - GetDocument().body()->SetInnerHTMLFromString( - "<style>" - " #t1 { color: red !important }" - " #t2 { color: black }" - " #t4 { animation-name: dummy-animation }" - "</style>" - "<div id='t1'>Green</div>" - "<div id='t2'>White</div>" - "<div id='t3' style='color: black !important'>White</div>" - "<div id='t4'>I animate!</div>" - "<div></div>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style> + #t1 { color: red !important } + #t2 { color: black } + #t4 { animation-name: dummy-animation } + </style> + <div id='t1'>Green</div> + <div id='t2'>White</div> + <div id='t3' style='color: black !important'>White</div> + <div id='t4'>I animate!</div> + <div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* t1 = GetDocument().getElementById("t1"); @@ -282,17 +283,18 @@ } TEST_F(StyleEngineTest, RuleSetInvalidationTypeSelectors) { - GetDocument().body()->SetInnerHTMLFromString( - "<div>" - " <span></span>" - " <div></div>" - "</div>" - "<b></b><b></b><b></b><b></b>" - "<i id=i>" - " <i>" - " <b></b>" - " </i>" - "</i>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <div> + <span></span> + <div></div> + </div> + <b></b><b></b><b></b><b></b> + <i id=i> + <i> + <b></b> + </i> + </i> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -327,10 +329,11 @@ } TEST_F(StyleEngineTest, RuleSetInvalidationCustomPseudo) { - GetDocument().body()->SetInnerHTMLFromString( - "<style>progress { -webkit-appearance:none }</style>" - "<progress></progress>" - "<div></div><div></div><div></div><div></div><div></div><div></div>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style>progress { -webkit-appearance:none }</style> + <progress></progress> + <div></div><div></div><div></div><div></div><div></div><div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -387,13 +390,14 @@ } TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) { - GetDocument().body()->SetInnerHTMLFromString( - "<div id=host>" - " <span slot=other class=s1></span>" - " <span class=s2></span>" - " <span class=s1></span>" - " <span></span>" - "</div>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <div id=host> + <span slot=other class=s1></span> + <span class=s2></span> + <span class=s1></span> + <span></span> + </div> + )HTML"); Element* host = GetDocument().getElementById("host"); ASSERT_TRUE(host); @@ -488,11 +492,12 @@ } TEST_F(StyleEngineTest, HasViewportDependentMediaQueries) { - GetDocument().body()->SetInnerHTMLFromString( - "<style>div {}</style>" - "<style id='sheet' media='(min-width: 200px)'>" - " div {}" - "</style>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style>div {}</style> + <style id='sheet' media='(min-width: 200px)'> + div {} + </style> + )HTML"); Element* style_element = GetDocument().getElementById("sheet"); @@ -608,14 +613,15 @@ } TEST_F(StyleEngineTest, ScheduleInvalidationAfterSubtreeRecalc) { - GetDocument().body()->SetInnerHTMLFromString( - "<style id='s1'>" - " .t1 span { color: green }" - " .t2 span { color: green }" - "</style>" - "<style id='s2'>div { background: lime }</style>" - "<div id='t1'></div>" - "<div id='t2'></div>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style id='s1'> + .t1 span { color: green } + .t2 span { color: green } + </style> + <style id='s2'>div { background: lime }</style> + <div id='t1'></div> + <div id='t2'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* t1 = GetDocument().getElementById("t1"); @@ -692,13 +698,14 @@ init, ASSERT_NO_EXCEPTION); ASSERT_TRUE(shadow_root); - shadow_root->SetInnerHTMLFromString( - "<style>" - " span { color: green }" - " t1 { color: green }" - "</style>" - "<div id='t1'></div>" - "<span></span>"); + shadow_root->SetInnerHTMLFromString(R"HTML( + <style> + span { color: green } + t1 { color: green } + </style> + <div id='t1'></div> + <span></span> + )HTML"); GetStyleEngine().UpdateActiveStyle(); EXPECT_FALSE(GetDocument().ChildNeedsStyleInvalidation());
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp index 0611a492..23436b60 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp +++ b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp
@@ -58,6 +58,16 @@ return keyword_value_; } +void CSSKeywordValue::setValue(const String& keyword, + ExceptionState& exception_state) { + if (keyword.IsEmpty()) { + exception_state.ThrowTypeError( + "CSSKeywordValue does not support empty strings"); + return; + } + keyword_value_ = keyword; +} + CSSValueID CSSKeywordValue::KeywordValueID() const { return CssValueKeywordID(keyword_value_); }
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h index 84c431ff..94d533c 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h +++ b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h
@@ -25,7 +25,7 @@ StyleValueType GetType() const override { return kKeywordType; } const String& value() const; - void setValue(const String& keyword) { keyword_value_ = keyword; } + void setValue(const String& keyword, ExceptionState&); CSSValueID KeywordValueID() const; const CSSValue* ToCSSValue() const override;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.idl b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.idl index c080343..8572fd17 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.idl +++ b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.idl
@@ -10,5 +10,5 @@ Exposed(Window CSSTypedOM, PaintWorklet CSSTypedOM), RaisesException=Constructor ] interface CSSKeywordValue : CSSStyleValue { - attribute DOMString value; + [RaisesException=Setter] attribute DOMString value; };
diff --git a/third_party/WebKit/Source/core/css/parser/CSS.proto b/third_party/WebKit/Source/core/css/parser/CSS.proto index b42a906..f00a05f4 100644 --- a/third_party/WebKit/Source/core/css/parser/CSS.proto +++ b/third_party/WebKit/Source/core/css/parser/CSS.proto
@@ -581,11 +581,47 @@ Page page = 3; FontFace font_face = 4; Viewport viewport = 5; + SupportsRule supports_rule = 6; } } +message SupportsRule { + required SupportsCondition supports_condition = 1; + repeated AtRuleOrRulesets at_rule_or_rulesets = 2; +} + +message AtRuleOrRulesets { + required AtRuleOrRuleset first = 1; + repeated AtRuleOrRuleset laters = 2; +} + +message AtRuleOrRuleset { + required Ruleset ruleset = 1; + optional NestedAtRule at_rule = 2; +} + +message SupportsCondition { + // Using PropertyAndValue rather than declaration means that there + // will always be a declaration. This is syntactically correct but + // means we may miss some error paths. + // TODO(metzman): Figure out what to do about generating invalid output that + // causes more coverage. Maybe doing so infrequently is the correct move. + required PropertyAndValue property_and_value = 1; // Default. + // TODO(metzman): Do functions also need to be supported? + required bool not_condition = 2; + oneof rhs { + BinarySupportsCondition and_supports_condition = 3; + BinarySupportsCondition or_supports_condition = 4; + } +} + +message BinarySupportsCondition { + required SupportsCondition condition_1 = 1; + required SupportsCondition condition_2 = 2; +} + message Viewport { - repeated ViewportPropertyAndValue props_and_vals = 1; + repeated ViewportPropertyAndValue properties_and_values = 1; } message ViewportPropertyAndValue { @@ -1520,10 +1556,10 @@ message Declaration { // property ':' S* expr prio? | /* empty */ - optional NonEmptyDeclaration nonempty_declaration = 1; + optional PropertyAndValue property_and_value = 1; } -message NonEmptyDeclaration { +message PropertyAndValue { required Property property = 1; required Expr expr = 2; enum Prio {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.cpp b/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.cpp index d3bfd3e..4d4f04c 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.cpp
@@ -11,6 +11,9 @@ namespace css_proto_converter { +const int Converter::kAtRuleDepthLimit = 5; +const int Converter::kSupportsConditionDepthLimit = 5; + const std::string Converter::kViewportPropertyLookupTable[] = { "", // This is just to fill the zeroth spot. It should not be used. "min-width", "max-width", "width", "min-height", @@ -1633,8 +1636,8 @@ void Converter::Visit(const Viewport& viewport) { string_ += " @viewport {"; - for (auto& prop_and_val : viewport.props_and_vals()) - AppendPropertyAndValue(prop_and_val, kViewportPropertyLookupTable); + for (auto& property_and_value : viewport.properties_and_values()) + AppendPropertyAndValue(property_and_value, kViewportPropertyLookupTable); string_ += " } "; } @@ -1645,17 +1648,78 @@ string_ += "\"; "; } -void Converter::Visit(const NestedAtRule& nested_at_rule) { +void Converter::Visit(const AtRuleOrRulesets& at_rule_or_rulesets, int depth) { + Visit(at_rule_or_rulesets.first(), depth); + for (auto& later : at_rule_or_rulesets.laters()) + Visit(later, depth); +} + +void Converter::Visit(const AtRuleOrRuleset& at_rule_or_ruleset, int depth) { + if (at_rule_or_ruleset.has_at_rule()) + Visit(at_rule_or_ruleset.at_rule(), depth); + else // Default. + Visit(at_rule_or_ruleset.ruleset()); +} + +void Converter::Visit(const NestedAtRule& nested_at_rule, int depth) { + if (++depth > kAtRuleDepthLimit) + return; + if (nested_at_rule.has_ruleset()) Visit(nested_at_rule.ruleset()); else if (nested_at_rule.has_media()) Visit(nested_at_rule.media()); else if (nested_at_rule.has_viewport()) Visit(nested_at_rule.viewport()); + else if (nested_at_rule.has_supports_rule()) + Visit(nested_at_rule.supports_rule(), depth); // Else apppend nothing. // TODO(metzman): Support pages and font-faces. } +void Converter::Visit(const SupportsRule& supports_rule, int depth) { + string_ += "@supports "; + Visit(supports_rule.supports_condition(), depth); + string_ += " { "; + for (auto& at_rule_or_ruleset : supports_rule.at_rule_or_rulesets()) + Visit(at_rule_or_ruleset, depth); + string_ += " } "; +} + +void Converter::AppendBinarySupportsCondition( + const BinarySupportsCondition& binary_condition, + std::string binary_operator, + int depth) { + Visit(binary_condition.condition_1(), depth); + string_ += " " + binary_operator + " "; + Visit(binary_condition.condition_2(), depth); +} + +void Converter::Visit(const SupportsCondition& supports_condition, int depth) { + bool under_depth_limit = ++depth <= kSupportsConditionDepthLimit; + + if (supports_condition.not_condition()) + string_ += " not "; + + string_ += "("; + + if (under_depth_limit && supports_condition.has_and_supports_condition()) { + AppendBinarySupportsCondition(supports_condition.or_supports_condition(), + "and", depth); + } else if (under_depth_limit && + supports_condition.has_or_supports_condition()) { + AppendBinarySupportsCondition(supports_condition.or_supports_condition(), + "or", depth); + } else { + // Use the required property_and_value field if the or_supports_condition + // and and_supports_condition are unset or if we have reached the depth + // limit and don't want another nested condition. + Visit(supports_condition.property_and_value()); + } + + string_ += ")"; +} + void Converter::Visit(const Import& import) { string_ += "@import "; AppendTableValue(import.src_id(), kImportLookupTable); @@ -1912,20 +1976,20 @@ } void Converter::Visit(const Declaration& declaration) { - if (declaration.has_nonempty_declaration()) - Visit(declaration.nonempty_declaration()); + if (declaration.has_property_and_value()) + Visit(declaration.property_and_value()); // else empty } -void Converter::Visit(const NonEmptyDeclaration& nonempty_declaration) { - Visit(nonempty_declaration.property()); +void Converter::Visit(const PropertyAndValue& property_and_value) { + Visit(property_and_value.property()); string_ += " : "; int value_id = 0; - if (nonempty_declaration.has_value_id()) - value_id = nonempty_declaration.value_id(); - Visit(nonempty_declaration.expr(), value_id); - if (nonempty_declaration.has_prio()) - string_ += " !important"; + if (property_and_value.has_value_id()) + value_id = property_and_value.value_id(); + Visit(property_and_value.expr(), value_id); + if (property_and_value.has_prio()) + string_ += " !important "; } void Converter::Visit(const Expr& expr, int declaration_value_id) { @@ -2015,7 +2079,7 @@ } void Converter::Reset() { - string_ = ""; + string_.clear(); } template <size_t TableSize>
diff --git a/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.h b/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.h index 36f4b5dd..c88afc9 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.h +++ b/third_party/WebKit/Source/core/css/parser/CSSProtoConverter.h
@@ -18,6 +18,9 @@ private: std::string string_; + + static const int kAtRuleDepthLimit; + static const int kSupportsConditionDepthLimit; static const std::string kPseudoLookupTable[]; static const std::string kMediaTypeLookupTable[]; static const std::string kMfNameLookupTable[]; @@ -49,7 +52,7 @@ void Visit(const FunctionToken&); void Visit(const StyleSheet&); void Visit(const CharsetDeclaration&); - void Visit(const NestedAtRule&); + void Visit(const NestedAtRule&, int depth = 0); void Visit(const Import&); void Visit(const Namespace&); void Visit(const NamespacePrefix&); @@ -63,7 +66,7 @@ void Visit(const Ruleset&); void Visit(const SelectorList&); void Visit(const Declaration&); - void Visit(const NonEmptyDeclaration&); + void Visit(const PropertyAndValue&); void Visit(const Expr&, int declaration_value_id = 0); void Visit(const OperatorTerm&); void Visit(const Term&); @@ -89,6 +92,15 @@ void Visit(const PseudoPage&); void Visit(const ViewportValue&); void Visit(const Viewport&); + void Visit(const SupportsRule&, int depth); + void Visit(const SupportsCondition&, int depth); + void AppendBinarySupportsCondition( + const BinarySupportsCondition& binary_condition, + std::string binary_operator, + int depth); + void Visit(const AtRuleOrRulesets&, int depth); + void Visit(const AtRuleOrRuleset&, int depth); + void Reset(); template <class T, size_t TableSize> void AppendPropertyAndValue(T property_and_value,
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleAdjusterTest.cpp b/third_party/WebKit/Source/core/css/resolver/StyleAdjusterTest.cpp index 59c0d8e..81e15222 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleAdjusterTest.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleAdjusterTest.cpp
@@ -16,15 +16,17 @@ TEST_F(StyleAdjusterTest, TouchActionPropagatedAcrossIframes) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; } iframe { display: block; } </style>" - "<iframe id='owner' src='http://test.com' width='500' height='500' " - "style='touch-action: none'>" - "</iframe>"); - SetChildFrameHTML( - "<style>body { margin: 0; } #target { width: 200px; height: 200px; } " - "</style>" - "<div id='target' style='touch-action: pinch-zoom'></div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; } iframe { display: block; } </style> + <iframe id='owner' src='http://test.com' width='500' height='500' + style='touch-action: none'> + </iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style>body { margin: 0; } #target { width: 200px; height: 200px; } + </style> + <div id='target' style='touch-action: pinch-zoom'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* target = ChildDocument().getElementById("target"); @@ -40,12 +42,13 @@ TEST_F(StyleAdjusterTest, TouchActionPanningReEnabledByScrollers) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>#ancestor { margin: 0; touch-action: pinch-zoom; } " - "#scroller { overflow: scroll; width: 100px; height: 100px; } " - "#target { width: 200px; height: 200px; } </style>" - "<div id='ancestor'><div id='scroller'><div id='target'>" - "</div></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#ancestor { margin: 0; touch-action: pinch-zoom; } + #scroller { overflow: scroll; width: 100px; height: 100px; } + #target { width: 200px; height: 200px; } </style> + <div id='ancestor'><div id='scroller'><div id='target'> + </div></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* target = GetDocument().getElementById("target"); @@ -55,12 +58,13 @@ TEST_F(StyleAdjusterTest, TouchActionPropagatedWhenAncestorStyleChanges) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>#ancestor { margin: 0; touch-action: pan-x; } " - "#potential-scroller { width: 100px; height: 100px; overflow: hidden; } " - "#target { width: 200px; height: 200px; }</style>" - "<div id='ancestor'><div id='potential-scroller'><div id='target'>" - "</div></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#ancestor { margin: 0; touch-action: pan-x; } + #potential-scroller { width: 100px; height: 100px; overflow: hidden; } + #target { width: 200px; height: 200px; }</style> + <div id='ancestor'><div id='potential-scroller'><div id='target'> + </div></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* target = GetDocument().getElementById("target"); @@ -83,11 +87,12 @@ TEST_F(StyleAdjusterTest, TouchActionRestrictedByLowerAncestor) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<div id='ancestor' style='touch-action: pan'>" - "<div id='parent' style='touch-action: pan-right pan-y'>" - "<div id='target' style='touch-action: pan-x'>" - "</div></div></div>"); + SetBodyInnerHTML(R"HTML( + <div id='ancestor' style='touch-action: pan'> + <div id='parent' style='touch-action: pan-right pan-y'> + <div id='target' style='touch-action: pan-x'> + </div></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* target = GetDocument().getElementById("target");
diff --git a/third_party/WebKit/Source/core/dom/DocumentStatisticsCollectorTest.cpp b/third_party/WebKit/Source/core/dom/DocumentStatisticsCollectorTest.cpp index 876fb1be..b436f87 100644 --- a/third_party/WebKit/Source/core/dom/DocumentStatisticsCollectorTest.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentStatisticsCollectorTest.cpp
@@ -62,10 +62,11 @@ // This test checks non-existence of open graph articles can be recognized. TEST_F(DocumentStatisticsCollectorTest, NoOpenGraphArticle) { - SetHtmlInnerHTML( - "<head>" - " <meta property='og:type' content='movie' />" - "</head>"); + SetHtmlInnerHTML(R"HTML( + <head> + <meta property='og:type' content='movie' /> + </head> + )HTML"); WebDistillabilityFeatures features = DocumentStatisticsCollector::CollectStatistics(GetDocument()); @@ -74,14 +75,15 @@ // This test checks element counts are correct. TEST_F(DocumentStatisticsCollectorTest, CountElements) { - SetHtmlInnerHTML( - "<form>" - " <input type='text'>" - " <input type='password'>" - "</form>" - "<pre></pre>" - "<p><a> </a></p>" - "<ul><li><p><a> </a></p></li></ul>"); + SetHtmlInnerHTML(R"HTML( + <form> + <input type='text'> + <input type='password'> + </form> + <pre></pre> + <p><a> </a></p> + <ul><li><p><a> </a></p></li></ul> + )HTML"); WebDistillabilityFeatures features = DocumentStatisticsCollector::CollectStatistics(GetDocument());
diff --git a/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/third_party/WebKit/Source/core/dom/DocumentTest.cpp index 5bdb6e9..eb13cec 100644 --- a/third_party/WebKit/Source/core/dom/DocumentTest.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -372,24 +372,25 @@ // This tests that we properly resize and re-layout pages for printing in the // presence of media queries effecting elements in a subtree layout boundary TEST_F(DocumentTest, PrintRelayout) { - SetHtmlInnerHTML( - "<style>" - " div {" - " width: 100px;" - " height: 100px;" - " overflow: hidden;" - " }" - " span {" - " width: 50px;" - " height: 50px;" - " }" - " @media screen {" - " span {" - " width: 20px;" - " }" - " }" - "</style>" - "<p><div><span></span></div></p>"); + SetHtmlInnerHTML(R"HTML( + <style> + div { + width: 100px; + height: 100px; + overflow: hidden; + } + span { + width: 50px; + height: 50px; + } + @media screen { + span { + width: 20px; + } + } + </style> + <p><div><span></span></div></p> + )HTML"); FloatSize page_size(400, 400); float maximum_shrink_ratio = 1.6; @@ -539,12 +540,13 @@ } TEST_F(DocumentTest, StyleVersion) { - SetHtmlInnerHTML( - "<style>" - " .a * { color: green }" - " .b .c { color: green }" - "</style>" - "<div id='x'><span class='c'></span></div>"); + SetHtmlInnerHTML(R"HTML( + <style> + .a * { color: green } + .b .c { color: green } + </style> + <div id='x'><span class='c'></span></div> + )HTML"); Element* element = GetDocument().getElementById("x"); EXPECT_TRUE(element); @@ -880,13 +882,14 @@ // as it is more expensive than just doing layout. TEST_F(DocumentTest, EnsurePaintLocationDataValidForNodeCompositingInputsOnlyWhenNecessary) { - GetDocument().body()->SetInnerHTMLFromString( - "<div id='ancestor'>" - " <div id='sticky' style='position:sticky;'>" - " <div id='stickyChild'></div>" - " </div>" - " <div id='nonSticky'></div>" - "</div>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <div id='ancestor'> + <div id='sticky' style='position:sticky;'> + <div id='stickyChild'></div> + </div> + <div id='nonSticky'></div> + </div> + )HTML"); EXPECT_EQ(DocumentLifecycle::kStyleClean, GetDocument().Lifecycle().GetState()); @@ -924,10 +927,11 @@ // elements does not trigger a style recalc for viewport style propagation when // the computed style for another element in the document is recalculated. TEST_F(DocumentTest, ViewportPropagationNoRecalc) { - SetHtmlInnerHTML( - "<body style='direction:rtl'>" - " <div id=recalc></div>" - "</body>"); + SetHtmlInnerHTML(R"HTML( + <body style='direction:rtl'> + <div id=recalc></div> + </body> + )HTML"); int old_element_count = GetDocument().GetStyleEngine().StyleForElementCount(); @@ -957,11 +961,12 @@ // This test requires that scrollbars take up space. ScopedOverlayScrollbarsForTest no_overlay_scrollbars(false); - SetHtmlInnerHTML( - "<style>" - " body { margin: 0; }" - "</style>" - "<div id='content'>content</div>"); + SetHtmlInnerHTML(R"HTML( + <style> + body { margin: 0; } + </style> + <div id='content'>content</div> + )HTML"); // A hit test close to the bottom of the page without scrollbars should hit // the body element. @@ -983,11 +988,12 @@ // This test requires that scrollbars take up space. ScopedOverlayScrollbarsForTest no_overlay_scrollbars(false); - SetHtmlInnerHTML( - "<style>" - " body { margin: 0; }" - "</style>" - "<div id='content' style='height: 10px;'>content</div>"); + SetHtmlInnerHTML(R"HTML( + <style> + body { margin: 0; } + </style> + <div id='content' style='height: 10px;'>content</div> + )HTML"); // A hit test on the content div should hit it. auto* content = GetDocument().getElementById("content");
diff --git a/third_party/WebKit/Source/core/dom/ElementTest.cpp b/third_party/WebKit/Source/core/dom/ElementTest.cpp index cf25fb60..a047a93 100644 --- a/third_party/WebKit/Source/core/dom/ElementTest.cpp +++ b/third_party/WebKit/Source/core/dom/ElementTest.cpp
@@ -31,13 +31,14 @@ TEST_F(ElementTest, GetBoundingClientRectCorrectForStickyElementsAfterInsertion) { Document& document = GetDocument(); - SetBodyContent( - "<style>body { margin: 0 }" - "#scroller { overflow: scroll; height: 100px; width: 100px; }" - "#sticky { height: 25px; position: sticky; top: 0; left: 25px; }" - "#padding { height: 500px; width: 300px; }</style>" - "<div id='scroller'><div id='writer'></div><div id='sticky'></div>" - "<div id='padding'></div></div>"); + SetBodyContent(R"HTML( + <style>body { margin: 0 } + #scroller { overflow: scroll; height: 100px; width: 100px; } + #sticky { height: 25px; position: sticky; top: 0; left: 25px; } + #padding { height: 500px; width: 300px; }</style> + <div id='scroller'><div id='writer'></div><div id='sticky'></div> + <div id='padding'></div></div> + )HTML"); Element* scroller = document.getElementById("scroller"); Element* writer = document.getElementById("writer"); @@ -76,13 +77,14 @@ TEST_F(ElementTest, OffsetTopAndLeftCorrectForStickyElementsAfterInsertion) { Document& document = GetDocument(); - SetBodyContent( - "<style>body { margin: 0 }" - "#scroller { overflow: scroll; height: 100px; width: 100px; }" - "#sticky { height: 25px; position: sticky; top: 0; left: 25px; }" - "#padding { height: 500px; width: 300px; }</style>" - "<div id='scroller'><div id='writer'></div><div id='sticky'></div>" - "<div id='padding'></div></div>"); + SetBodyContent(R"HTML( + <style>body { margin: 0 } + #scroller { overflow: scroll; height: 100px; width: 100px; } + #sticky { height: 25px; position: sticky; top: 0; left: 25px; } + #padding { height: 500px; width: 300px; }</style> + <div id='scroller'><div id='writer'></div><div id='sticky'></div> + <div id='padding'></div></div> + )HTML"); Element* scroller = document.getElementById("scroller"); Element* writer = document.getElementById("writer"); @@ -132,13 +134,14 @@ TEST_F(ElementTest, BoundsInViewportCorrectForStickyElementsAfterInsertion) { Document& document = GetDocument(); - SetBodyContent( - "<style>body { margin: 0 }" - "#scroller { overflow: scroll; height: 100px; width: 100px; }" - "#sticky { height: 25px; position: sticky; top: 0; left: 25px; }" - "#padding { height: 500px; width: 300px; }</style>" - "<div id='scroller'><div id='writer'></div><div id='sticky'></div>" - "<div id='padding'></div></div>"); + SetBodyContent(R"HTML( + <style>body { margin: 0 } + #scroller { overflow: scroll; height: 100px; width: 100px; } + #sticky { height: 25px; position: sticky; top: 0; left: 25px; } + #padding { height: 500px; width: 300px; }</style> + <div id='scroller'><div id='writer'></div><div id='sticky'></div> + <div id='padding'></div></div> + )HTML"); Element* scroller = document.getElementById("scroller"); Element* writer = document.getElementById("writer"); @@ -177,17 +180,18 @@ TEST_F(ElementTest, StickySubtreesAreTrackedCorrectly) { Document& document = GetDocument(); - SetBodyContent( - "<div id='ancestor'>" - " <div id='outerSticky' style='position:sticky;'>" - " <div id='child'>" - " <div id='grandchild'></div>" - " <div id='innerSticky' style='position:sticky;'>" - " <div id='greatGrandchild'></div>" - " </div>" - " </div" - " </div>" - "</div>"); + SetBodyContent(R"HTML( + <div id='ancestor'> + <div id='outerSticky' style='position:sticky;'> + <div id='child'> + <div id='grandchild'></div> + <div id='innerSticky' style='position:sticky;'> + <div id='greatGrandchild'></div> + </div> + </div + </div> + </div> + )HTML"); LayoutObject* ancestor = document.getElementById("ancestor")->GetLayoutObject(); @@ -254,24 +258,25 @@ TEST_F(ElementTest, GetBoundingClientRectForSVG) { Document& document = GetDocument(); - SetBodyContent( - "<style>body { margin: 0 }</style>" - "<svg width='500' height='500'>" - " <rect id='rect' x='10' y='100' width='100' height='71'/>" - " <rect id='stroke' x='10' y='100' width='100' height='71' " - " stroke-width='7'/>" - " <rect id='stroke_transformed' x='10' y='100' width='100' height='71' " - " stroke-width='7' transform='translate(3, 5)'/>" - " <foreignObject id='foreign' x='10' y='100' width='100' height='71'/>" - " <foreignObject id='foreign_transformed' transform='translate(3, 5)' " - " x='10' y='100' width='100' height='71'/>" - " <svg id='svg' x='10' y='100'>" - " <rect width='100' height='71'/>" - " </svg>" - " <svg id='svg_stroke' x='10' y='100'>" - " <rect width='100' height='71' stroke-width='7'/>" - " </svg>" - "</svg>"); + SetBodyContent(R"HTML( + <style>body { margin: 0 }</style> + <svg width='500' height='500'> + <rect id='rect' x='10' y='100' width='100' height='71'/> + <rect id='stroke' x='10' y='100' width='100' height='71' + stroke-width='7'/> + <rect id='stroke_transformed' x='10' y='100' width='100' height='71' + stroke-width='7' transform='translate(3, 5)'/> + <foreignObject id='foreign' x='10' y='100' width='100' height='71'/> + <foreignObject id='foreign_transformed' transform='translate(3, 5)' + x='10' y='100' width='100' height='71'/> + <svg id='svg' x='10' y='100'> + <rect width='100' height='71'/> + </svg> + <svg id='svg_stroke' x='10' y='100'> + <rect width='100' height='71' stroke-width='7'/> + </svg> + </svg> + )HTML"); Element* rect = document.getElementById("rect"); DOMRect* rect_bounding_client_rect = rect->getBoundingClientRect();
diff --git a/third_party/WebKit/Source/core/dom/NthIndexCacheTest.cpp b/third_party/WebKit/Source/core/dom/NthIndexCacheTest.cpp index bfc89e3..afd89b4 100644 --- a/third_party/WebKit/Source/core/dom/NthIndexCacheTest.cpp +++ b/third_party/WebKit/Source/core/dom/NthIndexCacheTest.cpp
@@ -28,18 +28,19 @@ } TEST_F(NthIndexCacheTest, NthIndex) { - GetDocument().documentElement()->SetInnerHTMLFromString( - "<body>" - "<span " - "id=first></span><span></span><span></span><span></span><span></span>" - "<span></span><span></span><span></span><span></span><span></span>" - "Text does not count" - "<span id=nth-last-child></span>" - "<span id=nth-child></span>" - "<span></span><span></span><span></span><span></span><span></span>" - "<span></span><span></span><span></span><span></span><span " - "id=last></span>" - "</body>"); + GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML( + <body> + <span + id=first></span><span></span><span></span><span></span><span></span> + <span></span><span></span><span></span><span></span><span></span> + Text does not count + <span id=nth-last-child></span> + <span id=nth-child></span> + <span></span><span></span><span></span><span></span><span></span> + <span></span><span></span><span></span><span></span><span + id=last></span> + </body> + )HTML"); NthIndexCache nth_index_cache(GetDocument());
diff --git a/third_party/WebKit/Source/core/dom/RangeTest.cpp b/third_party/WebKit/Source/core/dom/RangeTest.cpp index 77a9a7d02..278e9d5 100644 --- a/third_party/WebKit/Source/core/dom/RangeTest.cpp +++ b/third_party/WebKit/Source/core/dom/RangeTest.cpp
@@ -317,13 +317,14 @@ } TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterOne) { - GetDocument().body()->SetInnerHTMLFromString( - "<style>" - " body { font-size: 20px; }" - " #sample::first-letter { font-size: 500%; }" - "</style>" - "<p id=sample>abc</p>" - "<p id=expected><span style='font-size: 500%'>a</span>bc</p>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style> + body { font-size: 20px; } + #sample::first-letter { font-size: 500%; } + </style> + <p id=sample>abc</p> + <p id=expected><span style='font-size: 500%'>a</span>bc</p> + )HTML"); GetDocument().UpdateStyleAndLayout(); Element* const expected = GetDocument().getElementById("expected"); @@ -361,13 +362,14 @@ } TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterThree) { - GetDocument().body()->SetInnerHTMLFromString( - "<style>" - " body { font-size: 20px; }" - " #sample::first-letter { font-size: 500%; }" - "</style>" - "<p id=sample>(a)bc</p>" - "<p id=expected><span style='font-size: 500%'>(a)</span>bc</p>"); + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style> + body { font-size: 20px; } + #sample::first-letter { font-size: 500%; } + </style> + <p id=sample>(a)bc</p> + <p id=expected><span style='font-size: 500%'>(a)</span>bc</p> + )HTML"); GetDocument().UpdateStyleAndLayout(); Element* const expected = GetDocument().getElementById("expected");
diff --git a/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp b/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp index efcd88e..30f6d45 100644 --- a/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp +++ b/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp
@@ -105,14 +105,15 @@ TEST_F(ShadowDOMVTest, FeatureSetSubtree) { LoadURL("about:blank"); auto* host = GetDocument().createElement("div"); - host->CreateShadowRootInternal().SetInnerHTMLFromString( - "<div>" - " <div></div>" - " <content select='*'></content>" - " <div>" - " <content select='div[foo=piyo]'></content>" - " </div>" - "</div>"); + host->CreateShadowRootInternal().SetInnerHTMLFromString(R"HTML( + <div> + <div></div> + <content select='*'></content> + <div> + <content select='div[foo=piyo]'></content> + </div> + </div> + )HTML"); EXPECT_FALSE(HasSelectorForIdInShadow(host, "foo")); EXPECT_FALSE(HasSelectorForClassInShadow(host, "foo")); EXPECT_TRUE(HasSelectorForAttributeInShadow(host, "foo"));
diff --git a/third_party/WebKit/Source/core/dom/TextTest.cpp b/third_party/WebKit/Source/core/dom/TextTest.cpp index 7651282d..1e078af4 100644 --- a/third_party/WebKit/Source/core/dom/TextTest.cpp +++ b/third_party/WebKit/Source/core/dom/TextTest.cpp
@@ -175,10 +175,11 @@ } TEST_F(TextTest, TextLayoutObjectIsNeeded_PreserveNewLine) { - SetBodyContent( - "<div id=pre style='white-space:pre'></div>" - "<div id=pre-line style='white-space:pre-line'></div>" - "<div id=pre-wrap style='white-space:pre-wrap'></div>"); + SetBodyContent(R"HTML( + <div id=pre style='white-space:pre'></div> + <div id=pre-line style='white-space:pre-line'></div> + <div id=pre-wrap style='white-space:pre-wrap'></div> + )HTML"); UpdateAllLifecyclePhases(); Text* text = Text::Create(GetDocument(), " ");
diff --git a/third_party/WebKit/Source/core/editing/commands/EditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditCommand.cpp index c549872..d9b7700 100644 --- a/third_party/WebKit/Source/core/editing/commands/EditCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/EditCommand.cpp
@@ -65,15 +65,14 @@ if (!layout_object || !layout_object->IsText()) return false; - const int offset_in_node = position.OffsetInContainerNode(); - // Use NG offset mapping when LayoutNG is enabled. if (auto* mapping = NGOffsetMapping::GetFor(position)) { - return mapping->IsBeforeNonCollapsedCharacter(node, offset_in_node); + return mapping->IsBeforeNonCollapsedContent(position); } // TODO(editing-dev): This doesn't handle first-letter correctly. Fix it. const LayoutText* layout_text = ToLayoutText(layout_object); + const int offset_in_node = position.OffsetInContainerNode(); for (InlineTextBox* box : InlineTextBoxesOf(*layout_text)) { if (offset_in_node < static_cast<int>(box->Start()) && !layout_text->ContainsReversedText()) {
diff --git a/third_party/WebKit/Source/core/exported/WebElementTest.cpp b/third_party/WebKit/Source/core/exported/WebElementTest.cpp index cab246f..07bc9672 100644 --- a/third_party/WebKit/Source/core/exported/WebElementTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebElementTest.cpp
@@ -132,16 +132,18 @@ InsertHTML("<div id=testElement contenteditable=true></div>"); EXPECT_TRUE(TestElement().IsEditable()); - InsertHTML( - "<div style='-webkit-user-modify: read-write'>" - " <div id=testElement></div>" - "</div>"); + InsertHTML(R"HTML( + <div style='-webkit-user-modify: read-write'> + <div id=testElement></div> + </div> + )HTML"); EXPECT_TRUE(TestElement().IsEditable()); - InsertHTML( - "<div style='-webkit-user-modify: read-write'>" - " <div id=testElement style='-webkit-user-modify: read-only'></div>" - "</div>"); + InsertHTML(R"HTML( + <div style='-webkit-user-modify: read-write'> + <div id=testElement style='-webkit-user-modify: read-only'></div> + </div> + )HTML"); EXPECT_FALSE(TestElement().IsEditable()); InsertHTML("<input id=testElement>");
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp index a58d7393..18a1ca5 100644 --- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -11344,12 +11344,13 @@ SimRequest main_resource("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<body dir='rtl'>" - " <div style='width:1px; height:1px; position:absolute; left:-10000px'>" - " </div>" - "</body>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <body dir='rtl'> + <div style='width:1px; height:1px; position:absolute; left:-10000px'> + </div> + </body> + )HTML"); Compositor().BeginFrame(); ScrollableArea* area = GetDocument().View()->LayoutViewportScrollableArea();
diff --git a/third_party/WebKit/Source/core/frame/DeferredLoadingTest.cpp b/third_party/WebKit/Source/core/frame/DeferredLoadingTest.cpp index 94e7243..58964f2 100644 --- a/third_party/WebKit/Source/core/frame/DeferredLoadingTest.cpp +++ b/third_party/WebKit/Source/core/frame/DeferredLoadingTest.cpp
@@ -259,10 +259,11 @@ ExpectCount(WouldLoadReason::kCreated, 1); ExpectTotalCount(6); - main_resource->Write( - "<script>theFrame.style.top='200vh';" - "theFrame.style.position='absolute';" - "theFrame.style.display='block';</script>"); + main_resource->Write(R"HTML( + <script>theFrame.style.top='200vh'; + theFrame.style.position='absolute'; + theFrame.style.display='block';</script> + )HTML"); main_resource->Finish(); CompositeFrame(); @@ -279,12 +280,13 @@ CompositeFrame(); - main_resource->Write( - "<script>frame = document.createElement('iframe');" - "frame.setAttribute('sandbox', true);" - "frame.style.display = 'none';" - "document.body.appendChild(frame);" - "</script>"); + main_resource->Write(R"HTML( + <script>frame = document.createElement('iframe'); + frame.setAttribute('sandbox', true); + frame.style.display = 'none'; + document.body.appendChild(frame); + </script> + )HTML"); main_resource->Finish(); CompositeFrame();
diff --git a/third_party/WebKit/Source/core/frame/DocumentLoadingRenderingTest.cpp b/third_party/WebKit/Source/core/frame/DocumentLoadingRenderingTest.cpp index 39989c2..874c0d4 100644 --- a/third_party/WebKit/Source/core/frame/DocumentLoadingRenderingTest.cpp +++ b/third_party/WebKit/Source/core/frame/DocumentLoadingRenderingTest.cpp
@@ -233,26 +233,28 @@ WebView().Resize(WebSize(800, 600)); - main_resource.Complete( - "<!DOCTYPE html>" - "<body style='background: red'>" - "<iframe id=frame src=frame.html style='border: none'></iframe>" - "<p style='transform: translateZ(0)'>Hello World</p>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <body style='background: red'> + <iframe id=frame src=frame.html style='border: none'></iframe> + <p style='transform: translateZ(0)'>Hello World</p> + )HTML"); // Main page is ready to begin painting as there's no pending sheets. // The frame is not yet loaded, so we only paint the top level page. auto frame1 = Compositor().BeginFrame(); EXPECT_TRUE(frame1.Contains(SimCanvas::kText)); - frame_resource.Complete( - "<!DOCTYPE html>" - "<style>html { background: pink }</style>" - "<link rel=stylesheet href=test.css>" - "<p style='background: yellow;'>Hello World</p>" - "<div style='transform: translateZ(0); background: green;'>" - " <p style='background: blue;'>Hello Layer</p>" - " <div style='position: relative; background: red;'>Hello World</div>" - "</div>"); + frame_resource.Complete(R"HTML( + <!DOCTYPE html> + <style>html { background: pink }</style> + <link rel=stylesheet href=test.css> + <p style='background: yellow;'>Hello World</p> + <div style='transform: translateZ(0); background: green;'> + <p style='background: blue;'>Hello Layer</p> + <div style='position: relative; background: red;'>Hello World</div> + </div> + )HTML"); // Trigger a layout with pending sheets. For example a page could trigger // this by doing offsetTop in a setTimeout, or by a parent frame executing @@ -309,15 +311,17 @@ WebView().Resize(WebSize(800, 600)); - main_resource.Complete( - "<!DOCTYPE html>" - "<body style='background: red'>" - "<iframe id=frame src=frame.html></iframe>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <body style='background: red'> + <iframe id=frame src=frame.html></iframe> + )HTML"); - frame_resource.Complete( - "<!DOCTYPE html>" - "<link rel=stylesheet href=frame.css>" - "<body style='background: blue'>"); + frame_resource.Complete(R"HTML( + <!DOCTYPE html> + <link rel=stylesheet href=frame.css> + <body style='background: blue'> + )HTML"); auto* child_frame = ToHTMLIFrameElement(GetDocument().getElementById("frame")); @@ -395,15 +399,16 @@ main_resource.Start(); - main_resource.Write( - "<html><body>" - " <div id='test' style='font-size: 16px'>test</div>" - " <script>" - " var link = document.createElement('link');" - " link.rel = 'import';" - " link.href = 'import.css';" - " document.head.appendChild(link);" - " </script>"); + main_resource.Write(R"HTML( + <html><body> + <div id='test' style='font-size: 16px'>test</div> + <script> + var link = document.createElement('link'); + link.rel = 'import'; + link.href = 'import.css'; + document.head.appendChild(link); + </script> + )HTML"); import_resource.Start(); // Import loader isn't finish, shoudn't paint.
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameViewTest.cpp b/third_party/WebKit/Source/core/frame/LocalFrameViewTest.cpp index 19a8995c..a36429d 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameViewTest.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameViewTest.cpp
@@ -140,10 +140,11 @@ // overflow layer would always be valid. TEST_P(LocalFrameViewTest, ViewportConstrainedObjectsHandledCorrectlyDuringLayout) { - SetBodyInnerHTML( - "<style>.container { height: 200%; }" - "#sticky { position: sticky; top: 0; height: 50px; }</style>" - "<div class='container'><div id='sticky'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>.container { height: 200%; } + #sticky { position: sticky; top: 0; height: 50px; }</style> + <div class='container'><div id='sticky'></div></div> + )HTML"); LayoutBoxModelObject* sticky = ToLayoutBoxModelObject( GetDocument().getElementById("sticky")->GetLayoutObject()); @@ -164,14 +165,15 @@ if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) return; - SetBodyInnerHTML( - "<style>.container { height: 200%; }" - "#sticky1 { position: sticky; top: 0; height: 50px; }" - "#sticky2 { position: sticky; height: 50px; }</style>" - "<div class='container'>" - " <div id='sticky1'></div>" - " <div id='sticky2'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>.container { height: 200%; } + #sticky1 { position: sticky; top: 0; height: 50px; } + #sticky2 { position: sticky; height: 50px; }</style> + <div class='container'> + <div id='sticky1'></div> + <div id='sticky2'></div> + </div> + )HTML"); LayoutBoxModelObject* sticky1 = ToLayoutBoxModelObject( GetDocument().getElementById("sticky1")->GetLayoutObject());
diff --git a/third_party/WebKit/Source/core/html/HTMLEmbedElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLEmbedElementTest.cpp index b26c934..d5767a2 100644 --- a/third_party/WebKit/Source/core/html/HTMLEmbedElementTest.cpp +++ b/third_party/WebKit/Source/core/html/HTMLEmbedElementTest.cpp
@@ -44,15 +44,16 @@ // Load <object> element with a <embed> child. // This can be seen on sites with Flash cookies, // for example on www.yandex.ru - SetHtmlInnerHTML( - "<div>" - "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='1' " - "height='1' id='fco'>" - "<param name='movie' value='//site.com/flash-cookie.swf'>" - "<param name='allowScriptAccess' value='Always'>" - "<embed src='//site.com/flash-cookie.swf' allowscriptaccess='Always' " - "width='1' height='1' id='fce'>" - "</object></div>"); + SetHtmlInnerHTML(R"HTML( + <div> + <object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='1' + height='1' id='fco'> + <param name='movie' value='//site.com/flash-cookie.swf'> + <param name='allowScriptAccess' value='Always'> + <embed src='//site.com/flash-cookie.swf' allowscriptaccess='Always' + width='1' height='1' id='fce'> + </object></div> + )HTML"); auto* object_element = GetDocument().getElementById("fco"); ASSERT_TRUE(object_element);
diff --git a/third_party/WebKit/Source/core/html/ImageData.cpp b/third_party/WebKit/Source/core/html/ImageData.cpp index c1f33c3..814d5587 100644 --- a/third_party/WebKit/Source/core/html/ImageData.cpp +++ b/third_party/WebKit/Source/core/html/ImageData.cpp
@@ -241,9 +241,6 @@ ImageDataStorageFormat storage_format) { ImageDataColorSettings color_settings; switch (color_space) { - case kLegacyCanvasColorSpace: - color_settings.setColorSpace(kLegacyCanvasColorSpaceName); - break; case kSRGBCanvasColorSpace: color_settings.setColorSpace(kSRGBCanvasColorSpaceName); break; @@ -497,8 +494,6 @@ CanvasColorSpace ImageData::GetCanvasColorSpace( const String& color_space_name) { - if (color_space_name == kLegacyCanvasColorSpaceName) - return kLegacyCanvasColorSpace; if (color_space_name == kSRGBCanvasColorSpaceName) return kSRGBCanvasColorSpace; if (color_space_name == kRec2020CanvasColorSpaceName) @@ -789,8 +784,6 @@ // The default color space for ImageData with U16/F32 data should be // extended-srgb color space. It is temporarily set to linear-rgb, which is // not correct, but fixes crbug.com/779419. - if (color_settings_.colorSpace() == kLegacyCanvasColorSpaceName) - color_settings_.setColorSpace(kSRGBCanvasColorSpaceName); switch (storage_format) { case kUint8ClampedArrayStorageFormat:
diff --git a/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl b/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl index 222a321..828808c 100644 --- a/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl +++ b/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl
@@ -11,6 +11,6 @@ }; dictionary ImageDataColorSettings { - CanvasColorSpace colorSpace = "legacy-srgb"; + CanvasColorSpace colorSpace = "srgb"; ImageDataStorageFormat storageFormat = "uint8"; };
diff --git a/third_party/WebKit/Source/core/html/MediaElementFillingViewportTest.cpp b/third_party/WebKit/Source/core/html/MediaElementFillingViewportTest.cpp index 661e198..506e0c3 100644 --- a/third_party/WebKit/Source/core/html/MediaElementFillingViewportTest.cpp +++ b/third_party/WebKit/Source/core/html/MediaElementFillingViewportTest.cpp
@@ -43,14 +43,15 @@ TEST_F(MediaElementFillingViewportTest, MostlyFillingViewport) { std::unique_ptr<SimRequest> main_resource = CreateMainResource(); - main_resource->Complete( - "<!DOCTYPE html>" - "<html>" - "<video id='video' style = 'position:fixed; left:0; top:0; width:100%; " - "height:100%;'>" - "source src='test.webm'" - "</video>" - "</html>"); + main_resource->Complete(R"HTML( + <!DOCTYPE html> + <html> + <video id='video' style = 'position:fixed; left:0; top:0; width:100%; + height:100%;'> + source src='test.webm' + </video> + </html> + )HTML"); Compositor().BeginFrame(); HTMLMediaElement* element = @@ -61,14 +62,15 @@ TEST_F(MediaElementFillingViewportTest, NotMostlyFillingViewport) { std::unique_ptr<SimRequest> main_resource = CreateMainResource(); - main_resource->Complete( - "<!DOCTYPE html>" - "<html>" - "<video id='video' style = 'position:fixed; left:0; top:0; width:80%; " - "height:80%;'>" - "source src='test.webm'" - "</video>" - "</html>"); + main_resource->Complete(R"HTML( + <!DOCTYPE html> + <html> + <video id='video' style = 'position:fixed; left:0; top:0; width:80%; + height:80%;'> + source src='test.webm' + </video> + </html> + )HTML"); Compositor().BeginFrame(); HTMLMediaElement* element = @@ -79,14 +81,15 @@ TEST_F(MediaElementFillingViewportTest, FillingViewportChanged) { std::unique_ptr<SimRequest> main_resource = CreateMainResource(); - main_resource->Complete( - "<!DOCTYPE html>" - "<html>" - "<video id='video' style = 'position:fixed; left:0; top:0; width:100%; " - "height:100%;'>" - "source src='test.webm'" - "</video>" - "</html>"); + main_resource->Complete(R"HTML( + <!DOCTYPE html> + <html> + <video id='video' style = 'position:fixed; left:0; top:0; width:100%; + height:100%;'> + source src='test.webm' + </video> + </html> + )HTML"); Compositor().BeginFrame(); HTMLMediaElement* element = @@ -105,14 +108,15 @@ TEST_F(MediaElementFillingViewportTest, LargeVideo) { std::unique_ptr<SimRequest> main_resource = CreateMainResource(); - main_resource->Complete( - "<!DOCTYPE html>" - "<html>" - "<video id='video' style = 'position:fixed; left:0; top:0; width:200%; " - "height:200%;'>" - "source src='test.webm'" - "</video>" - "</html>"); + main_resource->Complete(R"HTML( + <!DOCTYPE html> + <html> + <video id='video' style = 'position:fixed; left:0; top:0; width:200%; + height:200%;'> + source src='test.webm' + </video> + </html> + )HTML"); Compositor().BeginFrame(); HTMLMediaElement* element = @@ -123,14 +127,15 @@ TEST_F(MediaElementFillingViewportTest, VideoScrollOutHalf) { std::unique_ptr<SimRequest> main_resource = CreateMainResource(); - main_resource->Complete( - "<!DOCTYPE html>" - "<html>" - "<video id='video' style = 'position:fixed; left:0; top:0; width:100%; " - "height:100%;'>" - "source src='test.webm'" - "</video>" - "</html>"); + main_resource->Complete(R"HTML( + <!DOCTYPE html> + <html> + <video id='video' style = 'position:fixed; left:0; top:0; width:100%; + height:100%;'> + source src='test.webm' + </video> + </html> + )HTML"); Compositor().BeginFrame(); HTMLMediaElement* element =
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributes.idl b/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributes.idl index dbae755..d1093b58 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributes.idl +++ b/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributes.idl
@@ -38,9 +38,7 @@ dictionary CanvasContextCreationAttributes { // Canvas 2D attributes boolean alpha = true; // Also used for WebGL. - // TODO(crbug.com/637288): Do we keep "legacy-srgb" as the default? - // Must decide before shipping. - [RuntimeEnabled=ExperimentalCanvasFeatures] CanvasColorSpace colorSpace = "legacy-srgb"; + [RuntimeEnabled=ExperimentalCanvasFeatures] CanvasColorSpace colorSpace = "srgb"; [RuntimeEnabled=ExperimentalCanvasFeatures] CanvasPixelFormat pixelFormat = "8-8-8-8"; // WebGL attributes
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp index 41ca265b..0fec8c2 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -63,8 +63,6 @@ WTF::String CanvasRenderingContext::ColorSpaceAsString() const { switch (color_params_.ColorSpace()) { - case kLegacyCanvasColorSpace: - return kLegacyCanvasColorSpaceName; case kSRGBCanvasColorSpace: return kSRGBCanvasColorSpaceName; case kRec2020CanvasColorSpace:
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index 9a232764..a550bd29 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -48,7 +48,6 @@ class ImageBitmap; class WebLayer; -constexpr const char* kLegacyCanvasColorSpaceName = "legacy-srgb"; constexpr const char* kSRGBCanvasColorSpaceName = "srgb"; constexpr const char* kRec2020CanvasColorSpaceName = "rec2020"; constexpr const char* kP3CanvasColorSpaceName = "p3";
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLInputElementTest.cpp b/third_party/WebKit/Source/core/html/forms/HTMLInputElementTest.cpp index fc1824ab..822bfb40 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLInputElementTest.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLInputElementTest.cpp
@@ -73,13 +73,14 @@ } TEST_F(HTMLInputElementTest, FilteredDataListOptionsForMultipleEmail) { - GetDocument().documentElement()->SetInnerHTMLFromString( - "<input id=test value='foo@example.com, tkent' list=dl3 type=email " - "multiple>" - "<datalist id=dl3>" - "<option>keishi@chromium.org</option>" - "<option>tkent@chromium.org</option>" - "</datalist>"); + GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML( + <input id=test value='foo@example.com, tkent' list=dl3 type=email + multiple> + <datalist id=dl3> + <option>keishi@chromium.org</option> + <option>tkent@chromium.org</option> + </datalist> + )HTML"); auto options = TestElement().FilteredDataListOptions(); EXPECT_EQ(1u, options.size()); EXPECT_EQ("tkent@chromium.org", options[0]->value().Utf8());
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLSelectElementTest.cpp b/third_party/WebKit/Source/core/html/forms/HTMLSelectElementTest.cpp index 0d2b3c0..cb0af77 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLSelectElementTest.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLSelectElementTest.cpp
@@ -114,11 +114,12 @@ // restoreFormControlState() couldn't find matched OPTIONs. // crbug.com/627833. - GetDocument().documentElement()->SetInnerHTMLFromString( - "<select id='sel'>" - "<option selected>Default</option>" - "<option id='2'>222</option>" - "</select>"); + GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML( + <select id='sel'> + <option selected>Default</option> + <option id='2'>222</option> + </select> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("sel"); HTMLFormControlElementWithState* select = ToHTMLSelectElement(element); @@ -493,10 +494,11 @@ TEST_F(HTMLSelectElementTest, ScrollToOptionAfterLayoutCrash) { // crbug.com/737447 // This test passes if no crash. - GetDocument().documentElement()->SetInnerHTMLFromString( - "<style>*:checked { position:fixed; }</style>" - "<select multiple><<option>o1</option><option " - "selected>o2</option></select>"); + GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML( + <style>*:checked { position:fixed; }</style> + <select multiple><<option>o1</option><option + selected>o2</option></select> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); }
diff --git a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp index ea6d1ee..decf697 100644 --- a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
@@ -653,6 +653,9 @@ void HTMLMediaElement::FinishParsingChildren() { HTMLElement::FinishParsingChildren(); + if (FastHasAttribute(mutedAttr)) + muted_ = true; + if (Traversal<HTMLTrackElement>::FirstChild(*this)) ScheduleTextTrackResourceLoad(); } @@ -1146,9 +1149,6 @@ SetPlayerPreload(); - if (FastHasAttribute(mutedAttr)) - muted_ = true; - DCHECK(!media_source_); bool attempt_load = true;
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParserLoadingTest.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParserLoadingTest.cpp index 1df96dc..f82211088 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParserLoadingTest.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParserLoadingTest.cpp
@@ -47,13 +47,14 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"bodyDiv\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="bodyDiv"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("bodyDiv")); @@ -69,15 +70,16 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<style>" - "@import 'testHead.css'" - "</style>" - "</head><body>" - "<div id=\"bodyDiv\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <style> + @import 'testHead.css' + </style> + </head><body> + <div id="bodyDiv"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("bodyDiv")); @@ -94,15 +96,16 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<link rel=stylesheet href=testBody.css>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <link rel=stylesheet href=testBody.css> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -136,14 +139,15 @@ LoadURL("https://example.com/test.html"); main_resource.Start(); - main_resource.Write( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<link rel=stylesheet href=testBody1.css>" - "<div id=\"after1\"></div>"); + main_resource.Write(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <link rel=stylesheet href=testBody1.css> + <div id="after1"></div> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -161,10 +165,11 @@ EXPECT_FALSE(GetDocument().getElementById("after2")); EXPECT_FALSE(GetDocument().getElementById("after3")); - main_resource.Complete( - "<link rel=stylesheet href=testBody3.css>" - "<div id=\"after3\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <link rel=stylesheet href=testBody3.css> + <div id="after3"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -214,15 +219,16 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<link rel=stylesheet href=testBody.css type='print'>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <link rel=stylesheet href=testBody.css type='print'> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -240,17 +246,18 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<style>" - "@import 'testBody.css'" - "</style>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <style> + @import 'testBody.css' + </style> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -278,17 +285,18 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<script>" - "document.write('<link rel=stylesheet href=testBody.css>');" - "</script>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <script> + document.write('<link rel=stylesheet href=testBody.css>'); + </script> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -315,16 +323,17 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<style>" - "</style>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <style> + </style> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -340,15 +349,16 @@ LoadURL("https://example.com/test.html"); // The marquee tag has a shadow DOM that synchronously applies a stylesheet. - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "<link rel=stylesheet href=testHead.css>" - "</head><body>" - "<div id=\"before\"></div>" - "<marquee>Marquee</marquee>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + <link rel=stylesheet href=testHead.css> + </head><body> + <div id="before"></div> + <marquee>Marquee</marquee> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -364,22 +374,23 @@ LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><head>" - "</head><body>" - "<div id=\"before\"></div>" - "<script>" - "var attach = document.getElementsByTagName('script')[0];" - "var link = document.createElement('link');" - "link.rel = 'stylesheet';" - "link.type = 'text/css';" - "link.href = 'testAsync.css';" - "link.media = 'all';" - "attach.appendChild(link);" - "</script>" - "<div id=\"after\"></div>" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><head> + </head><body> + <div id="before"></div> + <script> + var attach = document.getElementsByTagName('script')[0]; + var link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = 'testAsync.css'; + link.media = 'all'; + attach.appendChild(link); + </script> + <div id="after"></div> + </body></html> + )HTML"); testing::RunPendingTasks(); EXPECT_TRUE(GetDocument().getElementById("before")); @@ -392,10 +403,11 @@ SimRequest main_resource("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html><body>no doc write" - "</body></html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html><body>no doc write + </body></html> + )HTML"); testing::RunPendingTasks(); histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0); @@ -405,11 +417,12 @@ SimRequest main_resource("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<script>" - "document.write('<a');" - "</script>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <script> + document.write('<a'); + </script> + )HTML"); testing::RunPendingTasks(); histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 1); @@ -419,11 +432,12 @@ SimRequest main_resource("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<script>" - "document.write('<svg>');" - "</script>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <script> + document.write('<svg>'); + </script> + )HTML"); testing::RunPendingTasks(); histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 1); @@ -447,11 +461,12 @@ SimRequest main_resource("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<script>" - "document.write('<p>hello world<\\/p><a>yo');" - "</script>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <script> + document.write('<p>hello world<\\/p><a>yo'); + </script> + )HTML"); testing::RunPendingTasks(); histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0); @@ -461,16 +476,17 @@ SimRequest main_resource("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - main_resource.Complete( - "<!DOCTYPE html>" - "<html>" - "<head>" - "<title></title>" - "<script>document.write('<p>testing');</script>" - "</head>" - "<body>" - "</body>" - "</html>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <html> + <head> + <title></title> + <script>document.write('<p>testing');</script> + </head> + <body> + </body> + </html> + )HTML"); testing::RunPendingTasks(); histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0);
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp index 89ee0f23..49d5a85a 100644 --- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp +++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
@@ -68,26 +68,25 @@ parsed_options.has_color_space_conversion = (options.colorSpaceConversion() != kImageBitmapOptionNone); - parsed_options.color_params.SetCanvasColorSpace(kLegacyCanvasColorSpace); - if (options.colorSpaceConversion() == kSRGBImageBitmapColorSpaceConversion) { - parsed_options.color_params.SetCanvasColorSpace(kSRGBCanvasColorSpace); - } else if (options.colorSpaceConversion() == - kLinearRGBImageBitmapColorSpaceConversion) { - parsed_options.color_params.SetCanvasColorSpace(kSRGBCanvasColorSpace); + parsed_options.color_params.SetCanvasColorSpace(kSRGBCanvasColorSpace); + if (options.colorSpaceConversion() != kSRGBImageBitmapColorSpaceConversion && + options.colorSpaceConversion() != kImageBitmapOptionNone && + options.colorSpaceConversion() != kImageBitmapOptionDefault) { parsed_options.color_params.SetCanvasPixelFormat(kF16CanvasPixelFormat); - } else if (options.colorSpaceConversion() == - kP3ImageBitmapColorSpaceConversion) { - parsed_options.color_params.SetCanvasColorSpace(kP3CanvasColorSpace); - parsed_options.color_params.SetCanvasPixelFormat(kF16CanvasPixelFormat); - } else if (options.colorSpaceConversion() == - kRec2020ImageBitmapColorSpaceConversion) { - parsed_options.color_params.SetCanvasColorSpace(kRec2020CanvasColorSpace); - parsed_options.color_params.SetCanvasPixelFormat(kF16CanvasPixelFormat); - } else if (options.colorSpaceConversion() != kImageBitmapOptionNone && - options.colorSpaceConversion() != kImageBitmapOptionDefault) { - NOTREACHED() - << "Invalid ImageBitmap creation attribute colorSpaceConversion: " - << options.colorSpaceConversion(); + if (options.colorSpaceConversion() == + kLinearRGBImageBitmapColorSpaceConversion) { + parsed_options.color_params.SetCanvasColorSpace(kSRGBCanvasColorSpace); + } else if (options.colorSpaceConversion() == + kP3ImageBitmapColorSpaceConversion) { + parsed_options.color_params.SetCanvasColorSpace(kP3CanvasColorSpace); + } else if (options.colorSpaceConversion() == + kRec2020ImageBitmapColorSpaceConversion) { + parsed_options.color_params.SetCanvasColorSpace(kRec2020CanvasColorSpace); + } else { + NOTREACHED() + << "Invalid ImageBitmap creation attribute colorSpaceConversion: " + << options.colorSpaceConversion(); + } } int source_width = source_size.Width();
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapTest.cpp index e561228..78a3e5a 100644 --- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapTest.cpp +++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapTest.cpp
@@ -364,8 +364,8 @@ ColorCorrectionTestUtils::CompareColorCorrectedPixels( converted_pixel.get(), transformed_pixel.get(), 1, - (color_type == kBGRA_8888_SkColorType) ? kUint8ClampedArrayStorageFormat - : kUint16ArrayStorageFormat, + (color_type == kN32_SkColorType) ? kUint8ClampedArrayStorageFormat + : kUint16ArrayStorageFormat, kAlphaMultiplied, kUnpremulRoundTripTolerance); } } @@ -486,8 +486,8 @@ ColorCorrectionTestUtils::CompareColorCorrectedPixels( converted_pixel.get(), transformed_pixel.get(), 1, - (color_type == kBGRA_8888_SkColorType) ? kUint8ClampedArrayStorageFormat - : kUint16ArrayStorageFormat, + (color_type == kN32_SkColorType) ? kUint8ClampedArrayStorageFormat + : kUint16ArrayStorageFormat, kAlphaMultiplied, kUnpremulRoundTripTolerance); } } @@ -602,8 +602,8 @@ ColorCorrectionTestUtils::CompareColorCorrectedPixels( converted_pixel.get(), transformed_pixel.get(), 1, - (color_type == kBGRA_8888_SkColorType) ? kUint8ClampedArrayStorageFormat - : kUint16ArrayStorageFormat, + (color_type == kN32_SkColorType) ? kUint8ClampedArrayStorageFormat + : kUint16ArrayStorageFormat, kAlphaMultiplied, unpremul_round_trip_tolerance); } } @@ -698,8 +698,8 @@ ColorCorrectionTestUtils::CompareColorCorrectedPixels( converted_pixel.get(), transformed_pixel.get(), 1, - (color_type == kBGRA_8888_SkColorType) ? kUint8ClampedArrayStorageFormat - : kUint16ArrayStorageFormat, + (color_type == kN32_SkColorType) ? kUint8ClampedArrayStorageFormat + : kUint16ArrayStorageFormat, kAlphaUnmultiplied, kUnpremulRoundTripTolerance); } }
diff --git a/third_party/WebKit/Source/core/input/OverscrollBehaviorTest.cpp b/third_party/WebKit/Source/core/input/OverscrollBehaviorTest.cpp index 8c31a7a..a5c88ad 100644 --- a/third_party/WebKit/Source/core/input/OverscrollBehaviorTest.cpp +++ b/third_party/WebKit/Source/core/input/OverscrollBehaviorTest.cpp
@@ -33,13 +33,14 @@ WebView().Resize(WebSize(400, 400)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='outer' style='height: 300px; width: 300px; overflow: " - "scroll;'>" - " <div id='inner' style='height: 500px; width: 500px; overflow: " - "scroll;'>" - " <div id='content' style='height: 700px; width: 700px;'>" - "</div></div></div>"); + request.Complete(R"HTML( + <div id='outer' style='height: 300px; width: 300px; overflow: + scroll;'> + <div id='inner' style='height: 500px; width: 500px; overflow: + scroll;'> + <div id='content' style='height: 700px; width: 700px;'> + </div></div></div> + )HTML"); Compositor().BeginFrame();
diff --git a/third_party/WebKit/Source/core/input/ScrollBoundaryBehaviorTest.cpp b/third_party/WebKit/Source/core/input/ScrollBoundaryBehaviorTest.cpp index e7ab741..ab41973 100644 --- a/third_party/WebKit/Source/core/input/ScrollBoundaryBehaviorTest.cpp +++ b/third_party/WebKit/Source/core/input/ScrollBoundaryBehaviorTest.cpp
@@ -34,13 +34,14 @@ WebView().Resize(WebSize(400, 400)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='outer' style='height: 300px; width: 300px; overflow: " - "scroll;'>" - " <div id='inner' style='height: 500px; width: 500px; overflow: " - "scroll;'>" - " <div id='content' style='height: 700px; width: 700px;'>" - "</div></div></div>"); + request.Complete(R"HTML( + <div id='outer' style='height: 300px; width: 300px; overflow: + scroll;'> + <div id='inner' style='height: 500px; width: 500px; overflow: + scroll;'> + <div id='content' style='height: 700px; width: 700px;'> + </div></div></div> + )HTML"); Compositor().BeginFrame();
diff --git a/third_party/WebKit/Source/core/input/TouchEventManagerTest.cpp b/third_party/WebKit/Source/core/input/TouchEventManagerTest.cpp index e56efd3..13dd2c1 100644 --- a/third_party/WebKit/Source/core/input/TouchEventManagerTest.cpp +++ b/third_party/WebKit/Source/core/input/TouchEventManagerTest.cpp
@@ -49,10 +49,11 @@ WebView().Resize(WebSize(400, 400)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<body style='padding: 0px; width: 400px; height: 400px;'>" - "<iframe id='target' style='width: 200px; height: 200px;'></iframe>" - "</body>"); + request.Complete(R"HTML( + <body style='padding: 0px; width: 400px; height: 400px;'> + <iframe id='target' style='width: 200px; height: 200px;'></iframe> + </body> + )HTML"); CheckEventListenerCallback* callback = CheckEventListenerCallback::Create(); GetDocument().body()->addEventListener(EventTypeNames::touchstart, callback);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMSnapshotAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMSnapshotAgent.cpp index 9388bf3f..c89be50 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMSnapshotAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMSnapshotAgent.cpp
@@ -309,14 +309,11 @@ if (!layout_object) return -1; - auto layout_tree_node = - protocol::DOMSnapshot::LayoutTreeNode::create() - .setDomNodeIndex(node_index) - .setBoundingBox(BuildRectForFloatRect( - node->IsElementNode() - ? FloatRect(ToElement(node)->BoundsInViewport()) - : layout_object->AbsoluteBoundingBoxRect())) - .build(); + auto layout_tree_node = protocol::DOMSnapshot::LayoutTreeNode::create() + .setDomNodeIndex(node_index) + .setBoundingBox(BuildRectForFloatRect( + layout_object->AbsoluteBoundingBoxRect())) + .build(); int style_index = GetStyleIndexForNode(node); if (style_index != -1)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp index 380629f4..dca7e75 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -570,6 +570,12 @@ Response InspectorPageAgent::getResourceTree( std::unique_ptr<protocol::Page::FrameResourceTree>* object) { + *object = BuildObjectForResourceTree(inspected_frames_->Root()); + return Response::OK(); +} + +Response InspectorPageAgent::getFrameTree( + std::unique_ptr<protocol::Page::FrameTree>* object) { *object = BuildObjectForFrameTree(inspected_frames_->Root()); return Response::OK(); } @@ -870,8 +876,28 @@ return frame_object; } -std::unique_ptr<protocol::Page::FrameResourceTree> +std::unique_ptr<protocol::Page::FrameTree> InspectorPageAgent::BuildObjectForFrameTree(LocalFrame* frame) { + std::unique_ptr<protocol::Page::FrameTree> result = + protocol::Page::FrameTree::create() + .setFrame(BuildObjectForFrame(frame)) + .build(); + + std::unique_ptr<protocol::Array<protocol::Page::FrameTree>> children_array; + for (Frame* child = frame->Tree().FirstChild(); child; + child = child->Tree().NextSibling()) { + if (!child->IsLocalFrame()) + continue; + if (!children_array) + children_array = protocol::Array<protocol::Page::FrameTree>::create(); + children_array->addItem(BuildObjectForFrameTree(ToLocalFrame(child))); + } + result->setChildFrames(std::move(children_array)); + return result; +} + +std::unique_ptr<protocol::Page::FrameResourceTree> +InspectorPageAgent::BuildObjectForResourceTree(LocalFrame* frame) { std::unique_ptr<protocol::Page::Frame> frame_object = BuildObjectForFrame(frame); std::unique_ptr<protocol::Array<protocol::Page::FrameResource>> subresources = @@ -924,7 +950,7 @@ if (!children_array) children_array = protocol::Array<protocol::Page::FrameResourceTree>::create(); - children_array->addItem(BuildObjectForFrameTree(ToLocalFrame(child))); + children_array->addItem(BuildObjectForResourceTree(ToLocalFrame(child))); } result->setChildFrames(std::move(children_array)); return result;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h index 281a4d0..4960b17 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
@@ -128,6 +128,8 @@ protocol::Response setAdBlockingEnabled(bool) override; protocol::Response getResourceTree( std::unique_ptr<protocol::Page::FrameResourceTree>* frame_tree) override; + protocol::Response getFrameTree( + std::unique_ptr<protocol::Page::FrameTree>*) override; void getResourceContent(const String& frame_id, const String& url, std::unique_ptr<GetResourceContentCallback>) override; @@ -216,7 +218,9 @@ void PageLayoutInvalidated(bool resized); std::unique_ptr<protocol::Page::Frame> BuildObjectForFrame(LocalFrame*); - std::unique_ptr<protocol::Page::FrameResourceTree> BuildObjectForFrameTree( + std::unique_ptr<protocol::Page::FrameTree> BuildObjectForFrameTree( + LocalFrame*); + std::unique_ptr<protocol::Page::FrameResourceTree> BuildObjectForResourceTree( LocalFrame*); Member<InspectedFrames> inspected_frames_; v8_inspector::V8InspectorSession* v8_session_;
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json index aac631b3..c53133a 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.json +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -167,6 +167,15 @@ "experimental": true }, { + "id": "FrameTree", + "type": "object", + "description": "Information about the Frame hierarchy.", + "properties": [ + { "name": "frame", "$ref": "Frame", "description": "Frame information for this tree item." }, + { "name": "childFrames", "type": "array", "optional": true, "items": { "$ref": "FrameTree" }, "description": "Child frames." } + ] + }, + { "id": "ScriptIdentifier", "type": "string", "description": "Unique script identifier.", @@ -409,6 +418,13 @@ "experimental": true }, { + "name": "getFrameTree", + "description": "Returns present frame tree structure.", + "returns": [ + { "name": "frameTree", "$ref": "FrameTree", "description": "Present frame tree structure." } + ] + }, + { "name": "getResourceContent", "description": "Returns content of the given resource.", "parameters": [
diff --git a/third_party/WebKit/Source/core/intersection_observer/IntersectionObserverTest.cpp b/third_party/WebKit/Source/core/intersection_observer/IntersectionObserverTest.cpp index 71d710a..09dcc97 100644 --- a/third_party/WebKit/Source/core/intersection_observer/IntersectionObserverTest.cpp +++ b/third_party/WebKit/Source/core/intersection_observer/IntersectionObserverTest.cpp
@@ -72,10 +72,11 @@ WebView().Resize(WebSize(800, 600)); SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<div id='leading-space' style='height: 700px;'></div>" - "<div id='target'></div>" - "<div id='trailing-space' style='height: 700px;'></div>"); + main_resource.Complete(R"HTML( + <div id='leading-space' style='height: 700px;'></div> + <div id='target'></div> + <div id='trailing-space' style='height: 700px;'></div> + )HTML"); IntersectionObserverInit observer_init; DummyExceptionStateForTesting exception_state; @@ -131,10 +132,11 @@ WebView().Resize(WebSize(800, 600)); SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<div id='leading-space' style='height: 700px;'></div>" - "<div id='target'></div>" - "<div id='trailing-space' style='height: 700px;'></div>"); + main_resource.Complete(R"HTML( + <div id='leading-space' style='height: 700px;'></div> + <div id='target'></div> + <div id='trailing-space' style='height: 700px;'></div> + )HTML"); IntersectionObserverInit observer_init; DummyExceptionStateForTesting exception_state;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockTest.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockTest.cpp index 01e08740..82960c91 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockTest.cpp
@@ -24,16 +24,17 @@ TEST_F(LayoutBlockTest, WidthAvailableToChildrenChanged) { ScopedOverlayScrollbarsForTest overlay_scrollbars(false); - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<div id='list' style='overflow-y:auto; width:150px; height:100px'>" - " <div style='height:20px'>Item</div>" - " <div style='height:20px'>Item</div>" - " <div style='height:20px'>Item</div>" - " <div style='height:20px'>Item</div>" - " <div style='height:20px'>Item</div>" - " <div style='height:20px'>Item</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <div id='list' style='overflow-y:auto; width:150px; height:100px'> + <div style='height:20px'>Item</div> + <div style='height:20px'>Item</div> + <div style='height:20px'>Item</div> + <div style='height:20px'>Item</div> + <div style='height:20px'>Item</div> + <div style='height:20px'>Item</div> + </div> + )HTML"); Element* list_element = GetDocument().getElementById("list"); ASSERT_TRUE(list_element); LayoutBox* list_box = ToLayoutBox(list_element->GetLayoutObject()); @@ -53,12 +54,13 @@ } TEST_F(LayoutBlockTest, OverflowWithTransformAndPerspective) { - SetBodyInnerHTML( - "<div id='target' style='width: 100px; height: 100px; overflow: scroll;" - " perspective: 200px;'>" - " <div style='transform: rotateY(-45deg); width: 140px; height: 100px'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='width: 100px; height: 100px; overflow: scroll; + perspective: 200px;'> + <div style='transform: rotateY(-45deg); width: 140px; height: 100px'> + </div> + </div> + )HTML"); LayoutBox* scroller = ToLayoutBox(GetDocument().getElementById("target")->GetLayoutObject()); EXPECT_EQ(119.5, scroller->LayoutOverflowRect().Width().ToFloat());
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObjectTest.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObjectTest.cpp index 52832862b..ac57800 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObjectTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObjectTest.cpp
@@ -35,16 +35,17 @@ // Verifies that the sticky constraints are correctly computed. TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraints) { - SetBodyInnerHTML( - "<style>#sticky { position: sticky; top: 0; width: 100px; height: 100px; " - "}" - "#container { box-sizing: border-box; position: relative; top: 100px; " - "height: 400px; width: 200px; padding: 10px; border: 5px solid black; }" - "#scroller { width: 400px; height: 100px; overflow: auto; " - "position: relative; top: 200px; border: 2px solid black; }" - ".spacer { height: 1000px; }</style>" - "<div id='scroller'><div id='container'><div " - "id='sticky'></div></div><div class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#sticky { position: sticky; top: 0; width: 100px; height: 100px; + } + #container { box-sizing: border-box; position: relative; top: 100px; + height: 400px; width: 200px; padding: 10px; border: 5px solid black; } + #scroller { width: 400px; height: 100px; overflow: auto; + position: relative; top: 200px; border: 2px solid black; } + .spacer { height: 1000px; }</style> + <div id='scroller'><div id='container'><div + id='sticky'></div></div><div class='spacer'></div></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -76,17 +77,18 @@ // Verifies that the sticky constraints are correctly computed in right to left. TEST_F(LayoutBoxModelObjectTest, StickyPositionVerticalRLConstraints) { - SetBodyInnerHTML( - "<style> html { -webkit-writing-mode: vertical-rl; } " - "#sticky { position: sticky; top: 0; width: 100px; height: 100px; " - "}" - "#container { box-sizing: border-box; position: relative; top: 100px; " - "height: 400px; width: 200px; padding: 10px; border: 5px solid black; }" - "#scroller { width: 400px; height: 100px; overflow: auto; " - "position: relative; top: 200px; border: 2px solid black; }" - ".spacer { height: 1000px; }</style>" - "<div id='scroller'><div id='container'><div " - "id='sticky'></div></div><div class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> html { -webkit-writing-mode: vertical-rl; } + #sticky { position: sticky; top: 0; width: 100px; height: 100px; + } + #container { box-sizing: border-box; position: relative; top: 100px; + height: 400px; width: 200px; padding: 10px; border: 5px solid black; } + #scroller { width: 400px; height: 100px; overflow: auto; + position: relative; top: 200px; border: 2px solid black; } + .spacer { height: 1000px; }</style> + <div id='scroller'><div id='container'><div + id='sticky'></div></div><div class='spacer'></div></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -118,17 +120,18 @@ // Verifies that the sticky constraints are not affected by transforms TEST_F(LayoutBoxModelObjectTest, StickyPositionTransforms) { - SetBodyInnerHTML( - "<style>#sticky { position: sticky; top: 0; width: 100px; height: 100px; " - "transform: scale(2); transform-origin: top left; }" - "#container { box-sizing: border-box; position: relative; top: 100px; " - "height: 400px; width: 200px; padding: 10px; border: 5px solid black; " - "transform: scale(2); transform-origin: top left; }" - "#scroller { height: 100px; overflow: auto; position: relative; top: " - "200px; }" - ".spacer { height: 1000px; }</style>" - "<div id='scroller'><div id='container'><div " - "id='sticky'></div></div><div class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#sticky { position: sticky; top: 0; width: 100px; height: 100px; + transform: scale(2); transform-origin: top left; } + #container { box-sizing: border-box; position: relative; top: 100px; + height: 400px; width: 200px; padding: 10px; border: 5px solid black; + transform: scale(2); transform-origin: top left; } + #scroller { height: 100px; overflow: auto; position: relative; top: + 200px; } + .spacer { height: 1000px; }</style> + <div id='scroller'><div id='container'><div + id='sticky'></div></div><div class='spacer'></div></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -156,16 +159,17 @@ // Verifies that the sticky constraints are correctly computed. TEST_F(LayoutBoxModelObjectTest, StickyPositionPercentageStyles) { - SetBodyInnerHTML( - "<style>#sticky { position: sticky; margin-top: 10%; top: 0; width: " - "100px; height: 100px; }" - "#container { box-sizing: border-box; position: relative; top: 100px; " - "height: 400px; width: 250px; padding: 5%; border: 5px solid black; }" - "#scroller { width: 400px; height: 100px; overflow: auto; position: " - "relative; top: 200px; }" - ".spacer { height: 1000px; }</style>" - "<div id='scroller'><div id='container'><div " - "id='sticky'></div></div><div class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#sticky { position: sticky; margin-top: 10%; top: 0; width: + 100px; height: 100px; } + #container { box-sizing: border-box; position: relative; top: 100px; + height: 400px; width: 250px; padding: 5%; border: 5px solid black; } + #scroller { width: 400px; height: 100px; overflow: auto; position: + relative; top: 200px; } + .spacer { height: 1000px; }</style> + <div id='scroller'><div id='container'><div + id='sticky'></div></div><div class='spacer'></div></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -192,14 +196,15 @@ // Verifies that the sticky constraints are correct when the sticky position // container is also the ancestor scroller. TEST_F(LayoutBoxModelObjectTest, StickyPositionContainerIsScroller) { - SetBodyInnerHTML( - "<style>#sticky { position: sticky; top: 0; width: 100px; height: 100px; " - "}" - "#scroller { height: 100px; width: 400px; overflow: auto; position: " - "relative; top: 200px; border: 2px solid black; }" - ".spacer { height: 1000px; }</style>" - "<div id='scroller'><div id='sticky'></div><div " - "class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#sticky { position: sticky; top: 0; width: 100px; height: 100px; + } + #scroller { height: 100px; width: 400px; overflow: auto; position: + relative; top: 200px; border: 2px solid black; } + .spacer { height: 1000px; }</style> + <div id='scroller'><div id='sticky'></div><div + class='spacer'></div></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -224,17 +229,18 @@ // Verifies that the sticky constraints are correct when the sticky position // object has an anonymous containing block. TEST_F(LayoutBoxModelObjectTest, StickyPositionAnonymousContainer) { - SetBodyInnerHTML( - "<style>#sticky { display: inline-block; position: sticky; top: 0; " - "width: 100px; height: 100px; }" - "#container { box-sizing: border-box; position: relative; top: 100px; " - "height: 400px; width: 200px; padding: 10px; border: 5px solid black; }" - "#scroller { height: 100px; overflow: auto; position: relative; top: " - "200px; }" - ".header { height: 50px; }" - ".spacer { height: 1000px; }</style>" - "<div id='scroller'><div id='container'><div class='header'></div><div " - "id='sticky'></div></div><div class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#sticky { display: inline-block; position: sticky; top: 0; + width: 100px; height: 100px; } + #container { box-sizing: border-box; position: relative; top: 100px; + height: 400px; width: 200px; padding: 10px; border: 5px solid black; } + #scroller { height: 100px; overflow: auto; position: relative; top: + 200px; } + .header { height: 50px; } + .spacer { height: 1000px; }</style> + <div id='scroller'><div id='container'><div class='header'></div><div + id='sticky'></div></div><div class='spacer'></div></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -257,17 +263,18 @@ } TEST_F(LayoutBoxModelObjectTest, StickyPositionTableContainers) { - SetBodyInnerHTML( - "<style> td, th { height: 50px; width: 50px; } " - "#sticky { position: sticky; left: 0; will-change: transform; }" - "table {border: none; }" - "#scroller { overflow: auto; }" - "</style>" - "<div id='scroller'>" - "<table cellspacing='0' cellpadding='0'>" - " <thead><tr><td></td></tr></thead>" - " <tr><td id='sticky'></td></tr>" - "</table></div>"); + SetBodyInnerHTML(R"HTML( + <style> td, th { height: 50px; width: 50px; } + #sticky { position: sticky; left: 0; will-change: transform; } + table {border: none; } + #scroller { overflow: auto; } + </style> + <div id='scroller'> + <table cellspacing='0' cellpadding='0'> + <thead><tr><td></td></tr></thead> + <tr><td id='sticky'></td></tr> + </table></div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -287,21 +294,22 @@ // Tests that when a non-layer changes size it invalidates the constraints for // sticky position elements within the same scroller. TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) { - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: auto; display: flex; width: 200px; }" - "#target { width: 50px; }" - "#sticky { position: sticky; top: 0; }" - ".container { width: 100px; margin-left: auto; margin-right: auto; }" - ".hide { display: none; }" - "</style>" - "<div id='scroller'>" - " <div style='flex: 1'>" - " <div class='container'><div id='sticky'></div>" - " </div>" - "</div>" - "<div class='spacer' id='target'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: auto; display: flex; width: 200px; } + #target { width: 50px; } + #sticky { position: sticky; top: 0; } + .container { width: 100px; margin-left: auto; margin-right: auto; } + .hide { display: none; } + </style> + <div id='scroller'> + <div style='flex: 1'> + <div class='container'><div id='sticky'></div> + </div> + </div> + <div class='spacer' id='target'></div> + </div> + )HTML"); LayoutBoxModelObject* scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); @@ -343,22 +351,23 @@ // cells can be sticky in CSS2.1, but we can test the former. TEST_F(LayoutBoxModelObjectTest, StickyPositionFindsCorrectStickyBoxShiftingAncestor) { - SetBodyInnerHTML( - "<style>#stickyOuterDiv { position: sticky; top: 0;}" - "#stickyOuterInline { position: sticky; top: 0; display: inline; }" - "#unanchoredSticky { position: sticky; display: inline; }" - ".inline { display: inline; }" - "#stickyInnerInline { position: sticky; top: 0; display: inline; " - "}</style>" - "<div id='stickyOuterDiv'>" - " <div id='stickyOuterInline'>" - " <div id='unanchoredSticky'>" - " <div class='inline'>" - " <div id='stickyInnerInline'></div>" - " </div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#stickyOuterDiv { position: sticky; top: 0;} + #stickyOuterInline { position: sticky; top: 0; display: inline; } + #unanchoredSticky { position: sticky; display: inline; } + .inline { display: inline; } + #stickyInnerInline { position: sticky; top: 0; display: inline; + }</style> + <div id='stickyOuterDiv'> + <div id='stickyOuterInline'> + <div id='unanchoredSticky'> + <div class='inline'> + <div id='stickyInnerInline'></div> + </div> + </div> + </div> + </div> + )HTML"); PaintLayer* sticky_outer_div = GetPaintLayerByElementId("stickyOuterDiv"); PaintLayer* sticky_outer_inline = @@ -402,20 +411,21 @@ StickyPositionFindsCorrectContainingBlockShiftingAncestor) { // We make the scroller itself sticky in order to check that elements do not // detect it as their containing-block shifting ancestor. - SetBodyInnerHTML( - "<style>#scroller { overflow-y: scroll; position: sticky; top: 0;}" - "#stickyParent { position: sticky; top: 0;}" - "#stickyChild { position: sticky; top: 0;}" - "#unanchoredSticky { position: sticky; }" - "#stickyNestedChild { position: sticky; top: 0;}</style>" - "<div id='scroller'>" - " <div id='stickyParent'>" - " <div id='unanchoredSticky'>" - " <div id='stickyChild'></div>" - " <div><div id='stickyNestedChild'></div></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { overflow-y: scroll; position: sticky; top: 0;} + #stickyParent { position: sticky; top: 0;} + #stickyChild { position: sticky; top: 0;} + #unanchoredSticky { position: sticky; } + #stickyNestedChild { position: sticky; top: 0;}</style> + <div id='scroller'> + <div id='stickyParent'> + <div id='unanchoredSticky'> + <div id='stickyChild'></div> + <div><div id='stickyNestedChild'></div></div> + </div> + </div> + </div> + )HTML"); PaintLayer* scroller = GetPaintLayerByElementId("scroller"); PaintLayer* sticky_parent = GetPaintLayerByElementId("stickyParent"); @@ -454,11 +464,12 @@ // not make a difference for containing-block shifting ancestor calculations. TEST_F(LayoutBoxModelObjectTest, StickyPositionFindsCorrectContainingBlockShiftingAncestorRoot) { - SetBodyInnerHTML( - "<style>#stickyParent { position: sticky; top: 0;}" - "#stickyGrandchild { position: sticky; top: 0;}</style>" - "<div id='stickyParent'><div><div id='stickyGrandchild'></div></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#stickyParent { position: sticky; top: 0;} + #stickyGrandchild { position: sticky; top: 0;}</style> + <div id='stickyParent'><div><div id='stickyGrandchild'></div></div> + </div> + )HTML"); PaintLayer* sticky_parent = GetPaintLayerByElementId("stickyParent"); PaintLayer* sticky_grandchild = GetPaintLayerByElementId("stickyGrandchild"); @@ -484,12 +495,13 @@ // we have to skip over elements to find the correct ancestor. TEST_F(LayoutBoxModelObjectTest, StickyPositionFindsCorrectContainingBlockShiftingAncestorTable) { - SetBodyInnerHTML( - "<style>#scroller { overflow-y: scroll; }" - "#stickyOuter { position: sticky; top: 0;}" - "#stickyTh { position: sticky; top: 0;}</style>" - "<div id='scroller'><div id='stickyOuter'><table><thead><tr>" - "<th id='stickyTh'></th></tr></thead></table></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { overflow-y: scroll; } + #stickyOuter { position: sticky; top: 0;} + #stickyTh { position: sticky; top: 0;}</style> + <div id='scroller'><div id='stickyOuter'><table><thead><tr> + <th id='stickyTh'></th></tr></thead></table></div></div> + )HTML"); PaintLayer* scroller = GetPaintLayerByElementId("scroller"); PaintLayer* sticky_outer = GetPaintLayerByElementId("stickyOuter"); @@ -513,14 +525,15 @@ // Verifies that the calculated position:sticky offsets are correct when we have // a simple case of nested sticky elements. TEST_F(LayoutBoxModelObjectTest, StickyPositionNested) { - SetBodyInnerHTML( - "<style>#scroller { height: 100px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px }" - "#stickyParent { position: sticky; top: 0; height: 50px; }" - "#stickyChild { position: sticky; top: 0; height: 25px; }" - "#postPadding { height: 200px }</style>" - "<div id='scroller'><div id='prePadding'></div><div id='stickyParent'>" - "<div id='stickyChild'></div></div><div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { height: 100px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px } + #stickyParent { position: sticky; top: 0; height: 50px; } + #stickyChild { position: sticky; top: 0; height: 25px; } + #postPadding { height: 200px }</style> + <div id='scroller'><div id='prePadding'></div><div id='stickyParent'> + <div id='stickyChild'></div></div><div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* sticky_parent = ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent")); @@ -555,14 +568,15 @@ // Verifies that the calculated position:sticky offsets are correct when the // child has a larger edge constraint value than the parent. TEST_F(LayoutBoxModelObjectTest, StickyPositionChildHasLargerTop) { - SetBodyInnerHTML( - "<style>#scroller { height: 100px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px }" - "#stickyParent { position: sticky; top: 0; height: 50px; }" - "#stickyChild { position: sticky; top: 25px; height: 25px; }" - "#postPadding { height: 200px }</style>" - "<div id='scroller'><div id='prePadding'></div><div id='stickyParent'>" - "<div id='stickyChild'></div></div><div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { height: 100px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px } + #stickyParent { position: sticky; top: 0; height: 50px; } + #stickyChild { position: sticky; top: 25px; height: 25px; } + #postPadding { height: 200px }</style> + <div id='scroller'><div id='prePadding'></div><div id='stickyParent'> + <div id='stickyChild'></div></div><div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* sticky_parent = ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent")); @@ -597,14 +611,15 @@ // Verifies that the calculated position:sticky offsets are correct when the // child has a smaller edge constraint value than the parent. TEST_F(LayoutBoxModelObjectTest, StickyPositionParentHasLargerTop) { - SetBodyInnerHTML( - "<style>#scroller { height: 100px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px }" - "#stickyParent { position: sticky; top: 25px; height: 50px; }" - "#stickyChild { position: sticky; top: 0; height: 25px; }" - "#postPadding { height: 200px }</style>" - "<div id='scroller'><div id='prePadding'></div><div id='stickyParent'>" - "<div id='stickyChild'></div></div><div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { height: 100px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px } + #stickyParent { position: sticky; top: 25px; height: 50px; } + #stickyChild { position: sticky; top: 0; height: 25px; } + #postPadding { height: 200px }</style> + <div id='scroller'><div id='prePadding'></div><div id='stickyParent'> + <div id='stickyChild'></div></div><div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* sticky_parent = ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent")); @@ -639,14 +654,15 @@ // Verifies that the calculated position:sticky offsets are correct when the // child has a large enough edge constraint value to push outside of its parent. TEST_F(LayoutBoxModelObjectTest, StickyPositionChildPushingOutsideParent) { - SetBodyInnerHTML( - "<style> #scroller { height: 100px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px; }" - "#stickyParent { position: sticky; top: 0; height: 50px; }" - "#stickyChild { position: sticky; top: 50px; height: 25px; }" - "#postPadding { height: 200px }</style>" - "<div id='scroller'><div id='prePadding'></div><div id='stickyParent'>" - "<div id='stickyChild'></div></div><div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> #scroller { height: 100px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px; } + #stickyParent { position: sticky; top: 0; height: 50px; } + #stickyChild { position: sticky; top: 50px; height: 25px; } + #postPadding { height: 200px }</style> + <div id='scroller'><div id='prePadding'></div><div id='stickyParent'> + <div id='stickyChild'></div></div><div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* sticky_parent = ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent")); @@ -683,16 +699,17 @@ // sticky must correct both its sticky box constraint rect and its containing // block constaint rect. TEST_F(LayoutBoxModelObjectTest, StickyPositionTripleNestedDiv) { - SetBodyInnerHTML( - "<style>#scroller { height: 200px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px; }" - "#outmostSticky { position: sticky; top: 0; height: 100px; }" - "#middleSticky { position: sticky; top: 0; height: 75px; }" - "#innerSticky { position: sticky; top: 25px; height: 25px; }" - "#postPadding { height: 400px }</style>" - "<div id='scroller'><div id='prePadding'></div><div id='outmostSticky'>" - "<div id='middleSticky'><div id='innerSticky'></div></div></div>" - "<div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { height: 200px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px; } + #outmostSticky { position: sticky; top: 0; height: 100px; } + #middleSticky { position: sticky; top: 0; height: 75px; } + #innerSticky { position: sticky; top: 25px; height: 25px; } + #postPadding { height: 400px }</style> + <div id='scroller'><div id='prePadding'></div><div id='outmostSticky'> + <div id='middleSticky'><div id='innerSticky'></div></div></div> + <div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* outmost_sticky = ToLayoutBoxModelObject(GetLayoutObjectByElementId("outmostSticky")); @@ -739,18 +756,19 @@ // of tables. Tables are special as the containing block for table elements is // always the root level <table>. TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedStickyTable) { - SetBodyInnerHTML( - "<style>table { border-collapse: collapse; }" - "td, th { height: 25px; width: 25px; padding: 0; }" - "#scroller { height: 100px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px; }" - "#stickyDiv { position: sticky; top: 0; height: 200px; }" - "#stickyTh { position: sticky; top: 0; }" - "#postPadding { height: 200px; }</style>" - "<div id='scroller'><div id='prePadding'></div><div id='stickyDiv'>" - "<table><thead><tr><th id='stickyTh'></th></tr></thead><tbody><tr><td>" - "</td></tr><tr><td></td></tr><tr><td></td></tr><tr><td></td></tr></tbody>" - "</table></div><div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>table { border-collapse: collapse; } + td, th { height: 25px; width: 25px; padding: 0; } + #scroller { height: 100px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px; } + #stickyDiv { position: sticky; top: 0; height: 200px; } + #stickyTh { position: sticky; top: 0; } + #postPadding { height: 200px; }</style> + <div id='scroller'><div id='prePadding'></div><div id='stickyDiv'> + <table><thead><tr><th id='stickyTh'></th></tr></thead><tbody><tr><td> + </td></tr><tr><td></td></tr><tr><td></td></tr><tr><td></td></tr></tbody> + </table></div><div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* sticky_div = ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyDiv")); @@ -809,20 +827,21 @@ // This is a rare case that can be replicated by nesting tables so that a sticky // cell contains another table that has sticky elements. See the HTML below. TEST_F(LayoutBoxModelObjectTest, StickyPositionComplexTableNesting) { - SetBodyInnerHTML( - "<style>table { border-collapse: collapse; }" - "td, th { height: 25px; width: 25px; padding: 0; }" - "#scroller { height: 100px; width: 100px; overflow-y: auto; }" - "#prePadding { height: 50px; }" - "#outerStickyTh { height: 50px; position: sticky; top: 0; }" - "#innerStickyTh { position: sticky; top: 25px; }" - "#postPadding { height: 200px; }</style>" - "<div id='scroller'><div id='prePadding'></div>" - "<table><thead><tr><th id='outerStickyTh'><table><thead><tr>" - "<th id='innerStickyTh'></th></tr></thead><tbody><tr><td></td></tr>" - "</tbody></table></th></tr></thead><tbody><tr><td></td></tr><tr><td></td>" - "</tr><tr><td></td></tr><tr><td></td></tr></tbody></table>" - "<div id='postPadding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>table { border-collapse: collapse; } + td, th { height: 25px; width: 25px; padding: 0; } + #scroller { height: 100px; width: 100px; overflow-y: auto; } + #prePadding { height: 50px; } + #outerStickyTh { height: 50px; position: sticky; top: 0; } + #innerStickyTh { position: sticky; top: 25px; } + #postPadding { height: 200px; }</style> + <div id='scroller'><div id='prePadding'></div> + <table><thead><tr><th id='outerStickyTh'><table><thead><tr> + <th id='innerStickyTh'></th></tr></thead><tbody><tr><td></td></tr> + </tbody></table></th></tr></thead><tbody><tr><td></td></tr><tr><td></td> + </tr><tr><td></td></tr><tr><td></td></tr></tbody></table> + <div id='postPadding'></div></div> + )HTML"); LayoutBoxModelObject* outer_sticky_th = ToLayoutBoxModelObject(GetLayoutObjectByElementId("outerStickyTh")); @@ -853,25 +872,26 @@ // Verifies that the calculated position:sticky offsets are correct in the case // of nested inline elements. TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedInlineElements) { - SetBodyInnerHTML( - "<style>#scroller { width: 100px; height: 100px; overflow-y: scroll; }" - "#paddingBefore { height: 50px; }" - "#outerInline { display: inline; position: sticky; top: 0; }" - "#unanchoredSticky { position: sticky; display: inline; }" - ".inline {display: inline;}" - "#innerInline { display: inline; position: sticky; top: 25px; }" - "#paddingAfter { height: 200px; }</style>" - "<div id='scroller'>" - " <div id='paddingBefore'></div>" - " <div id='outerInline'>" - " <div id='unanchoredSticky'>" - " <div class='inline'>" - " <div id='innerInline'></div>" - " </div>" - " </div>" - " </div>" - " <div id='paddingAfter'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#scroller { width: 100px; height: 100px; overflow-y: scroll; } + #paddingBefore { height: 50px; } + #outerInline { display: inline; position: sticky; top: 0; } + #unanchoredSticky { position: sticky; display: inline; } + .inline {display: inline;} + #innerInline { display: inline; position: sticky; top: 25px; } + #paddingAfter { height: 200px; }</style> + <div id='scroller'> + <div id='paddingBefore'></div> + <div id='outerInline'> + <div id='unanchoredSticky'> + <div class='inline'> + <div id='innerInline'></div> + </div> + </div> + </div> + <div id='paddingAfter'></div> + </div> + )HTML"); LayoutBoxModelObject* outer_inline = ToLayoutBoxModelObject(GetLayoutObjectByElementId("outerInline")); @@ -893,16 +913,17 @@ // Verifies that the calculated position:sticky offsets are correct in the case // of an intermediate position:fixed element. TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedFixedPos) { - SetBodyInnerHTML( - "<style>body { margin: 0; }" - "#scroller { height: 200px; width: 100px; overflow-y: auto; }" - "#outerSticky { position: sticky; top: 0; height: 50px; }" - "#fixedDiv { position: fixed; top: 0; left: 300px; height: 100px; " - "width: 100px; }" - "#innerSticky { position: sticky; top: 25px; height: 25px; }" - "#padding { height: 400px }</style>" - "<div id='scroller'><div id='outerSticky'><div id='fixedDiv'>" - "<div id='innerSticky'></div></div></div><div id='padding'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; } + #scroller { height: 200px; width: 100px; overflow-y: auto; } + #outerSticky { position: sticky; top: 0; height: 50px; } + #fixedDiv { position: fixed; top: 0; left: 300px; height: 100px; + width: 100px; } + #innerSticky { position: sticky; top: 25px; height: 25px; } + #padding { height: 400px }</style> + <div id='scroller'><div id='outerSticky'><div id='fixedDiv'> + <div id='innerSticky'></div></div></div><div id='padding'></div></div> + )HTML"); LayoutBoxModelObject* outer_sticky = ToLayoutBoxModelObject(GetLayoutObjectByElementId("outerSticky")); @@ -951,14 +972,15 @@ } TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) { - SetBodyInnerHTML( - "<style>" - " .stacked { background: red; position: relative; height: 2000px; }" - " .non-stacked { all: inherit }" - "</style>" - "<div style='height: 100px; backface-visibility: hidden'>" - " <div id='target' class='stacked'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .stacked { background: red; position: relative; height: 2000px; } + .non-stacked { all: inherit } + </style> + <div style='height: 100px; backface-visibility: hidden'> + <div id='target' class='stacked'></div> + </div> + )HTML"); auto* target_element = GetDocument().getElementById("target"); auto* target = target_element->GetLayoutBoxModelObject(); @@ -993,15 +1015,16 @@ // Tests that when a sticky object is removed from the root scroller it // correctly clears its viewport constrained position: https://crbug.com/755307. TEST_F(LayoutBoxModelObjectTest, StickyRemovedFromRootScrollableArea) { - SetBodyInnerHTML( - "<style>" - "body { height: 5000px; }" - "#scroller { height: 100px; }" - "#sticky { position: sticky; top: 0; height: 50px; width: 50px; }" - "</style>" - "<div id='scroller'>" - " <div id='sticky'></div>" - " </div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { height: 5000px; } + #scroller { height: 100px; } + #sticky { position: sticky; top: 0; height: 50px; width: 50px; } + </style> + <div id='scroller'> + <div id='sticky'></div> + </div> + )HTML"); LayoutBoxModelObject* sticky = ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky"));
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxTest.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxTest.cpp index efba67f..677568b 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBoxTest.cpp
@@ -16,46 +16,48 @@ class LayoutBoxTest : public RenderingTest {}; TEST_F(LayoutBoxTest, BackgroundObscuredInRect) { - SetBodyInnerHTML( - "<style>.column { width: 295.4px; padding-left: 10.4px; } " - ".white-background { background: red; position: relative; overflow: " - "hidden; border-radius: 1px; }" - ".black-background { height: 100px; background: black; color: white; } " - "</style>" - "<div class='column'> <div> <div id='target' class='white-background'> " - "<div class='black-background'></div> </div> </div> </div>"); + SetBodyInnerHTML(R"HTML( + <style>.column { width: 295.4px; padding-left: 10.4px; } + .white-background { background: red; position: relative; overflow: + hidden; border-radius: 1px; } + .black-background { height: 100px; background: black; color: white; } + </style> + <div class='column'> <div> <div id='target' class='white-background'> + <div class='black-background'></div> </div> </div> </div> + )HTML"); LayoutObject* layout_object = GetLayoutObjectByElementId("target"); ASSERT_TRUE(layout_object); ASSERT_TRUE(layout_object->BackgroundIsKnownToBeObscured()); } TEST_F(LayoutBoxTest, BackgroundRect) { - SetBodyInnerHTML( - "<style>div { position: absolute; width: 100px; height: 100px; padding: " - "10px; border: 10px solid black; overflow: scroll; }" - "#target1 { background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) border-box, green " - "content-box;}" - "#target2 { background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) content-box, green " - "local border-box;}" - "#target3 { background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) content-box, rgba(0, " - "255, 0, 0.5) border-box;}" - "#target4 { background-image: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg), none;" - " background-clip: content-box, border-box;" - " background-blend-mode: normal, multiply;" - " background-color: green; }" - "#target5 { background: none border-box, green content-box;}" - "#target6 { background: green content-box local; }" - "</style>" - "<div id='target1'></div>" - "<div id='target2'></div>" - "<div id='target3'></div>" - "<div id='target4'></div>" - "<div id='target5'></div>" - "<div id='target6'></div>"); + SetBodyInnerHTML(R"HTML( + <style>div { position: absolute; width: 100px; height: 100px; padding: + 10px; border: 10px solid black; overflow: scroll; } + #target1 { background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) border-box, green + content-box;} + #target2 { background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) content-box, green + local border-box;} + #target3 { background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) content-box, rgba(0, + 255, 0, 0.5) border-box;} + #target4 { background-image: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg), none; + background-clip: content-box, border-box; + background-blend-mode: normal, multiply; + background-color: green; } + #target5 { background: none border-box, green content-box;} + #target6 { background: green content-box local; } + </style> + <div id='target1'></div> + <div id='target2'></div> + <div id='target3'></div> + <div id='target4'></div> + <div id='target5'></div> + <div id='target6'></div> + )HTML"); // #target1's opaque background color only fills the content box but its // translucent image extends to the borders. @@ -104,17 +106,18 @@ } TEST_F(LayoutBoxTest, LocationContainer) { - SetBodyInnerHTML( - "<div id='div'>" - " <b>Inline content<img id='img'></b>" - "</div>" - "<table id='table'>" - " <tbody id='tbody'>" - " <tr id='row'>" - " <td id='cell' style='width: 100px; height: 80px'></td>" - " </tr>" - " </tbody>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <div id='div'> + <b>Inline content<img id='img'></b> + </div> + <table id='table'> + <tbody id='tbody'> + <tr id='row'> + <td id='cell' style='width: 100px; height: 80px'></td> + </tr> + </tbody> + </table> + )HTML"); const LayoutBox* body = GetDocument().body()->GetLayoutBox(); const LayoutBox* div = ToLayoutBox(GetLayoutObjectByElementId("div")); @@ -133,11 +136,12 @@ } TEST_F(LayoutBoxTest, TopLeftLocationFlipped) { - SetBodyInnerHTML( - "<div style='width: 600px; height: 200px; writing-mode: vertical-rl'>" - " <div id='box1' style='width: 100px'></div>" - " <div id='box2' style='width: 200px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='width: 600px; height: 200px; writing-mode: vertical-rl'> + <div id='box1' style='width: 100px'></div> + <div id='box2' style='width: 200px'></div> + </div> + )HTML"); const LayoutBox* box1 = ToLayoutBox(GetLayoutObjectByElementId("box1")); EXPECT_EQ(LayoutPoint(0, 0), box1->Location()); @@ -149,20 +153,21 @@ } TEST_F(LayoutBoxTest, TableRowCellTopLeftLocationFlipped) { - SetBodyInnerHTML( - "<div style='writing-mode: vertical-rl'>" - " <table style='border-spacing: 0'>" - " <thead><tr><td style='width: 50px'></td></tr></thead>" - " <tbody>" - " <tr id='row1'>" - " <td id='cell1' style='width: 100px; height: 80px'></td>" - " </tr>" - " <tr id='row2'>" - " <td id='cell2' style='width: 300px; height: 80px'></td>" - " </tr>" - " </tbody>" - " </table>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='writing-mode: vertical-rl'> + <table style='border-spacing: 0'> + <thead><tr><td style='width: 50px'></td></tr></thead> + <tbody> + <tr id='row1'> + <td id='cell1' style='width: 100px; height: 80px'></td> + </tr> + <tr id='row2'> + <td id='cell2' style='width: 300px; height: 80px'></td> + </tr> + </tbody> + </table> + </div> + )HTML"); // location and physicalLocation of a table row or a table cell should be // relative to the containing section. @@ -185,13 +190,14 @@ } TEST_F(LayoutBoxTest, LocationContainerOfSVG) { - SetBodyInnerHTML( - "<svg id='svg' style='writing-mode:vertical-rl' width='500' height='500'>" - " <foreignObject x='44' y='77' width='100' height='80' id='foreign'>" - " <div id='child' style='width: 33px; height: 55px'>" - " </div>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg' style='writing-mode:vertical-rl' width='500' height='500'> + <foreignObject x='44' y='77' width='100' height='80' id='foreign'> + <div id='child' style='width: 33px; height: 55px'> + </div> + </foreignObject> + </svg> + )HTML"); const LayoutBox* svg_root = ToLayoutBox(GetLayoutObjectByElementId("svg")); const LayoutBox* foreign = ToLayoutBox(GetLayoutObjectByElementId("foreign")); const LayoutBox* child = ToLayoutBox(GetLayoutObjectByElementId("child")); @@ -214,15 +220,16 @@ } TEST_F(LayoutBoxTest, ControlClip) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " #target {" - " position: relative;" - " width: 100px; height: 50px;" - " }" - "</style>" - "<input id='target' type='button' value='some text'/>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #target { + position: relative; + width: 100px; height: 50px; + } + </style> + <input id='target' type='button' value='some text'/> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); EXPECT_TRUE(target->HasControlClip()); EXPECT_TRUE(target->HasClipRelatedProperty()); @@ -238,11 +245,12 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id='target' style='-webkit-mask-image: url(#a);" - " width: 100px; height: 100px; background: blue'>" - " <div style='width: 300px; height: 10px; background: green'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='-webkit-mask-image: url(#a); + width: 100px; height: 100px; background: blue'> + <div style='width: 300px; height: 10px; background: green'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); EXPECT_TRUE(target->HasMask()); @@ -254,11 +262,12 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id='target' style='-webkit-mask-image: url(#a); overflow: hidden;" - " width: 100px; height: 100px; background: blue'>" - " <div style='width: 300px; height: 10px; background: green'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='-webkit-mask-image: url(#a); overflow: hidden; + width: 100px; height: 100px; background: blue'> + <div style='width: 300px; height: 10px; background: green'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); EXPECT_TRUE(target->HasMask()); @@ -271,12 +280,13 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id='target' style='-webkit-mask-box-image-source: url(#a); " - "-webkit-mask-box-image-outset: 10px 20px;" - " width: 100px; height: 100px; background: blue'>" - " <div style='width: 300px; height: 10px; background: green'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='-webkit-mask-box-image-source: url(#a); + -webkit-mask-box-image-outset: 10px 20px; + width: 100px; height: 100px; background: blue'> + <div style='width: 300px; height: 10px; background: green'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); EXPECT_TRUE(target->HasMask()); @@ -288,12 +298,13 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id='target' style='-webkit-mask-box-image-source: url(#a); " - "-webkit-mask-box-image-outset: 10px 20px; overflow: hidden;" - " width: 100px; height: 100px; background: blue'>" - " <div style='width: 300px; height: 10px; background: green'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='-webkit-mask-box-image-source: url(#a); + -webkit-mask-box-image-outset: 10px 20px; overflow: hidden; + width: 100px; height: 100px; background: blue'> + <div style='width: 300px; height: 10px; background: green'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); EXPECT_TRUE(target->HasMask()); @@ -303,24 +314,25 @@ } TEST_F(LayoutBoxTest, ContentsVisualOverflowPropagation) { - SetBodyInnerHTML( - "<style>" - " div { width: 100px; height: 100px }" - "</style>" - "<div id='a'>" - " <div style='height: 50px'></div>" - " <div id='b' style='writing-mode: vertical-rl; margin-left: 60px'>" - " <div style='width: 30px'></div>" - " <div id='c' style='margin-top: 40px'>" - " <div style='width: 10px'></div>" - " <div style='margin-top: 20px; margin-left: 10px'></div>" - " </div>" - " <div id='d' style='writing-mode: vertical-lr; margin-top: 40px'>" - " <div style='width: 10px'></div>" - " <div style='margin-top: 20px'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { width: 100px; height: 100px } + </style> + <div id='a'> + <div style='height: 50px'></div> + <div id='b' style='writing-mode: vertical-rl; margin-left: 60px'> + <div style='width: 30px'></div> + <div id='c' style='margin-top: 40px'> + <div style='width: 10px'></div> + <div style='margin-top: 20px; margin-left: 10px'></div> + </div> + <div id='d' style='writing-mode: vertical-lr; margin-top: 40px'> + <div style='width: 10px'></div> + <div style='margin-top: 20px'></div> + </div> + </div> + </div> + )HTML"); auto* c = ToLayoutBox(GetLayoutObjectByElementId("c")); EXPECT_EQ(LayoutRect(0, 0, 100, 100), c->SelfVisualOverflowRect());
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp index b8c51a10..aea052fd 100644 --- a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
@@ -88,6 +88,10 @@ layout_object_->SetShouldDoFullPaintInvalidation(); } +bool LayoutImageResource::ImageHasRelativeSize() const { + return cached_image_ && cached_image_->GetImage()->HasRelativeSize(); +} + LayoutSize LayoutImageResource::ImageSize(float multiplier) const { if (!cached_image_) return LayoutSize();
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.h b/third_party/WebKit/Source/core/layout/LayoutImageResource.h index 879ba7c..d6cbcb01 100644 --- a/third_party/WebKit/Source/core/layout/LayoutImageResource.h +++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
@@ -63,9 +63,7 @@ // the "broken image". void UseBrokenImage(); - virtual bool ImageHasRelativeSize() const { - return cached_image_ ? cached_image_->ImageHasRelativeSize() : false; - } + virtual bool ImageHasRelativeSize() const; virtual LayoutSize ImageSize(float multiplier) const;
diff --git a/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp b/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp index f13e9eb1..ef11b4cd 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp
@@ -42,15 +42,16 @@ } TEST_F(LayoutInlineTest, RegionHitTest) { - SetBodyInnerHTML( - "<div><span id='lotsOfBoxes'>" - "This is a test line<br>This is a test line<br>This is a test line<br>" - "This is a test line<br>This is a test line<br>This is a test line<br>" - "This is a test line<br>This is a test line<br>This is a test line<br>" - "This is a test line<br>This is a test line<br>This is a test line<br>" - "This is a test line<br>This is a test line<br>This is a test line<br>" - "This is a test line<br>This is a test line<br>This is a test line<br>" - "</span></div>"); + SetBodyInnerHTML(R"HTML( + <div><span id='lotsOfBoxes'> + This is a test line<br>This is a test line<br>This is a test line<br> + This is a test line<br>This is a test line<br>This is a test line<br> + This is a test line<br>This is a test line<br>This is a test line<br> + This is a test line<br>This is a test line<br>This is a test line<br> + This is a test line<br>This is a test line<br>This is a test line<br> + This is a test line<br>This is a test line<br>This is a test line<br> + </span></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/core/layout/LayoutMediaTest.cpp b/third_party/WebKit/Source/core/layout/LayoutMediaTest.cpp index ada2872..c7866b3 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMediaTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMediaTest.cpp
@@ -11,41 +11,45 @@ using LayoutMediaTest = RenderingTest; TEST_F(LayoutMediaTest, DisallowInlineChild) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-media-controls { display: inline; }" - "</style>" - "<video id='video'></video>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-media-controls { display: inline; } + </style> + <video id='video'></video> + )HTML"); EXPECT_FALSE(GetLayoutObjectByElementId("video")->SlowFirstChild()); } TEST_F(LayoutMediaTest, DisallowBlockChild) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-media-controls { display: block; }" - "</style>" - "<video id='video'></video>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-media-controls { display: block; } + </style> + <video id='video'></video> + )HTML"); EXPECT_FALSE(GetLayoutObjectByElementId("video")->SlowFirstChild()); } TEST_F(LayoutMediaTest, DisallowOutOfFlowPositionedChild) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-media-controls { position: absolute; }" - "</style>" - "<video id='video'></video>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-media-controls { position: absolute; } + </style> + <video id='video'></video> + )HTML"); EXPECT_FALSE(GetLayoutObjectByElementId("video")->SlowFirstChild()); } TEST_F(LayoutMediaTest, DisallowFloatingChild) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-media-controls { float: left; }" - "</style>" - "<video id='video'></video>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-media-controls { float: left; } + </style> + <video id='video'></video> + )HTML"); EXPECT_FALSE(GetLayoutObjectByElementId("video")->SlowFirstChild()); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp b/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp index dd7c46b8..a3ec15e7 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp
@@ -119,13 +119,14 @@ } TEST_F(LayoutObjectTest, PaintingLayerOfOverflowClipLayerUnderColumnSpanAll) { - SetBodyInnerHTML( - "<div id='columns' style='columns: 3'>" - " <div style='column-span: all'>" - " <div id='overflow-clip-layer' style='height: 100px; overflow: " - "hidden'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='columns' style='columns: 3'> + <div style='column-span: all'> + <div id='overflow-clip-layer' style='height: 100px; overflow: + hidden'></div> + </div> + </div> + )HTML"); LayoutObject* overflow_clip_object = GetLayoutObjectByElementId("overflow-clip-layer"); @@ -134,12 +135,13 @@ } TEST_F(LayoutObjectTest, FloatUnderBlock) { - SetBodyInnerHTML( - "<div id='layered-div' style='position: absolute'>" - " <div id='container'>" - " <div id='floating' style='float: left'>FLOAT</div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='layered-div' style='position: absolute'> + <div id='container'> + <div id='floating' style='float: left'>FLOAT</div> + </div> + </div> + )HTML"); LayoutBoxModelObject* layered_div = ToLayoutBoxModelObject(GetLayoutObjectByElementId("layered-div")); @@ -154,14 +156,15 @@ } TEST_F(LayoutObjectTest, FloatUnderInline) { - SetBodyInnerHTML( - "<div id='layered-div' style='position: absolute'>" - " <div id='container'>" - " <span id='layered-span' style='position: relative'>" - " <div id='floating' style='float: left'>FLOAT</div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='layered-div' style='position: absolute'> + <div id='container'> + <span id='layered-span' style='position: relative'> + <div id='floating' style='float: left'>FLOAT</div> + </span> + </div> + </div> + )HTML"); LayoutBoxModelObject* layered_div = ToLayoutBoxModelObject(GetLayoutObjectByElementId("layered-div"));
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp index b53ddef..6b45161f 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp
@@ -108,12 +108,13 @@ TEST_F(LayoutTableCellTest, BackgroundIsKnownToBeOpaqueWithLayerAndCollapsedBorder) { - SetBodyInnerHTML( - "<table style='border-collapse: collapse'>" - " <td id='cell' style='will-change: transform; background-color: blue'>" - " Cell" - " </td>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-collapse: collapse'> + <td id='cell' style='will-change: transform; background-color: blue'> + Cell + </td> + </table> + )HTML"); EXPECT_FALSE(GetCellByElementId("cell")->BackgroundIsKnownToBeOpaqueInRect( LayoutRect(0, 0, 1, 1))); } @@ -144,23 +145,24 @@ } TEST_F(LayoutTableCellTest, IsInStartAndEndColumn) { - SetBodyInnerHTML( - "<table id='table'>" - " <tr>" - " <td id='cell11' colspan='2000'></td>" - " <td id='cell12'></td>" - " <td id='cell13'></td>" - " </tr>" - " <tr>" - " <td id='cell21' rowspan='2'></td>" - " <td id='cell22'></td>" - " <td id='cell23' colspan='2000'></td>" - " </tr>" - " <tr>" - " <td id='cell31'></td>" - " <td id='cell32'></td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table id='table'> + <tr> + <td id='cell11' colspan='2000'></td> + <td id='cell12'></td> + <td id='cell13'></td> + </tr> + <tr> + <td id='cell21' rowspan='2'></td> + <td id='cell22'></td> + <td id='cell23' colspan='2000'></td> + </tr> + <tr> + <td id='cell31'></td> + <td id='cell32'></td> + </tr> + </table> + )HTML"); const auto* cell11 = GetCellByElementId("cell11"); const auto* cell12 = GetCellByElementId("cell12"); @@ -192,27 +194,28 @@ } TEST_F(LayoutTableCellTest, IsInStartAndEndColumnRTL) { - SetBodyInnerHTML( - "<style>" - " table { direction: rtl }" - " td { direction: ltr }" - "</style>" - "<table id='table'>" - " <tr>" - " <td id='cell11' colspan='2000'></td>" - " <td id='cell12'></td>" - " <td id='cell13'></td>" - " </tr>" - " <tr>" - " <td id='cell21' rowspan='2'></td>" - " <td id='cell22'></td>" - " <td id='cell23' colspan='2000'></td>" - " </tr>" - " <tr>" - " <td id='cell31'></td>" - " <td id='cell32'></td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + table { direction: rtl } + td { direction: ltr } + </style> + <table id='table'> + <tr> + <td id='cell11' colspan='2000'></td> + <td id='cell12'></td> + <td id='cell13'></td> + </tr> + <tr> + <td id='cell21' rowspan='2'></td> + <td id='cell22'></td> + <td id='cell23' colspan='2000'></td> + </tr> + <tr> + <td id='cell31'></td> + <td id='cell32'></td> + </tr> + </table> + )HTML"); const auto* cell11 = GetCellByElementId("cell11"); const auto* cell12 = GetCellByElementId("cell12"); @@ -244,19 +247,20 @@ } TEST_F(LayoutTableCellTest, BorderWidthsWithCollapsedBorders) { - SetBodyInnerHTML( - "<style>" - " table { border-collapse: collapse }" - " td { border: 0px solid blue; padding: 0 }" - " div { width: 100px; height: 100px }" - "</style>" - "<table>" - " <tr>" - " <td id='cell1' style='border-bottom-width: 10px;" - " outline: 3px solid blue'><div></div></td>" - " <td id='cell2' style='border-width: 3px 15px'><div></div></td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + table { border-collapse: collapse } + td { border: 0px solid blue; padding: 0 } + div { width: 100px; height: 100px } + </style> + <table> + <tr> + <td id='cell1' style='border-bottom-width: 10px; + outline: 3px solid blue'><div></div></td> + <td id='cell2' style='border-width: 3px 15px'><div></div></td> + </tr> + </table> + )HTML"); auto* cell1 = GetCellByElementId("cell1"); auto* cell2 = GetCellByElementId("cell2");
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableColTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableColTest.cpp index c970451..54dd7a25 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableColTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableColTest.cpp
@@ -13,13 +13,14 @@ TEST_F(LayoutTableColTest, LocalVisualRectSPv1) { ScopedSlimmingPaintV175ForTest spv175(false); - SetBodyInnerHTML( - "<table id='table' style='width: 200px; height: 200px'>" - " <col id='col1' style='visibility: hidden'>" - " <col id='col2' style='visibility: collapse'>" - " <col id='col3'>" - " <tr><td></td><td></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table id='table' style='width: 200px; height: 200px'> + <col id='col1' style='visibility: hidden'> + <col id='col2' style='visibility: collapse'> + <col id='col3'> + <tr><td></td><td></td></tr> + </table> + )HTML"); auto table_local_visual_rect = GetLayoutObjectByElementId("table")->LocalVisualRect(); @@ -34,13 +35,14 @@ TEST_F(LayoutTableColTest, LocalVisualRectSPv175) { ScopedSlimmingPaintV175ForTest spv175(true); - SetBodyInnerHTML( - "<table style='width: 200px; height: 200px'>" - " <col id='col1' style='visibility: hidden'>" - " <col id='col2' style='visibility: collapse'>" - " <col id='col3'>" - " <tr><td></td><td></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='width: 200px; height: 200px'> + <col id='col1' style='visibility: hidden'> + <col id='col2' style='visibility: collapse'> + <col id='col3'> + <tr><td></td><td></td></tr> + </table> + )HTML"); EXPECT_EQ(LayoutRect(), GetLayoutObjectByElementId("col1")->LocalVisualRect());
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRowTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRowTest.cpp index 41563e8..86ffacd 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableRowTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableRowTest.cpp
@@ -77,34 +77,37 @@ TEST_F(LayoutTableRowTest, BackgroundIsKnownToBeOpaqueWithLayerAndCollapsedBorder) { - SetBodyInnerHTML( - "<table style='border-collapse: collapse'>" - " <tr id='row' style='will-change: transform;" - " background-color: blue'>" - " <td>Cell</td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-collapse: collapse'> + <tr id='row' style='will-change: transform; + background-color: blue'> + <td>Cell</td> + </tr> + </table> + )HTML"); EXPECT_FALSE(GetRowByElementId("row")->BackgroundIsKnownToBeOpaqueInRect( LayoutRect(0, 0, 1, 1))); } TEST_F(LayoutTableRowTest, BackgroundIsKnownToBeOpaqueWithBorderSpacing) { - SetBodyInnerHTML( - "<table style='border-spacing: 10px'>" - " <tr id='row' style='background-color: blue'><td>Cell</td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-spacing: 10px'> + <tr id='row' style='background-color: blue'><td>Cell</td></tr> + </table> + )HTML"); EXPECT_FALSE(GetRowByElementId("row")->BackgroundIsKnownToBeOpaqueInRect( LayoutRect(0, 0, 1, 1))); } TEST_F(LayoutTableRowTest, BackgroundIsKnownToBeOpaqueWithEmptyCell) { - SetBodyInnerHTML( - "<table style='border-spacing: 10px'>" - " <tr id='row' style='background-color: blue'><td>Cell</td></tr>" - " <tr style='background-color: blue'><td>Cell</td><td>Cell</td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-spacing: 10px'> + <tr id='row' style='background-color: blue'><td>Cell</td></tr> + <tr style='background-color: blue'><td>Cell</td><td>Cell</td></tr> + </table> + )HTML"); EXPECT_FALSE(GetRowByElementId("row")->BackgroundIsKnownToBeOpaqueInRect( LayoutRect(0, 0, 1, 1))); @@ -119,24 +122,25 @@ // | F | | | | row3 // +---+ +---+---+ // Cell D has an outline which creates overflow. - SetBodyInnerHTML( - "<style>" - " td { width: 100px; height: 100px; padding: 0 }" - "</style>" - "<table style='border-spacing: 10px'>" - " <tr id='row1'>" - " <td>A</td>" - " <td rowspan='2'>B</td>" - " <td rowspan='3'>C</td>" - " </tr>" - " <tr id='row2'>" - " <td style='outline: 10px solid blue'>D</td>" - " <td rowspan='2'>E</td>" - " </tr>" - " <tr id='row3'>" - " <td>F</td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + td { width: 100px; height: 100px; padding: 0 } + </style> + <table style='border-spacing: 10px'> + <tr id='row1'> + <td>A</td> + <td rowspan='2'>B</td> + <td rowspan='3'>C</td> + </tr> + <tr id='row2'> + <td style='outline: 10px solid blue'>D</td> + <td rowspan='2'>E</td> + </tr> + <tr id='row3'> + <td>F</td> + </tr> + </table> + )HTML"); auto* row1 = GetRowByElementId("row1"); EXPECT_EQ(LayoutRect(120, 0, 210, 320), row1->ContentsVisualOverflowRect()); @@ -152,19 +156,20 @@ } TEST_F(LayoutTableRowTest, VisualOverflowWithCollapsedBorders) { - SetBodyInnerHTML( - "<style>" - " table { border-collapse: collapse }" - " td { border: 0px solid blue; padding: 0 }" - " div { width: 100px; height: 100px }" - "</style>" - "<table>" - " <tr id='row'>" - " <td style='border-bottom-width: 10px;" - " outline: 3px solid blue'><div></div></td>" - " <td style='border-width: 3px 15px'><div></div></td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + table { border-collapse: collapse } + td { border: 0px solid blue; padding: 0 } + div { width: 100px; height: 100px } + </style> + <table> + <tr id='row'> + <td style='border-bottom-width: 10px; + outline: 3px solid blue'><div></div></td> + <td style='border-width: 3px 15px'><div></div></td> + </tr> + </table> + )HTML"); auto* row = GetRowByElementId("row"); @@ -183,15 +188,16 @@ } TEST_F(LayoutTableRowTest, LayoutOverflow) { - SetBodyInnerHTML( - "<table style='border-spacing: 0'>" - " <tr id='row'>" - " <td style='100px; height: 100px; padding: 0'>" - " <div style='position: relative; top: 50px; left: 50px;" - " width: 100px; height: 100px'></div>" - " </td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-spacing: 0'> + <tr id='row'> + <td style='100px; height: 100px; padding: 0'> + <div style='position: relative; top: 50px; left: 50px; + width: 100px; height: 100px'></div> + </td> + </tr> + </table> + )HTML"); EXPECT_EQ(LayoutRect(0, 0, 150, 150), GetRowByElementId("row")->LayoutOverflowRect());
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp index 4c6cda3f..e131ba9 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp
@@ -35,13 +35,14 @@ TEST_F(LayoutTableSectionTest, BackgroundIsKnownToBeOpaqueWithLayerAndCollapsedBorder) { - SetBodyInnerHTML( - "<table style='border-collapse: collapse'>" - " <thead id='section' style='will-change: transform;" - " background-color: blue'>" - " <tr><td>Cell</td></tr>" - " </thead>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-collapse: collapse'> + <thead id='section' style='will-change: transform; + background-color: blue'> + <tr><td>Cell</td></tr> + </thead> + </table> + )HTML"); auto* section = GetSectionByElementId("section"); EXPECT_TRUE(section); @@ -50,12 +51,13 @@ } TEST_F(LayoutTableSectionTest, BackgroundIsKnownToBeOpaqueWithBorderSpacing) { - SetBodyInnerHTML( - "<table style='border-spacing: 10px'>" - " <thead id='section' style='background-color: blue'>" - " <tr><td>Cell</td></tr>" - " </thead>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-spacing: 10px'> + <thead id='section' style='background-color: blue'> + <tr><td>Cell</td></tr> + </thead> + </table> + )HTML"); auto* section = GetSectionByElementId("section"); EXPECT_TRUE(section); @@ -64,13 +66,14 @@ } TEST_F(LayoutTableSectionTest, BackgroundIsKnownToBeOpaqueWithEmptyCell) { - SetBodyInnerHTML( - "<table style='border-spacing: 10px'>" - " <thead id='section' style='background-color: blue'>" - " <tr><td>Cell</td></tr>" - " <tr><td>Cell</td><td>Cell</td></tr>" - " </thead>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border-spacing: 10px'> + <thead id='section' style='background-color: blue'> + <tr><td>Cell</td></tr> + <tr><td>Cell</td><td>Cell</td></tr> + </thead> + </table> + )HTML"); auto* section = GetSectionByElementId("section"); EXPECT_TRUE(section); @@ -79,10 +82,11 @@ } TEST_F(LayoutTableSectionTest, EmptySectionDirtiedRowsAndEffeciveColumns) { - SetBodyInnerHTML( - "<table style='border: 100px solid red'>" - " <thead id='section'></thead>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table style='border: 100px solid red'> + <thead id='section'></thead> + </table> + )HTML"); auto* section = GetSectionByElementId("section"); EXPECT_TRUE(section); @@ -99,18 +103,19 @@ } TEST_F(LayoutTableSectionTest, PrimaryCellAtAndOriginatingCellAt) { - SetBodyInnerHTML( - "<table>" - " <tbody id='section'>" - " <tr>" - " <td id='cell00'></td>" - " <td id='cell01' rowspan='2'></td>" - " </tr>" - " <tr>" - " <td id='cell10' colspan='2'></td>" - " </tr>" - " </tbody>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table> + <tbody id='section'> + <tr> + <td id='cell00'></td> + <td id='cell01' rowspan='2'></td> + </tr> + <tr> + <td id='cell10' colspan='2'></td> + </tr> + </tbody> + </table> + )HTML"); // x,yO: A cell originates from this grid slot. // x,yS: A cell originating from x,y spans into this slot. @@ -133,26 +138,27 @@ } TEST_F(LayoutTableSectionTest, DirtiedRowsAndEffectiveColumnsWithSpans) { - SetBodyInnerHTML( - "<style>" - " td { width: 100px; height: 100px; padding: 0 }" - " table { border-spacing: 0 }" - "</style>" - "<table>" - " <tbody id='section'>" - " <tr>" - " <td></td>" - " <td rowspan='2'></td>" - " <td rowspan='2'></td>" - " </tr>" - " <tr>" - " <td colspan='2'></td>" - " </tr>" - " <tr>" - " <td colspan='3'></td>" - " </tr>" - " </tbody>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + td { width: 100px; height: 100px; padding: 0 } + table { border-spacing: 0 } + </style> + <table> + <tbody id='section'> + <tr> + <td></td> + <td rowspan='2'></td> + <td rowspan='2'></td> + </tr> + <tr> + <td colspan='2'></td> + </tr> + <tr> + <td colspan='3'></td> + </tr> + </tbody> + </table> + )HTML"); // x,yO: A cell originates from this grid slot. // x,yS: A cell originating from x,y spans into this slot. @@ -220,19 +226,20 @@ TEST_F(LayoutTableSectionTest, DirtiedRowsAndEffectiveColumnsWithCollapsedBorders) { - SetBodyInnerHTML( - "<style>" - " td { width: 100px; height: 100px; padding: 0; border: 2px solid; }" - " table { border-collapse: collapse }" - "</style>" - "<table>" - " <tbody id='section'>" - " <tr><td></td><td></td><td></td><td></td></tr>" - " <tr><td></td><td></td><td></td><td></td></tr>" - " <tr><td></td><td></td><td></td><td></td></tr>" - " <tr><td></td><td></td><td></td><td></td></tr>" - " </tbody>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + td { width: 100px; height: 100px; padding: 0; border: 2px solid; } + table { border-collapse: collapse } + </style> + <table> + <tbody id='section'> + <tr><td></td><td></td><td></td><td></td></tr> + <tr><td></td><td></td><td></td><td></td></tr> + <tr><td></td><td></td><td></td><td></td></tr> + <tr><td></td><td></td><td></td><td></td></tr> + </tbody> + </table> + )HTML"); // Dirtied rows and columns are expanded by 1 cell in each side to ensure // collapsed borders are covered. @@ -274,22 +281,23 @@ } TEST_F(LayoutTableSectionTest, VisualOverflowWithCollapsedBorders) { - SetBodyInnerHTML( - "<style>" - " table { border-collapse: collapse }" - " td { border: 0px solid blue; padding: 0 }" - " div { width: 100px; height: 100px }" - "</style>" - "<table>" - " <tbody id='section'>" - " <tr>" - " <td style='border-bottom-width: 10px;" - " outline: 3px solid blue'><div></div></td>" - " <td style='border-width: 3px 15px'><div></div></td>" - " </tr>" - " <tr style='outline: 8px solid green'><td><div></div></td></tr>" - " </tbody>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + table { border-collapse: collapse } + td { border: 0px solid blue; padding: 0 } + div { width: 100px; height: 100px } + </style> + <table> + <tbody id='section'> + <tr> + <td style='border-bottom-width: 10px; + outline: 3px solid blue'><div></div></td> + <td style='border-width: 3px 15px'><div></div></td> + </tr> + <tr style='outline: 8px solid green'><td><div></div></td></tr> + </tbody> + </table> + )HTML"); auto* section = GetSectionByElementId("section"); @@ -313,11 +321,12 @@ } TEST_F(LayoutTableSectionTest, OverflowingCells) { - SetBodyInnerHTML( - "<style>" - " td { width: 10px; height: 10px }" - " td.overflow { outline: 10px solid blue }" - "</style>"); + SetBodyInnerHTML(R"HTML( + <style> + td { width: 10px; height: 10px } + td.overflow { outline: 10px solid blue } + </style> + )HTML"); LayoutRect paint_rect(50, 50, 50, 50); auto* small_section = CreateSection(20, 20);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp index 8cd7c90..7437bc9 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
@@ -19,22 +19,23 @@ }; TEST_F(LayoutTableTest, OverflowWithCollapsedBorders) { - SetBodyInnerHTML( - "<style>" - " table { border-collapse: collapse }" - " td { border: 0px solid blue; padding: 0; width: 100px; height: 100px }" - "</style>" - "<table id='table'>" - " <tr>" - " <td style='border-top-width: 2px; border-left-width: 2px;" - " outline: 6px solid blue'></td>" - " <td style='border-top-width: 4px; border-right-width: 10px'></td>" - " </tr>" - " <tr style='outline: 8px solid green'>" - " <td style='border-left-width: 20px'></td>" - " <td style='border-right-width: 20px'></td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + table { border-collapse: collapse } + td { border: 0px solid blue; padding: 0; width: 100px; height: 100px } + </style> + <table id='table'> + <tr> + <td style='border-top-width: 2px; border-left-width: 2px; + outline: 6px solid blue'></td> + <td style='border-top-width: 4px; border-right-width: 10px'></td> + </tr> + <tr style='outline: 8px solid green'> + <td style='border-left-width: 20px'></td> + <td style='border-right-width: 20px'></td> + </tr> + </table> + )HTML"); auto* table = GetTableByElementId("table"); @@ -115,38 +116,39 @@ } TEST_F(LayoutTableTest, CollapsedBordersWithCol) { - SetBodyInnerHTML( - "<style>table { border-collapse: collapse }</style>" - "<table id='table1' style='border: hidden'>" - " <colgroup>" - " <col span='2000' style='border: 10px solid'>" - " <col span='2000' style='border: 20px solid'>" - " </colgroup>" - " <tr>" - " <td colspan='2000'>A</td>" - " <td colspan='2000'>B</td>" - " </tr>" - "</table>" - "<table id='table2' style='border: 10px solid'>" - " <colgroup>" - " <col span='2000' style='border: 10px solid'>" - " <col span='2000' style='border: 20px solid'>" - " </colgroup>" - " <tr>" - " <td colspan='2000' style='border: hidden'>C</td>" - " <td colspan='2000' style='border: hidden'>D</td>" - " </tr>" - "</table>" - "<table id='table3'>" - " <colgroup>" - " <col span='2000' style='border: 10px solid'>" - " <col span='2000' style='border: 20px solid'>" - " </colgroup>" - " <tr>" - " <td colspan='2000' style='border: 12px solid'>E</td>" - " <td colspan='2000' style='border: 16px solid'>F</td>" - " </tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style>table { border-collapse: collapse }</style> + <table id='table1' style='border: hidden'> + <colgroup> + <col span='2000' style='border: 10px solid'> + <col span='2000' style='border: 20px solid'> + </colgroup> + <tr> + <td colspan='2000'>A</td> + <td colspan='2000'>B</td> + </tr> + </table> + <table id='table2' style='border: 10px solid'> + <colgroup> + <col span='2000' style='border: 10px solid'> + <col span='2000' style='border: 20px solid'> + </colgroup> + <tr> + <td colspan='2000' style='border: hidden'>C</td> + <td colspan='2000' style='border: hidden'>D</td> + </tr> + </table> + <table id='table3'> + <colgroup> + <col span='2000' style='border: 10px solid'> + <col span='2000' style='border: 20px solid'> + </colgroup> + <tr> + <td colspan='2000' style='border: 12px solid'>E</td> + <td colspan='2000' style='border: 16px solid'>F</td> + </tr> + </table> + )HTML"); // Table has hidden border. auto* table1 = GetTableByElementId("table1"); @@ -175,21 +177,22 @@ } TEST_F(LayoutTableTest, WidthPercentagesExceedHundred) { - SetBodyInnerHTML( - "<style>#outer { width: 2000000px; }" - "table { border-collapse: collapse; }</style>" - "<div id='outer'>" - "<table id='onlyTable'>" - " <tr>" - " <td width='100%'>" - " <div></div>" - " </td>" - " <td width='60%'>" - " <div width='10px;'></div>" - " </td>" - " </tr>" - "</table>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#outer { width: 2000000px; } + table { border-collapse: collapse; }</style> + <div id='outer'> + <table id='onlyTable'> + <tr> + <td width='100%'> + <div></div> + </td> + <td width='60%'> + <div width='10px;'></div> + </td> + </tr> + </table> + </div> + )HTML"); // Table width should be TableLayoutAlgorithm::kMaxTableWidth auto* table = GetTableByElementId("onlyTable"); @@ -197,18 +200,19 @@ } TEST_F(LayoutTableTest, CloseToMaxWidth) { - SetBodyInnerHTML( - "<style>#outer { width: 2000000px; }" - "table { border-collapse: collapse; }</style>" - "<div id='outer'>" - "<table id='onlyTable' width='999999px;'>" - " <tr>" - " <td>" - " <div></div>" - " </td>" - " </tr>" - "</table>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#outer { width: 2000000px; } + table { border-collapse: collapse; }</style> + <div id='outer'> + <table id='onlyTable' width='999999px;'> + <tr> + <td> + <div></div> + </td> + </tr> + </table> + </div> + )HTML"); // Table width should be 999999 auto* table = GetTableByElementId("onlyTable"); @@ -216,10 +220,11 @@ } TEST_F(LayoutTableTest, PaddingWithCollapsedBorder) { - SetBodyInnerHTML( - "<table id='table' style='padding: 20px; border-collapse: collapse'>" - " <tr><td>TD</td</tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table id='table' style='padding: 20px; border-collapse: collapse'> + <tr><td>TD</td</tr> + </table> + )HTML"); auto* table = GetTableByElementId("table"); EXPECT_EQ(0, table->PaddingLeft()); @@ -235,11 +240,12 @@ } TEST_F(LayoutTableTest, OutOfOrderHeadAndBody) { - SetBodyInnerHTML( - "<table id='table' style='border-collapse: collapse'>" - " <tbody id='body'><tr><td>Body</td></tr></tbody>" - " <thead id='head'></thead>" - "<table>"); + SetBodyInnerHTML(R"HTML( + <table id='table' style='border-collapse: collapse'> + <tbody id='body'><tr><td>Body</td></tr></tbody> + <thead id='head'></thead> + <table> + )HTML"); auto* table = GetTableByElementId("table"); EXPECT_EQ(ToLayoutTableSection(GetLayoutObjectByElementId("head")), table->TopSection()); @@ -252,11 +258,12 @@ } TEST_F(LayoutTableTest, OutOfOrderFootAndBody) { - SetBodyInnerHTML( - "<table id='table'>" - " <tfoot id='foot'></tfoot>" - " <tbody id='body'><tr><td>Body</td></tr></tbody>" - "<table>"); + SetBodyInnerHTML(R"HTML( + <table id='table'> + <tfoot id='foot'></tfoot> + <tbody id='body'><tr><td>Body</td></tr></tbody> + <table> + )HTML"); auto* table = GetTableByElementId("table"); EXPECT_EQ(ToLayoutTableSection(GetLayoutObjectByElementId("body")), table->TopSection()); @@ -269,12 +276,13 @@ } TEST_F(LayoutTableTest, OutOfOrderHeadFootAndBody) { - SetBodyInnerHTML( - "<table id='table' style='border-collapse: collapse'>" - " <tfoot id='foot'><tr><td>foot</td></tr></tfoot>" - " <thead id='head'><tr><td>head</td></tr></thead>" - " <tbody id='body'><tr><td>Body</td></tr></tbody>" - "<table>"); + SetBodyInnerHTML(R"HTML( + <table id='table' style='border-collapse: collapse'> + <tfoot id='foot'><tr><td>foot</td></tr></tfoot> + <thead id='head'><tr><td>head</td></tr></thead> + <tbody id='body'><tr><td>Body</td></tr></tbody> + <table> + )HTML"); auto* table = GetTableByElementId("table"); EXPECT_EQ(ToLayoutTableSection(GetLayoutObjectByElementId("head")), table->TopSection());
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp index c50872e..3f25a81b 100644 --- a/third_party/WebKit/Source/core/layout/LayoutText.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -1926,8 +1926,10 @@ const Node* node = GetNode(); if (!node) return Position(); - if (node->IsTextNode()) + if (node->IsTextNode()) { + // TODO(layout-dev): Support offset change due to text-transform. return Position(node, offset); + } if (IsBR()) { DCHECK(IsHTMLBRElement(node)); DCHECK_LE(offset, 1u); @@ -1937,17 +1939,39 @@ return Position(); } +Optional<unsigned> LayoutText::CaretOffsetForPosition( + const Position& position) const { + // ::first-letter handling should be done by LayoutTextFragment override. + DCHECK(!IsTextFragment()); + if (position.IsNull() || position.AnchorNode() != GetNode()) + return WTF::nullopt; + if (GetNode()->IsTextNode()) { + // TODO(xiaochengh): Consider Before/AfterAnchor. + DCHECK(position.IsOffsetInAnchor()) << position; + // TODO(layout-dev): Support offset change due to text-transform. + DCHECK_LE(position.OffsetInContainerNode(), static_cast<int>(TextLength())) + << position; + return position.OffsetInContainerNode(); + } + if (IsBR()) { + DCHECK(position.IsBeforeAnchor() || position.IsAfterAnchor()) << position; + return position.IsBeforeAnchor() ? 0 : 1; + } + NOTREACHED(); + return WTF::nullopt; +} + int LayoutText::CaretMinOffset() const { if (auto* mapping = GetNGOffsetMapping()) { - // ::first-letter handling should be done by LayoutTextFragment override. - DCHECK(!IsTextFragment()); - if (!GetNode()) + const Position first_position = PositionForCaretOffset(0); + if (first_position.IsNull()) return 0; - Optional<unsigned> candidate = - mapping->StartOfNextNonCollapsedCharacter(*GetNode(), 0); + Optional<unsigned> candidate = CaretOffsetForPosition( + mapping->StartOfNextNonCollapsedContent(first_position)); // Align with the legacy behavior that 0 is returned if the entire node // contains only collapsed whitespaces. - return candidate ? *candidate : 0; + const bool fully_collapsed = !candidate || *candidate == TextLength(); + return fully_collapsed ? 0 : *candidate; } InlineTextBox* box = FirstTextBox(); @@ -1961,15 +1985,15 @@ int LayoutText::CaretMaxOffset() const { if (auto* mapping = GetNGOffsetMapping()) { - // ::first-letter handling should be done by LayoutTextFragment override. - DCHECK(!IsTextFragment()); - if (!GetNode()) + const Position last_position = PositionForCaretOffset(TextLength()); + if (last_position.IsNull()) return TextLength(); - Optional<unsigned> candidate = - mapping->EndOfLastNonCollapsedCharacter(*GetNode(), TextLength()); - // Align with the legacy behavior that |TextLength()| is returned if the + Optional<unsigned> candidate = CaretOffsetForPosition( + mapping->EndOfLastNonCollapsedContent(last_position)); + // Align with the legacy behavior that |TextLenght()| is returned if the // entire node contains only collapsed whitespaces. - return candidate ? *candidate : TextLength(); + const bool fully_collapsed = !candidate || *candidate == 0u; + return fully_collapsed ? TextLength() : *candidate; } InlineTextBox* box = LastTextBox(); @@ -2014,16 +2038,17 @@ bool LayoutText::ContainsCaretOffset(int text_offset) const { DCHECK_GE(text_offset, 0); if (auto* mapping = GetNGOffsetMapping()) { - // ::first-letter handling should be done by LayoutTextFragment override. - DCHECK(!IsTextFragment()); - if (!GetNode()) + if (text_offset > static_cast<int>(TextLength())) return false; - if (mapping->IsBeforeNonCollapsedCharacter(*GetNode(), text_offset)) + const Position position = PositionForCaretOffset(text_offset); + if (position.IsNull()) + return false; + if (text_offset < static_cast<int>(TextLength()) && + mapping->IsBeforeNonCollapsedContent(position)) return true; - if (!mapping->IsAfterNonCollapsedCharacter(*GetNode(), text_offset)) + if (!text_offset || !mapping->IsAfterNonCollapsedContent(position)) return false; - return *mapping->GetCharacterBefore(*GetNode(), text_offset) != - kNewlineCharacter; + return *mapping->GetCharacterBefore(position) != kNewlineCharacter; } for (InlineTextBox* box : InlineTextBoxesOf(*this)) { @@ -2076,11 +2101,12 @@ bool LayoutText::IsBeforeNonCollapsedCharacter(unsigned text_offset) const { if (auto* mapping = GetNGOffsetMapping()) { - // ::first-letter handling should be done by LayoutTextFragment override. - DCHECK(!IsTextFragment()); - if (!GetNode()) + if (text_offset >= TextLength()) return false; - return mapping->IsBeforeNonCollapsedCharacter(*GetNode(), text_offset); + const Position position = PositionForCaretOffset(text_offset); + if (position.IsNull()) + return false; + return mapping->IsBeforeNonCollapsedContent(position); } InlineTextBox* const last_text_box = LastTextBox(); @@ -2108,11 +2134,12 @@ bool LayoutText::IsAfterNonCollapsedCharacter(unsigned text_offset) const { if (auto* mapping = GetNGOffsetMapping()) { - // ::first-letter handling should be done by LayoutTextFragment override. - DCHECK(!IsTextFragment()); - if (!GetNode()) + if (!text_offset) return false; - return mapping->IsAfterNonCollapsedCharacter(*GetNode(), text_offset); + const Position position = PositionForCaretOffset(text_offset); + if (position.IsNull()) + return false; + return mapping->IsAfterNonCollapsedContent(position); } InlineTextBox* const last_text_box = LastTextBox();
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.h b/third_party/WebKit/Source/core/layout/LayoutText.h index ccb49bf..f6ca5c5 100644 --- a/third_party/WebKit/Source/core/layout/LayoutText.h +++ b/third_party/WebKit/Source/core/layout/LayoutText.h
@@ -206,17 +206,22 @@ // TODO(layout-dev): Fix it when text-transform changes text length. virtual Position PositionForCaretOffset(unsigned) const; + // Returns the offset in the |text_| string that corresponds to the given + // position in DOM; Returns nullopt is the position is not in this LayoutText. + // TODO(layout-dev): Fix it when text-transform changes text length. + virtual Optional<unsigned> CaretOffsetForPosition(const Position&) const; + // Returns true if the offset (0-based in the |text_| string) is next to a // non-collapsed non-linebreak character, or before a forced linebreak (<br>, // or segment break in node with style white-space: pre/pre-line/pre-wrap). // TODO(editing-dev): The behavior is introduced by crrev.com/e3eb4e in // InlineTextBox::ContainsCaretOffset(). Try to understand it. - virtual bool ContainsCaretOffset(int) const; + bool ContainsCaretOffset(int) const; // Return true if the offset (0-based in the |text_| string) is before/after a // non-collapsed character in this LayoutText, respectively. - virtual bool IsBeforeNonCollapsedCharacter(unsigned) const; - virtual bool IsAfterNonCollapsedCharacter(unsigned) const; + bool IsBeforeNonCollapsedCharacter(unsigned) const; + bool IsAfterNonCollapsedCharacter(unsigned) const; int CaretMinOffset() const override; int CaretMaxOffset() const override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp b/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp index 82c7271..5c5f708 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp
@@ -179,94 +179,21 @@ const Text* node = AssociatedTextNode(); if (!node) return Position(); + // TODO(layout-dev): Support offset change due to text-transform. return Position(node, Start() + offset); } -int LayoutTextFragment::CaretMinOffset() const { - auto* mapping = GetNGOffsetMapping(); - if (!mapping) - return LayoutText::CaretMinOffset(); - - const Node* node = AssociatedTextNode(); - if (!node) - return 0; - - Optional<unsigned> candidate = - mapping->StartOfNextNonCollapsedCharacter(*node, Start()); - DCHECK(!candidate || *candidate >= Start()); - // Align with the legacy behavior that 0 is returned if the entire layout - // object contains only collapsed whitespaces. - const bool fully_collapsed = - !candidate || *candidate >= Start() + FragmentLength(); - return fully_collapsed ? 0 : *candidate - Start(); -} - -int LayoutTextFragment::CaretMaxOffset() const { - auto* mapping = GetNGOffsetMapping(); - if (!mapping) - return LayoutText::CaretMaxOffset(); - - const Node* node = AssociatedTextNode(); - if (!node) - return 0; - - Optional<unsigned> candidate = mapping->EndOfLastNonCollapsedCharacter( - *node, Start() + FragmentLength()); - // Align with the legacy behavior that FragmentLength() is returned if the - // entire layout object contains only collapsed whitespaces. - const bool fully_collapsed = !candidate || *candidate <= Start(); - return fully_collapsed ? FragmentLength() : *candidate - Start(); -} - -bool LayoutTextFragment::ContainsCaretOffset(int text_offset) const { - auto* mapping = GetNGOffsetMapping(); - if (!mapping) - return LayoutText::ContainsCaretOffset(text_offset); - - DCHECK_GE(text_offset, 0); - if (text_offset > static_cast<int>(FragmentLength())) - return false; - const Node* node = AssociatedTextNode(); - if (!node) - return false; - const unsigned dom_offset = text_offset + Start(); - if (mapping->IsBeforeNonCollapsedCharacter(*node, dom_offset)) - return true; - if (text_offset == 0) - return false; - if (!mapping->IsAfterNonCollapsedCharacter(*node, dom_offset)) - return false; - return *mapping->GetCharacterBefore(*node, dom_offset) != kNewlineCharacter; -} - -bool LayoutTextFragment::IsBeforeNonCollapsedCharacter( - unsigned text_offset) const { - auto* mapping = GetNGOffsetMapping(); - if (!mapping) - return LayoutText::IsBeforeNonCollapsedCharacter(text_offset); - - if (text_offset >= FragmentLength()) - return false; - const Node* node = AssociatedTextNode(); - if (!node) - return false; - const unsigned dom_offset = text_offset + Start(); - return mapping->IsBeforeNonCollapsedCharacter(*node, dom_offset); -} - -bool LayoutTextFragment::IsAfterNonCollapsedCharacter( - unsigned text_offset) const { - auto* mapping = GetNGOffsetMapping(); - if (!mapping) - return LayoutText::IsAfterNonCollapsedCharacter(text_offset); - - if (!text_offset) - return false; - const Node* node = AssociatedTextNode(); - if (!node) - return false; - const unsigned dom_offset = text_offset + Start(); - return mapping->IsAfterNonCollapsedCharacter(*node, dom_offset); +Optional<unsigned> LayoutTextFragment::CaretOffsetForPosition( + const Position& position) const { + if (position.IsNull() || position.AnchorNode() != AssociatedTextNode()) + return WTF::nullopt; + // TODO(xiaochengh): Consider Before/AfterAnchor. + DCHECK(position.IsOffsetInAnchor()) << position; + // TODO(layout-dev): Support offset change due to text-transform. + unsigned dom_offset = position.OffsetInContainerNode(); + if (dom_offset < Start() || dom_offset > Start() + FragmentLength()) + return WTF::nullopt; + return dom_offset - Start(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextFragment.h b/third_party/WebKit/Source/core/layout/LayoutTextFragment.h index cdf10f87..97e35b8 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextFragment.h +++ b/third_party/WebKit/Source/core/layout/LayoutTextFragment.h
@@ -52,11 +52,7 @@ bool IsTextFragment() const override { return true; } Position PositionForCaretOffset(unsigned) const override; - bool ContainsCaretOffset(int) const override; - bool IsBeforeNonCollapsedCharacter(unsigned) const override; - bool IsAfterNonCollapsedCharacter(unsigned) const override; - int CaretMinOffset() const override; - int CaretMaxOffset() const override; + Optional<unsigned> CaretOffsetForPosition(const Position&) const override; unsigned Start() const { return start_; } unsigned FragmentLength() const { return fragment_length_; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp index 39c2f60..fec3c9c 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp
@@ -86,16 +86,17 @@ TEST_F(LayoutTextTest, WidthWithHugeLengthAvoidsOverflow) { // The test case from http://crbug.com/647820 uses a 288-length string, so for // posterity we follow that closely. - SetBodyInnerHTML( - "<div " - "id='target'>" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div + id='target'> + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + </div> + )HTML"); // Width may vary by platform and we just want to make sure it's something // roughly reasonable. const float width = GetBasicText()->Width(
diff --git a/third_party/WebKit/Source/core/layout/LayoutViewTest.cpp b/third_party/WebKit/Source/core/layout/LayoutViewTest.cpp index 137b9b6..ef33a6f 100644 --- a/third_party/WebKit/Source/core/layout/LayoutViewTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutViewTest.cpp
@@ -11,13 +11,14 @@ class LayoutViewTest : public RenderingTest {}; TEST_F(LayoutViewTest, UpdateCountersLayout) { - SetBodyInnerHTML( - "<style>" - " div.incX { counter-increment: x }" - " div.incY { counter-increment: y }" - " div::before { content: counter(y) }" - "</style>" - "<div id=inc></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div.incX { counter-increment: x } + div.incY { counter-increment: y } + div::before { content: counter(y) } + </style> + <div id=inc></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* inc = GetDocument().getElementById("inc");
diff --git a/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp b/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp index 1c2582ff..66caba8 100644 --- a/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp +++ b/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp
@@ -141,11 +141,12 @@ } TEST_P(MapCoordinatesTest, SimpleBlock) { - SetBodyInnerHTML( - "<div style='margin:666px; border:8px solid; padding:7px;'>" - " <div id='target' style='margin:10px; border:666px; " - "padding:666px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='margin:666px; border:8px solid; padding:7px;'> + <div id='target' style='margin:10px; border:666px; + padding:666px;'></div> + </div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); FloatPoint mapped_point = MapLocalToAncestor( @@ -157,13 +158,14 @@ } TEST_P(MapCoordinatesTest, OverflowClip) { - SetBodyInnerHTML( - "<div id='overflow' style='height: 100px; width: 100px; border:8px " - "solid; padding:7px; overflow:scroll'>" - " <div style='height:200px; width:200px'></div>" - " <div id='target' style='margin:10px; border:666px; " - "padding:666px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='overflow' style='height: 100px; width: 100px; border:8px + solid; padding:7px; overflow:scroll'> + <div style='height:200px; width:200px'></div> + <div id='target' style='margin:10px; border:666px; + padding:666px;'></div> + </div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutObject* overflow = GetLayoutObjectByElementId("overflow"); @@ -208,13 +210,14 @@ } TEST_P(MapCoordinatesTest, RelposInlineInRelposInline) { - SetBodyInnerHTML( - "<div style='padding-left:10px;'>" - " <span style='position:relative; left:5px; top:6px;'>" - " <span id='target' style='position:relative; left:50px; " - "top:100px;'>text</span>" - " </span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='padding-left:10px;'> + <span style='position:relative; left:5px; top:6px;'> + <span id='target' style='position:relative; left:50px; + top:100px;'>text</span> + </span> + </div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutInline* parent = ToLayoutInline(target->Parent()); @@ -241,14 +244,15 @@ } TEST_P(MapCoordinatesTest, RelPosBlock) { - SetBodyInnerHTML( - "<div id='container' style='margin:666px; border:8px solid; " - "padding:7px;'>" - " <div id='middle' style='margin:30px; border:1px solid;'>" - " <div id='target' style='position:relative; left:50px; top:50px; " - "margin:10px; border:666px; padding:666px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='margin:666px; border:8px solid; + padding:7px;'> + <div id='middle' style='margin:30px; border:1px solid;'> + <div id='target' style='position:relative; left:50px; top:50px; + margin:10px; border:666px; padding:666px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -275,15 +279,16 @@ } TEST_P(MapCoordinatesTest, AbsPos) { - SetBodyInnerHTML( - "<div id='container' style='position:relative; margin:666px; border:8px " - "solid; padding:7px;'>" - " <div id='staticChild' style='margin:30px; padding-top:666px;'>" - " <div style='padding-top:666px;'></div>" - " <div id='target' style='position:absolute; left:-1px; top:-1px; " - "margin:10px; border:666px; padding:666px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position:relative; margin:666px; border:8px + solid; padding:7px;'> + <div id='staticChild' style='margin:30px; padding-top:666px;'> + <div style='padding-top:666px;'></div> + <div id='target' style='position:absolute; left:-1px; top:-1px; + margin:10px; border:666px; padding:666px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -311,15 +316,16 @@ } TEST_P(MapCoordinatesTest, AbsPosAuto) { - SetBodyInnerHTML( - "<div id='container' style='position:absolute; margin:666px; border:8px " - "solid; padding:7px;'>" - " <div id='staticChild' style='margin:30px; padding-top:5px;'>" - " <div style='padding-top:20px;'></div>" - " <div id='target' style='position:absolute; margin:10px; " - "border:666px; padding:666px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position:absolute; margin:666px; border:8px + solid; padding:7px;'> + <div id='staticChild' style='margin:30px; padding-top:5px;'> + <div style='padding-top:20px;'></div> + <div id='target' style='position:absolute; margin:10px; + border:666px; padding:666px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -348,15 +354,16 @@ TEST_P(MapCoordinatesTest, FixedPos) { // Assuming BODY margin of 8px. - SetBodyInnerHTML( - "<div id='container' style='position:absolute; margin:4px; border:5px " - "solid; padding:7px;'>" - " <div id='staticChild' style='padding-top:666px;'>" - " <div style='padding-top:666px;'></div>" - " <div id='target' style='position:fixed; left:-1px; top:-1px; " - "margin:10px; border:666px; padding:666px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position:absolute; margin:4px; border:5px + solid; padding:7px;'> + <div id='staticChild' style='padding-top:666px;'> + <div style='padding-top:666px;'></div> + <div id='target' style='position:fixed; left:-1px; top:-1px; + margin:10px; border:666px; padding:666px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* static_child = @@ -406,15 +413,16 @@ TEST_P(MapCoordinatesTest, FixedPosAuto) { // Assuming BODY margin of 8px. - SetBodyInnerHTML( - "<div id='container' style='position:absolute; margin:3px; border:8px " - "solid; padding:7px;'>" - " <div id='staticChild' style='padding-top:5px;'>" - " <div style='padding-top:20px;'></div>" - " <div id='target' style='position:fixed; margin:10px; " - "border:666px; padding:666px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position:absolute; margin:3px; border:8px + solid; padding:7px;'> + <div id='staticChild' style='padding-top:5px;'> + <div style='padding-top:20px;'></div> + <div id='target' style='position:fixed; margin:10px; + border:666px; padding:666px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* static_child = @@ -466,18 +474,19 @@ TEST_P(MapCoordinatesTest, FixedPosInFixedPos) { // Assuming BODY margin of 8px. - SetBodyInnerHTML( - "<div id='container' style='position:absolute; margin:4px; border:5px " - "solid; padding:7px;'>" - " <div id='staticChild' style='padding-top:666px;'>" - " <div style='padding-top:666px;'></div>" - " <div id='outerFixed' style='position:fixed; left:100px; " - "top:100px; margin:10px; border:666px; padding:666px;'>" - " <div id='target' style='position:fixed; left:-1px; " - "top:-1px; margin:10px; border:666px; padding:666px;'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position:absolute; margin:4px; border:5px + solid; padding:7px;'> + <div id='staticChild' style='padding-top:666px;'> + <div style='padding-top:666px;'></div> + <div id='outerFixed' style='position:fixed; left:100px; + top:100px; margin:10px; border:666px; padding:666px;'> + <div id='target' style='position:fixed; left:-1px; + top:-1px; margin:10px; border:666px; padding:666px;'></div> + </div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* outer_fixed = @@ -534,12 +543,13 @@ } TEST_P(MapCoordinatesTest, FixedPosInFixedPosScrollView) { - SetBodyInnerHTML( - "<div style='height: 4000px'></div>" - "<div id='container' style='position:fixed; top: 100px; left: 100px'>" - " <div id='target' style='position:fixed; top: 200px; left: 200px'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='height: 4000px'></div> + <div id='container' style='position:fixed; top: 100px; left: 100px'> + <div id='target' style='position:fixed; top: 200px; left: 200px'> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -569,12 +579,13 @@ } TEST_P(MapCoordinatesTest, FixedPosInAbsolutePosScrollView) { - SetBodyInnerHTML( - "<div style='height: 4000px'></div>" - "<div id='container' style='position:absolute; top: 100px; left: 100px'>" - " <div id='target' style='position:fixed; top: 200px; left: 200px'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='height: 4000px'></div> + <div id='container' style='position:absolute; top: 100px; left: 100px'> + <div id='target' style='position:fixed; top: 200px; left: 200px'> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -604,13 +615,14 @@ } TEST_P(MapCoordinatesTest, FixedPosInTransform) { - SetBodyInnerHTML( - "<style>#container { transform: translateY(100px); position: absolute; " - "left: 0; top: 100px; }" - ".fixed { position: fixed; top: 0; }" - ".spacer { height: 2000px; } </style>" - "<div id='container'><div class='fixed' id='target'></div></div>" - "<div class='spacer'></div>"); + SetBodyInnerHTML(R"HTML( + <style>#container { transform: translateY(100px); position: absolute; + left: 0; top: 100px; } + .fixed { position: fixed; top: 0; } + .spacer { height: 2000px; } </style> + <div id='container'><div class='fixed' id='target'></div></div> + <div class='spacer'></div> + )HTML"); GetDocument().View()->LayoutViewportScrollableArea()->SetScrollOffset( ScrollOffset(0.0, 50), kProgrammaticScroll); @@ -645,13 +657,14 @@ } TEST_P(MapCoordinatesTest, FixedPosInContainPaint) { - SetBodyInnerHTML( - "<style>#container { contain: paint; position: absolute; left: 0; top: " - "100px; }" - ".fixed { position: fixed; top: 0; }" - ".spacer { height: 2000px; } </style>" - "<div id='container'><div class='fixed' id='target'></div></div>" - "<div class='spacer'></div>"); + SetBodyInnerHTML(R"HTML( + <style>#container { contain: paint; position: absolute; left: 0; top: + 100px; } + .fixed { position: fixed; top: 0; } + .spacer { height: 2000px; } </style> + <div id='container'><div class='fixed' id='target'></div></div> + <div class='spacer'></div> + )HTML"); GetDocument().View()->LayoutViewportScrollableArea()->SetScrollOffset( ScrollOffset(0.0, 50), kProgrammaticScroll); @@ -688,12 +701,13 @@ // TODO(chrishtr): add more multi-frame tests. TEST_P(MapCoordinatesTest, FixedPosInIFrameWhenMainFrameScrolled) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div style='width: 200; height: 8000px'></div>" - "<iframe src='http://test.com' width='500' height='500' " - "frameBorder='0'>" - "</iframe>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div style='width: 200; height: 8000px'></div> + <iframe src='http://test.com' width='500' height='500' + frameBorder='0'> + </iframe> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; } #target { width: 200px; height: 200px; " "position:fixed}</style><div id=target></div>"); @@ -717,11 +731,12 @@ TEST_P(MapCoordinatesTest, IFrameTransformed) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<iframe style='transform: scale(2)' src='http://test.com' " - "width='500' height='500' frameBorder='0'>" - "</iframe>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <iframe style='transform: scale(2)' src='http://test.com' + width='500' height='500' frameBorder='0'> + </iframe> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; } #target { width: 200px; " "height: 8000px}</style><div id=target></div>"); @@ -749,17 +764,19 @@ TEST_P(MapCoordinatesTest, FixedPosInScrolledIFrameWithTransform) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>* { margin: 0; }</style>" - "<div style='position: absolute; left: 0px; top: 0px; width: 1024px; " - "height: 768px; transform-origin: 0 0; transform: scale(0.5, 0.5);'>" - " <iframe frameborder=0 src='http://test.com' " - "sandbox='allow-same-origin' width='1024' height='768'></iframe>" - "</div>"); - SetChildFrameHTML( - "<style>* { margin: 0; } #target { width: 200px; height: 200px; " - "position:fixed}</style><div id=target></div>" - "<div style='width: 200; height: 8000px'></div>"); + SetBodyInnerHTML(R"HTML( + <style>* { margin: 0; }</style> + <div style='position: absolute; left: 0px; top: 0px; width: 1024px; + height: 768px; transform-origin: 0 0; transform: scale(0.5, 0.5);'> + <iframe frameborder=0 src='http://test.com' + sandbox='allow-same-origin' width='1024' height='768'></iframe> + </div> + )HTML"); + SetChildFrameHTML(R"HTML( + <style>* { margin: 0; } #target { width: 200px; height: 200px; + position:fixed}</style><div id=target></div> + <div style='width: 200; height: 8000px'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); ChildDocument().View()->LayoutViewportScrollableArea()->SetScrollOffset( @@ -776,12 +793,13 @@ } TEST_P(MapCoordinatesTest, MulticolWithText) { - SetBodyInnerHTML( - "<div id='multicol' style='columns:2; column-gap:20px; width:400px; " - "line-height:50px; padding:5px; orphans:1; widows:1;'>" - " <br id='sibling'>" - " text" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='multicol' style='columns:2; column-gap:20px; width:400px; + line-height:50px; padding:5px; orphans:1; widows:1;'> + <br id='sibling'> + text + </div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("sibling")->NextSibling(); ASSERT_TRUE(target->IsText()); @@ -802,11 +820,12 @@ } TEST_P(MapCoordinatesTest, MulticolWithInline) { - SetBodyInnerHTML( - "<div id='multicol' style='columns:2; column-gap:20px; width:400px; " - "line-height:50px; padding:5px; orphans:1; widows:1;'>" - " <span id='target'><br>text</span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='multicol' style='columns:2; column-gap:20px; width:400px; + line-height:50px; padding:5px; orphans:1; widows:1;'> + <span id='target'><br>text</span> + </div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* flow_thread = ToLayoutBox(target->Parent()); @@ -826,14 +845,15 @@ } TEST_P(MapCoordinatesTest, MulticolWithBlock) { - SetBodyInnerHTML( - "<div id='container' style='-webkit-columns:3; -webkit-column-gap:0; " - "column-fill:auto; width:300px; height:100px; border:8px solid; " - "padding:7px;'>" - " <div style='height:110px;'></div>" - " <div id='target' style='margin:10px; border:13px; " - "padding:13px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='-webkit-columns:3; -webkit-column-gap:0; + column-fill:auto; width:300px; height:100px; border:8px solid; + padding:7px;'> + <div style='height:110px;'></div> + <div id='target' style='margin:10px; border:13px; + padding:13px;'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -860,11 +880,12 @@ } TEST_P(MapCoordinatesTest, MulticolWithBlockAbove) { - SetBodyInnerHTML( - "<div id='container' style='columns:3; column-gap:0; " - "column-fill:auto; width:300px; height:200px;'>" - " <div id='target' style='margin-top:-50px; height:100px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='columns:3; column-gap:0; + column-fill:auto; width:300px; height:200px;'> + <div id='target' style='margin-top:-50px; height:100px;'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -890,17 +911,18 @@ } TEST_P(MapCoordinatesTest, NestedMulticolWithBlock) { - SetBodyInnerHTML( - "<div id='outerMulticol' style='columns:2; column-gap:0; " - "column-fill:auto; width:560px; height:215px; border:8px solid; " - "padding:7px;'>" - " <div style='height:10px;'></div>" - " <div id='innerMulticol' style='columns:2; column-gap:0; border:8px " - "solid; padding:7px;'>" - " <div style='height:630px;'></div>" - " <div id='target' style='width:50px; height:50px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='outerMulticol' style='columns:2; column-gap:0; + column-fill:auto; width:560px; height:215px; border:8px solid; + padding:7px;'> + <div style='height:10px;'></div> + <div id='innerMulticol' style='columns:2; column-gap:0; border:8px + solid; padding:7px;'> + <div style='height:630px;'></div> + <div id='target' style='width:50px; height:50px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* outer_multicol = @@ -947,16 +969,17 @@ } TEST_P(MapCoordinatesTest, MulticolWithAbsPosInRelPos) { - SetBodyInnerHTML( - "<div id='multicol' style='-webkit-columns:3; -webkit-column-gap:0; " - "column-fill:auto; width:300px; height:100px; border:8px solid; " - "padding:7px;'>" - " <div style='height:110px;'></div>" - " <div id='relpos' style='position:relative; left:4px; top:4px;'>" - " <div id='target' style='position:absolute; left:15px; top:15px; " - "margin:10px; border:13px; padding:13px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='multicol' style='-webkit-columns:3; -webkit-column-gap:0; + column-fill:auto; width:300px; height:100px; border:8px solid; + padding:7px;'> + <div style='height:110px;'></div> + <div id='relpos' style='position:relative; left:4px; top:4px;'> + <div id='target' style='position:absolute; left:15px; top:15px; + margin:10px; border:13px; padding:13px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* multicol = ToLayoutBox(GetLayoutObjectByElementId("multicol")); @@ -988,17 +1011,18 @@ } TEST_P(MapCoordinatesTest, MulticolWithAbsPosNotContained) { - SetBodyInnerHTML( - "<div id='container' style='position:relative; margin:666px; border:7px " - "solid; padding:3px;'>" - " <div id='multicol' style='-webkit-columns:3; -webkit-column-gap:0; " - "column-fill:auto; width:300px; height:100px; border:8px solid; " - "padding:7px;'>" - " <div style='height:110px;'></div>" - " <div id='target' style='position:absolute; left:-1px; top:-1px; " - "margin:10px; border:13px; padding:13px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position:relative; margin:666px; border:7px + solid; padding:3px;'> + <div id='multicol' style='-webkit-columns:3; -webkit-column-gap:0; + column-fill:auto; width:300px; height:100px; border:8px solid; + padding:7px;'> + <div style='height:110px;'></div> + <div id='target' style='position:absolute; left:-1px; top:-1px; + margin:10px; border:13px; padding:13px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1035,12 +1059,13 @@ } TEST_P(MapCoordinatesTest, MulticolRtl) { - SetBodyInnerHTML( - "<div id='container' style='columns:3; column-gap:0; column-fill:auto; " - "width:300px; height:200px; direction:rtl;'>" - " <div style='height:200px;'></div>" - " <div id='target' style='height:50px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='columns:3; column-gap:0; column-fill:auto; + width:300px; height:200px; direction:rtl;'> + <div style='height:200px;'></div> + <div id='target' style='height:50px;'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1066,13 +1091,14 @@ } TEST_P(MapCoordinatesTest, MulticolWithLargeBorder) { - SetBodyInnerHTML( - "<div id='container' style='columns:3; column-gap:0; column-fill:auto; " - "width:300px; height:200px; border:200px solid;'>" - " <div style='height:200px;'></div>" - " <div id='target' style='height:50px;'></div>" - " <div style='height:200px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='columns:3; column-gap:0; column-fill:auto; + width:300px; height:200px; border:200px solid;'> + <div style='height:200px;'></div> + <div id='target' style='height:50px;'></div> + <div style='height:200px;'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1098,14 +1124,15 @@ } TEST_P(MapCoordinatesTest, FlippedBlocksWritingModeWithText) { - SetBodyInnerHTML( - "<div style='-webkit-writing-mode:vertical-rl;'>" - " <div style='width:13px;'></div>" - " <div style='width:200px; height:400px; line-height:50px;'>" - " <br id='sibling'>text" - " </div>" - " <div style='width:5px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='-webkit-writing-mode:vertical-rl;'> + <div style='width:13px;'></div> + <div style='width:200px; height:400px; line-height:50px;'> + <br id='sibling'>text + </div> + <div style='width:5px;'></div> + </div> + )HTML"); LayoutObject* br = GetLayoutObjectByElementId("sibling"); LayoutObject* text = br->NextSibling(); @@ -1143,16 +1170,17 @@ } TEST_P(MapCoordinatesTest, FlippedBlocksWritingModeWithInline) { - SetBodyInnerHTML( - "<div style='-webkit-writing-mode:vertical-rl;'>" - " <div style='width:13px;'></div>" - " <div style='width:200px; height:400px; line-height:50px;'>" - " <span>" - " <span id='target'><br>text</span>" - " </span>" - " </div>" - " <div style='width:7px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='-webkit-writing-mode:vertical-rl;'> + <div style='width:13px;'></div> + <div style='width:200px; height:400px; line-height:50px;'> + <span> + <span id='target'><br>text</span> + </span> + </div> + <div style='width:7px;'></div> + </div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); ASSERT_TRUE(target); @@ -1208,14 +1236,15 @@ } TEST_P(MapCoordinatesTest, FlippedBlocksWritingModeWithBlock) { - SetBodyInnerHTML( - "<div id='container' style='-webkit-writing-mode:vertical-rl; border:8px " - "solid; padding:7px; width:200px; height:200px;'>" - " <div id='middle' style='border:1px solid;'>" - " <div style='width:30px;'></div>" - " <div id='target' style='margin:6px; width:25px;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='-webkit-writing-mode:vertical-rl; border:8px + solid; padding:7px; width:200px; height:200px;'> + <div id='middle' style='border:1px solid;'> + <div style='width:30px;'></div> + <div id='target' style='margin:6px; width:25px;'></div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1240,35 +1269,36 @@ } TEST_P(MapCoordinatesTest, Table) { - SetBodyInnerHTML( - "<style>td { padding: 2px; }</style>" - "<div id='container' style='border:3px solid;'>" - " <table style='margin:9px; border:5px solid; border-spacing:10px;'>" - " <thead>" - " <tr>" - " <td>" - " <div style='width:100px; height:100px;'></div>" - " </td>" - " </tr>" - " </thead>" - " <tbody>" - " <tr>" - " <td>" - " <div style='width:100px; height:100px;'></div>" - " </td>" - " </tr>" - " <tr>" - " <td>" - " <div style='width:100px; height:100px;'></div>" - " </td>" - " <td>" - " <div id='target' style='width:100px; " - "height:10px;'></div>" - " </td>" - " </tr>" - " </tbody>" - " </table>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>td { padding: 2px; }</style> + <div id='container' style='border:3px solid;'> + <table style='margin:9px; border:5px solid; border-spacing:10px;'> + <thead> + <tr> + <td> + <div style='width:100px; height:100px;'></div> + </td> + </tr> + </thead> + <tbody> + <tr> + <td> + <div style='width:100px; height:100px;'></div> + </td> + </tr> + <tr> + <td> + <div style='width:100px; height:100px;'></div> + </td> + <td> + <div id='target' style='width:100px; + height:10px;'></div> + </td> + </tr> + </tbody> + </table> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1339,16 +1369,17 @@ } while (false) TEST_P(MapCoordinatesTest, Transforms) { - SetBodyInnerHTML( - "<div id='container'>" - " <div id='outerTransform' style='transform:rotate(45deg); " - "width:200px; height:200px;'>" - " <div id='innerTransform' style='transform:rotate(45deg); " - "width:200px; height:200px;'>" - " <div id='target' style='width:200px; height:200px;'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container'> + <div id='outerTransform' style='transform:rotate(45deg); + width:200px; height:200px;'> + <div id='innerTransform' style='transform:rotate(45deg); + width:200px; height:200px;'> + <div id='target' style='width:200px; height:200px;'></div> + </div> + </div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1406,12 +1437,13 @@ } TEST_P(MapCoordinatesTest, SVGShape) { - SetBodyInnerHTML( - "<svg id='container'>" - " <g transform='translate(100 200)'>" - " <rect id='target' width='100' height='100'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container'> + <g transform='translate(100 200)'> + <rect id='target' width='100' height='100'/> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1423,13 +1455,14 @@ } TEST_P(MapCoordinatesTest, SVGShapeScale) { - SetBodyInnerHTML( - "<svg id='container'>" - " <g transform='scale(2) translate(50 40)'>" - " <rect id='target' transform='translate(50 80)' x='66' y='77' " - "width='100' height='100'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container'> + <g transform='scale(2) translate(50 40)'> + <rect id='target' transform='translate(50 80)' x='66' y='77' + width='100' height='100'/> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1441,12 +1474,13 @@ } TEST_P(MapCoordinatesTest, SVGShapeWithViewBoxWithoutScale) { - SetBodyInnerHTML( - "<svg id='container' viewBox='0 0 200 200' width='400' height='200'>" - " <g transform='translate(100 50)'>" - " <rect id='target' width='100' height='100'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container' viewBox='0 0 200 200' width='400' height='200'> + <g transform='translate(100 50)'> + <rect id='target' width='100' height='100'/> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1458,12 +1492,13 @@ } TEST_P(MapCoordinatesTest, SVGShapeWithViewBoxWithScale) { - SetBodyInnerHTML( - "<svg id='container' viewBox='0 0 100 100' width='400' height='200'>" - " <g transform='translate(50 50)'>" - " <rect id='target' width='100' height='100'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container' viewBox='0 0 100 100' width='400' height='200'> + <g transform='translate(50 50)'> + <rect id='target' width='100' height='100'/> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1475,13 +1510,14 @@ } TEST_P(MapCoordinatesTest, SVGShapeWithViewBoxWithNonZeroOffset) { - SetBodyInnerHTML( - "<svg id='container' viewBox='100 100 200 200' width='400' height='200'>" - " <g transform='translate(100 50)'>" - " <rect id='target' transform='translate(100 100)' width='100' " - "height='100'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container' viewBox='100 100 200 200' width='400' height='200'> + <g transform='translate(100 50)'> + <rect id='target' transform='translate(100 100)' width='100' + height='100'/> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1493,13 +1529,14 @@ } TEST_P(MapCoordinatesTest, SVGShapeWithViewBoxWithNonZeroOffsetAndScale) { - SetBodyInnerHTML( - "<svg id='container' viewBox='100 100 100 100' width='400' height='200'>" - " <g transform='translate(50 50)'>" - " <rect id='target' transform='translate(100 100)' width='100' " - "height='100'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container' viewBox='100 100 100 100' width='400' height='200'> + <g transform='translate(50 50)'> + <rect id='target' transform='translate(100 100)' width='100' + height='100'/> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1511,17 +1548,18 @@ } TEST_P(MapCoordinatesTest, SVGForeignObject) { - SetBodyInnerHTML( - "<svg id='container' viewBox='0 0 100 100' width='400' height='200'>" - " <g transform='translate(50 50)'>" - " <foreignObject transform='translate(-25 -25)'>" - " <div xmlns='http://www.w3.org/1999/xhtml' id='target' " - "style='margin-left: 50px; border: 42px; padding: 84px; width: 50px; " - "height: 50px'>" - " </div>" - " </foreignObject>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='container' viewBox='0 0 100 100' width='400' height='200'> + <g transform='translate(50 50)'> + <foreignObject transform='translate(-25 -25)'> + <div xmlns='http://www.w3.org/1999/xhtml' id='target' + style='margin-left: 50px; border: 42px; padding: 84px; width: 50px; + height: 50px'> + </div> + </foreignObject> + </g> + </svg> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); LayoutBox* container = ToLayoutBox(GetLayoutObjectByElementId("container")); @@ -1546,13 +1584,14 @@ } TEST_P(MapCoordinatesTest, LocalToAbsoluteTransform) { - SetBodyInnerHTML( - "<div id='container' style='position: absolute; left: 0; top: 0;'>" - " <div id='scale' style='transform: scale(2.0); transform-origin: left " - "top;'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: absolute; left: 0; top: 0;'> + <div id='scale' style='transform: scale(2.0); transform-origin: left + top;'> + <div id='child'></div> + </div> + </div> + )HTML"); LayoutBoxModelObject* container = ToLayoutBoxModelObject(GetLayoutObjectByElementId("container")); TransformationMatrix container_matrix = container->LocalToAbsoluteTransform(); @@ -1569,16 +1608,17 @@ } TEST_P(MapCoordinatesTest, LocalToAncestorTransform) { - SetBodyInnerHTML( - "<div id='container'>" - " <div id='rotate1' style='transform: rotate(45deg); transform-origin: " - "left top;'>" - " <div id='rotate2' style='transform: rotate(90deg); " - "transform-origin: left top;'>" - " <div id='child'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container'> + <div id='rotate1' style='transform: rotate(45deg); transform-origin: + left top;'> + <div id='rotate2' style='transform: rotate(90deg); + transform-origin: left top;'> + <div id='child'></div> + </div> + </div> + </div> + )HTML"); LayoutBoxModelObject* container = ToLayoutBoxModelObject(GetLayoutObjectByElementId("container")); LayoutBoxModelObject* rotate1 = @@ -1615,21 +1655,22 @@ TEST_P(MapCoordinatesTest, LocalToAbsoluteTransformFlattens) { GetDocument().GetFrame()->GetSettings()->SetAcceleratedCompositingEnabled( true); - SetBodyInnerHTML( - "<div style='position: absolute; left: 0; top: 0;'>" - " <div style='transform: rotateY(45deg); " - "-webkit-transform-style:preserve-3d;'>" - " <div style='transform: rotateY(-45deg); " - "-webkit-transform-style:preserve-3d;'>" - " <div id='child1'></div>" - " </div>" - " </div>" - " <div style='transform: rotateY(45deg);'>" - " <div style='transform: rotateY(-45deg);'>" - " <div id='child2'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='position: absolute; left: 0; top: 0;'> + <div style='transform: rotateY(45deg); + -webkit-transform-style:preserve-3d;'> + <div style='transform: rotateY(-45deg); + -webkit-transform-style:preserve-3d;'> + <div id='child1'></div> + </div> + </div> + <div style='transform: rotateY(45deg);'> + <div style='transform: rotateY(-45deg);'> + <div id='child2'></div> + </div> + </div> + </div> + )HTML"); LayoutObject* child1 = GetLayoutObjectByElementId("child1"); LayoutObject* child2 = GetLayoutObjectByElementId("child2"); TransformationMatrix matrix;
diff --git a/third_party/WebKit/Source/core/layout/PaginationTest.cpp b/third_party/WebKit/Source/core/layout/PaginationTest.cpp index 770f9b2b..51cd2c5 100644 --- a/third_party/WebKit/Source/core/layout/PaginationTest.cpp +++ b/third_party/WebKit/Source/core/layout/PaginationTest.cpp
@@ -38,22 +38,24 @@ }; TEST_F(PaginationStrutTest, LineWithStrut) { - SetBodyInnerHTML( - "<div id='paged' style='overflow:-webkit-paged-y; height:200px; " - "line-height:150px;'>" - " line1<br>" - " line2<br>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='paged' style='overflow:-webkit-paged-y; height:200px; + line-height:150px;'> + line1<br> + line2<br> + </div> + )HTML"); EXPECT_EQ(0, StrutForLine("paged", 0)); EXPECT_EQ(50, StrutForLine("paged", 1)); } TEST_F(PaginationStrutTest, BlockWithStrut) { - SetBodyInnerHTML( - "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" - " <div id='block1'>line1</div>" - " <div id='block2'>line2</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'> + <div id='block1'>line1</div> + <div id='block2'>line2</div> + </div> + )HTML"); EXPECT_EQ(0, StrutForBox("block1")); EXPECT_EQ(0, StrutForLine("block1", 0)); EXPECT_EQ(50, StrutForBox("block2")); @@ -61,33 +63,36 @@ } TEST_F(PaginationStrutTest, FloatWithStrut) { - SetBodyInnerHTML( - "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" - " <div style='height:120px;'></div>" - " <div id='float' style='float:left;'>line</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'> + <div style='height:120px;'></div> + <div id='float' style='float:left;'>line</div> + </div> + )HTML"); EXPECT_EQ(80, StrutForBox("float")); EXPECT_EQ(0, StrutForLine("float", 0)); } TEST_F(PaginationStrutTest, UnbreakableBlockWithStrut) { - SetBodyInnerHTML( - "<style>img { display:block; width:100px; height:150px; outline:4px " - "solid blue; padding:0; border:none; margin:0; }</style>" - "<div style='overflow:-webkit-paged-y; height:200px;'>" - " <img id='img1'>" - " <img id='img2'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>img { display:block; width:100px; height:150px; outline:4px + solid blue; padding:0; border:none; margin:0; }</style> + <div style='overflow:-webkit-paged-y; height:200px;'> + <img id='img1'> + <img id='img2'> + </div> + )HTML"); EXPECT_EQ(0, StrutForBox("img1")); EXPECT_EQ(50, StrutForBox("img2")); } TEST_F(PaginationStrutTest, BreakBefore) { - SetBodyInnerHTML( - "<div style='overflow:-webkit-paged-y; height:400px; line-height:50px;'>" - " <div id='block1'>line1</div>" - " <div id='block2' style='break-before:page;'>line2</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:-webkit-paged-y; height:400px; line-height:50px;'> + <div id='block1'>line1</div> + <div id='block2' style='break-before:page;'>line2</div> + </div> + )HTML"); EXPECT_EQ(0, StrutForBox("block1")); EXPECT_EQ(0, StrutForLine("block1", 0)); EXPECT_EQ(350, StrutForBox("block2")); @@ -95,13 +100,14 @@ } TEST_F(PaginationStrutTest, BlockWithStrutPropagatedFromInnerBlock) { - SetBodyInnerHTML( - "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" - " <div id='block1'>line1</div>" - " <div id='block2' style='padding-top:2px;'>" - " <div id='innerBlock' style='padding-top:2px;'>line2</div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'> + <div id='block1'>line1</div> + <div id='block2' style='padding-top:2px;'> + <div id='innerBlock' style='padding-top:2px;'>line2</div> + </div> + </div> + )HTML"); EXPECT_EQ(0, StrutForBox("block1")); EXPECT_EQ(0, StrutForLine("block1", 0)); EXPECT_EQ(50, StrutForBox("block2")); @@ -110,17 +116,18 @@ } TEST_F(PaginationStrutTest, BlockWithStrutPropagatedFromUnbreakableInnerBlock) { - SetBodyInnerHTML( - "<div style='overflow:-webkit-paged-y; height:400px; line-height:150px;'>" - " <div id='block1'>line1</div>" - " <div id='block2' style='padding-top:2px;'>" - " <div id='innerBlock' style='padding-top:2px; " - "break-inside:avoid;'>" - " line2<br>" - " line3<br>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:-webkit-paged-y; height:400px; line-height:150px;'> + <div id='block1'>line1</div> + <div id='block2' style='padding-top:2px;'> + <div id='innerBlock' style='padding-top:2px; + break-inside:avoid;'> + line2<br> + line3<br> + </div> + </div> + </div> + )HTML"); EXPECT_EQ(0, StrutForBox("block1")); EXPECT_EQ(0, StrutForLine("block1", 0)); EXPECT_EQ(250, StrutForBox("block2")); @@ -130,14 +137,15 @@ } TEST_F(PaginationStrutTest, InnerBlockWithBreakBefore) { - SetBodyInnerHTML( - "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" - " <div id='block1'>line1</div>" - " <div id='block2' style='padding-top:2px;'>" - " <div id='innerBlock' style='padding-top:2px; " - "break-before:page;'>line2</div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'> + <div id='block1'>line1</div> + <div id='block2' style='padding-top:2px;'> + <div id='innerBlock' style='padding-top:2px; + break-before:page;'>line2</div> + </div> + </div> + )HTML"); EXPECT_EQ(0, StrutForBox("block1")); EXPECT_EQ(0, StrutForLine("block1", 0)); // There's no class A break point before #innerBlock (they only exist
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp index 2504244..8fad4b5 100644 --- a/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp
@@ -79,10 +79,11 @@ // failure when running with other tests. Dig into this more and fix. TEST_P(ScrollAnchorTest, UMAMetricUpdated) { HistogramTester histogram_tester; - SetBodyInnerHTML( - "<style> body { height: 1000px } div { height: 100px } </style>" - "<div id='block1'>abc</div>" - "<div id='block2'>def</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { height: 1000px } div { height: 100px } </style> + <div id='block1'>abc</div> + <div id='block2'>def</div> + )HTML"); ScrollableArea* viewport = LayoutViewport(); @@ -104,13 +105,14 @@ // TODO(skobes): Convert this to web-platform-tests when visual viewport API is // launched (http://crbug.com/635031). TEST_P(ScrollAnchorTest, VisualViewportAnchors) { - SetBodyInnerHTML( - "<style>" - " * { font-size: 1.2em; font-family: sans-serif; }" - " div { height: 100px; width: 20px; background-color: pink; }" - "</style>" - "<div id='div'></div>" - "<div id='text'><b>This is a scroll anchoring test</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { font-size: 1.2em; font-family: sans-serif; } + div { height: 100px; width: 20px; background-color: pink; } + </style> + <div id='div'></div> + <div id='text'><b>This is a scroll anchoring test</div> + )HTML"); ScrollableArea* l_viewport = LayoutViewport(); VisualViewport& v_viewport = GetVisualViewport(); @@ -143,14 +145,15 @@ // Test that a non-anchoring scroll on scroller clears scroll anchors for all // parent scrollers. TEST_P(ScrollAnchorTest, ClearScrollAnchorsOnAncestors) { - SetBodyInnerHTML( - "<style>" - " body { height: 1000px } div { height: 200px }" - " #scroller { height: 100px; width: 200px; overflow: scroll; }" - "</style>" - "<div id='changer'>abc</div>" - "<div id='anchor'>def</div>" - "<div id='scroller'><div></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { height: 1000px } div { height: 200px } + #scroller { height: 100px; width: 200px; overflow: scroll; } + </style> + <div id='changer'>abc</div> + <div id='anchor'>def</div> + <div id='scroller'><div></div></div> + )HTML"); ScrollableArea* viewport = LayoutViewport(); @@ -169,24 +172,25 @@ } TEST_P(ScrollAnchorTest, AncestorClearingWithSiblingReference) { - SetBodyInnerHTML( - "<style>" - ".scroller {" - " overflow: scroll;" - " width: 400px;" - " height: 400px;" - "}" - ".space {" - " width: 100px;" - " height: 600px;" - "}" - "</style>" - "<div id='s1' class='scroller'>" - " <div id='anchor' class='space'></div>" - "</div>" - "<div id='s2' class='scroller'>" - " <div class='space'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .scroller { + overflow: scroll; + width: 400px; + height: 400px; + } + .space { + width: 100px; + height: 600px; + } + </style> + <div id='s1' class='scroller'> + <div id='anchor' class='space'></div> + </div> + <div id='s2' class='scroller'> + <div class='space'></div> + </div> + )HTML"); Element* s1 = GetDocument().getElementById("s1"); Element* s2 = GetDocument().getElementById("s2"); Element* anchor = GetDocument().getElementById("anchor"); @@ -210,10 +214,11 @@ } TEST_P(ScrollAnchorTest, FractionalOffsetsAreRoundedBeforeComparing) { - SetBodyInnerHTML( - "<style> body { height: 1000px } </style>" - "<div id='block1' style='height: 50.4px'>abc</div>" - "<div id='block2' style='height: 100px'>def</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { height: 1000px } </style> + <div id='block1' style='height: 50.4px'>abc</div> + <div id='block2' style='height: 100px'>def</div> + )HTML"); ScrollableArea* viewport = LayoutViewport(); ScrollLayoutViewport(ScrollOffset(0, 100)); @@ -226,11 +231,12 @@ } TEST_P(ScrollAnchorTest, AvoidStickyAnchorWhichMovesWithScroll) { - SetBodyInnerHTML( - "<style> body { height: 1000px } </style>" - "<div id='block1' style='height: 50px'>abc</div>" - "<div id='block2' style='height: 100px; position: sticky; top: 0;'>" - " def</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { height: 1000px } </style> + <div id='block1' style='height: 50px'>abc</div> + <div id='block2' style='height: 100px; position: sticky; top: 0;'> + def</div> + )HTML"); ScrollableArea* viewport = LayoutViewport(); ScrollLayoutViewport(ScrollOffset(0, 60)); @@ -243,17 +249,18 @@ } TEST_P(ScrollAnchorTest, AnchorWithLayerInScrollingDiv) { - SetBodyInnerHTML( - "<style>" - " #scroller { overflow: scroll; width: 500px; height: 400px; }" - " div { height: 100px }" - " #block2 { overflow: hidden }" - " #space { height: 1000px; }" - "</style>" - "<div id='scroller'><div id='space'>" - "<div id='block1'>abc</div>" - "<div id='block2'>def</div>" - "</div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; width: 500px; height: 400px; } + div { height: 100px } + #block2 { overflow: hidden } + #space { height: 1000px; } + </style> + <div id='scroller'><div id='space'> + <div id='block1'>abc</div> + <div id='block2'>def</div> + </div></div> + )HTML"); ScrollableArea* scroller = ScrollerForElement(GetDocument().getElementById("scroller")); @@ -278,19 +285,20 @@ // Verify that a nested scroller with a div that has its own PaintLayer can be // removed without causing a crash. This test passes if it doesn't crash. TEST_P(ScrollAnchorTest, RemoveScrollerWithLayerInScrollingDiv) { - SetBodyInnerHTML( - "<style>" - " body { height: 2000px }" - " #scroller { overflow: scroll; width: 500px; height: 400px}" - " #block1 { height: 100px; width: 100px; overflow: hidden}" - " #anchor { height: 1000px; }" - "</style>" - "<div id='changer1'></div>" - "<div id='scroller'>" - " <div id='changer2'></div>" - " <div id='block1'></div>" - " <div id='anchor'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { height: 2000px } + #scroller { overflow: scroll; width: 500px; height: 400px} + #block1 { height: 100px; width: 100px; overflow: hidden} + #anchor { height: 1000px; } + </style> + <div id='changer1'></div> + <div id='scroller'> + <div id='changer2'></div> + <div id='block1'></div> + <div id='anchor'></div> + </div> + )HTML"); ScrollableArea* viewport = LayoutViewport(); ScrollableArea* scroller = @@ -318,27 +326,28 @@ } TEST_P(ScrollAnchorTest, FlexboxDelayedClampingAlsoDelaysAdjustment) { - SetBodyInnerHTML( - "<style>" - " html { overflow: hidden; }" - " body {" - " position: absolute; display: flex;" - " top: 0; bottom: 0; margin: 0;" - " }" - " #scroller { overflow: auto; }" - " #spacer { width: 600px; height: 1200px; }" - " #before { height: 50px; }" - " #anchor {" - " width: 100px; height: 100px;" - " background-color: #8f8;" - " }" - "</style>" - "<div id='scroller'>" - " <div id='spacer'>" - " <div id='before'></div>" - " <div id='anchor'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { overflow: hidden; } + body { + position: absolute; display: flex; + top: 0; bottom: 0; margin: 0; + } + #scroller { overflow: auto; } + #spacer { width: 600px; height: 1200px; } + #before { height: 50px; } + #anchor { + width: 100px; height: 100px; + background-color: #8f8; + } + </style> + <div id='scroller'> + <div id='spacer'> + <div id='before'></div> + <div id='anchor'></div> + </div> + </div> + )HTML"); Element* scroller = GetDocument().getElementById("scroller"); scroller->setScrollTop(100); @@ -348,26 +357,27 @@ } TEST_P(ScrollAnchorTest, FlexboxDelayedAdjustmentRespectsSANACLAP) { - SetBodyInnerHTML( - "<style>" - " html { overflow: hidden; }" - " body {" - " position: absolute; display: flex;" - " top: 0; bottom: 0; margin: 0;" - " }" - " #scroller { overflow: auto; }" - " #spacer { width: 600px; height: 1200px; }" - " #anchor {" - " position: relative; top: 50px;" - " width: 100px; height: 100px;" - " background-color: #8f8;" - " }" - "</style>" - "<div id='scroller'>" - " <div id='spacer'>" - " <div id='anchor'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { overflow: hidden; } + body { + position: absolute; display: flex; + top: 0; bottom: 0; margin: 0; + } + #scroller { overflow: auto; } + #spacer { width: 600px; height: 1200px; } + #anchor { + position: relative; top: 50px; + width: 100px; height: 100px; + background-color: #8f8; + } + </style> + <div id='scroller'> + <div id='spacer'> + <div id='anchor'></div> + </div> + </div> + )HTML"); Element* scroller = GetDocument().getElementById("scroller"); scroller->setScrollTop(100); @@ -381,30 +391,31 @@ // TODO(skobes): Convert this to web-platform-tests when document.rootScroller // is launched (http://crbug.com/505516). TEST_P(ScrollAnchorTest, NonDefaultRootScroller) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar {" - " width: 0px; height: 0px;" - " }" - " body, html {" - " margin: 0px; width: 100%; height: 100%;" - " }" - " #rootscroller {" - " overflow: scroll; width: 100%; height: 100%;" - " }" - " .spacer {" - " height: 600px; width: 100px;" - " }" - " #target {" - " height: 100px; width: 100px; background-color: red;" - " }" - "</style>" - "<div id='rootscroller'>" - " <div id='firstChild' class='spacer'></div>" - " <div id='target'></div>" - " <div class='spacer'></div>" - "</div>" - "<div class='spacer'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { + width: 0px; height: 0px; + } + body, html { + margin: 0px; width: 100%; height: 100%; + } + #rootscroller { + overflow: scroll; width: 100%; height: 100%; + } + .spacer { + height: 600px; width: 100px; + } + #target { + height: 100px; width: 100px; background-color: red; + } + </style> + <div id='rootscroller'> + <div id='firstChild' class='spacer'></div> + <div id='target'></div> + <div class='spacer'></div> + </div> + <div class='spacer'></div> + )HTML"); Element* root_scroller_element = GetDocument().getElementById("rootscroller"); @@ -438,10 +449,11 @@ // This test verifies that scroll anchoring is disabled when the document is in // printing mode. TEST_P(ScrollAnchorTest, AnchoringDisabledForPrinting) { - SetBodyInnerHTML( - "<style> body { height: 1000px } div { height: 100px } </style>" - "<div id='block1'>abc</div>" - "<div id='block2'>def</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { height: 1000px } div { height: 100px } </style> + <div id='block1'>abc</div> + <div id='block2'>def</div> + )HTML"); ScrollableArea* viewport = LayoutViewport(); ScrollLayoutViewport(ScrollOffset(0, 150));
diff --git a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp index e9903a20..f472b8c 100644 --- a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp
@@ -245,29 +245,30 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " ::-webkit-scrollbar {" - " height: 16px;" - " width: 16px" - " }" - " ::-webkit-scrollbar-thumb {" - " background-color: rgba(0,0,0,.2);" - " }" - " html, body{" - " margin: 0;" - " height: 100%;" - " }" - " .box {" - " width: 100%;" - " height: 100%;" - " }" - " .transformed {" - " transform: translateY(100px);" - " }" - "</style>" - "<div id='box' class='box'></div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + ::-webkit-scrollbar { + height: 16px; + width: 16px + } + ::-webkit-scrollbar-thumb { + background-color: rgba(0,0,0,.2); + } + html, body{ + margin: 0; + height: 100%; + } + .box { + width: 100%; + height: 100%; + } + .transformed { + transform: translateY(100px); + } + </style> + <div id='box' class='box'></div> + )HTML"); ScrollableArea* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); @@ -301,13 +302,14 @@ WebView().SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " body{" - " height: 300%;" - " }" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body{ + height: 300%; + } + </style> + )HTML"); Compositor().BeginFrame(); // This test is specifically checking the behavior when overlay scrollbars @@ -326,20 +328,21 @@ WebView().Resize(WebSize(200, 200)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - ".noscrollbars::-webkit-scrollbar { display: none; }" - "#div{ height: 100px; width:100px; overflow:scroll; }" - ".big{ height: 2000px; }" - "body { overflow:scroll; }" - "</style>" - "<div id='div'>" - " <div class='big'>" - " </div>" - "</div>" - "<div class='big'>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + .noscrollbars::-webkit-scrollbar { display: none; } + #div{ height: 100px; width:100px; overflow:scroll; } + .big{ height: 2000px; } + body { overflow:scroll; } + </style> + <div id='div'> + <div class='big'> + </div> + </div> + <div class='big'> + </div> + )HTML"); Compositor().BeginFrame(); // This test is specifically checking the behavior when overlay scrollbars @@ -397,15 +400,16 @@ WebView().Resize(WebSize(200, 200)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " #scrollable { height: 100px; width: 100px; overflow: scroll; }" - " #content { height: 200px; width: 200px;}" - "</style>" - "<div id='scrollable'>" - " <div id='content'></div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + #scrollable { height: 100px; width: 100px; overflow: scroll; } + #content { height: 200px; width: 200px;} + </style> + <div id='scrollable'> + <div id='content'></div> + </div> + )HTML"); Compositor().BeginFrame(); Document& document = GetDocument(); @@ -436,15 +440,16 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " #scroller { overflow: scroll; width: 1000px; height: 1000px }" - " #spacer { width: 2000px; height: 2000px }" - "</style>" - "<div id='scroller'>" - " <div id='spacer'></div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + #scroller { overflow: scroll; width: 1000px; height: 1000px } + #spacer { width: 2000px; height: 2000px } + </style> + <div id='scroller'> + <div id='spacer'></div> + </div> + )HTML"); Compositor().BeginFrame(); Document& document = GetDocument(); @@ -501,25 +506,26 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " margin: 0;" - "}" - "#d1 {" - " width: 200px;" - " height: 200px;" - " overflow: auto;" - " cursor: move;" - "}" - "#d2 {" - " height: 400px;" - "}" - "</style>" - "<div id='d1'>" - " <div id='d2'></div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + #d1 { + width: 200px; + height: 200px; + overflow: auto; + cursor: move; + } + #d2 { + height: 400px; + } + </style> + <div id='d1'> + <div id='d2'></div> + </div> + )HTML"); Compositor().BeginFrame(); Document& document = GetDocument(); @@ -545,16 +551,17 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<a id='a' href='javascript:void(0);'>" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "</a>" - "<div style='position: absolute; top: 1000px'>" - " end" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <a id='a' href='javascript:void(0);'> + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + </a> + <div style='position: absolute; top: 1000px'> + end + </div> + )HTML"); Compositor().BeginFrame(); @@ -619,29 +626,30 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "#scrollbar {" - " position: absolute;" - " top: 0;" - " left: 0;" - " height: 180px;" - " width: 180px;" - " overflow-x: auto;" - "}" - "::-webkit-scrollbar {" - " width: 8px;" - "}" - "::-webkit-scrollbar-thumb {" - " background-color: hsla(0, 0%, 56%, 0.6);" - "}" - "</style>" - "<div id='scrollbar'>" - " <div style='position: absolute; top: 1000px;'>" - " make scrollbar show" - " </div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + #scrollbar { + position: absolute; + top: 0; + left: 0; + height: 180px; + width: 180px; + overflow-x: auto; + } + ::-webkit-scrollbar { + width: 8px; + } + ::-webkit-scrollbar-thumb { + background-color: hsla(0, 0%, 56%, 0.6); + } + </style> + <div id='scrollbar'> + <div style='position: absolute; top: 1000px;'> + make scrollbar show + </div> + </div> + )HTML"); Compositor().BeginFrame(); @@ -686,20 +694,21 @@ SimRequest main_resource("https://example.com/", "text/html"); SimRequest frame_resource("https://example.com/iframe.html", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " margin: 0;" - " height: 2000px;" - "}" - "iframe {" - " height: 200px;" - " width: 200px;" - "}" - "</style>" - "<iframe id='iframe' src='iframe.html'>" - "</iframe>"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + height: 2000px; + } + iframe { + height: 200px; + width: 200px; + } + </style> + <iframe id='iframe' src='iframe.html'> + </iframe> + )HTML"); Compositor().BeginFrame(); frame_resource.Complete("<!DOCTYPE html>"); @@ -761,23 +770,24 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "#parent {" - " position: absolute;" - " top: 0;" - " left: 0;" - " height: 180px;" - " width: 180px;" - " overflow-y: scroll;" - "}" - "</style>" - "<div id='parent'>" - " <div id='child' style='position: absolute; top: 1000px;'>" - " make scrollbar enabled" - " </div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + #parent { + position: absolute; + top: 0; + left: 0; + height: 180px; + width: 180px; + overflow-y: scroll; + } + </style> + <div id='parent'> + <div id='child' style='position: absolute; top: 1000px;'> + make scrollbar enabled + </div> + </div> + )HTML"); Compositor().BeginFrame(); @@ -848,13 +858,14 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " overflow: scroll;" - "}" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + overflow: scroll; + } + </style> + )HTML"); Compositor().BeginFrame(); @@ -879,28 +890,29 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "#scrollbar {" - " position: absolute;" - " top: 0;" - " left: 0;" - " height: 180px;" - " width: 180px;" - " overflow-x: auto;" - "}" - "::-webkit-scrollbar {" - " width: 8px;" - "}" - "::-webkit-scrollbar-thumb {" - " background-color: hsla(0, 0%, 56%, 0.6);" - "}" - "</style>" - "<div id='scrollbar'>" - " <div style='position: absolute; top: 1000px;'>make scrollbar " - "shows</div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + #scrollbar { + position: absolute; + top: 0; + left: 0; + height: 180px; + width: 180px; + overflow-x: auto; + } + ::-webkit-scrollbar { + width: 8px; + } + ::-webkit-scrollbar-thumb { + background-color: hsla(0, 0%, 56%, 0.6); + } + </style> + <div id='scrollbar'> + <div style='position: absolute; top: 1000px;'>make scrollbar + shows</div> + </div> + )HTML"); Compositor().BeginFrame(); @@ -944,21 +956,22 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style type='text/css'>" - " ::-webkit-scrollbar {" - " width: 16px;" - " height: 16px;" - " overflow: visible;" - " }" - " div {" - " width: 1000px;" - " }" - "</style>" - "<div style='position: absolute; top: 1000px;'>" - " end" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style type='text/css'> + ::-webkit-scrollbar { + width: 16px; + height: 16px; + overflow: visible; + } + div { + width: 1000px; + } + </style> + <div style='position: absolute; top: 1000px;'> + end + </div> + )HTML"); // No DCHECK Fails. Issue 676678. Compositor().BeginFrame(); @@ -997,26 +1010,27 @@ SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); RunTasksForPeriod(kMockOverlayFadeOutDelayMS); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " #space {" - " width: 1000px;" - " height: 1000px;" - " }" - " #container {" - " width: 200px;" - " height: 200px;" - " overflow: scroll;" - " /* Ensure the scroller is non-composited. */" - " border: border: 2px solid;" - " border-radius: 25px;" - " }" - " div { height:1000px; width: 200px; }" - "</style>" - "<div id='container'>" - " <div id='space'></div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + #space { + width: 1000px; + height: 1000px; + } + #container { + width: 200px; + height: 200px; + overflow: scroll; + /* Ensure the scroller is non-composited. */ + border: border: 2px solid; + border-radius: 25px; + } + div { height:1000px; width: 200px; } + </style> + <div id='container'> + <div id='space'></div> + </div> + )HTML"); Compositor().BeginFrame(); // This test is specifically checking the behavior when overlay scrollbars // are enabled. @@ -1197,15 +1211,16 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " margin: 0;" - " background: blue;" - " height: 10px;" - " width: 799px;" - "}"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + background: blue; + height: 10px; + width: 799px; + } + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_FALSE(layout_viewport->VerticalScrollbar()); @@ -1220,15 +1235,16 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " margin: 0;" - " background: blue;" - " height: 599px;" - " width: 10px;" - "}"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + background: blue; + height: 599px; + width: 10px; + } + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_FALSE(layout_viewport->VerticalScrollbar()); @@ -1244,15 +1260,16 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " margin: 0;" - " background: blue;" - " height: 599px;" - " width: 799px;" - "}"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + background: blue; + height: 599px; + width: 799px; + } + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_FALSE(layout_viewport->VerticalScrollbar()); @@ -1268,15 +1285,16 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - "body {" - " margin: 0;" - " background: blue;" - " height: 600px;" - " width: 800px;" - "}"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + background: blue; + height: 600px; + width: 800px; + } + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_FALSE(layout_viewport->VerticalScrollbar()); @@ -1292,16 +1310,17 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " html { height: 100%; }" - " body {" - " margin: 0;" - " width: 101%;" - " height: 10px;" - " }" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + html { height: 100%; } + body { + margin: 0; + width: 101%; + height: 10px; + } + </style> + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_FALSE(layout_viewport->VerticalScrollbar()); @@ -1317,16 +1336,17 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " html { height: 100%; }" - " body {" - " margin: 0;" - " width: 101%;" - " height: 100%;" - " }" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + html { height: 100%; } + body { + margin: 0; + width: 101%; + height: 100%; + } + </style> + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_FALSE(layout_viewport->VerticalScrollbar()); @@ -1342,16 +1362,17 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " html { height: 100%; }" - " body {" - " margin: 0;" - " width: 10px;" - " height: 101%;" - " }" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + html { height: 100%; } + body { + margin: 0; + width: 10px; + height: 101%; + } + </style> + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_TRUE(layout_viewport->VerticalScrollbar()); @@ -1367,16 +1388,17 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " html { height: 100%; }" - " body {" - " margin: 0;" - " width: 100%;" - " height: 101%;" - " }" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + html { height: 100%; } + body { + margin: 0; + width: 100%; + height: 101%; + } + </style> + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_TRUE(layout_viewport->VerticalScrollbar()); @@ -1392,16 +1414,17 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - " html { height: 100%; }" - " body {" - " margin: 0;" - " width: 101%;" - " height: 101%;" - " }" - "</style>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + html { height: 100%; } + body { + margin: 0; + width: 101%; + height: 101%; + } + </style> + )HTML"); Compositor().BeginFrame(); auto* layout_viewport = GetDocument().View()->LayoutViewportScrollableArea(); EXPECT_TRUE(layout_viewport->VerticalScrollbar());
diff --git a/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp b/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp index 18b4913f..30deaa2 100644 --- a/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp +++ b/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp
@@ -45,20 +45,21 @@ }; TEST_F(TextAutosizerTest, SimpleParagraph) { - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='autosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='autosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); Element* autosized = GetDocument().getElementById("autosized"); EXPECT_FLOAT_EQ(16.f, autosized->GetLayoutObject()->Style()->SpecifiedFontSize()); @@ -69,38 +70,39 @@ } TEST_F(TextAutosizerTest, TextSizeAdjustDisablesAutosizing) { - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='textSizeAdjustAuto' style='text-size-adjust: auto;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>" - "<div id='textSizeAdjustNone' style='text-size-adjust: none;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>" - "<div id='textSizeAdjust100' style='text-size-adjust: 100%;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='textSizeAdjustAuto' style='text-size-adjust: auto;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + <div id='textSizeAdjustNone' style='text-size-adjust: none;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + <div id='textSizeAdjust100' style='text-size-adjust: 100%;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); LayoutObject* text_size_adjust_auto = GetDocument().getElementById("textSizeAdjustAuto")->GetLayoutObject(); EXPECT_FLOAT_EQ(16.f, text_size_adjust_auto->Style()->SpecifiedFontSize()); @@ -116,23 +118,24 @@ } TEST_F(TextAutosizerTest, ParagraphWithChangingTextSizeAdjustment) { - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " .none { text-size-adjust: none; }" - " .small { text-size-adjust: 50%; }" - " .large { text-size-adjust: 150%; }" - "</style>" - "<div id='autosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + .none { text-size-adjust: none; } + .small { text-size-adjust: 50%; } + .large { text-size-adjust: 150%; } + </style> + <div id='autosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); Element* autosized_div = GetDocument().getElementById("autosized"); EXPECT_FLOAT_EQ( 16.f, autosized_div->GetLayoutObject()->Style()->SpecifiedFontSize()); @@ -169,20 +172,21 @@ } TEST_F(TextAutosizerTest, ZeroTextSizeAdjustment) { - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='textSizeAdjustZero' style='text-size-adjust: 0%;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='textSizeAdjustZero' style='text-size-adjust: 0%;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); LayoutObject* text_size_adjust_zero = GetDocument().getElementById("textSizeAdjustZero")->GetLayoutObject(); EXPECT_FLOAT_EQ(16.f, text_size_adjust_zero->Style()->SpecifiedFontSize()); @@ -235,29 +239,30 @@ } TEST_F(TextAutosizerTest, NestedTextSizeAdjust) { - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='textSizeAdjustA' style='text-size-adjust: 47%;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - " <div id='textSizeAdjustB' style='text-size-adjust: 53%;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='textSizeAdjustA' style='text-size-adjust: 47%;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + <div id='textSizeAdjustB' style='text-size-adjust: 53%;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + </div> + )HTML"); LayoutObject* text_size_adjust_a = GetDocument().getElementById("textSizeAdjustA")->GetLayoutObject(); EXPECT_FLOAT_EQ(16.f, text_size_adjust_a->Style()->SpecifiedFontSize()); @@ -271,20 +276,21 @@ } TEST_F(TextAutosizerTest, PrefixedTextSizeAdjustIsAlias) { - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='textSizeAdjust' style='-webkit-text-size-adjust: 50%;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='textSizeAdjust' style='-webkit-text-size-adjust: 50%;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); LayoutObject* text_size_adjust = GetDocument().getElementById("textSizeAdjust")->GetLayoutObject(); EXPECT_FLOAT_EQ(16.f, text_size_adjust->Style()->SpecifiedFontSize()); @@ -295,20 +301,21 @@ TEST_F(TextAutosizerTest, AccessibilityFontScaleFactor) { GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(1.5); - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='autosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='autosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); Element* autosized = GetDocument().getElementById("autosized"); EXPECT_FLOAT_EQ(16.f, autosized->GetLayoutObject()->Style()->SpecifiedFontSize()); @@ -320,31 +327,32 @@ TEST_F(TextAutosizerTest, AccessibilityFontScaleFactorWithTextSizeAdjustNone) { GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(1.5); - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " #autosized { width: 400px; text-size-adjust: 100%; }" - " #notAutosized { width: 100px; text-size-adjust: 100%; }" - "</style>" - "<div id='autosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>" - "<div id='notAutosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + #autosized { width: 400px; text-size-adjust: 100%; } + #notAutosized { width: 100px; text-size-adjust: 100%; } + </style> + <div id='autosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + <div id='notAutosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); Element* autosized = GetDocument().getElementById("autosized"); EXPECT_FLOAT_EQ(16.f, autosized->GetLayoutObject()->Style()->SpecifiedFontSize()); @@ -364,20 +372,21 @@ TEST_F(TextAutosizerTest, ChangingAccessibilityFontScaleFactor) { GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(1); - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='autosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='autosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); Element* autosized = GetDocument().getElementById("autosized"); EXPECT_FLOAT_EQ(16.f, autosized->GetLayoutObject()->Style()->SpecifiedFontSize()); @@ -399,29 +408,30 @@ TEST_F(TextAutosizerTest, TextSizeAdjustDoesNotDisableAccessibility) { GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(1.5); - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='textSizeAdjustNone' style='text-size-adjust: none;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>" - "<div id='textSizeAdjustDouble' style='text-size-adjust: 200%;'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='textSizeAdjustNone' style='text-size-adjust: none;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + <div id='textSizeAdjustDouble' style='text-size-adjust: 200%;'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); Element* text_size_adjust_none = GetDocument().getElementById("textSizeAdjustNone"); EXPECT_FLOAT_EQ( @@ -468,14 +478,15 @@ TEST_F(TextAutosizerTest, DISABLED_TextSizeAdjustWithoutNeedingAutosizing) { GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride( IntSize(800, 600)); - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='textSizeAdjust' style='text-size-adjust: 150%;'>" - " Text" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='textSizeAdjust' style='text-size-adjust: 150%;'> + Text + </div> + )HTML"); LayoutObject* text_size_adjust = GetDocument().getElementById("textSizeAdjust")->GetLayoutObject(); @@ -486,21 +497,22 @@ } TEST_F(TextAutosizerTest, DeviceScaleAdjustmentWithViewport) { - SetBodyInnerHTML( - "<meta name='viewport' content='width=800'>" - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='autosized'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do" - " eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim" - " ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut" - " aliquip ex ea commodo consequat. Duis aute irure dolor in" - " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla" - " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in" - " culpa qui officia deserunt mollit anim id est laborum." - "</div>"); + SetBodyInnerHTML(R"HTML( + <meta name='viewport' content='width=800'> + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='autosized'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + </div> + )HTML"); GetDocument().GetSettings()->SetViewportMetaEnabled(true); GetDocument().GetSettings()->SetDeviceScaleAdjustment(1.5f); @@ -528,19 +540,20 @@ } TEST_F(TextAutosizerTest, ChangingSuperClusterFirstText) { - SetBodyInnerHTML( - "<meta name='viewport' content='width=800'>" - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " .supercluster { width:560px; }" - "</style>" - "<div class='supercluster'>" - " <div id='longText'>short blah blah</div>" - "</div>" - "<div class='supercluster'>" - " <div id='shortText'>short blah blah</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <meta name='viewport' content='width=800'> + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + .supercluster { width:560px; } + </style> + <div class='supercluster'> + <div id='longText'>short blah blah</div> + </div> + <div class='supercluster'> + <div id='shortText'>short blah blah</div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* long_text_element = GetDocument().getElementById("longText"); @@ -572,19 +585,20 @@ } TEST_F(TextAutosizerTest, ChangingSuperClusterSecondText) { - SetBodyInnerHTML( - "<meta name='viewport' content='width=800'>" - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " .supercluster { width:560px; }" - "</style>" - "<div class='supercluster'>" - " <div id='shortText'>short blah blah</div>" - "</div>" - "<div class='supercluster'>" - " <div id='longText'>short blah blah</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <meta name='viewport' content='width=800'> + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + .supercluster { width:560px; } + </style> + <div class='supercluster'> + <div id='shortText'>short blah blah</div> + </div> + <div class='supercluster'> + <div id='longText'>short blah blah</div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* long_text_element = GetDocument().getElementById("longText"); @@ -616,19 +630,20 @@ } TEST_F(TextAutosizerTest, AddingSuperCluster) { - SetBodyInnerHTML( - "<meta name='viewport' content='width=800'>" - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " .supercluster { width:560px; }" - "</style>" - "<div>" - " <div class='supercluster' id='shortText'>" - " short blah blah" - " </div>" - "</div>" - "<div id='container'></div>"); + SetBodyInnerHTML(R"HTML( + <meta name='viewport' content='width=800'> + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + .supercluster { width:560px; } + </style> + <div> + <div class='supercluster' id='shortText'> + short blah blah + </div> + </div> + <div id='container'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* container = GetDocument().getElementById("container"); @@ -662,20 +677,21 @@ } TEST_F(TextAutosizerTest, ChangingInheritedClusterTextInsideSuperCluster) { - SetBodyInnerHTML( - "<meta name='viewport' content='width=800'>" - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " .supercluster { width:560px; }" - " .cluster{width:560px;}" - "</style>" - "<div class='supercluster'>" - " <div class='cluster' id='longText'>short blah blah</div>" - "</div>" - "<div class='supercluster'>" - " <div class='cluster' id='shortText'>short blah blah</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <meta name='viewport' content='width=800'> + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + .supercluster { width:560px; } + .cluster{width:560px;} + </style> + <div class='supercluster'> + <div class='cluster' id='longText'>short blah blah</div> + </div> + <div class='supercluster'> + <div class='cluster' id='shortText'>short blah blah</div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* long_text_element = GetDocument().getElementById("longText"); @@ -707,40 +723,41 @@ } TEST_F(TextAutosizerTest, AutosizeInnerContentOfRuby) { - SetBodyInnerHTML( - "<meta name='viewport' content='width=800'>" - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - "</style>" - "<div id='autosized'>" - " 東京特許許可局許可局長 今日" - " <ruby>" - " <rb id='rubyInline'>急遽</rb>" - " <rp>(</rp>" - " <rt>きゅうきょ</rt>" - " <rp>)</rp>" - " </ruby>" - " 許可却下、<br><br>" - " <span>" - " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec " - " sed diam facilisis, elementum elit at, elementum sem. Aliquam " - " consectetur leo at nisi fermentum, vitae maximus libero " - "sodales. Sed " - " laoreet congue ipsum, at tincidunt ante tempor sed. Cras eget " - "erat " - " mattis urna vestibulum porta. Sed tempus vitae dui et suscipit. " - " Curabitur laoreet accumsan pharetra. Nunc facilisis, elit sit " - "amet " - " sollicitudin condimentum, ipsum velit ultricies mi, eget " - "dapibus nunc " - " nulla nec sapien. Fusce dictum imperdiet aliquet." - " </span>" - " <ruby style='display:block'>" - " <rb id='rubyBlock'>拼音</rb>" - " <rt>pin yin</rt>" - " </ruby>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <meta name='viewport' content='width=800'> + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + </style> + <div id='autosized'> + 東京特許許可局許可局長 今日 + <ruby> + <rb id='rubyInline'>急遽</rb> + <rp>(</rp> + <rt>きゅうきょ</rt> + <rp>)</rp> + </ruby> + 許可却下、<br><br> + <span> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec + sed diam facilisis, elementum elit at, elementum sem. Aliquam + consectetur leo at nisi fermentum, vitae maximus libero + sodales. Sed + laoreet congue ipsum, at tincidunt ante tempor sed. Cras eget + erat + mattis urna vestibulum porta. Sed tempus vitae dui et suscipit. + Curabitur laoreet accumsan pharetra. Nunc facilisis, elit sit + amet + sollicitudin condimentum, ipsum velit ultricies mi, eget + dapibus nunc + nulla nec sapien. Fusce dictum imperdiet aliquet. + </span> + <ruby style='display:block'> + <rb id='rubyBlock'>拼音</rb> + <rt>pin yin</rt> + </ruby> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ruby_inline = GetDocument().getElementById("rubyInline"); @@ -917,23 +934,24 @@ // Change setting triggers updating device scale factor GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride( IntSize(400, 300)); - SetBodyInnerHTML( - "<style>" - " html { font-size: 16px; }" - " body { width: 800px; margin: 0; overflow-y: hidden; }" - " .target { width: 560px; }" - "</style>" - "<body>" - " <div id='target'>" - " Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed " - " do eiusmod tempor incididunt ut labore et dolore magna aliqua." - " Ut enim ad minim veniam, quis nostrud exercitation ullamco " - " laboris nisi ut aliquip ex ea commodo consequat. Duis aute " - " irure dolor in reprehenderit in voluptate velit esse cillum " - " dolore eu fugiat nulla pariatur. Excepteur sint occaecat " - " cupidatat non proident, sunt in culpa qui officia deserunt " - " </div>" - "</body>"); + SetBodyInnerHTML(R"HTML( + <style> + html { font-size: 16px; } + body { width: 800px; margin: 0; overflow-y: hidden; } + .target { width: 560px; } + </style> + <body> + <div id='target'> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed + do eiusmod tempor incididunt ut labore et dolore magna aliqua. + Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute + irure dolor in reprehenderit in voluptate velit esse cillum + dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt + </div> + </body> + )HTML"); Element* target = GetDocument().getElementById("target"); // (specified font-size = 16px) * (thread flow layout width = 800px) /
diff --git a/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp index e7d2505..ea87c188 100644 --- a/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp +++ b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
@@ -79,12 +79,13 @@ }; TEST_F(VisualRectMappingTest, LayoutText) { - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>" - " <span><img style='width: 20px; height: 100px'></span>" - " text text text text text text text" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='container' style='overflow: scroll; width: 50px; height: 50px'> + <span><img style='width: 20px; height: 100px'></span> + text text text text text text text + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -114,12 +115,13 @@ TEST_F(VisualRectMappingTest, LayoutInline) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>" - " <span><img style='width: 20px; height: 100px'></span>" - " <span id='leaf'></span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='container' style='overflow: scroll; width: 50px; height: 50px'> + <span><img style='width: 20px; height: 100px'></span> + <span id='leaf'></span> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -149,12 +151,13 @@ TEST_F(VisualRectMappingTest, LayoutView) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id=frameContainer>" - " <iframe src='http://test.com' width='50' height='50' " - " frameBorder='0'></iframe>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id=frameContainer> + <iframe src='http://test.com' width='50' height='50' + frameBorder='0'></iframe> + </div> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; }</style>" "<span><img style='width: 20px; height: 100px'></span>text text text"); @@ -193,16 +196,18 @@ TEST_F(VisualRectMappingTest, LayoutViewSubpixelRounding) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id=frameContainer style='position: relative; left: 0.5px'>" - " <iframe style='position: relative; left: 0.5px' width='200'" - " height='200' src='http://test.com' frameBorder='0'></iframe>" - "</div>"); - SetChildFrameHTML( - "<style>body { margin: 0; }</style>" - "<div id='target' style='position: relative; width: 100px; height: 100px;" - " left: 0.5px'></div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id=frameContainer style='position: relative; left: 0.5px'> + <iframe style='position: relative; left: 0.5px' width='200' + height='200' src='http://test.com' frameBorder='0'></iframe> + </div> + )HTML"); + SetChildFrameHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='target' style='position: relative; width: 100px; height: 100px; + left: 0.5px'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -221,12 +226,13 @@ TEST_F(VisualRectMappingTest, LayoutViewDisplayNone) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id=frameContainer>" - " <iframe id='frame' src='http://test.com' width='50' height='50' " - " frameBorder='0'></iframe>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id=frameContainer> + <iframe id='frame' src='http://test.com' width='50' height='50' + frameBorder='0'></iframe> + </div> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; }</style>" "<div style='width:100px;height:100px;'></div>"); @@ -258,11 +264,12 @@ } TEST_F(VisualRectMappingTest, SelfFlippedWritingMode) { - SetBodyInnerHTML( - "<div id='target' style='writing-mode: vertical-rl;" - " box-shadow: 40px 20px black; width: 100px; height: 50px;" - " position: absolute; top: 111px; left: 222px'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='writing-mode: vertical-rl; + box-shadow: 40px 20px black; width: 100px; height: 50px; + position: absolute; top: 111px; left: 222px'> + </div> + )HTML"); LayoutBlock* target = ToLayoutBlock(GetLayoutObjectByElementId("target")); LayoutRect local_visual_rect = target->LocalVisualRect(); @@ -289,13 +296,14 @@ } TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode) { - SetBodyInnerHTML( - "<div id='container' style='writing-mode: vertical-rl;" - " position: absolute; top: 111px; left: 222px'>" - " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" - " height: 90px'></div>" - " <div style='width: 100px; height: 100px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='writing-mode: vertical-rl; + position: absolute; top: 111px; left: 222px'> + <div id='target' style='box-shadow: 40px 20px black; width: 100px; + height: 90px'></div> + <div style='width: 100px; height: 100px'></div> + </div> + )HTML"); LayoutBlock* target = ToLayoutBlock(GetLayoutObjectByElementId("target")); LayoutRect target_local_visual_rect = target->LocalVisualRect(); @@ -340,13 +348,14 @@ } TEST_F(VisualRectMappingTest, ContainerOverflowScroll) { - SetBodyInnerHTML( - "<div id='container' style='position: absolute; top: 111px; left: 222px;" - " border: 10px solid red; overflow: scroll; width: 50px;" - " height: 80px'>" - " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" - " height: 90px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: absolute; top: 111px; left: 222px; + border: 10px solid red; overflow: scroll; width: 50px; + height: 80px'> + <div id='target' style='box-shadow: 40px 20px black; width: 100px; + height: 90px'></div> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -397,15 +406,16 @@ } TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowScroll) { - SetBodyInnerHTML( - "<div id='container' style='writing-mode: vertical-rl;" - " position: absolute; top: 111px; left: 222px; border: solid red;" - " border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px;" - " height: 80px'>" - " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" - " height: 90px'></div>" - " <div style='width: 100px; height: 100px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='writing-mode: vertical-rl; + position: absolute; top: 111px; left: 222px; border: solid red; + border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px; + height: 80px'> + <div id='target' style='box-shadow: 40px 20px black; width: 100px; + height: 90px'></div> + <div style='width: 100px; height: 100px'></div> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -471,13 +481,14 @@ } TEST_F(VisualRectMappingTest, ContainerOverflowHidden) { - SetBodyInnerHTML( - "<div id='container' style='position: absolute; top: 111px; left: 222px;" - " border: 10px solid red; overflow: hidden; width: 50px;" - " height: 80px;'>" - " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" - " height: 90px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: absolute; top: 111px; left: 222px; + border: 10px solid red; overflow: hidden; width: 50px; + height: 80px;'> + <div id='target' style='box-shadow: 40px 20px black; width: 100px; + height: 90px'></div> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -502,15 +513,16 @@ } TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowHidden) { - SetBodyInnerHTML( - "<div id='container' style='writing-mode: vertical-rl; " - " position: absolute; top: 111px; left: 222px; border: solid red; " - " border-width: 10px 20px 30px 40px; overflow: hidden; width: 50px; " - " height: 80px'>" - " <div id='target' style='box-shadow: 40px 20px black; width: 100px; " - " height: 90px'></div>" - " <div style='width: 100px; height: 100px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='writing-mode: vertical-rl; + position: absolute; top: 111px; left: 222px; border: solid red; + border-width: 10px 20px 30px 40px; overflow: hidden; width: 50px; + height: 80px'> + <div id='target' style='box-shadow: 40px 20px black; width: 100px; + height: 90px'></div> + <div style='width: 100px; height: 100px'></div> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -545,15 +557,16 @@ } TEST_F(VisualRectMappingTest, ContainerAndTargetDifferentFlippedWritingMode) { - SetBodyInnerHTML( - "<div id='container' style='writing-mode: vertical-rl;" - " position: absolute; top: 111px; left: 222px; border: solid red;" - " border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px;" - " height: 80px'>" - " <div id='target' style='writing-mode: vertical-lr; width: 100px;" - " height: 90px; box-shadow: 40px 20px black'></div>" - " <div style='width: 100px; height: 100px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='writing-mode: vertical-rl; + position: absolute; top: 111px; left: 222px; border: solid red; + border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px; + height: 80px'> + <div id='target' style='writing-mode: vertical-lr; width: 100px; + height: 90px; box-shadow: 40px 20px black'></div> + <div style='width: 100px; height: 100px'></div> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); @@ -593,18 +606,19 @@ GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<div id='stacking-context' style='opacity: 0.9; background: blue;" - " will-change: transform'>" - " <div id='scroller' style='overflow: scroll; width: 80px;" - " height: 80px'>" - " <div id='absolute' style='position: absolute; top: 111px;" - " left: 222px; width: 50px; height: 50px; background: green'>" - " </div>" - " <div id='normal-flow' style='width: 2000px; height: 2000px;" - " background: yellow'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='stacking-context' style='opacity: 0.9; background: blue; + will-change: transform'> + <div id='scroller' style='overflow: scroll; width: 80px; + height: 80px'> + <div id='absolute' style='position: absolute; top: 111px; + left: 222px; width: 50px; height: 50px; background: green'> + </div> + <div id='normal-flow' style='width: 2000px; height: 2000px; + background: yellow'></div> + </div> + </div> + )HTML"); LayoutBlock* scroller = ToLayoutBlock(GetLayoutObjectByElementId("scroller")); scroller->SetScrollTop(LayoutUnit(77)); @@ -673,11 +687,12 @@ } TEST_F(VisualRectMappingTest, CSSClip) { - SetBodyInnerHTML( - "<div id='container' style='position: absolute; top: 0px; left: 0px; " - " clip: rect(0px, 200px, 200px, 0px)'>" - " <div id='target' style='width: 400px; height: 400px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: absolute; top: 0px; left: 0px; + clip: rect(0px, 200px, 200px, 0px)'> + <div id='target' style='width: 400px; height: 400px'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); @@ -687,11 +702,12 @@ } TEST_F(VisualRectMappingTest, ContainPaint) { - SetBodyInnerHTML( - "<div id='container' style='position: absolute; top: 0px; left: 0px; " - " width: 200px; height: 200px; contain: paint'>" - " <div id='target' style='width: 400px; height: 400px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: absolute; top: 0px; left: 0px; + width: 200px; height: 200px; contain: paint'> + <div id='target' style='width: 400px; height: 400px'></div> + </div> + )HTML"); LayoutBox* target = ToLayoutBox(GetLayoutObjectByElementId("target")); @@ -701,13 +717,14 @@ } TEST_F(VisualRectMappingTest, FloatUnderInline) { - SetBodyInnerHTML( - "<div style='position: absolute; top: 55px; left: 66px'>" - " <span id='span' style='position: relative; top: 100px; left: 200px'>" - " <div id='target' style='float: left; width: 33px; height: 44px'>" - " </div>" - " </span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='position: absolute; top: 55px; left: 66px'> + <span id='span' style='position: relative; top: 100px; left: 200px'> + <div id='target' style='float: left; width: 33px; height: 44px'> + </div> + </span> + </div> + )HTML"); LayoutBoxModelObject* span = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span")); @@ -728,20 +745,21 @@ TEST_F(VisualRectMappingTest, ShouldAccountForPreserve3d) { EnableCompositing(); - SetBodyInnerHTML( - "<style>" - "* { margin: 0; }" - "#container {" - " transform: rotateX(-45deg);" - " width: 100px; height: 100px;" - "}" - "#target {" - " transform-style: preserve-3d; transform: rotateX(45deg);" - " background: lightblue;" - " width: 100px; height: 100px;" - "}" - "</style>" - "<div id='container'><div id='target'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #container { + transform: rotateX(-45deg); + width: 100px; height: 100px; + } + #target { + transform-style: preserve-3d; transform: rotateX(45deg); + background: lightblue; + width: 100px; height: 100px; + } + </style> + <div id='container'><div id='target'></div></div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); LayoutBlock* target = ToLayoutBlock(GetLayoutObjectByElementId("target")); @@ -757,21 +775,22 @@ TEST_F(VisualRectMappingTest, ShouldAccountForPreserve3dNested) { EnableCompositing(); - SetBodyInnerHTML( - "<style>" - "* { margin: 0; }" - "#container {" - " transform-style: preserve-3d;" - " transform: rotateX(-45deg);" - " width: 100px; height: 100px;" - "}" - "#target {" - " transform-style: preserve-3d; transform: rotateX(45deg);" - " background: lightblue;" - " width: 100px; height: 100px;" - "}" - "</style>" - "<div id='container'><div id='target'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #container { + transform-style: preserve-3d; + transform: rotateX(-45deg); + width: 100px; height: 100px; + } + #target { + transform-style: preserve-3d; transform: rotateX(45deg); + background: lightblue; + width: 100px; height: 100px; + } + </style> + <div id='container'><div id='target'></div></div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); LayoutBlock* target = ToLayoutBlock(GetLayoutObjectByElementId("target")); @@ -786,20 +805,21 @@ TEST_F(VisualRectMappingTest, ShouldAccountForPerspective) { EnableCompositing(); - SetBodyInnerHTML( - "<style>" - "* { margin: 0; }" - "#container {" - " transform: rotateX(-45deg); perspective: 100px;" - " width: 100px; height: 100px;" - "}" - "#target {" - " transform-style: preserve-3d; transform: rotateX(45deg);" - " background: lightblue;" - " width: 100px; height: 100px;" - "}" - "</style>" - "<div id='container'><div id='target'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #container { + transform: rotateX(-45deg); perspective: 100px; + width: 100px; height: 100px; + } + #target { + transform-style: preserve-3d; transform: rotateX(45deg); + background: lightblue; + width: 100px; height: 100px; + } + </style> + <div id='container'><div id='target'></div></div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); LayoutBlock* target = ToLayoutBlock(GetLayoutObjectByElementId("target")); @@ -818,21 +838,22 @@ TEST_F(VisualRectMappingTest, ShouldAccountForPerspectiveNested) { EnableCompositing(); - SetBodyInnerHTML( - "<style>" - "* { margin: 0; }" - "#container {" - " transform-style: preserve-3d;" - " transform: rotateX(-45deg); perspective: 100px;" - " width: 100px; height: 100px;" - "}" - "#target {" - " transform-style: preserve-3d; transform: rotateX(45deg);" - " background: lightblue;" - " width: 100px; height: 100px;" - "}" - "</style>" - "<div id='container'><div id='target'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #container { + transform-style: preserve-3d; + transform: rotateX(-45deg); perspective: 100px; + width: 100px; height: 100px; + } + #target { + transform-style: preserve-3d; transform: rotateX(45deg); + background: lightblue; + width: 100px; height: 100px; + } + </style> + <div id='container'><div id='target'></div></div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); LayoutBlock* target = ToLayoutBlock(GetLayoutObjectByElementId("target")); @@ -850,27 +871,28 @@ TEST_F(VisualRectMappingTest, PerspectivePlusScroll) { EnableCompositing(); - SetBodyInnerHTML( - "<style>" - "* { margin: 0; }" - "#container {" - " perspective: 100px;" - " width: 100px; height: 100px;" - " overflow: scroll;" - "}" - "#target {" - " transform: rotatex(45eg);" - " background: lightblue;" - " width: 100px; height: 100px;" - "}" - "#spacer {" - " width: 10px; height:2000px;" - "}" - "</style>" - "<div id='container'>" - " <div id='target'></div>" - " <div id='spacer'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #container { + perspective: 100px; + width: 100px; height: 100px; + overflow: scroll; + } + #target { + transform: rotatex(45eg); + background: lightblue; + width: 100px; height: 100px; + } + #spacer { + width: 10px; height:2000px; + } + </style> + <div id='container'> + <div id='target'></div> + <div id='spacer'></div> + </div> + )HTML"); LayoutBlock* container = ToLayoutBlock(GetLayoutObjectByElementId("container")); ToElement(container->GetNode())->scrollTo(0, 5);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc index bab0dda..0933041 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc
@@ -30,6 +30,10 @@ return {*position.AnchorNode(), 1}; } +// TODO(xiaochengh): Introduce predicates for comparing Position and +// NGOffsetMappingUnit, to reduce position-offset conversion and ad-hoc +// predicates below. + } // namespace NGOffsetMappingUnit::NGOffsetMappingUnit(NGOffsetMappingUnitType type, @@ -150,9 +154,12 @@ NGOffsetMapping::~NGOffsetMapping() = default; -const NGOffsetMappingUnit* NGOffsetMapping::GetMappingUnitForDOMOffset( - const Node& node, - unsigned offset) const { +const NGOffsetMappingUnit* NGOffsetMapping::GetMappingUnitForPosition( + const Position& position) const { + DCHECK(NGOffsetMapping::AcceptsPosition(position)); + const auto node_and_offset = ToNodeOffsetPair(position); + const Node& node = node_and_offset.first; + const unsigned offset = node_and_offset.second; unsigned range_start; unsigned range_end; std::tie(range_start, range_end) = ranges_.at(&node); @@ -200,71 +207,85 @@ Optional<unsigned> NGOffsetMapping::GetTextContentOffset( const Position& position) const { DCHECK(NGOffsetMapping::AcceptsPosition(position)) << position; - const auto node_offset_pair = ToNodeOffsetPair(position); - const NGOffsetMappingUnit* unit = GetMappingUnitForDOMOffset( - node_offset_pair.first, node_offset_pair.second); + const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position); if (!unit) return WTF::nullopt; - return unit->ConvertDOMOffsetToTextContent(node_offset_pair.second); + return unit->ConvertDOMOffsetToTextContent(ToNodeOffsetPair(position).second); } -Optional<unsigned> NGOffsetMapping::StartOfNextNonCollapsedCharacter( - const Node& node, - unsigned offset) const { - const NGOffsetMappingUnit* unit = GetMappingUnitForDOMOffset(node, offset); +Position NGOffsetMapping::StartOfNextNonCollapsedContent( + const Position& position) const { + DCHECK(NGOffsetMapping::AcceptsPosition(position)) << position; + const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position); if (!unit) - return WTF::nullopt; + return Position(); + const auto node_and_offset = ToNodeOffsetPair(position); + const Node& node = node_and_offset.first; + const unsigned offset = node_and_offset.second; while (unit != units_.end() && unit->GetOwner() == node) { if (unit->DOMEnd() > offset && - unit->GetType() != NGOffsetMappingUnitType::kCollapsed) - return std::max(offset, unit->DOMStart()); + unit->GetType() != NGOffsetMappingUnitType::kCollapsed) { + const unsigned result = std::max(offset, unit->DOMStart()); + return CreatePositionForOffsetMapping(node, result); + } ++unit; } - return WTF::nullopt; + return Position(); } -Optional<unsigned> NGOffsetMapping::EndOfLastNonCollapsedCharacter( - const Node& node, - unsigned offset) const { - const NGOffsetMappingUnit* unit = GetMappingUnitForDOMOffset(node, offset); +Position NGOffsetMapping::EndOfLastNonCollapsedContent( + const Position& position) const { + DCHECK(NGOffsetMapping::AcceptsPosition(position)) << position; + const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position); if (!unit) - return WTF::nullopt; + return Position(); + const auto node_and_offset = ToNodeOffsetPair(position); + const Node& node = node_and_offset.first; + const unsigned offset = node_and_offset.second; while (unit->GetOwner() == node) { if (unit->DOMStart() < offset && - unit->GetType() != NGOffsetMappingUnitType::kCollapsed) - return std::min(offset, unit->DOMEnd()); + unit->GetType() != NGOffsetMappingUnitType::kCollapsed) { + const unsigned result = std::min(offset, unit->DOMEnd()); + return CreatePositionForOffsetMapping(node, result); + } if (unit == units_.begin()) break; --unit; } - return WTF::nullopt; + return Position(); } -bool NGOffsetMapping::IsBeforeNonCollapsedCharacter(const Node& node, - unsigned offset) const { - const NGOffsetMappingUnit* unit = GetMappingUnitForDOMOffset(node, offset); +bool NGOffsetMapping::IsBeforeNonCollapsedContent( + const Position& position) const { + DCHECK(NGOffsetMapping::AcceptsPosition(position)); + const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position); + const unsigned offset = ToNodeOffsetPair(position).second; return unit && offset < unit->DOMEnd() && unit->GetType() != NGOffsetMappingUnitType::kCollapsed; } -bool NGOffsetMapping::IsAfterNonCollapsedCharacter(const Node& node, - unsigned offset) const { +bool NGOffsetMapping::IsAfterNonCollapsedContent( + const Position& position) const { + DCHECK(NGOffsetMapping::AcceptsPosition(position)); + const auto node_and_offset = ToNodeOffsetPair(position); + const Node& node = node_and_offset.first; + const unsigned offset = node_and_offset.second; if (!offset) return false; // In case we have one unit ending at |offset| and another starting at // |offset|, we need to find the former. Hence, search with |offset - 1|. - const NGOffsetMappingUnit* unit = - GetMappingUnitForDOMOffset(node, offset - 1); + const NGOffsetMappingUnit* unit = GetMappingUnitForPosition( + CreatePositionForOffsetMapping(node, offset - 1)); return unit && offset > unit->DOMStart() && unit->GetType() != NGOffsetMappingUnitType::kCollapsed; } -Optional<UChar> NGOffsetMapping::GetCharacterBefore(const Node& node, - unsigned offset) const { - Optional<unsigned> text_content_offset = - GetTextContentOffset(CreatePositionForOffsetMapping(node, offset)); +Optional<UChar> NGOffsetMapping::GetCharacterBefore( + const Position& position) const { + DCHECK(NGOffsetMapping::AcceptsPosition(position)); + Optional<unsigned> text_content_offset = GetTextContentOffset(position); if (!text_content_offset || !*text_content_offset) return WTF::nullopt; return text_[*text_content_offset - 1];
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h index 3f249c7..41d7343 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h
@@ -123,10 +123,9 @@ // mapping object easier when we are holding LayoutObject instead of Node. static const NGOffsetMapping* GetFor(const LayoutObject*); - // Returns the NGOffsetMappingUnit that contains the given offset in the DOM - // node. If there are multiple qualifying units, returns the last one. - const NGOffsetMappingUnit* GetMappingUnitForDOMOffset(const Node&, - unsigned) const; + // Returns the NGOffsetMappingUnit that contains the given position. + // If there are multiple qualifying units, returns the last one. + const NGOffsetMappingUnit* GetMappingUnitForPosition(const Position&) const; // Returns all NGOffsetMappingUnits whose DOM ranges has non-empty (but // possibly collapsed) intersections with the passed in DOM offset range. @@ -138,29 +137,21 @@ // Returns nullopt when the position is not laid out in this block. Optional<unsigned> GetTextContentOffset(const Position&) const; - // Starting from the given DOM offset in the node, finds the first non- - // collapsed character and returns the offset before it; Or returns nullopt if - // such a character does not exist. - Optional<unsigned> StartOfNextNonCollapsedCharacter(const Node&, - unsigned offset) const; + // Starting from the given position, searches for non-collapsed content in + // the same node in forward/backward direction and returns the position + // before/after it; Returns null if there is no more non-collapsed content in + // the same node. + Position StartOfNextNonCollapsedContent(const Position&) const; + Position EndOfLastNonCollapsedContent(const Position&) const; - // Starting from the given DOM offset in the node, reversely finds the first - // non-collapsed character and returns the offset after it; Or returns nullopt - // if such a character does not exist. - Optional<unsigned> EndOfLastNonCollapsedCharacter(const Node&, - unsigned offset) const; + // Returns true if the position is right before/after non-collapsed content. + // Note that false is returned if the position is already at node end/start. + bool IsBeforeNonCollapsedContent(const Position&) const; + bool IsAfterNonCollapsedContent(const Position&) const; - // Returns true if the offset is right before a non-collapsed character. If - // the offset is at the end of the node, returns false. - bool IsBeforeNonCollapsedCharacter(const Node&, unsigned offset) const; - - // Returns true if the offset is right after a non-collapsed character. If the - // offset is at the beginning of the node, returns false. - bool IsAfterNonCollapsedCharacter(const Node&, unsigned offset) const; - - // Maps the given DOM offset to text content, and then returns the text + // Maps the given position to text content, and then returns the text // content character before the offset. Returns nullopt if it does not exist. - Optional<UChar> GetCharacterBefore(const Node&, unsigned offset) const; + Optional<UChar> GetCharacterBefore(const Position&) const; // ------ Mapping APIs from text content to DOM ------
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc index 4fde841f..fc33eff 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -46,31 +46,29 @@ return ToLayoutText(parent->firstChild()->GetLayoutObject()); } - const NGOffsetMappingUnit* GetUnitForDOMOffset(const Node& node, - unsigned offset) const { - return GetOffsetMapping().GetMappingUnitForDOMOffset(node, offset); + const NGOffsetMappingUnit* GetUnitForPosition( + const Position& position) const { + return GetOffsetMapping().GetMappingUnitForPosition(position); } Optional<unsigned> GetTextContentOffset(const Position& position) const { return GetOffsetMapping().GetTextContentOffset(position); } - Optional<unsigned> StartOfNextNonCollapsedCharacter(const Node& node, - unsigned offset) const { - return GetOffsetMapping().StartOfNextNonCollapsedCharacter(node, offset); + Position StartOfNextNonCollapsedContent(const Position& position) const { + return GetOffsetMapping().StartOfNextNonCollapsedContent(position); } - Optional<unsigned> EndOfLastNonCollapsedCharacter(const Node& node, - unsigned offset) const { - return GetOffsetMapping().EndOfLastNonCollapsedCharacter(node, offset); + Position EndOfLastNonCollapsedContent(const Position& position) const { + return GetOffsetMapping().EndOfLastNonCollapsedContent(position); } - bool IsBeforeNonCollapsedCharacter(const Node& node, unsigned offset) const { - return GetOffsetMapping().IsBeforeNonCollapsedCharacter(node, offset); + bool IsBeforeNonCollapsedContent(const Position& position) const { + return GetOffsetMapping().IsBeforeNonCollapsedContent(position); } - bool IsAfterNonCollapsedCharacter(const Node& node, unsigned offset) const { - return GetOffsetMapping().IsAfterNonCollapsedCharacter(node, offset); + bool IsAfterNonCollapsedContent(const Position& position) const { + return GetOffsetMapping().IsAfterNonCollapsedContent(position); } Position GetFirstPosition(unsigned offset) const { @@ -122,10 +120,10 @@ ASSERT_EQ(1u, result.GetRanges().size()); TEST_RANGE(result.GetRanges(), foo_node, 0u, 1u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 2)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 3)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 2))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 3))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(foo_node, 1))); @@ -142,27 +140,33 @@ EXPECT_EQ(Position(foo_node, 2), GetLastPosition(2)); EXPECT_EQ(Position(foo_node, 3), GetLastPosition(3)); - EXPECT_EQ(0u, *StartOfNextNonCollapsedCharacter(*foo_node, 0)); - EXPECT_EQ(1u, *StartOfNextNonCollapsedCharacter(*foo_node, 1)); - EXPECT_EQ(2u, *StartOfNextNonCollapsedCharacter(*foo_node, 2)); - EXPECT_FALSE(StartOfNextNonCollapsedCharacter(*foo_node, 3)); + EXPECT_EQ(Position(foo_node, 0), + StartOfNextNonCollapsedContent(Position(foo_node, 0))); + EXPECT_EQ(Position(foo_node, 1), + StartOfNextNonCollapsedContent(Position(foo_node, 1))); + EXPECT_EQ(Position(foo_node, 2), + StartOfNextNonCollapsedContent(Position(foo_node, 2))); + EXPECT_TRUE(StartOfNextNonCollapsedContent(Position(foo_node, 3)).IsNull()); - EXPECT_FALSE(EndOfLastNonCollapsedCharacter(*foo_node, 0)); - EXPECT_EQ(1u, *EndOfLastNonCollapsedCharacter(*foo_node, 1)); - EXPECT_EQ(2u, *EndOfLastNonCollapsedCharacter(*foo_node, 2)); - EXPECT_EQ(3u, *EndOfLastNonCollapsedCharacter(*foo_node, 3)); + EXPECT_TRUE(EndOfLastNonCollapsedContent(Position(foo_node, 0)).IsNull()); + EXPECT_EQ(Position(foo_node, 1), + EndOfLastNonCollapsedContent(Position(foo_node, 1))); + EXPECT_EQ(Position(foo_node, 2), + EndOfLastNonCollapsedContent(Position(foo_node, 2))); + EXPECT_EQ(Position(foo_node, 3), + EndOfLastNonCollapsedContent(Position(foo_node, 3))); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*foo_node, 0)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*foo_node, 1)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*foo_node, 2)); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(foo_node, 0))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(foo_node, 1))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(foo_node, 2))); EXPECT_FALSE( - IsBeforeNonCollapsedCharacter(*foo_node, 3)); // false at node end + IsBeforeNonCollapsedContent(Position(foo_node, 3))); // false at node end // false at node start - EXPECT_FALSE(IsAfterNonCollapsedCharacter(*foo_node, 0)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 1)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 2)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 3)); + EXPECT_FALSE(IsAfterNonCollapsedContent(Position(foo_node, 0))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 1))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 2))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 3))); } TEST_F(NGOffsetMappingTest, TwoTextNodes) { @@ -185,14 +189,14 @@ TEST_RANGE(result.GetRanges(), foo_node, 0u, 1u); TEST_RANGE(result.GetRanges(), bar_node, 1u, 2u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 2)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 3)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*bar_node, 0)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*bar_node, 1)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*bar_node, 2)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*bar_node, 3)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 2))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 3))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(bar_node, 0))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(bar_node, 1))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(bar_node, 2))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(bar_node, 3))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(foo_node, 1))); @@ -206,29 +210,29 @@ EXPECT_EQ(Position(foo_node, 3), GetFirstPosition(3)); EXPECT_EQ(Position(bar_node, 0), GetLastPosition(3)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*foo_node, 0)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*foo_node, 1)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*foo_node, 2)); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(foo_node, 0))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(foo_node, 1))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(foo_node, 2))); EXPECT_FALSE( - IsBeforeNonCollapsedCharacter(*foo_node, 3)); // false at node end + IsBeforeNonCollapsedContent(Position(foo_node, 3))); // false at node end - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*bar_node, 0)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*bar_node, 1)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*bar_node, 2)); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(bar_node, 0))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(bar_node, 1))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(bar_node, 2))); EXPECT_FALSE( - IsBeforeNonCollapsedCharacter(*bar_node, 3)); // false at node end + IsBeforeNonCollapsedContent(Position(bar_node, 3))); // false at node end // false at node start - EXPECT_FALSE(IsAfterNonCollapsedCharacter(*foo_node, 0)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 1)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 2)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 3)); + EXPECT_FALSE(IsAfterNonCollapsedContent(Position(foo_node, 0))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 1))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 2))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 3))); // false at node start - EXPECT_FALSE(IsAfterNonCollapsedCharacter(*bar_node, 0)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*bar_node, 1)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*bar_node, 2)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*bar_node, 3)); + EXPECT_FALSE(IsAfterNonCollapsedContent(Position(bar_node, 0))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(bar_node, 1))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(bar_node, 2))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(bar_node, 3))); } TEST_F(NGOffsetMappingTest, BRBetweenTextNodes) { @@ -256,17 +260,18 @@ TEST_RANGE(result.GetRanges(), br_node, 1u, 2u); TEST_RANGE(result.GetRanges(), bar_node, 2u, 3u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 2)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 3)); - - // TODO(xiaochengh): Add test cases for BR@BeforeNode and BR@AfterNode - - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 0)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 1)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 2)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 3)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 2))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 3))); + EXPECT_EQ(&result.GetUnits()[1], + GetUnitForPosition(Position::BeforeNode(*br_node))); + EXPECT_EQ(&result.GetUnits()[1], + GetUnitForPosition(Position::AfterNode(*br_node))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 0))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 1))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 2))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 3))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(foo_node, 1))); @@ -303,15 +308,15 @@ ASSERT_EQ(1u, result.GetRanges().size()); TEST_RANGE(result.GetRanges(), node, 0u, 3u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*node, 2)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*node, 3)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*node, 4)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*node, 5)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*node, 6)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*node, 7)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*node, 8)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(node, 2))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(node, 3))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(node, 4))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(node, 5))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(node, 6))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(node, 7))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(node, 8))); EXPECT_EQ(0u, *GetTextContentOffset(Position(node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(node, 1))); @@ -326,33 +331,36 @@ EXPECT_EQ(Position(node, 4), GetFirstPosition(4)); EXPECT_EQ(Position(node, 5), GetLastPosition(4)); - EXPECT_EQ(3u, *StartOfNextNonCollapsedCharacter(*node, 3)); - EXPECT_EQ(5u, *StartOfNextNonCollapsedCharacter(*node, 4)); - EXPECT_EQ(5u, *StartOfNextNonCollapsedCharacter(*node, 5)); + EXPECT_EQ(Position(node, 3), + StartOfNextNonCollapsedContent(Position(node, 3))); + EXPECT_EQ(Position(node, 5), + StartOfNextNonCollapsedContent(Position(node, 4))); + EXPECT_EQ(Position(node, 5), + StartOfNextNonCollapsedContent(Position(node, 5))); - EXPECT_EQ(3u, *EndOfLastNonCollapsedCharacter(*node, 3)); - EXPECT_EQ(4u, *EndOfLastNonCollapsedCharacter(*node, 4)); - EXPECT_EQ(4u, *EndOfLastNonCollapsedCharacter(*node, 5)); + EXPECT_EQ(Position(node, 3), EndOfLastNonCollapsedContent(Position(node, 3))); + EXPECT_EQ(Position(node, 4), EndOfLastNonCollapsedContent(Position(node, 4))); + EXPECT_EQ(Position(node, 4), EndOfLastNonCollapsedContent(Position(node, 5))); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 0)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 1)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 2)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 3)); - EXPECT_FALSE(IsBeforeNonCollapsedCharacter(*node, 4)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 5)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 6)); - EXPECT_TRUE(IsBeforeNonCollapsedCharacter(*node, 7)); - EXPECT_FALSE(IsBeforeNonCollapsedCharacter(*node, 8)); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 0))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 1))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 2))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 3))); + EXPECT_FALSE(IsBeforeNonCollapsedContent(Position(node, 4))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 5))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 6))); + EXPECT_TRUE(IsBeforeNonCollapsedContent(Position(node, 7))); + EXPECT_FALSE(IsBeforeNonCollapsedContent(Position(node, 8))); - EXPECT_FALSE(IsAfterNonCollapsedCharacter(*node, 0)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 1)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 2)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 3)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 4)); - EXPECT_FALSE(IsAfterNonCollapsedCharacter(*node, 5)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 6)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 7)); - EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 8)); + EXPECT_FALSE(IsAfterNonCollapsedContent(Position(node, 0))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 1))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 2))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 3))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 4))); + EXPECT_FALSE(IsAfterNonCollapsedContent(Position(node, 5))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 6))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 7))); + EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 8))); } TEST_F(NGOffsetMappingTest, FullyCollapsedWhiteSpaceNode) { @@ -385,17 +393,17 @@ TEST_RANGE(result.GetRanges(), space_node, 1u, 2u); TEST_RANGE(result.GetRanges(), bar_node, 2u, 3u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 2)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 3)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 4)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*space_node, 0)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*space_node, 1)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 0)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 1)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 2)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 3)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 2))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 3))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 4))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(space_node, 0))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(space_node, 1))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 0))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 1))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 2))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 3))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(foo_node, 1))); @@ -412,8 +420,9 @@ EXPECT_EQ(Position(foo_node, 4), GetFirstPosition(4)); EXPECT_EQ(Position(bar_node, 0), GetLastPosition(4)); - EXPECT_FALSE(EndOfLastNonCollapsedCharacter(*space_node, 1u)); - EXPECT_FALSE(StartOfNextNonCollapsedCharacter(*space_node, 0u)); + EXPECT_TRUE(EndOfLastNonCollapsedContent(Position(space_node, 1u)).IsNull()); + EXPECT_TRUE( + StartOfNextNonCollapsedContent(Position(space_node, 0u)).IsNull()); } TEST_F(NGOffsetMappingTest, ReplacedElement) { @@ -439,22 +448,20 @@ TEST_RANGE(result.GetRanges(), img_node, 1u, 2u); TEST_RANGE(result.GetRanges(), bar_node, 2u, 3u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 2)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 3)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 4)); - - // TODO(xiaochengh): Pass positions IMG@BeforeNode and IMG@AfterNode instead - // of (node, offset) pairs. - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*img_node, 0)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*img_node, 1)); - - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 0)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 1)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 2)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 3)); - EXPECT_EQ(&result.GetUnits()[2], GetUnitForDOMOffset(*bar_node, 4)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 2))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 3))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 4))); + EXPECT_EQ(&result.GetUnits()[1], + GetUnitForPosition(Position::BeforeNode(*img_node))); + EXPECT_EQ(&result.GetUnits()[1], + GetUnitForPosition(Position::AfterNode(*img_node))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 0))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 1))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 2))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 3))); + EXPECT_EQ(&result.GetUnits()[2], GetUnitForPosition(Position(bar_node, 4))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(foo_node, 1))); @@ -490,9 +497,9 @@ ASSERT_EQ(1u, result.GetRanges().size()); TEST_RANGE(result.GetRanges(), foo_node, 0u, 1u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 2)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 2))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(1u, *GetTextContentOffset(Position(foo_node, 1))); @@ -519,11 +526,11 @@ ASSERT_EQ(1u, result.GetRanges().size()); TEST_RANGE(result.GetRanges(), foo_node, 0u, 2u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*foo_node, 1)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*foo_node, 2)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*foo_node, 3)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*foo_node, 4)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(foo_node, 2))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(foo_node, 3))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(foo_node, 4))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 0))); EXPECT_EQ(0u, *GetTextContentOffset(Position(foo_node, 1))); @@ -552,10 +559,10 @@ ASSERT_EQ(1u, result.GetRanges().size()); TEST_RANGE(result.GetRanges(), text_node, 0u, 2u); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*text_node, 0)); - EXPECT_EQ(&result.GetUnits()[0], GetUnitForDOMOffset(*text_node, 1)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*text_node, 2)); - EXPECT_EQ(&result.GetUnits()[1], GetUnitForDOMOffset(*text_node, 3)); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(text_node, 0))); + EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(text_node, 1))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(text_node, 2))); + EXPECT_EQ(&result.GetUnits()[1], GetUnitForPosition(Position(text_node, 3))); EXPECT_EQ(0u, *GetTextContentOffset(Position(text_node, 0))); EXPECT_EQ(0u, *GetTextContentOffset(Position(text_node, 1))); @@ -602,14 +609,18 @@ ASSERT_EQ(1u, remaining_text_result.GetRanges().size()); TEST_RANGE(remaining_text_result.GetRanges(), text_node, 0u, 1u); - EXPECT_EQ(&first_letter_result.GetUnits()[0], - first_letter_result.GetMappingUnitForDOMOffset(*text_node, 0)); - EXPECT_EQ(&remaining_text_result.GetUnits()[0], - remaining_text_result.GetMappingUnitForDOMOffset(*text_node, 1)); - EXPECT_EQ(&remaining_text_result.GetUnits()[0], - remaining_text_result.GetMappingUnitForDOMOffset(*text_node, 2)); - EXPECT_EQ(&remaining_text_result.GetUnits()[0], - remaining_text_result.GetMappingUnitForDOMOffset(*text_node, 3)); + EXPECT_EQ( + &first_letter_result.GetUnits()[0], + first_letter_result.GetMappingUnitForPosition(Position(text_node, 0))); + EXPECT_EQ( + &remaining_text_result.GetUnits()[0], + remaining_text_result.GetMappingUnitForPosition(Position(text_node, 1))); + EXPECT_EQ( + &remaining_text_result.GetUnits()[0], + remaining_text_result.GetMappingUnitForPosition(Position(text_node, 2))); + EXPECT_EQ( + &remaining_text_result.GetUnits()[0], + remaining_text_result.GetMappingUnitForPosition(Position(text_node, 3))); EXPECT_EQ(0u, *first_letter_result.GetTextContentOffset(Position(text_node, 0))); @@ -631,8 +642,8 @@ Element* div = GetDocument().getElementById("t"); const Node* text_node = div->firstChild(); - EXPECT_FALSE(EndOfLastNonCollapsedCharacter(*text_node, 1u)); - EXPECT_FALSE(StartOfNextNonCollapsedCharacter(*text_node, 0u)); + EXPECT_TRUE(EndOfLastNonCollapsedContent(Position(text_node, 1u)).IsNull()); + EXPECT_TRUE(StartOfNextNonCollapsedContent(Position(text_node, 0u)).IsNull()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGForeignObjectTest.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGForeignObjectTest.cpp index 33fc9cf29..1a6081a 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGForeignObjectTest.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGForeignObjectTest.cpp
@@ -23,14 +23,15 @@ }; TEST_F(LayoutSVGForeignObjectTest, DivInForeignObject) { - SetBodyInnerHTML( - "<style>body { margin: 0 }</style>" - "<svg id='svg' style='width: 500px; height: 400px'>" - " <foreignObject id='foreign' x='100' y='100' width='300' height='200'>" - " <div id='div' style='margin: 50px; width: 200px; height: 100px'>" - " </div>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0 }</style> + <svg id='svg' style='width: 500px; height: 400px'> + <foreignObject id='foreign' x='100' y='100' width='300' height='200'> + <div id='div' style='margin: 50px; width: 200px; height: 100px'> + </div> + </foreignObject> + </svg> + )HTML"); const auto& svg = *GetDocument().getElementById("svg"); const auto& foreign_object = *GetLayoutObjectByElementId("foreign"); @@ -75,20 +76,22 @@ } TEST_F(LayoutSVGForeignObjectTest, IframeInForeignObject) { - SetBodyInnerHTML( - "<style>body { margin: 0 }</style>" - "<svg id='svg' style='width: 500px; height: 450px'>" - " <foreignObject id='foreign' x='100' y='100' width='300' height='250'>" - " <iframe style='border: none; margin: 30px;" - " width: 240px; height: 190px'></iframe>" - " </foreignObject>" - "</svg>"); - SetChildFrameHTML( - "<style>" - " body { margin: 0 }" - " * { background: white; }" - "</style>" - "<div id='div' style='margin: 70px; width: 100px; height: 50px'></div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0 }</style> + <svg id='svg' style='width: 500px; height: 450px'> + <foreignObject id='foreign' x='100' y='100' width='300' height='250'> + <iframe style='border: none; margin: 30px; + width: 240px; height: 190px'></iframe> + </foreignObject> + </svg> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + body { margin: 0 } + * { background: white; } + </style> + <div id='div' style='margin: 70px; width: 100px; height: 50px'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); const auto& svg = *GetDocument().getElementById("svg");
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRootTest.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRootTest.cpp index 4d2f5c0..cebbdfc 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRootTest.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRootTest.cpp
@@ -14,11 +14,12 @@ using LayoutSVGRootTest = RenderingTest; TEST_F(LayoutSVGRootTest, VisualRectMappingWithoutViewportClipWithBorder) { - SetBodyInnerHTML( - "<svg id='root' style='border: 10px solid red; width: 200px; height: " - "100px; overflow: visible' viewBox='0 0 200 100'>" - " <rect id='rect' x='80' y='80' width='100' height='100'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='root' style='border: 10px solid red; width: 200px; height: + 100px; overflow: visible' viewBox='0 0 200 100'> + <rect id='rect' x='80' y='80' width='100' height='100'/> + </svg> + )HTML"); const LayoutSVGRoot& root = *ToLayoutSVGRoot(GetLayoutObjectByElementId("root")); @@ -41,11 +42,12 @@ } TEST_F(LayoutSVGRootTest, VisualRectMappingWithViewportClipAndBorder) { - SetBodyInnerHTML( - "<svg id='root' style='border: 10px solid red; width: 200px; height: " - "100px; overflow: hidden' viewBox='0 0 200 100'>" - " <rect id='rect' x='80' y='80' width='100' height='100'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='root' style='border: 10px solid red; width: 200px; height: + 100px; overflow: hidden' viewBox='0 0 200 100'> + <rect id='rect' x='80' y='80' width='100' height='100'/> + </svg> + )HTML"); const LayoutSVGRoot& root = *ToLayoutSVGRoot(GetLayoutObjectByElementId("root")); @@ -70,11 +72,12 @@ } TEST_F(LayoutSVGRootTest, VisualRectMappingWithViewportClipWithoutBorder) { - SetBodyInnerHTML( - "<svg id='root' style='width: 200px; height: 100px; overflow: hidden' " - "viewBox='0 0 200 100'>" - " <rect id='rect' x='80' y='80' width='100' height='100'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='root' style='width: 200px; height: 100px; overflow: hidden' + viewBox='0 0 200 100'> + <rect id='rect' x='80' y='80' width='100' height='100'/> + </svg> + )HTML"); const LayoutSVGRoot& root = *ToLayoutSVGRoot(GetLayoutObjectByElementId("root"));
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp index 85071a9..74d1da6 100644 --- a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp +++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
@@ -209,20 +209,6 @@ return image_.get(); } -bool ImageResourceContent::UsesImageContainerSize() const { - if (image_) - return image_->UsesContainerSize(); - - return false; -} - -bool ImageResourceContent::ImageHasRelativeSize() const { - if (image_) - return image_->HasRelativeSize(); - - return false; -} - IntSize ImageResourceContent::IntrinsicSize( RespectImageOrientationEnum should_respect_image_orientation) { if (!image_)
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h index d5e6650..f33b6aa 100644 --- a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h +++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h
@@ -60,8 +60,6 @@ blink::Image* GetImage(); bool HasImage() const { return image_.get(); } - bool UsesImageContainerSize() const; - bool ImageHasRelativeSize() const; // The device pixel ratio we got from the server for this image, or 1.0. float DevicePixelRatioHeaderValue() const; bool HasDevicePixelRatioHeaderValue() const;
diff --git a/third_party/WebKit/Source/core/page/DragControllerTest.cpp b/third_party/WebKit/Source/core/page/DragControllerTest.cpp index 6a771d6..82bdd03ab 100644 --- a/third_party/WebKit/Source/core/page/DragControllerTest.cpp +++ b/third_party/WebKit/Source/core/page/DragControllerTest.cpp
@@ -137,23 +137,24 @@ } TEST_P(DragControllerTest, DragImageForSelectionClipsToViewport) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " html, body { height: 2000px; }" - " div {" - " width: 20px;" - " height: 1000px;" - " font-size: 30px;" - " overflow: hidden;" - " margin-top: 2px;" - " }" - "</style>" - "<div>" - " a<br>b<br>c<br>d<br>e<br>f<br>g<br>h<br>i<br>j<br>k<br>l<br>m<br>n<br>" - " a<br>b<br>c<br>d<br>e<br>f<br>g<br>h<br>i<br>j<br>k<br>l<br>m<br>n<br>" - " a<br>b<br>c<br>d<br>e<br>f<br>g<br>h<br>i<br>j<br>k<br>l<br>m<br>n<br>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + html, body { height: 2000px; } + div { + width: 20px; + height: 1000px; + font-size: 30px; + overflow: hidden; + margin-top: 2px; + } + </style> + <div> + a<br>b<br>c<br>d<br>e<br>f<br>g<br>h<br>i<br>j<br>k<br>l<br>m<br>n<br> + a<br>b<br>c<br>d<br>e<br>f<br>g<br>h<br>i<br>j<br>k<br>l<br>m<br>n<br> + a<br>b<br>c<br>d<br>e<br>f<br>g<br>h<br>i<br>j<br>k<br>l<br>m<br>n<br> + </div> + )HTML"); const int page_scale_factor = 2; GetFrame().GetPage()->SetPageScaleFactor(page_scale_factor); GetFrame().Selection().SelectAll(); @@ -205,32 +206,34 @@ } TEST_P(DragControllerTest, DragImageForSelectionClipsChildFrameToViewport) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " html, body { height: 2000px; }" - " iframe {" - " margin-top: 200px;" - " border: none;" - " width: 50px;" - " height: 50px;" - " }" - "</style>" - "<iframe></iframe>"); - SetChildFrameHTML( - "<style>" - " * { margin: 0; } " - " html, body { height: 2000px; }" - " div {" - " width: 30px;" - " height: 20px;" - " font-size: 30px;" - " overflow: hidden;" - " margin-top: 5px;" - " margin-bottom: 500px;" - " }" - "</style>" - "<div>abcdefg</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + html, body { height: 2000px; } + iframe { + margin-top: 200px; + border: none; + width: 50px; + height: 50px; + } + </style> + <iframe></iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + * { margin: 0; } + html, body { height: 2000px; } + div { + width: 30px; + height: 20px; + font-size: 30px; + overflow: hidden; + margin-top: 5px; + margin-bottom: 500px; + } + </style> + <div>abcdefg</div> + )HTML"); UpdateAllLifecyclePhases(); auto& child_frame = *ToLocalFrame(GetFrame().Tree().FirstChild()); child_frame.Selection().SelectAll(); @@ -281,32 +284,34 @@ TEST_P(DragControllerTest, DragImageForSelectionClipsChildFrameToViewportWithPageScaleFactor) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " html, body { height: 2000px; }" - " iframe {" - " margin-top: 200px;" - " border: none;" - " width: 50px;" - " height: 50px;" - " }" - "</style>" - "<iframe></iframe>"); - SetChildFrameHTML( - "<style>" - " * { margin: 0; } " - " html, body { height: 2000px; }" - " div {" - " width: 30px;" - " height: 20px;" - " font-size: 30px;" - " overflow: hidden;" - " margin-top: 5px;" - " margin-bottom: 500px;" - " }" - "</style>" - "<div>abcdefg</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + html, body { height: 2000px; } + iframe { + margin-top: 200px; + border: none; + width: 50px; + height: 50px; + } + </style> + <iframe></iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + * { margin: 0; } + html, body { height: 2000px; } + div { + width: 30px; + height: 20px; + font-size: 30px; + overflow: hidden; + margin-top: 5px; + margin-bottom: 500px; + } + </style> + <div>abcdefg</div> + )HTML"); const int page_scale_factor = 2; GetFrame().GetPage()->SetPageScaleFactor(page_scale_factor); UpdateAllLifecyclePhases(); @@ -362,18 +367,19 @@ } TEST_P(DragControllerTest, DragImageOffsetWithPageScaleFactor) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " div {" - " width: 50px;" - " height: 40px;" - " font-size: 30px;" - " overflow: hidden;" - " margin-top: 2px;" - " }" - "</style>" - "<div id='drag'>abcdefg<br>abcdefg<br>abcdefg</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + div { + width: 50px; + height: 40px; + font-size: 30px; + overflow: hidden; + margin-top: 2px; + } + </style> + <div id='drag'>abcdefg<br>abcdefg<br>abcdefg</div> + )HTML"); const int page_scale_factor = 2; GetFrame().GetPage()->SetPageScaleFactor(page_scale_factor); GetFrame().Selection().SelectAll(); @@ -403,18 +409,19 @@ } TEST_P(DragControllerTest, DragLinkWithPageScaleFactor) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; } " - " a {" - " width: 50px;" - " height: 40px;" - " font-size: 30px;" - " margin-top: 2px;" - " display: block;" - " }" - "</style>" - "<a id='drag' href='https://foobarbaz.com'>foobarbaz</a>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + a { + width: 50px; + height: 40px; + font-size: 30px; + margin-top: 2px; + display: block; + } + </style> + <a id='drag' href='https://foobarbaz.com'>foobarbaz</a> + )HTML"); const int page_scale_factor = 2; GetFrame().GetPage()->SetPageScaleFactor(page_scale_factor); GetFrame().Selection().SelectAll();
diff --git a/third_party/WebKit/Source/core/page/PrintContextTest.cpp b/third_party/WebKit/Source/core/page/PrintContextTest.cpp index f60bfdc9..99608b4e 100644 --- a/third_party/WebKit/Source/core/page/PrintContextTest.cpp +++ b/third_party/WebKit/Source/core/page/PrintContextTest.cpp
@@ -229,13 +229,14 @@ TEST_F(PrintContextTest, LinkTargetSvg) { MockPageContextCanvas canvas; - SetBodyInnerHTML( - "<svg width='100' height='100'>" - "<a xlink:href='http://www.w3.org'><rect x='20' y='20' width='50' " - "height='50'/></a>" - "<text x='10' y='90'><a " - "xlink:href='http://www.google.com'><tspan>google</tspan></a></text>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg width='100' height='100'> + <a xlink:href='http://www.w3.org'><rect x='20' y='20' width='50' + height='50'/></a> + <text x='10' y='90'><a + xlink:href='http://www.google.com'><tspan>google</tspan></a></text> + </svg> + )HTML"); PrintSinglePage(canvas); const Vector<MockPageContextCanvas::Operation>& operations = @@ -305,11 +306,12 @@ TEST_F(PrintContextFrameTest, WithSubframe) { GetDocument().SetBaseURLOverride(KURL("http://a.com/")); - SetBodyInnerHTML( - "<style>::-webkit-scrollbar { display: none }</style>" - "<iframe src='http://b.com/' width='500' height='500'" - " style='border-width: 5px; margin: 5px; position: absolute; top: 90px; " - "left: 90px'></iframe>"); + SetBodyInnerHTML(R"HTML( + <style>::-webkit-scrollbar { display: none }</style> + <iframe src='http://b.com/' width='500' height='500' + style='border-width: 5px; margin: 5px; position: absolute; top: 90px; + left: 90px'></iframe> + )HTML"); SetChildFrameHTML( AbsoluteBlockHtmlForLink(50, 60, 70, 80, "#fragment") + AbsoluteBlockHtmlForLink(150, 160, 170, 180, "http://www.google.com") + @@ -330,11 +332,12 @@ TEST_F(PrintContextFrameTest, WithScrolledSubframe) { GetDocument().SetBaseURLOverride(KURL("http://a.com/")); - SetBodyInnerHTML( - "<style>::-webkit-scrollbar { display: none }</style>" - "<iframe src='http://b.com/' width='500' height='500'" - " style='border-width: 5px; margin: 5px; position: absolute; top: 90px; " - "left: 90px'></iframe>"); + SetBodyInnerHTML(R"HTML( + <style>::-webkit-scrollbar { display: none }</style> + <iframe src='http://b.com/' width='500' height='500' + style='border-width: 5px; margin: 5px; position: absolute; top: 90px; + left: 90px'></iframe> + )HTML"); SetChildFrameHTML( AbsoluteBlockHtmlForLink(10, 10, 20, 20, "http://invisible.com") + AbsoluteBlockHtmlForLink(50, 60, 70, 80, "http://partly.visible.com") +
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollMetricsTest.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollMetricsTest.cpp index e428cae5..7d64dd3 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollMetricsTest.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollMetricsTest.cpp
@@ -123,15 +123,16 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, TouchAndWheelGeneralTest) { - SetUpHtml( - "<style>" - " .box { overflow:scroll; width: 100px; height: 100px; }" - " .translucent { opacity: 0.5; }" - " .spacer { height: 1000px; }" - "</style>" - "<div id='box' class='translucent box'>" - " <div class='spacer'></div>" - "</div>"); + SetUpHtml(R"HTML( + <style> + .box { overflow:scroll; width: 100px; height: 100px; } + .translucent { opacity: 0.5; } + .spacer { height: 1000px; } + </style> + <div id='box' class='translucent box'> + <div class='spacer'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -157,16 +158,17 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, CompositedScrollableAreaTest) { - SetUpHtml( - "<style>" - " .box { overflow:scroll; width: 100px; height: 100px; }" - " .translucent { opacity: 0.5; }" - " .composited { will-change: transform; }" - " .spacer { height: 1000px; }" - "</style>" - "<div id='box' class='translucent box'>" - " <div class='spacer'></div>" - "</div>"); + SetUpHtml(R"HTML( + <style> + .box { overflow:scroll; width: 100px; height: 100px; } + .translucent { opacity: 0.5; } + .composited { will-change: transform; } + .spacer { height: 1000px; } + </style> + <div id='box' class='translucent box'> + <div class='spacer'></div> + </div> + )HTML"); WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); GetDocument().View()->SetParentVisible(true); @@ -194,15 +196,16 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, NotScrollableAreaTest) { - SetUpHtml( - "<style>.box { overflow:scroll; width: 100px; height: 100px; }" - " .translucent { opacity: 0.5; }" - " .hidden { overflow: hidden; }" - " .spacer { height: 1000px; }" - "</style>" - "<div id='box' class='translucent box'>" - " <div class='spacer'></div>" - "</div>"); + SetUpHtml(R"HTML( + <style>.box { overflow:scroll; width: 100px; height: 100px; } + .translucent { opacity: 0.5; } + .hidden { overflow: hidden; } + .spacer { height: 1000px; } + </style> + <div id='box' class='translucent box'> + <div class='spacer'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -223,25 +226,26 @@ } TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, NestedScrollersTest) { - SetUpHtml( - "<style>" - " .container { overflow:scroll; width: 200px; height: 200px; }" - " .box { overflow:scroll; width: 100px; height: 100px; }" - " .translucent { opacity: 0.5; }" - " .transform { transform: scale(0.8); }" - " .with-border-radius { border: 5px solid; border-radius: 5px; }" - " .spacer { height: 1000px; }" - " .composited { will-change: transform; }" - "</style>" - "<div id='container' class='container with-border-radius'>" - " <div class='translucent box'>" - " <div id='inner' class='composited transform box'>" - " <div class='spacer'></div>" - " </div>" - " <div class='spacer'></div>" - " </div>" - " <div class='spacer'></div>" - "</div>"); + SetUpHtml(R"HTML( + <style> + .container { overflow:scroll; width: 200px; height: 200px; } + .box { overflow:scroll; width: 100px; height: 100px; } + .translucent { opacity: 0.5; } + .transform { transform: scale(0.8); } + .with-border-radius { border: 5px solid; border-radius: 5px; } + .spacer { height: 1000px; } + .composited { will-change: transform; } + </style> + <div id='container' class='container with-border-radius'> + <div class='translucent box'> + <div id='inner' class='composited transform box'> + <div class='spacer'></div> + </div> + <div class='spacer'></div> + </div> + <div class='spacer'></div> + </div> + )HTML"); WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); GetDocument().View()->SetParentVisible(true);
diff --git a/third_party/WebKit/Source/core/page/scrolling/SmoothScrollTest.cpp b/third_party/WebKit/Source/core/page/scrolling/SmoothScrollTest.cpp index 073601b2..3fa4fb6 100644 --- a/third_party/WebKit/Source/core/page/scrolling/SmoothScrollTest.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/SmoothScrollTest.cpp
@@ -77,12 +77,13 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='space' style='height: 1000px'></div>" - "<div id='container' style='height: 600px; overflow: scroll'>" - " <div id='space1' style='height: 1000px'></div>" - " <div id='content' style='height: 1000px'></div>" - "</div>"); + request.Complete(R"HTML( + <div id='space' style='height: 1000px'></div> + <div id='container' style='height: 600px; overflow: scroll'> + <div id='space1' style='height: 1000px'></div> + <div id='content' style='height: 1000px'></div> + </div> + )HTML"); Element* container = GetDocument().getElementById("container"); Element* content = GetDocument().getElementById("content"); @@ -124,15 +125,16 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='container2' style='height: 1000px; overflow: scroll'>" - " <div id='space2' style='height: 1200px'></div>" - " <div id='content2' style='height: 1000px'></div>" - "</div>" - "<div id='container1' style='height: 600px; overflow: scroll'>" - " <div id='space1' style='height: 1000px'></div>" - " <div id='content1' style='height: 1000px'></div>" - "</div>"); + request.Complete(R"HTML( + <div id='container2' style='height: 1000px; overflow: scroll'> + <div id='space2' style='height: 1200px'></div> + <div id='content2' style='height: 1000px'></div> + </div> + <div id='container1' style='height: 600px; overflow: scroll'> + <div id='space1' style='height: 1000px'></div> + <div id='content1' style='height: 1000px'></div> + </div> + )HTML"); Element* container1 = GetDocument().getElementById("container1"); Element* container2 = GetDocument().getElementById("container2"); @@ -188,12 +190,13 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='space' style='height: 1000px'></div>" - "<div id='container' style='height: 600px; overflow: scroll'>" - " <div id='space1' style='height: 1000px'></div>" - " <div id='content' style='height: 1000px'></div>" - "</div>"); + request.Complete(R"HTML( + <div id='space' style='height: 1000px'></div> + <div id='container' style='height: 600px; overflow: scroll'> + <div id='space1' style='height: 1000px'></div> + <div id='content' style='height: 1000px'></div> + </div> + )HTML"); Element* container = GetDocument().getElementById("container"); Element* content = GetDocument().getElementById("content"); @@ -234,11 +237,12 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='container' style='height: 2500px; width: 2500px;'>" - "<div id='content' style='height: 500px; width: 500px;" - "margin-left: 1000px; margin-right: 1000px; margin-top: 1000px;" - "margin-bottom: 1000px'></div></div>"); + request.Complete(R"HTML( + <div id='container' style='height: 2500px; width: 2500px;'> + <div id='content' style='height: 500px; width: 500px; + margin-left: 1000px; margin-right: 1000px; margin-top: 1000px; + margin-bottom: 1000px'></div></div> + )HTML"); int content_height = 500; int content_width = 500; @@ -290,16 +294,17 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='space' style='height: 1000px'></div>" - "<div id='container' style='height: 600px; overflow: scroll;" - " scroll-behavior: smooth'>" - " <div id='space1' style='height: 1000px'></div>" - " <div id='inner_container' style='height: 1000px; overflow: scroll;'>" - " <div id='space2' style='height: 1000px'></div>" - " <div id='content' style='height: 1000px;'></div>" - " </div>" - "</div>"); + request.Complete(R"HTML( + <div id='space' style='height: 1000px'></div> + <div id='container' style='height: 600px; overflow: scroll; + scroll-behavior: smooth'> + <div id='space1' style='height: 1000px'></div> + <div id='inner_container' style='height: 1000px; overflow: scroll;'> + <div id='space2' style='height: 1000px'></div> + <div id='content' style='height: 1000px;'></div> + </div> + </div> + )HTML"); Element* container = GetDocument().getElementById("container"); Element* inner_container = GetDocument().getElementById("inner_container"); @@ -340,13 +345,14 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='container' style='height: 600px; overflow: scroll;" - " scroll-behavior: smooth'>" - " <div id='space' style='height: 1000px'></div>" - " <div style='height: 1000px'><a name='link' " - "id='content'>hello</a></div>" - "</div>"); + request.Complete(R"HTML( + <div id='container' style='height: 600px; overflow: scroll; + scroll-behavior: smooth'> + <div id='space' style='height: 1000px'></div> + <div style='height: 1000px'><a name='link' + id='content'>hello</a></div> + </div> + )HTML"); Element* content = GetDocument().getElementById("content"); Element* container = GetDocument().getElementById("container"); @@ -373,11 +379,12 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<div id='container' style='height: 400px; overflow: hidden;'>" - " <div id='space' style='height: 500px'></div>" - " <div style='height: 500px'>hello</div>" - "</div>"); + request.Complete(R"HTML( + <div id='container' style='height: 400px; overflow: hidden;'> + <div id='space' style='height: 500px'></div> + <div style='height: 500px'>hello</div> + </div> + )HTML"); Element* container = GetDocument().getElementById("container"); Compositor().BeginFrame(); ASSERT_EQ(container->scrollTop(), 0); @@ -423,41 +430,42 @@ WebView().Resize(WebSize(800, 600)); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); - request.Complete( - "<!DOCTYPE html>" - "<style>" - ".scroller {" - " scroll-behavior: smooth;" - " overflow: scroll;" - " position: absolute;" - " z-index: 0;" - " border: 10px solid #cce;" - "}" - "#outer {" - " width: 350px;" - " height: 200px;" - " left: 50px;" - " top: 50px;" - "}" - "#inner {" - " width: 200px;" - " height: 100px;" - " left: 50px;" - " top: 200px;" - "}" - "#target {" - " margin: 200px 0 20px 200px;" - " width: 50px;" - " height: 30px;" - " background-color: #c88;" - "}" - "</style>" - "<body>" - "<div class='scroller' id='outer'>" - " <div class='scroller' id='inner'>" - " <div id='target'></div>" - " </div>" - "</div>"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + .scroller { + scroll-behavior: smooth; + overflow: scroll; + position: absolute; + z-index: 0; + border: 10px solid #cce; + } + #outer { + width: 350px; + height: 200px; + left: 50px; + top: 50px; + } + #inner { + width: 200px; + height: 100px; + left: 50px; + top: 200px; + } + #target { + margin: 200px 0 20px 200px; + width: 50px; + height: 30px; + background-color: #c88; + } + </style> + <body> + <div class='scroller' id='outer'> + <div class='scroller' id='inner'> + <div id='target'></div> + </div> + </div> + )HTML"); Compositor().BeginFrame();
diff --git a/third_party/WebKit/Source/core/page/scrolling/SnapCoordinatorTest.cpp b/third_party/WebKit/Source/core/page/scrolling/SnapCoordinatorTest.cpp index c58340d8..ead4757 100644 --- a/third_party/WebKit/Source/core/page/scrolling/SnapCoordinatorTest.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/SnapCoordinatorTest.cpp
@@ -30,28 +30,29 @@ void SetUp() override { page_holder_ = DummyPageHolder::Create(); - SetHTML( - "<style>" - " #snap-container {" - " height: 1000px;" - " width: 1000px;" - " overflow: scroll;" - " scroll-snap-type: both mandatory;" - " }" - " #snap-element-fixed-position {" - " position: fixed;" - " }" - "</style>" - "<body>" - " <div id='snap-container'>" - " <div id='snap-element'></div>" - " <div id='intermediate'>" - " <div id='nested-snap-element'></div>" - " </div>" - " <div id='snap-element-fixed-position'></div>" - " <div style='width:2000px; height:2000px;'></div>" - " </div>" - "</body>"); + SetHTML(R"HTML( + <style> + #snap-container { + height: 1000px; + width: 1000px; + overflow: scroll; + scroll-snap-type: both mandatory; + } + #snap-element-fixed-position { + position: fixed; + } + </style> + <body> + <div id='snap-container'> + <div id='snap-element'></div> + <div id='intermediate'> + <div id='nested-snap-element'></div> + </div> + <div id='snap-element-fixed-position'></div> + <div style='width:2000px; height:2000px;'></div> + </div> + </body> + )HTML"); GetDocument().UpdateStyleAndLayout(); } @@ -139,34 +140,36 @@ // Add a new snap element Element& container = *GetDocument().getElementById("snap-container"); - container.SetInnerHTMLFromString( - "<div style='scroll-snap-align: start;'>" - " <div style='width:2000px; height:2000px;'></div>" - "</div>"); + container.SetInnerHTMLFromString(R"HTML( + <div style='scroll-snap-align: start;'> + <div style='width:2000px; height:2000px;'></div> + </div> + )HTML"); GetDocument().UpdateStyleAndLayout(); EXPECT_EQ(1U, SizeOfSnapAreas(SnapContainer())); } TEST_P(SnapCoordinatorTest, LayoutViewCapturesWhenBodyElementViewportDefining) { - SetHTML( - "<style>" - "body {" - " overflow: scroll;" - " scroll-snap-type: both mandatory;" - " height: 1000px;" - " width: 1000px;" - " margin: 5px;" - "}" - "</style>" - "<body>" - " <div id='snap-element' style='scroll-snap-align: start;></div>" - " <div id='intermediate'>" - " <div id='nested-snap-element'" - " style='scroll-snap-align: start;'></div>" - " </div>" - " <div style='width:2000px; height:2000px;'></div>" - "</body>"); + SetHTML(R"HTML( + <style> + body { + overflow: scroll; + scroll-snap-type: both mandatory; + height: 1000px; + width: 1000px; + margin: 5px; + } + </style> + <body> + <div id='snap-element' style='scroll-snap-align: start;></div> + <div id='intermediate'> + <div id='nested-snap-element' + style='scroll-snap-align: start;'></div> + </div> + <div style='width:2000px; height:2000px;'></div> + </body> + )HTML"); GetDocument().UpdateStyleAndLayout(); @@ -182,28 +185,29 @@ TEST_P(SnapCoordinatorTest, LayoutViewCapturesWhenDocumentElementViewportDefining) { - SetHTML( - "<style>" - ":root {" - " overflow: scroll;" - " scroll-snap-type: both mandatory;" - " height: 500px;" - " width: 500px;" - "}" - "body {" - " margin: 5px;" - "}" - "</style>" - "<html>" - " <body>" - " <div id='snap-element' style='scroll-snap-align: start;></div>" - " <div id='intermediate'>" - " <div id='nested-snap-element'" - " style='scroll-snap-align: start;'></div>" - " </div>" - " <div style='width:2000px; height:2000px;'></div>" - " </body>" - "</html>"); + SetHTML(R"HTML( + <style> + :root { + overflow: scroll; + scroll-snap-type: both mandatory; + height: 500px; + width: 500px; + } + body { + margin: 5px; + } + </style> + <html> + <body> + <div id='snap-element' style='scroll-snap-align: start;></div> + <div id='intermediate'> + <div id='nested-snap-element' + style='scroll-snap-align: start;'></div> + </div> + <div style='width:2000px; height:2000px;'></div> + </body> + </html> + )HTML"); GetDocument().UpdateStyleAndLayout(); @@ -221,33 +225,34 @@ TEST_P(SnapCoordinatorTest, BodyCapturesWhenBodyOverflowAndDocumentElementViewportDefining) { - SetHTML( - "<style>" - ":root {" - " overflow: scroll;" - " scroll-snap-type: both mandatory;" - " height: 500px;" - " width: 500px;" - "}" - "body {" - " overflow: scroll;" - " scroll-snap-type: both mandatory;" - " height: 1000px;" - " width: 1000px;" - " margin: 5px;" - "}" - "</style>" - "<html>" - " <body style='overflow: scroll; scroll-snap-type: both mandatory; " - "height:1000px; width:1000px;'>" - " <div id='snap-element' style='scroll-snap-align: start;></div>" - " <div id='intermediate'>" - " <div id='nested-snap-element'" - " style='scroll-snap-align: start;'></div>" - " </div>" - " <div style='width:2000px; height:2000px;'></div>" - " </body>" - "</html>"); + SetHTML(R"HTML( + <style> + :root { + overflow: scroll; + scroll-snap-type: both mandatory; + height: 500px; + width: 500px; + } + body { + overflow: scroll; + scroll-snap-type: both mandatory; + height: 1000px; + width: 1000px; + margin: 5px; + } + </style> + <html> + <body style='overflow: scroll; scroll-snap-type: both mandatory; + height:1000px; width:1000px;'> + <div id='snap-element' style='scroll-snap-align: start;></div> + <div id='intermediate'> + <div id='nested-snap-element' + style='scroll-snap-align: start;'></div> + </div> + <div style='width:2000px; height:2000px;'></div> + </body> + </html> + )HTML"); GetDocument().UpdateStyleAndLayout();
diff --git a/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp b/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp index b05cfe9..cc08006 100644 --- a/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp
@@ -21,17 +21,18 @@ ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations)); TEST_P(BlockPainterTest, ScrollHitTestProperties) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none; }" - " body { margin: 0 }" - " #container { width: 200px; height: 200px;" - " overflow: scroll; background: blue; }" - " #child { width: 100px; height: 300px; background: green; }" - "</style>" - "<div id='container'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none; } + body { margin: 0 } + #container { width: 200px; height: 200px; + overflow: scroll; background: blue; } + #child { width: 100px; height: 300px; background: green; } + </style> + <div id='container'> + <div id='child'></div> + </div> + )HTML"); auto& container = *GetLayoutObjectByElementId("container"); auto& child = *GetLayoutObjectByElementId("child"); @@ -102,13 +103,14 @@ } TEST_P(BlockPainterTest, FrameScrollHitTestProperties) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none; }" - " body { margin: 0; }" - " #child { width: 100px; height: 2000px; background: green; }" - "</style>" - "<div id='child'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none; } + body { margin: 0; } + #child { width: 100px; height: 2000px; background: green; } + </style> + <div id='child'></div> + )HTML"); auto& html = *GetDocument().documentElement()->GetLayoutObject(); auto& child = *GetLayoutObjectByElementId("child");
diff --git a/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp b/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp index 6b49940..19357a6 100644 --- a/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp +++ b/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp
@@ -80,40 +80,41 @@ RenderingTest::SetUp(); GetDocument().SetCompatibilityMode(Document::kNoQuirksMode); EnableCompositing(); - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0;" - " height: 0;" - " }" - " ::-webkit-scrollbar { display: none }" - " #target {" - " width: 50px;" - " height: 100px;" - " transform-origin: 0 0;" - " }" - " .border {" - " border-width: 20px 10px;" - " border-style: solid;" - " border-color: red;" - " }" - " .solid-composited-scroller {" - " overflow: scroll;" - " will-change: transform;" - " background: #ccc;" - " }" - " .local-background {" - " background-attachment: local;" - " overflow: scroll;" - " }" - " .gradient {" - " background-image: linear-gradient(blue, yellow)" - " }" - " .transform {" - " transform: scale(2);" - " }" - "</style>" - "<div id='target' class='border'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0; + height: 0; + } + ::-webkit-scrollbar { display: none } + #target { + width: 50px; + height: 100px; + transform-origin: 0 0; + } + .border { + border-width: 20px 10px; + border-style: solid; + border-color: red; + } + .solid-composited-scroller { + overflow: scroll; + will-change: transform; + background: #ccc; + } + .local-background { + background-attachment: local; + overflow: scroll; + } + .gradient { + background-image: linear-gradient(blue, yellow) + } + .transform { + transform: scale(2); + } + </style> + <div id='target' class='border'></div> + )HTML"); } FragmentData fragment_data_; }; @@ -543,18 +544,20 @@ } TEST_P(BoxPaintInvalidatorTest, NonCompositedLayoutViewResize) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " iframe { display: block; width: 100px; height: 100px; border: none; }" - "</style>" - "<iframe id='iframe'></iframe>"); - SetChildFrameHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0; background: green; height: 0 }" - "</style>" - "<div id='content' style='width: 200px; height: 200px'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + iframe { display: block; width: 100px; height: 100px; border: none; } + </style> + <iframe id='iframe'></iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0; background: green; height: 0 } + </style> + <div id='content' style='width: 200px; height: 200px'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* iframe = GetDocument().getElementById("iframe"); Element* content = ChildDocument().getElementById("content"); @@ -591,22 +594,24 @@ } TEST_P(BoxPaintInvalidatorTest, NonCompositedLayoutViewGradientResize) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " iframe { display: block; width: 100px; height: 100px; border: none; }" - "</style>" - "<iframe id='iframe'></iframe>"); - SetChildFrameHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body {" - " margin: 0;" - " height: 0;" - " background-image: linear-gradient(blue, yellow);" - " }" - "</style>" - "<div id='content' style='width: 200px; height: 200px'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + iframe { display: block; width: 100px; height: 100px; border: none; } + </style> + <iframe id='iframe'></iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { + margin: 0; + height: 0; + background-image: linear-gradient(blue, yellow); + } + </style> + <div id='content' style='width: 200px; height: 200px'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* iframe = GetDocument().getElementById("iframe"); Element* content = ChildDocument().getElementById("content");
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidatorTest.cpp b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidatorTest.cpp index c181fd0..632dea2 100644 --- a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidatorTest.cpp +++ b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidatorTest.cpp
@@ -21,27 +21,28 @@ return; EnableCompositing(); - SetBodyInnerHTML( - "<style>div { width: 10px; height: 10px; background-color: green; " - "}</style>" - "<div id='container' style='position: fixed'>" - " <div id='normal-child'></div>" - " <div id='stacked-child' style='position: relative'></div>" - " <div id='composited-stacking-context' style='will-change: transform'>" - " <div id='normal-child-of-composited-stacking-context'></div>" - " <div id='stacked-child-of-composited-stacking-context' " - "style='position: relative'></div>" - " </div>" - " <div id='composited-non-stacking-context' style='backface-visibility: " - "hidden'>" - " <div id='normal-child-of-composited-non-stacking-context'></div>" - " <div id='stacked-child-of-composited-non-stacking-context' " - "style='position: relative'></div>" - " <div " - "id='non-stacked-layered-child-of-composited-non-stacking-context' " - "style='overflow: scroll'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>div { width: 10px; height: 10px; background-color: green; + }</style> + <div id='container' style='position: fixed'> + <div id='normal-child'></div> + <div id='stacked-child' style='position: relative'></div> + <div id='composited-stacking-context' style='will-change: transform'> + <div id='normal-child-of-composited-stacking-context'></div> + <div id='stacked-child-of-composited-stacking-context' + style='position: relative'></div> + </div> + <div id='composited-non-stacking-context' style='backface-visibility: + hidden'> + <div id='normal-child-of-composited-non-stacking-context'></div> + <div id='stacked-child-of-composited-non-stacking-context' + style='position: relative'></div> + <div + id='non-stacked-layered-child-of-composited-non-stacking-context' + style='overflow: scroll'></div> + </div> + </div> + )HTML"); GetDocument().View()->SetTracksPaintInvalidations(true); ObjectPaintInvalidator(*GetLayoutObjectByElementId("container")) @@ -71,15 +72,16 @@ return; EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative'>" - " <span id='span' style='position: relative; will-change: transform'>" - " <div id='target' style='float: right'></div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative'> + <span id='span' style='position: relative; will-change: transform'> + <div id='target' style='float: right'></div> + </span> + </div> + </div> + )HTML"); auto* target = GetLayoutObjectByElementId("target"); auto* containing_block = GetLayoutObjectByElementId("containingBlock"); @@ -157,18 +159,19 @@ return; EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='position: relative; will-change: transform'>" - " <span id='innerSpan'" - " style='position: relative; will-change: transform'>" - " <div id='target' style='float: right'></div>" - " </span>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='position: relative; will-change: transform'> + <span id='innerSpan' + style='position: relative; will-change: transform'> + <div id='target' style='float: right'></div> + </span> + </span> + </div> + </div> + )HTML"); auto* target = GetLayoutObjectByElementId("target"); auto* containing_block = GetLayoutObjectByElementId("containingBlock"); @@ -224,10 +227,11 @@ return; EnableCompositing(); - SetBodyInnerHTML( - "<span id='span' style='position: relative; will-change: transform'>" - " <div id='target' style='position: relative; float: right'></div>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <span id='span' style='position: relative; will-change: transform'> + <div id='target' style='position: relative; float: right'></div> + </span> + )HTML"); auto* target = GetLayoutObjectByElementId("target"); auto* target_layer = ToLayoutBoxModelObject(target)->Layer();
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp index 1ffd6c8..d35f4863 100644 --- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -102,13 +102,14 @@ } TEST_P(PaintControllerPaintTestForSlimmingPaintV2, ChunkIdClientCacheFlag) { - SetBodyInnerHTML( - "<div id='div' style='width: 200px; height: 200px; opacity: 0.5'>" - " <div style='width: 100px; height: 100px; background-color: " - "blue'></div>" - " <div style='width: 100px; height: 100px; background-color: " - "blue'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='div' style='width: 200px; height: 200px; opacity: 0.5'> + <div style='width: 100px; height: 100px; background-color: + blue'></div> + <div style='width: 100px; height: 100px; background-color: + blue'></div> + </div> + )HTML"); LayoutBlock& div = *ToLayoutBlock(GetLayoutObjectByElementId("div")); LayoutObject& sub_div = *div.FirstChild(); LayoutObject& sub_div2 = *sub_div.NextSibling(); @@ -139,11 +140,12 @@ } TEST_P(PaintControllerPaintTestForSlimmingPaintV2, CompositingNoFold) { - SetBodyInnerHTML( - "<div id='div' style='width: 200px; height: 200px; opacity: 0.5'>" - " <div style='width: 100px; height: 100px; background-color: " - "blue'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='div' style='width: 200px; height: 200px; opacity: 0.5'> + <div style='width: 100px; height: 100px; background-color: + blue'></div> + </div> + )HTML"); LayoutBlock& div = *ToLayoutBlock(GetLayoutObjectByElementId("div")); LayoutObject& sub_div = *div.FirstChild(); @@ -158,17 +160,18 @@ if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) return; - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0; width: 10000px; height: 1000px }" - " div { position: absolute; width: 100px; height: 100px;" - " background: blue; }" - "</style>" - "<div id='div1' style='top: 0; left: 0'></div>" - "<div id='div2' style='top: 3000px; left: 3000px'></div>" - "<div id='div3' style='top: 6000px; left: 6000px'></div>" - "<div id='div4' style='top: 9000px; left: 9000px'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0; width: 10000px; height: 1000px } + div { position: absolute; width: 100px; height: 100px; + background: blue; } + </style> + <div id='div1' style='top: 0; left: 0'></div> + <div id='div2' style='top: 3000px; left: 3000px'></div> + <div id='div3' style='top: 6000px; left: 6000px'></div> + <div id='div4' style='top: 9000px; left: 9000px'></div> + )HTML"); auto& div1 = *GetLayoutObjectByElementId("div1"); auto& div2 = *GetLayoutObjectByElementId("div2"); @@ -199,20 +202,21 @@ // overflow clip and add a test case. TEST_P(PaintControllerPaintTestForSlimmingPaintV2, BlockScrollingNonLayeredContents) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0 }" - " div { width: 100px; height: 100px; background: blue; }" - " container { display: block; width: 200px; height: 200px;" - " overflow: scroll }" - "</style>" - "<container id='container'>" - " <div id='div1'></div>" - " <div id='div2' style='margin-top: 2900px; margin-left: 3000px'></div>" - " <div id='div3' style='margin-top: 2900px; margin-left: 6000px'></div>" - " <div id='div4' style='margin-top: 2900px; margin-left: 9000px'></div>" - "</container>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0 } + div { width: 100px; height: 100px; background: blue; } + container { display: block; width: 200px; height: 200px; + overflow: scroll } + </style> + <container id='container'> + <div id='div1'></div> + <div id='div2' style='margin-top: 2900px; margin-left: 3000px'></div> + <div id='div3' style='margin-top: 2900px; margin-left: 6000px'></div> + <div id='div4' style='margin-top: 2900px; margin-left: 9000px'></div> + </container> + )HTML"); auto& container = *ToLayoutBlock(GetLayoutObjectByElementId("container")); auto& div1 = *GetLayoutObjectByElementId("div1"); @@ -241,19 +245,20 @@ } TEST_P(PaintControllerPaintTestForSlimmingPaintV2, ScrollHitTestOrder) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0 }" - " #container { width: 200px; height: 200px;" - " overflow: scroll; background: red; }" - " #child { width: 100px; height: 300px; background: green; }" - " #forceDocumentScroll { height: 1000px; }" - "</style>" - "<div id='container'>" - " <div id='child'></div>" - "</div>" - "<div id='forceDocumentScroll'/>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0 } + #container { width: 200px; height: 200px; + overflow: scroll; background: red; } + #child { width: 100px; height: 300px; background: green; } + #forceDocumentScroll { height: 1000px; } + </style> + <div id='container'> + <div id='child'></div> + </div> + <div id='forceDocumentScroll'/> + )HTML"); auto& container = *ToLayoutBlock(GetLayoutObjectByElementId("container")); auto& child = *GetLayoutObjectByElementId("child"); @@ -271,24 +276,25 @@ TEST_P(PaintControllerPaintTestForSlimmingPaintV2, NonStackingScrollHitTestOrder) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0 }" - " #container { width: 200px; height: 200px;" - " overflow: scroll; background: blue;" - " position: relative; z-index: auto; }" - " #child { width: 80px; height: 20px; background: white; }" - " #negZChild { width: 60px; height: 300px; background: purple;" - " position: absolute; z-index: -1; top: 0; }" - " #posZChild { width: 40px; height: 300px; background: yellow;" - " position: absolute; z-index: 1; top: 0; }" - "</style>" - "<div id='container'>" - " <div id='child'></div>" - " <div id='negZChild'></div>" - " <div id='posZChild'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0 } + #container { width: 200px; height: 200px; + overflow: scroll; background: blue; + position: relative; z-index: auto; } + #child { width: 80px; height: 20px; background: white; } + #negZChild { width: 60px; height: 300px; background: purple; + position: absolute; z-index: -1; top: 0; } + #posZChild { width: 40px; height: 300px; background: yellow; + position: absolute; z-index: 1; top: 0; } + </style> + <div id='container'> + <div id='child'></div> + <div id='negZChild'></div> + <div id='posZChild'></div> + </div> + )HTML"); auto& container = *ToLayoutBlock(GetLayoutObjectByElementId("container")); auto& child = *GetLayoutObjectByElementId("child"); @@ -311,24 +317,25 @@ } TEST_P(PaintControllerPaintTestForSlimmingPaintV2, StackingScrollHitTestOrder) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0 }" - " #container { width: 200px; height: 200px;" - " overflow: scroll; background: blue;" - " position: relative; z-index: 0; }" - " #child { width: 80px; height: 20px; background: white; }" - " #negZChild { width: 60px; height: 300px; background: purple;" - " position: absolute; z-index: -1; top: 0; }" - " #posZChild { width: 40px; height: 300px; background: yellow;" - " position: absolute; z-index: 1; top: 0; }" - "</style>" - "<div id='container'>" - " <div id='child'></div>" - " <div id='negZChild'></div>" - " <div id='posZChild'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0 } + #container { width: 200px; height: 200px; + overflow: scroll; background: blue; + position: relative; z-index: 0; } + #child { width: 80px; height: 20px; background: white; } + #negZChild { width: 60px; height: 300px; background: purple; + position: absolute; z-index: -1; top: 0; } + #posZChild { width: 40px; height: 300px; background: yellow; + position: absolute; z-index: 1; top: 0; } + </style> + <div id='container'> + <div id='child'></div> + <div id='negZChild'></div> + <div id='posZChild'></div> + </div> + )HTML"); auto& container = *ToLayoutBlock(GetLayoutObjectByElementId("container")); auto& child = *GetLayoutObjectByElementId("child"); @@ -350,24 +357,25 @@ TEST_P(PaintControllerPaintTestForSlimmingPaintV2, NonStackingScrollHitTestOrderWithoutBackground) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none }" - " body { margin: 0 }" - " #container { width: 200px; height: 200px;" - " overflow: scroll; background: transparent;" - " position: relative; z-index: auto; }" - " #child { width: 80px; height: 20px; background: white; }" - " #negZChild { width: 60px; height: 300px; background: purple;" - " position: absolute; z-index: -1; top: 0; }" - " #posZChild { width: 40px; height: 300px; background: yellow;" - " position: absolute; z-index: 1; top: 0; }" - "</style>" - "<div id='container'>" - " <div id='child'></div>" - " <div id='negZChild'></div>" - " <div id='posZChild'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none } + body { margin: 0 } + #container { width: 200px; height: 200px; + overflow: scroll; background: transparent; + position: relative; z-index: auto; } + #child { width: 80px; height: 20px; background: white; } + #negZChild { width: 60px; height: 300px; background: purple; + position: absolute; z-index: -1; top: 0; } + #posZChild { width: 40px; height: 300px; background: yellow; + position: absolute; z-index: 1; top: 0; } + </style> + <div id='container'> + <div id='child'></div> + <div id='negZChild'></div> + <div id='posZChild'></div> + </div> + )HTML"); auto& container = *ToLayoutBlock(GetLayoutObjectByElementId("container")); auto& child = *GetLayoutObjectByElementId("child");
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp index ee78135..2647ebf 100644 --- a/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp
@@ -40,21 +40,22 @@ // revealed additional background that can be scrolled into view. TEST_P(PaintInvalidationTest, RecalcOverflowInvalidatesBackground) { GetDocument().GetPage()->GetSettings().SetViewportEnabled(true); - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<style type='text/css'>" - " body, html {" - " width: 100%;" - " height: 100%;" - " margin: 0px;" - " }" - " #container {" - " will-change: transform;" - " width: 100%;" - " height: 100%;" - " }" - "</style>" - "<div id='container'></div>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style type='text/css'> + body, html { + width: 100%; + height: 100%; + margin: 0px; + } + #container { + will-change: transform; + width: 100%; + height: 100%; + } + </style> + <div id='container'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -77,12 +78,13 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<style>" - " body { margin: 10px }" - " iframe { width: 100px; height: 100px; border: none; }" - "</style>" - "<iframe id='iframe'></iframe>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 10px } + iframe { width: 100px; height: 100px; border: none; } + </style> + <iframe id='iframe'></iframe> + )HTML"); Element* iframe = GetDocument().getElementById("iframe"); LayoutView* child_layout_view = ChildDocument().GetLayoutView(); @@ -103,28 +105,29 @@ // on transform change causing no visual change. TEST_P(PaintInvalidationTest, InvisibleTransformUnderFixedOnScroll) { EnableCompositing(); - SetBodyInnerHTML( - "<style>" - " #fixed {" - " position: fixed;" - " top: 0;" - " left: 0;" - " width: 100px;" - " height: 100px;" - " background-color: blue;" - " }" - " #transform {" - " width: 100px;" - " height: 100px;" - " background-color: yellow;" - " will-change: transform;" - " transform: translate(10px, 20px);" - " }" - "</style>" - "<div style='height: 2000px'></div>" - "<div id='fixed' style='visibility: hidden'>" - " <div id='transform'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #fixed { + position: fixed; + top: 0; + left: 0; + width: 100px; + height: 100px; + background-color: blue; + } + #transform { + width: 100px; + height: 100px; + background-color: yellow; + will-change: transform; + transform: translate(10px, 20px); + } + </style> + <div style='height: 2000px'></div> + <div id='fixed' style='visibility: hidden'> + <div id='transform'></div> + </div> + )HTML"); auto& fixed = *GetDocument().getElementById("fixed"); const auto& fixed_object = ToLayoutBox(*fixed.GetLayoutObject()); @@ -171,11 +174,12 @@ TEST_P(PaintInvalidationTest, DelayedFullPaintInvalidation) { EnableCompositing(); - SetBodyInnerHTML( - "<style>body { margin: 0 }</style>" - "<div style='height: 4000px'></div>" - "<div id='target' style='width: 100px; height: 100px; background: blue'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0 }</style> + <div style='height: 4000px'></div> + <div id='target' style='width: 100px; height: 100px; background: blue'> + </div> + )HTML"); auto* target = GetLayoutObjectByElementId("target"); target->SetShouldDoFullPaintInvalidationWithoutGeometryChange( @@ -209,16 +213,17 @@ TEST_P(PaintInvalidationTest, SVGHiddenContainer) { EnableCompositing(); - SetBodyInnerHTML( - "<svg style='position: absolute; top: 100px; left: 100px'>" - " <mask id='mask'>" - " <g transform='scale(2)'>" - " <rect id='mask-rect' x='11' y='22' width='33' height='44'/>" - " </g>" - " </mask>" - " <rect id='real-rect' x='55' y='66' width='7' height='8'" - " mask='url(#mask)'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg style='position: absolute; top: 100px; left: 100px'> + <mask id='mask'> + <g transform='scale(2)'> + <rect id='mask-rect' x='11' y='22' width='33' height='44'/> + </g> + </mask> + <rect id='real-rect' x='55' y='66' width='7' height='8' + mask='url(#mask)'/> + </svg> + )HTML"); // mask_rect's visual rect is in coordinates of the mask. auto* mask_rect = GetLayoutObjectByElementId("mask-rect");
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp index ce0b4f4d..432eed0 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp
@@ -31,11 +31,12 @@ }; TEST_F(PaintLayerClipperTest, BackgroundClipRectSubpixelAccumulation) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<svg id=target width=200 height=300 style='position: relative'>" - " <rect width=400 height=500 fill='blue'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <svg id=target width=200 height=300 style='position: relative'> + <rect width=400 height=500 fill='blue'/> + </svg> + )HTML"); Element* target = GetDocument().getElementById("target"); PaintLayer* target_paint_layer = @@ -57,11 +58,12 @@ } TEST_F(PaintLayerClipperTest, LayoutSVGRoot) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<svg id=target width=200 height=300 style='position: relative'>" - " <rect width=400 height=500 fill='blue'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <svg id=target width=200 height=300 style='position: relative'> + <rect width=400 height=500 fill='blue'/> + </svg> + )HTML"); Element* target = GetDocument().getElementById("target"); PaintLayer* target_paint_layer = @@ -90,10 +92,11 @@ } TEST_F(PaintLayerClipperTest, ControlClip) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<input id=target style='position:absolute; width: 200px; height: 300px'" - " type=button>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <input id=target style='position:absolute; width: 200px; height: 300px' + type=button> + )HTML"); Element* target = GetDocument().getElementById("target"); PaintLayer* target_paint_layer = ToLayoutBoxModelObject(target->GetLayoutObject())->Layer(); @@ -129,11 +132,12 @@ } TEST_F(PaintLayerClipperTest, RoundedClip) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<div id='target' style='position:absolute; width: 200px; height: 300px;" - " overflow: hidden; border-radius: 1px'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <div id='target' style='position:absolute; width: 200px; height: 300px; + overflow: hidden; border-radius: 1px'> + </div> + )HTML"); Element* target = GetDocument().getElementById("target"); PaintLayer* target_paint_layer = @@ -164,14 +168,15 @@ } TEST_F(PaintLayerClipperTest, RoundedClipNested) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<div id='parent' style='position:absolute; width: 200px; height: 300px;" - " overflow: hidden; border-radius: 1px'>" - " <div id='child' style='position: relative; width: 500px; " - " height: 500px'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <div id='parent' style='position:absolute; width: 200px; height: 300px; + overflow: hidden; border-radius: 1px'> + <div id='child' style='position: relative; width: 500px; + height: 500px'> + </div> + </div> + )HTML"); Element* parent = GetDocument().getElementById("parent"); PaintLayer* parent_paint_layer = @@ -200,13 +205,14 @@ } TEST_F(PaintLayerClipperTest, ControlClipSelect) { - SetBodyInnerHTML( - "<select id='target' style='position: relative; width: 100px; " - " background: none; border: none; padding: 0px 15px 0px 5px;'>" - " <option>" - " Test long texttttttttttttttttttttttttttttttt" - " </option>" - "</select>"); + SetBodyInnerHTML(R"HTML( + <select id='target' style='position: relative; width: 100px; + background: none; border: none; padding: 0px 15px 0px 5px;'> + <option> + Test long texttttttttttttttttttttttttttttttt + </option> + </select> + )HTML"); Element* target = GetDocument().getElementById("target"); PaintLayer* target_paint_layer = ToLayoutBoxModelObject(target->GetLayoutObject())->Layer(); @@ -235,13 +241,14 @@ } TEST_F(PaintLayerClipperTest, LayoutSVGRootChild) { - SetBodyInnerHTML( - "<svg width=200 height=300 style='position: relative'>" - " <foreignObject width=400 height=500>" - " <div id=target xmlns='http://www.w3.org/1999/xhtml' " - "style='position: relative'></div>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg width=200 height=300 style='position: relative'> + <foreignObject width=400 height=500> + <div id=target xmlns='http://www.w3.org/1999/xhtml' + style='position: relative'></div> + </foreignObject> + </svg> + )HTML"); Element* target = GetDocument().getElementById("target"); PaintLayer* target_paint_layer = @@ -262,11 +269,12 @@ } TEST_F(PaintLayerClipperTest, ContainPaintClip) { - SetBodyInnerHTML( - "<div id='target'" - " style='contain: paint; width: 200px; height: 200px; overflow: auto'>" - " <div style='height: 400px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' + style='contain: paint; width: 200px; height: 200px; overflow: auto'> + <div style='height: 400px'></div> + </div> + )HTML"); LayoutRect infinite_rect(LayoutRect::InfiniteIntRect()); PaintLayer* layer = @@ -296,12 +304,13 @@ } TEST_F(PaintLayerClipperTest, NestedContainPaintClip) { - SetBodyInnerHTML( - "<div style='contain: paint; width: 200px; height: 200px; overflow: " - "auto'>" - " <div id='target' style='contain: paint; height: 400px'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='contain: paint; width: 200px; height: 200px; overflow: + auto'> + <div id='target' style='contain: paint; height: 400px'> + </div> + </div> + )HTML"); LayoutRect infinite_rect(LayoutRect::InfiniteIntRect()); PaintLayer* layer = @@ -331,15 +340,16 @@ } TEST_F(PaintLayerClipperTest, LocalClipRectFixedUnderTransform) { - SetBodyInnerHTML( - "<div id='transformed'" - " style='will-change: transform; width: 100px; height: 100px;" - " overflow: hidden'>" - " <div id='fixed' " - " style='position: fixed; width: 100px; height: 100px;" - " top: -50px'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='transformed' + style='will-change: transform; width: 100px; height: 100px; + overflow: hidden'> + <div id='fixed' + style='position: fixed; width: 100px; height: 100px; + top: -50px'> + </div> + </div> + )HTML"); LayoutRect infinite_rect(LayoutRect::InfiniteIntRect()); PaintLayer* transformed = @@ -362,18 +372,19 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<style>" - "div { " - " width: 5px; height: 5px; background: blue; overflow: hidden;" - " position: relative;" - "}" - "</style>" - "<div id='parent'>" - " <div id='child'>" - " <div id='grandchild'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { + width: 5px; height: 5px; background: blue; overflow: hidden; + position: relative; + } + </style> + <div id='parent'> + <div id='child'> + <div id='grandchild'></div> + </div> + </div> + )HTML"); PaintLayer* parent = ToLayoutBoxModelObject(GetLayoutObjectByElementId("parent"))->Layer(); @@ -396,18 +407,19 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<style>" - "div { " - " width: 5px; height: 5px; background: blue;" - " position: relative;" - "}" - "</style>" - "<div id='parent'>" - " <div id='child'>" - " <div id='grandchild'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { + width: 5px; height: 5px; background: blue; + position: relative; + } + </style> + <div id='parent'> + <div id='child'> + <div id='grandchild'></div> + </div> + </div> + )HTML"); PaintLayer* parent = ToLayoutBoxModelObject(GetLayoutObjectByElementId("parent"))->Layer(); @@ -425,14 +437,15 @@ } TEST_F(PaintLayerClipperTest, CSSClip) { - SetBodyInnerHTML( - "<style>" - " #target { " - " width: 400px; height: 400px; position: absolute;" - " clip: rect(0, 50px, 100px, 0); " - " }" - "</style>" - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #target { + width: 400px; height: 400px; position: absolute; + clip: rect(0, 50px, 100px, 0); + } + </style> + <div id='target'></div> + )HTML"); PaintLayer* target = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer(); @@ -451,15 +464,16 @@ } TEST_F(PaintLayerClipperTest, Filter) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0 }" - " #target { " - " filter: drop-shadow(0 3px 4px #333); overflow: hidden;" - " width: 100px; height: 200px; border: 40px solid blue; margin: 50px;" - " }" - "</style>" - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0 } + #target { + filter: drop-shadow(0 3px 4px #333); overflow: hidden; + width: 100px; height: 200px; border: 40px solid blue; margin: 50px; + } + </style> + <div id='target'></div> + )HTML"); PaintLayer* target = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer(); @@ -525,19 +539,20 @@ } TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithCSSClip) { - SetBodyInnerHTML( - "<style>" - " #root { " - " width: 400px; height: 400px;" - " position: absolute; clip: rect(0, 50px, 100px, 0);" - " }" - " #target {" - " position: relative;" - " }" - "</style>" - "<div id='root'>" - " <div id='target'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #root { + width: 400px; height: 400px; + position: absolute; clip: rect(0, 50px, 100px, 0); + } + #target { + position: relative; + } + </style> + <div id='root'> + <div id='target'></div> + </div> + )HTML"); PaintLayer* root = ToLayoutBoxModelObject(GetLayoutObjectByElementId("root"))->Layer(); @@ -558,19 +573,20 @@ } TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithOverflowClip) { - SetBodyInnerHTML( - "<style>" - " #root { " - " width: 400px; height: 400px;" - " overflow: hidden;" - " }" - " #target {" - " position: relative;" - " }" - "</style>" - "<div id='root'>" - " <div id='target'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #root { + width: 400px; height: 400px; + overflow: hidden; + } + #target { + position: relative; + } + </style> + <div id='root'> + <div id='target'></div> + </div> + )HTML"); PaintLayer* root = ToLayoutBoxModelObject(GetLayoutObjectByElementId("root"))->Layer(); @@ -591,20 +607,21 @@ } TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithBothClip) { - SetBodyInnerHTML( - "<style>" - " #root { " - " width: 400px; height: 400px;" - " position: absolute; clip: rect(0, 50px, 100px, 0);" - " overflow: hidden;" - " }" - " #target {" - " position: relative;" - " }" - "</style>" - "<div id='root'>" - " <div id='target'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #root { + width: 400px; height: 400px; + position: absolute; clip: rect(0, 50px, 100px, 0); + overflow: hidden; + } + #target { + position: relative; + } + </style> + <div id='root'> + <div id='target'></div> + </div> + )HTML"); PaintLayer* root = ToLayoutBoxModelObject(GetLayoutObjectByElementId("root"))->Layer(); @@ -625,14 +642,15 @@ } TEST_F(PaintLayerClipperTest, Fragmentation) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<div id=root style='width: 200px; height: 100px; columns: 2; " - "column-gap: 0'>" - " <div id=target style='width: 100px; height: 200px; " - " background: lightblue; position: relative'>" - " </div" - "</div>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <div id=root style='width: 200px; height: 100px; columns: 2; + column-gap: 0'> + <div id=target style='width: 100px; height: 200px; + background: lightblue; position: relative'> + </div + </div> + )HTML"); Element* root = GetDocument().getElementById("root"); PaintLayer* root_paint_layer =
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp index fc65843..6d426ff 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -54,21 +54,22 @@ ::testing::ValuesIn(kDefaultPaintTestConfigurations)); TEST_P(PaintLayerPainterTest, CachedSubsequence) { - SetBodyInnerHTML( - "<div id='container1' style='position: relative; z-index: 1;" - " width: 200px; height: 200px; background-color: blue'>" - " <div id='content1' style='position: absolute; width: 100px;" - " height: 100px; background-color: red'></div>" - "</div>" - "<div id='filler1' style='position: relative; z-index: 2;" - " width: 20px; height: 20px; background-color: gray'></div>" - "<div id='container2' style='position: relative; z-index: 3;" - " width: 200px; height: 200px; background-color: blue'>" - " <div id='content2' style='position: absolute; width: 100px;" - " height: 100px; background-color: green;'></div>" - "</div>" - "<div id='filler2' style='position: relative; z-index: 4;" - " width: 20px; height: 20px; background-color: gray'></div>"); + SetBodyInnerHTML(R"HTML( + <div id='container1' style='position: relative; z-index: 1; + width: 200px; height: 200px; background-color: blue'> + <div id='content1' style='position: absolute; width: 100px; + height: 100px; background-color: red'></div> + </div> + <div id='filler1' style='position: relative; z-index: 2; + width: 20px; height: 20px; background-color: gray'></div> + <div id='container2' style='position: relative; z-index: 3; + width: 200px; height: 200px; background-color: blue'> + <div id='content2' style='position: absolute; width: 100px; + height: 100px; background-color: green;'></div> + </div> + <div id='filler2' style='position: relative; z-index: 4; + width: 20px; height: 20px; background-color: gray'></div> + )HTML"); auto& container1 = *GetLayoutObjectByElementId("container1"); auto& content1 = *GetLayoutObjectByElementId("content1"); @@ -158,25 +159,26 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id='container1' style='position: relative; z-index: 1;" - " width: 200px; height: 200px; background-color: blue'>" - " <div id='content1' style='position: absolute; width: 100px;" - " height: 100px; background-color: green'></div>" - "</div>" - "<div id='container2' style='position: relative; z-index: 1;" - " width: 200px; height: 200px; background-color: blue'>" - " <div id='content2a' style='position: absolute; width: 100px;" - " height: 100px; background-color: green'></div>" - " <div id='content2b' style='position: absolute; top: 200px;" - " width: 100px; height: 100px; background-color: green'></div>" - "</div>" - "<div id='container3' style='position: absolute; z-index: 2;" - " left: 300px; top: 0; width: 200px; height: 200px;" - " background-color: blue'>" - " <div id='content3' style='position: absolute; width: 200px;" - " height: 200px; background-color: green'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container1' style='position: relative; z-index: 1; + width: 200px; height: 200px; background-color: blue'> + <div id='content1' style='position: absolute; width: 100px; + height: 100px; background-color: green'></div> + </div> + <div id='container2' style='position: relative; z-index: 1; + width: 200px; height: 200px; background-color: blue'> + <div id='content2a' style='position: absolute; width: 100px; + height: 100px; background-color: green'></div> + <div id='content2b' style='position: absolute; top: 200px; + width: 100px; height: 100px; background-color: green'></div> + </div> + <div id='container3' style='position: absolute; z-index: 2; + left: 300px; top: 0; width: 200px; height: 200px; + background-color: blue'> + <div id='content3' style='position: absolute; width: 200px; + height: 200px; background-color: green'></div> + </div> + )HTML"); InvalidateAll(RootPaintController()); LayoutObject& container1 = @@ -252,11 +254,12 @@ CachedSubsequenceOnInterestRectChangeUnderInvalidationChecking) { ScopedPaintUnderInvalidationCheckingForTest under_invalidation_checking(true); - SetBodyInnerHTML( - "<style>p { width: 200px; height: 50px; background: green }</style>" - "<div id='target' style='position: relative; z-index: 1'>" - " <p></p><p></p><p></p><p></p>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>p { width: 200px; height: 50px; background: green }</style> + <div id='target' style='position: relative; z-index: 1'> + <p></p><p></p><p></p><p></p> + </div> + )HTML"); InvalidateAll(RootPaintController()); // |target| will be fully painted. @@ -273,17 +276,18 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceOnStyleChangeWithInterestRectClipping) { - SetBodyInnerHTML( - "<div id='container1' style='position: relative; z-index: 1;" - " width: 200px; height: 200px; background-color: blue'>" - " <div id='content1' style='position: absolute; width: 100px;" - " height: 100px; background-color: red'></div>" - "</div>" - "<div id='container2' style='position: relative; z-index: 1;" - " width: 200px; height: 200px; background-color: blue'>" - " <div id='content2' style='position: absolute; width: 100px;" - " height: 100px; background-color: green'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container1' style='position: relative; z-index: 1; + width: 200px; height: 200px; background-color: blue'> + <div id='content1' style='position: absolute; width: 100px; + height: 100px; background-color: red'></div> + </div> + <div id='container2' style='position: relative; z-index: 1; + width: 200px; height: 200px; background-color: blue'> + <div id='content2' style='position: absolute; width: 100px; + height: 100px; background-color: green'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); // PaintResult of all subsequences will be MayBeClippedByPaintDirtyRect. IntRect interest_rect(0, 0, 50, 300); @@ -342,14 +346,15 @@ "width: 50px; height: 50px; background-color: green"; AtomicString style_with_outline = "outline: 1px solid blue; " + style_without_outline; - SetBodyInnerHTML( - "<div id='self-painting-layer' style='position: absolute'>" - " <div id='non-self-painting-layer' style='overflow: hidden'>" - " <div>" - " <div id='outline'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='self-painting-layer' style='position: absolute'> + <div id='non-self-painting-layer' style='overflow: hidden'> + <div> + <div id='outline'></div> + </div> + </div> + </div> + )HTML"); LayoutObject& outline_div = *GetDocument().getElementById("outline")->GetLayoutObject(); ToHTMLElement(outline_div.GetNode()) @@ -407,15 +412,16 @@ AtomicString style_without_float = "width: 50px; height: 50px; background-color: green"; AtomicString style_with_float = "float: left; " + style_without_float; - SetBodyInnerHTML( - "<div id='self-painting-layer' style='position: absolute'>" - " <div id='non-self-painting-layer' style='overflow: hidden'>" - " <div>" - " <div id='float' style='width: 10px; height: 10px; " - " background-color: blue'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='self-painting-layer' style='position: absolute'> + <div id='non-self-painting-layer' style='overflow: hidden'> + <div> + <div id='float' style='width: 10px; height: 10px; + background-color: blue'></div> + </div> + </div> + </div> + )HTML"); LayoutObject& float_div = *GetDocument().getElementById("float")->GetLayoutObject(); ToHTMLElement(float_div.GetNode()) @@ -458,15 +464,16 @@ } TEST_P(PaintLayerPainterTest, PaintPhaseFloatUnderInlineLayer) { - SetBodyInnerHTML( - "<div id='self-painting-layer' style='position: absolute'>" - " <div id='non-self-painting-layer' style='overflow: hidden'>" - " <span id='span' style='position: relative'>" - " <div id='float' style='width: 10px; height: 10px; " - " background-color: blue; float: left'></div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='self-painting-layer' style='position: absolute'> + <div id='non-self-painting-layer' style='overflow: hidden'> + <span id='span' style='position: relative'> + <div id='float' style='width: 10px; height: 10px; + background-color: blue; float: left'></div> + </span> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); LayoutObject& float_div = @@ -499,14 +506,15 @@ AtomicString style_without_background = "width: 50px; height: 50px"; AtomicString style_with_background = "background: blue; " + style_without_background; - SetBodyInnerHTML( - "<div id='self-painting-layer' style='position: absolute'>" - " <div id='non-self-painting-layer' style='overflow: hidden'>" - " <div>" - " <div id='background'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='self-painting-layer' style='position: absolute'> + <div id='non-self-painting-layer' style='overflow: hidden'> + <div> + <div id='background'></div> + </div> + </div> + </div> + )HTML"); LayoutObject& background_div = *GetDocument().getElementById("background")->GetLayoutObject(); ToHTMLElement(background_div.GetNode()) @@ -570,14 +578,15 @@ } TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnLayerRemoval) { - SetBodyInnerHTML( - "<div id='layer' style='position: relative'>" - " <div style='height: 100px'>" - " <div style='height: 20px; outline: 1px solid red;" - " background-color: green'>outline and background</div>" - " <div style='float: left'>float</div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='layer' style='position: relative'> + <div style='height: 100px'> + <div style='height: 20px; outline: 1px solid red; + background-color: green'>outline and background</div> + <div style='float: left'>float</div> + </div> + </div> + )HTML"); LayoutBoxModelObject& layer_div = *ToLayoutBoxModelObject( GetDocument().getElementById("layer")->GetLayoutObject()); @@ -605,14 +614,15 @@ } TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnLayerAddition) { - SetBodyInnerHTML( - "<div id='will-be-layer'>" - " <div style='height: 100px'>" - " <div style='height: 20px; outline: 1px solid red;" - " background-color: green'>outline and background</div>" - " <div style='float: left'>float</div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='will-be-layer'> + <div style='height: 100px'> + <div style='height: 20px; outline: 1px solid red; + background-color: green'>outline and background</div> + <div style='float: left'>float</div> + </div> + </div> + )HTML"); LayoutBoxModelObject& layer_div = *ToLayoutBoxModelObject( GetDocument().getElementById("will-be-layer")->GetLayoutObject()); @@ -638,15 +648,16 @@ } TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingSelfPainting) { - SetBodyInnerHTML( - "<div id='will-be-self-painting' style='width: 100px; height: 100px; " - "overflow: hidden'>" - " <div>" - " <div style='outline: 1px solid red; background-color: green'>" - " outline and background" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='will-be-self-painting' style='width: 100px; height: 100px; + overflow: hidden'> + <div> + <div style='outline: 1px solid red; background-color: green'> + outline and background + </div> + </div> + </div> + )HTML"); LayoutBoxModelObject& layer_div = *ToLayoutBoxModelObject( GetDocument().getElementById("will-be-self-painting")->GetLayoutObject()); @@ -672,15 +683,16 @@ } TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingNonSelfPainting) { - SetBodyInnerHTML( - "<div id='will-be-non-self-painting' style='width: 100px; height: 100px; " - "overflow: hidden; position: relative'>" - " <div>" - " <div style='outline: 1px solid red; background-color: green'>" - " outline and background" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='will-be-non-self-painting' style='width: 100px; height: 100px; + overflow: hidden; position: relative'> + <div> + <div style='outline: 1px solid red; background-color: green'> + outline and background + </div> + </div> + </div> + )HTML"); LayoutBoxModelObject& layer_div = *ToLayoutBoxModelObject(GetDocument() @@ -713,12 +725,13 @@ // "position: relative" makes the table and td self-painting layers. // The table's layer should be marked needsPaintPhaseDescendantBlockBackground // because it will paint collapsed borders in the phase. - SetBodyInnerHTML( - "<table id='table' style='position: relative; border-collapse: collapse'>" - " <tr><td style='position: relative; border: 1px solid green'>" - " Cell" - " </td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table id='table' style='position: relative; border-collapse: collapse'> + <tr><td style='position: relative; border: 1px solid green'> + Cell + </td></tr> + </table> + )HTML"); LayoutBoxModelObject& table = *ToLayoutBoxModelObject(GetLayoutObjectByElementId("table")); @@ -730,12 +743,13 @@ TEST_P(PaintLayerPainterTest, TableCollapsedBorderNeedsPaintPhaseDescendantBlockBackgroundsDynamic) { - SetBodyInnerHTML( - "<table id='table' style='position: relative'>" - " <tr><td style='position: relative; border: 1px solid green'>" - " Cell" - " </td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <table id='table' style='position: relative'> + <tr><td style='position: relative; border: 1px solid green'> + Cell + </td></tr> + </table> + )HTML"); LayoutBoxModelObject& table = *ToLayoutBoxModelObject(GetLayoutObjectByElementId("table")); @@ -793,98 +807,104 @@ } TEST_P(PaintLayerPainterTest, DoPaintWithEffectAnimationZeroOpacity) { - SetBodyInnerHTML( - "<style> " - "div { " - " width: 100px; " - " height: 100px; " - " animation-name: example; " - " animation-duration: 4s; " - "} " - "@keyframes example { " - " from { opacity: 0.0;} " - " to { opacity: 1.0;} " - "} " - "</style> " - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { + width: 100px; + height: 100px; + animation-name: example; + animation-duration: 4s; + } + @keyframes example { + from { opacity: 0.0;} + to { opacity: 1.0;} + } + </style> + <div id='target'></div> + )HTML"); ExpectPaintedOutputInvisible("target", false); } TEST_P(PaintLayerPainterTest, DoPaintWithTransformAnimationZeroOpacity) { - SetBodyInnerHTML( - "<style> " - "div#target { " - " animation-name: example; " - " animation-duration: 4s; " - " opacity: 0.0; " - "} " - "@keyframes example { " - " from { transform: translate(0px, 0px); } " - " to { transform: translate(3em, 0px); } " - "} " - "</style> " - "<div id='target'>x</div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div#target { + animation-name: example; + animation-duration: 4s; + opacity: 0.0; + } + @keyframes example { + from { transform: translate(0px, 0px); } + to { transform: translate(3em, 0px); } + } + </style> + <div id='target'>x</div></div> + )HTML"); ExpectPaintedOutputInvisible("target", false); } TEST_P(PaintLayerPainterTest, DoPaintWithTransformAnimationZeroOpacityWillChangeOpacity) { - SetBodyInnerHTML( - "<style> " - "div#target { " - " animation-name: example; " - " animation-duration: 4s; " - " opacity: 0.0; " - " will-change: opacity; " - "} " - "@keyframes example { " - " from { transform: translate(0px, 0px); } " - " to { transform: translate(3em, 0px); } " - "} " - "</style> " - "<div id='target'>x</div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div#target { + animation-name: example; + animation-duration: 4s; + opacity: 0.0; + will-change: opacity; + } + @keyframes example { + from { transform: translate(0px, 0px); } + to { transform: translate(3em, 0px); } + } + </style> + <div id='target'>x</div></div> + )HTML"); ExpectPaintedOutputInvisible("target", false); } TEST_P(PaintLayerPainterTest, DoPaintWithWillChangeOpacity) { - SetBodyInnerHTML( - "<style> " - "div { " - " width: 100px; " - " height: 100px; " - " will-change: opacity;" - "}" - "</style> " - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { + width: 100px; + height: 100px; + will-change: opacity; + } + </style> + <div id='target'></div> + )HTML"); ExpectPaintedOutputInvisible("target", false); } TEST_P(PaintLayerPainterTest, DoPaintWithZeroOpacityAndWillChangeOpacity) { - SetBodyInnerHTML( - "<style> " - "div { " - " width: 100px; " - " height: 100px; " - " opacity: 0; " - " will-change: opacity;" - "}" - "</style> " - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { + width: 100px; + height: 100px; + opacity: 0; + will-change: opacity; + } + </style> + <div id='target'></div> + )HTML"); ExpectPaintedOutputInvisible("target", false); } TEST_P(PaintLayerPainterTest, DoPaintWithNoContentAndZeroOpacityAndWillChangeOpacity) { - SetBodyInnerHTML( - "<style> " - "div { " - " width: 100px; " - " height: 100px; " - " opacity: 0; " - " will-change: opacity;" - "}" - "</style> " - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { + width: 100px; + height: 100px; + opacity: 0; + will-change: opacity; + } + </style> + <div id='target'></div> + )HTML"); ExpectPaintedOutputInvisible("target", false); }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp index 2ec70ce..65239c9d 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp
@@ -64,58 +64,59 @@ CanPaintBackgroundOntoScrollingContentsLayer) { GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<style>" - ".scroller { overflow: scroll; will-change: transform; width: 300px; " - "height: 300px;} .spacer { height: 1000px; }" - "#scroller13::-webkit-scrollbar { width: 13px; height: 13px;}" - "</style>" - "<div id='scroller1' class='scroller' style='background: white local;'>" - " <div id='negative-composited-child' style='background-color: red; " - "width: 1px; height: 1px; position: absolute; backface-visibility: " - "hidden; z-index: -1'></div>" - " <div class='spacer'></div>" - "</div>" - "<div id='scroller2' class='scroller' style='background: white " - "content-box; padding: 10px;'><div class='spacer'></div></div>" - "<div id='scroller3' class='scroller' style='background: white local " - "content-box; padding: 10px;'><div class='spacer'></div></div>" - "<div id='scroller4' class='scroller' style='background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg), white local;'><div " - "class='spacer'></div></div>" - "<div id='scroller5' class='scroller' style='background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) local, white " - "local;'><div class='spacer'></div></div>" - "<div id='scroller6' class='scroller' style='background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) local, white " - "padding-box; padding: 10px;'><div class='spacer'></div></div>" - "<div id='scroller7' class='scroller' style='background: " - "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) local, white " - "content-box; padding: 10px;'><div class='spacer'></div></div>" - "<div id='scroller8' class='scroller' style='background: white " - "border-box;'><div class='spacer'></div></div>" - "<div id='scroller9' class='scroller' style='background: white " - "border-box; border: 10px solid black;'><div class='spacer'></div></div>" - "<div id='scroller10' class='scroller' style='background: white " - "border-box; border: 10px solid rgba(0, 0, 0, 0.5);'><div " - "class='spacer'></div></div>" - "<div id='scroller11' class='scroller' style='background: white " - "content-box;'><div class='spacer'></div></div>" - "<div id='scroller12' class='scroller' style='background: white " - "content-box; padding: 10px;'><div class='spacer'></div></div>" - "<div id='scroller13' class='scroller' style='background: white " - "border-box;'><div class='spacer'></div></div>" - "<div id='scroller14' class='scroller' style='background: white; border: " - "1px solid black; outline: 1px solid blue; outline-offset: -1px;'><div " - "class='spacer'></div></div>" - "<div id='scroller15' class='scroller' style='background: white; border: " - "1px solid black; outline: 1px solid blue; outline-offset: -2px;'><div " - "class='spacer'></div></div>" - "<div id='scroller16' class='scroller' style='background: white; clip: " - "rect(0px,10px,10px,0px);'><div class='spacer'></div></div>" - "<div id='scroller17' class='scroller' style='background:" - "rgba(255, 255, 255, 0.5) border-box; border: 5px solid " - "rgba(0, 0, 0, 0.5);'><div class='spacer'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + .scroller { overflow: scroll; will-change: transform; width: 300px; + height: 300px;} .spacer { height: 1000px; } + #scroller13::-webkit-scrollbar { width: 13px; height: 13px;} + </style> + <div id='scroller1' class='scroller' style='background: white local;'> + <div id='negative-composited-child' style='background-color: red; + width: 1px; height: 1px; position: absolute; backface-visibility: + hidden; z-index: -1'></div> + <div class='spacer'></div> + </div> + <div id='scroller2' class='scroller' style='background: white + content-box; padding: 10px;'><div class='spacer'></div></div> + <div id='scroller3' class='scroller' style='background: white local + content-box; padding: 10px;'><div class='spacer'></div></div> + <div id='scroller4' class='scroller' style='background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg), white local;'><div + class='spacer'></div></div> + <div id='scroller5' class='scroller' style='background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) local, white + local;'><div class='spacer'></div></div> + <div id='scroller6' class='scroller' style='background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) local, white + padding-box; padding: 10px;'><div class='spacer'></div></div> + <div id='scroller7' class='scroller' style='background: + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUg) local, white + content-box; padding: 10px;'><div class='spacer'></div></div> + <div id='scroller8' class='scroller' style='background: white + border-box;'><div class='spacer'></div></div> + <div id='scroller9' class='scroller' style='background: white + border-box; border: 10px solid black;'><div class='spacer'></div></div> + <div id='scroller10' class='scroller' style='background: white + border-box; border: 10px solid rgba(0, 0, 0, 0.5);'><div + class='spacer'></div></div> + <div id='scroller11' class='scroller' style='background: white + content-box;'><div class='spacer'></div></div> + <div id='scroller12' class='scroller' style='background: white + content-box; padding: 10px;'><div class='spacer'></div></div> + <div id='scroller13' class='scroller' style='background: white + border-box;'><div class='spacer'></div></div> + <div id='scroller14' class='scroller' style='background: white; border: + 1px solid black; outline: 1px solid blue; outline-offset: -1px;'><div + class='spacer'></div></div> + <div id='scroller15' class='scroller' style='background: white; border: + 1px solid black; outline: 1px solid blue; outline-offset: -2px;'><div + class='spacer'></div></div> + <div id='scroller16' class='scroller' style='background: white; clip: + rect(0px,10px,10px,0px);'><div class='spacer'></div></div> + <div id='scroller17' class='scroller' style='background: + rgba(255, 255, 255, 0.5) border-box; border: 5px solid + rgba(0, 0, 0, 0.5);'><div class='spacer'></div></div> + )HTML"); // #scroller1 cannot paint background into scrolling contents layer because it // has a negative z-index child. @@ -214,14 +215,15 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueContainedLayersPromoted) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; " - "contain: paint; background: white local content-box; " - "border: 10px solid rgba(0, 255, 0, 0.5); }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; + contain: paint; background: white local content-box; + border: 10px solid rgba(0, 255, 0, 0.5); } + #scrolled { height: 300px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -240,18 +242,19 @@ TEST_F(PaintLayerScrollableAreaTest, NonContainedLayersNotPromoted) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; " - "background: white local content-box; " - "border: 10px solid rgba(0, 255, 0, 0.5); }" - "#scrolled { height: 300px; }" - "#positioned { position: relative; }" - "</style>" - "<div id=\"scroller\">" - " <div id=\"positioned\">Not contained by scroller.</div>" - " <div id=\"scrolled\"></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; + background: white local content-box; + border: 10px solid rgba(0, 255, 0, 0.5); } + #scrolled { height: 300px; } + #positioned { position: relative; } + </style> + <div id="scroller"> + <div id="positioned">Not contained by scroller.</div> + <div id="scrolled"></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -266,14 +269,15 @@ TEST_F(PaintLayerScrollableAreaTest, TransparentLayersNotPromoted) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; background: " - "rgba(0, 255, 0, 0.5) local content-box; border: 10px solid rgba(0, 255, " - "0, 0.5); contain: paint; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; background: + rgba(0, 255, 0, 0.5) local content-box; border: 10px solid rgba(0, 255, + 0, 0.5); contain: paint; } + #scrolled { height: 300px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -288,13 +292,14 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersDepromotedOnStyleChange) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; background: " - "white local content-box; contain: paint; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; background: + white local content-box; contain: paint; } + #scrolled { height: 300px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -318,13 +323,14 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersPromotedOnStyleChange) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; background: " - "rgba(255,255,255,0.5) local content-box; contain: paint; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; background: + rgba(255,255,255,0.5) local content-box; contain: paint; } + #scrolled { height: 300px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -352,15 +358,16 @@ TEST_F(PaintLayerScrollableAreaTest, OnlyNonTransformedOpaqueLayersPromoted) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; background: " - "white local content-box; contain: paint; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"parent\">" - " <div id=\"scroller\"><div id=\"scrolled\"></div></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; background: + white local content-box; contain: paint; } + #scrolled { height: 300px; } + </style> + <div id="parent"> + <div id="scroller"><div id="scrolled"></div></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -406,15 +413,16 @@ TEST_F(PaintLayerScrollableAreaTest, OnlyOpaqueLayersPromoted) { ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; background: " - "white local content-box; contain: paint; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"parent\">" - " <div id=\"scroller\"><div id=\"scrolled\"></div></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; background: + white local content-box; contain: paint; } + #scrolled { height: 300px; } + </style> + <div id="parent"> + <div id="scroller"><div id="scrolled"></div></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -457,12 +465,13 @@ // Test that <input> elements get promoted with "will-change:transform". TEST_F(PaintLayerScrollableAreaTest, InputElementPromotionTest) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<style>" - " .composited { will-change: transform; }" - "</style>" - "<input id='input' width=10 style='font-size:40pt;'/>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + .composited { will-change: transform; } + </style> + <input id='input' width=10 style='font-size:40pt;'/> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("input"); @@ -479,17 +488,18 @@ // Test that <select> elements get promoted with "will-change:transform". TEST_F(PaintLayerScrollableAreaTest, SelectElementPromotionTest) { - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<style>" - " .composited { will-change: transform; }" - "</style>" - "<select id='select' size='2'>" - " <option> value 1</option>" - " <option> value 2</option>" - " <option> value 3</option>" - " <option> value 4</option>" - "</select>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + .composited { will-change: transform; } + </style> + <select id='select' size='2'> + <option> value 1</option> + <option> value 2</option> + <option> value 3</option> + <option> value 4</option> + </select> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("select"); @@ -508,15 +518,16 @@ // Ensure OverlayScrollbarColorTheme get updated when page load TEST_F(PaintLayerScrollableAreaTest, OverlayScrollbarColorThemeUpdated) { - SetBodyInnerHTML( - "<style>" - "div { overflow: scroll; }" - "#white { background-color: white; }" - "#black { background-color: black; }" - "</style>" - "<div id=\"none\">a</div>" - "<div id=\"white\">b</div>" - "<div id=\"black\">c</div>"); + SetBodyInnerHTML(R"HTML( + <style> + div { overflow: scroll; } + #white { background-color: white; } + #black { background-color: black; } + </style> + <div id="none">a</div> + <div id="white">b</div> + <div id="black">c</div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* none = GetDocument().getElementById("none"); @@ -546,15 +557,16 @@ // scrolling contents layer to not be promoted. TEST_F(PaintLayerScrollableAreaTest, OnlyAutoClippedScrollingContentsLayerPromoted) { - SetBodyInnerHTML( - "<style>" - ".clip { clip: rect(0px,60px,50px,0px); }" - "#scroller { position: absolute; overflow: auto;" - "height: 100px; width: 100px; background: grey;" - "will-change:transform; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + .clip { clip: rect(0px,60px,50px,0px); } + #scroller { position: absolute; overflow: auto; + height: 100px; width: 100px; background: grey; + will-change:transform; } + #scrolled { height: 300px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scroller = GetDocument().getElementById("scroller"); @@ -579,12 +591,13 @@ } TEST_F(PaintLayerScrollableAreaTest, HideTooltipWhenScrollPositionChanges) { - SetBodyInnerHTML( - "<style>" - "#scroller { width: 100px; height: 100px; overflow: scroll; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { width: 100px; height: 100px; overflow: scroll; } + #scrolled { height: 300px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scroller = GetDocument().getElementById("scroller"); @@ -607,12 +620,13 @@ TEST_F(PaintLayerScrollableAreaTest, IncludeOverlayScrollbarsInVisibleWidth) { ScopedOverlayScrollbarsForTest overlay_scrollbars(false); - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: overlay; height: 100px; width: 100px; }" - "#scrolled { width: 100px; height: 200px; }" - "</style>" - "<div id=\"scroller\"><div id=\"scrolled\"></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: overlay; height: 100px; width: 100px; } + #scrolled { width: 100px; height: 200px; } + </style> + <div id="scroller"><div id="scrolled"></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scroller = GetDocument().getElementById("scroller"); ASSERT_TRUE(scroller); @@ -625,22 +639,23 @@ TEST_F(PaintLayerScrollableAreaTest, ShowAutoScrollbarsForVisibleContent) { ScopedOverlayScrollbarsForTest overlay_scrollbars(false); - SetBodyInnerHTML( - "<style>" - "#outerDiv {" - " width: 15px;" - " height: 100px;" - " overflow-y: auto;" - " overflow-x: hidden;" - "}" - "#innerDiv {" - " height:300px;" - " width: 1px;" - "}" - "</style>" - "<div id='outerDiv'>" - " <div id='innerDiv'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #outerDiv { + width: 15px; + height: 100px; + overflow-y: auto; + overflow-x: hidden; + } + #innerDiv { + height:300px; + width: 1px; + } + </style> + <div id='outerDiv'> + <div id='innerDiv'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* outer_div = GetDocument().getElementById("outerDiv"); ASSERT_TRUE(outer_div); @@ -654,21 +669,22 @@ TEST_F(PaintLayerScrollableAreaTest, FloatOverflowInRtlContainer) { ScopedOverlayScrollbarsForTest overlay_scrollbars(false); - SetBodyInnerHTML( - "<!DOCTYPE html>" - "<style>" - "#container {" - " width: 200px;" - " overflow-x: auto;" - " overflow-y: scroll;" - " direction: rtl;" - "}" - "</style>" - "<div id='container'>" - " <div style='float:left'>" - "lorem ipsum" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + #container { + width: 200px; + overflow-x: auto; + overflow-y: scroll; + direction: rtl; + } + </style> + <div id='container'> + <div style='float:left'> + lorem ipsum + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* container = GetDocument().getElementById("container"); ASSERT_TRUE(container); @@ -682,17 +698,18 @@ SlimmingPaintV2OverflowHiddenScrollOffsetInvalidation) { ScopedSlimmingPaintV2ForTest enabler(true); - SetBodyInnerHTML( - "<style>" - "#scroller {" - " overflow: hidden;" - " height: 200px;" - " width: 200px;" - "}" - "</style>" - "<div id='scroller'>" - " <div id='forceScroll' style='height: 2000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { + overflow: hidden; + height: 200px; + width: 200px; + } + </style> + <div id='scroller'> + <div id='forceScroll' style='height: 2000px;'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); auto* scroller = GetLayoutObjectByElementId("scroller"); @@ -739,18 +756,19 @@ TEST_F(PaintLayerScrollableAreaTest, SlimmingPaintV2ScrollDoesNotInvalidate) { ScopedSlimmingPaintV2ForTest enabler(true); - SetBodyInnerHTML( - "<style>" - " #scroller {" - " overflow: scroll;" - " height: 200px;" - " width: 200px;" - " background: linear-gradient(black, white);" - " }" - "</style>" - "<div id='scroller'>" - " <div id='forceScroll' style='height: 2000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { + overflow: scroll; + height: 200px; + width: 200px; + background: linear-gradient(black, white); + } + </style> + <div id='scroller'> + <div id='forceScroll' style='height: 2000px;'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); auto* scroller = GetLayoutObjectByElementId("scroller"); @@ -774,19 +792,20 @@ SlimmingPaintV2ScrollWithLocalBackgroundAttachment) { ScopedSlimmingPaintV2ForTest enabler(true); - SetBodyInnerHTML( - "<style>" - " #scroller {" - " overflow: scroll;" - " height: 200px;" - " width: 200px;" - " background: linear-gradient(black, white);" - " background-attachment: local;" - " }" - "</style>" - "<div id='scroller'>" - " <div id='forceScroll' style='height: 2000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { + overflow: scroll; + height: 200px; + width: 200px; + background: linear-gradient(black, white); + background-attachment: local; + } + </style> + <div id='scroller'> + <div id='forceScroll' style='height: 2000px;'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); auto* scroller = GetLayoutObjectByElementId("scroller");
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp index c1f2adb..f4a1146dd 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp
@@ -74,14 +74,15 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id=parent style='overflow: scroll; will-change: transform'>" - " <div class='target'" - " style='position: relative; transform: skew(-15deg);'>" - " </div>" - " <div style='width: 1000px; height: 500px; background: lightgray'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id=parent style='overflow: scroll; will-change: transform'> + <div class='target' + style='position: relative; transform: skew(-15deg);'> + </div> + <div style='width: 1000px; height: 500px; background: lightgray'> + </div> + </div> + )HTML"); PaintLayer* parent_layer = GetPaintLayerByElementId("parent"); EXPECT_EQ(LayoutRect(0, 0, 784, 500), @@ -120,11 +121,12 @@ } TEST_P(PaintLayerTest, PaintingExtentReflection) { - SetBodyInnerHTML( - "<div id='target' style='background-color: blue; position: absolute;" - " width: 110px; height: 120px; top: 40px; left: 60px;" - " -webkit-box-reflect: below 3px'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='background-color: blue; position: absolute; + width: 110px; height: 120px; top: 40px; left: 60px; + -webkit-box-reflect: below 3px'> + </div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); EXPECT_EQ(LayoutRect(60, 40, 110, 243), @@ -133,11 +135,12 @@ } TEST_P(PaintLayerTest, PaintingExtentReflectionWithTransform) { - SetBodyInnerHTML( - "<div id='target' style='background-color: blue; position: absolute;" - " width: 110px; height: 120px; top: 40px; left: 60px;" - " -webkit-box-reflect: below 3px; transform: translateX(30px)'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='background-color: blue; position: absolute; + width: 110px; height: 120px; top: 40px; left: 60px; + -webkit-box-reflect: below 3px; transform: translateX(30px)'> + </div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); EXPECT_EQ(LayoutRect(90, 40, 110, 243), @@ -165,21 +168,23 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() && !RuntimeEnabledFeatures::RootLayerScrollingEnabled()) return; - SetBodyInnerHTML( - "<div style='transform: translateZ(0)'>" - " <div id='target' style='position: fixed'></div>" - "</div>" - "<div style='width: 10px; height: 1000px'></div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform: translateZ(0)'> + <div id='target' style='position: fixed'></div> + </div> + <div style='width: 10px; height: 1000px'></div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); EXPECT_FALSE(layer->FixedToViewport()); } TEST_P(PaintLayerTest, ScrollsWithViewportFixedPositionInsideTransformNoScroll) { - SetBodyInnerHTML( - "<div style='transform: translateZ(0)'>" - " <div id='target' style='position: fixed'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform: translateZ(0)'> + <div id='target' style='position: fixed'></div> + </div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); // In SPv2 mode, we correctly determine that the frame doesn't scroll at all, @@ -191,22 +196,24 @@ } TEST_P(PaintLayerTest, SticksToScrollerStickyPosition) { - SetBodyInnerHTML( - "<div style='transform: translateZ(0)'>" - " <div id='target' style='position: sticky; top: 0;'></div>" - "</div>" - "<div style='width: 10px; height: 1000px'></div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform: translateZ(0)'> + <div id='target' style='position: sticky; top: 0;'></div> + </div> + <div style='width: 10px; height: 1000px'></div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); EXPECT_TRUE(layer->SticksToScroller()); } TEST_P(PaintLayerTest, SticksToScrollerNoAnchor) { - SetBodyInnerHTML( - "<div style='transform: translateZ(0)'>" - " <div id='target' style='position: sticky'></div>" - "</div>" - "<div style='width: 10px; height: 1000px'></div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform: translateZ(0)'> + <div id='target' style='position: sticky'></div> + </div> + <div style='width: 10px; height: 1000px'></div> + )HTML"); PaintLayer* layer = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer(); @@ -214,21 +221,23 @@ } TEST_P(PaintLayerTest, SticksToScrollerStickyPositionNoScroll) { - SetBodyInnerHTML( - "<div style='transform: translateZ(0)'>" - " <div id='target' style='position: sticky; top: 0;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform: translateZ(0)'> + <div id='target' style='position: sticky; top: 0;'></div> + </div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); EXPECT_TRUE(layer->SticksToScroller()); } TEST_P(PaintLayerTest, SticksToScrollerStickyPositionInsideScroller) { - SetBodyInnerHTML( - "<div style='overflow:scroll; width: 100px; height: 100px;'>" - " <div id='target' style='position: sticky; top: 0;'></div>" - " <div style='width: 50px; height: 1000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='overflow:scroll; width: 100px; height: 100px;'> + <div id='target' style='position: sticky; top: 0;'></div> + <div style='width: 50px; height: 1000px;'></div> + </div> + )HTML"); PaintLayer* layer = GetPaintLayerByElementId("target"); EXPECT_TRUE(layer->SticksToScroller()); @@ -239,12 +248,13 @@ return; EnableCompositing(); - SetBodyInnerHTML( - "<div id='scroll' style='width: 100px; height: 100px; overflow: scroll;" - " will-change: transform'>" - " <div id='content' style='position: relative; background: blue;" - " width: 2000px; height: 2000px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='scroll' style='width: 100px; height: 100px; overflow: scroll; + will-change: transform'> + <div id='content' style='position: relative; background: blue; + width: 2000px; height: 2000px'></div> + </div> + )HTML"); PaintLayer* scroll_layer = GetPaintLayerByElementId("scroll"); EXPECT_EQ(kPaintsIntoOwnBacking, scroll_layer->GetCompositingState()); @@ -269,11 +279,12 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<div id='scroll' style='width: 100px; height: 100px; overflow: scroll'>" - " <div id='content' style='position: relative; background: blue;" - " width: 2000px; height: 2000px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='scroll' style='width: 100px; height: 100px; overflow: scroll'> + <div id='content' style='position: relative; background: blue; + width: 2000px; height: 2000px'></div> + </div> + )HTML"); PaintLayer* scroll_layer = GetPaintLayerByElementId("scroll"); EXPECT_EQ(kNotComposited, scroll_layer->GetCompositingState()); @@ -292,15 +303,16 @@ } TEST_P(PaintLayerTest, HasNonIsolatedDescendantWithBlendMode) { - SetBodyInnerHTML( - "<div id='stacking-grandparent' style='isolation: isolate'>" - " <div id='stacking-parent' style='isolation: isolate'>" - " <div id='non-stacking-parent' style='position:relative'>" - " <div id='blend-mode' style='mix-blend-mode: overlay'>" - " </div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='stacking-grandparent' style='isolation: isolate'> + <div id='stacking-parent' style='isolation: isolate'> + <div id='non-stacking-parent' style='position:relative'> + <div id='blend-mode' style='mix-blend-mode: overlay'> + </div> + </div> + </div> + </div> + )HTML"); PaintLayer* stacking_grandparent = GetPaintLayerByElementId("stacking-grandparent"); PaintLayer* stacking_parent = GetPaintLayerByElementId("stacking-parent"); @@ -315,15 +327,16 @@ } TEST_P(PaintLayerTest, SubsequenceCachingStackingContexts) { - SetBodyInnerHTML( - "<div id='parent' style='position:relative'>" - " <div id='child1' style='position: relative'>" - " <div id='grandchild1' style='position: relative'></div>" - " </div>" - " <div id='child2' style='isolation: isolate'>" - " <div id='grandchild2' style='position: relative'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position:relative'> + <div id='child1' style='position: relative'> + <div id='grandchild1' style='position: relative'></div> + </div> + <div id='child2' style='isolation: isolate'> + <div id='grandchild2' style='position: relative'></div> + </div> + </div> + )HTML"); PaintLayer* parent = GetPaintLayerByElementId("parent"); PaintLayer* child1 = GetPaintLayerByElementId("child1"); PaintLayer* child2 = GetPaintLayerByElementId("child2"); @@ -349,31 +362,34 @@ } TEST_P(PaintLayerTest, SubsequenceCachingSVGRoot) { - SetBodyInnerHTML( - "<div id='parent' style='position: relative'>" - " <svg id='svgroot' style='position: relative'></svg>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position: relative'> + <svg id='svgroot' style='position: relative'></svg> + </div> + )HTML"); PaintLayer* svgroot = GetPaintLayerByElementId("svgroot"); EXPECT_FALSE(svgroot->SupportsSubsequenceCaching()); } TEST_P(PaintLayerTest, SubsequenceCachingMuticol) { - SetBodyInnerHTML( - "<div style='columns: 2'>" - " <svg id='svgroot' style='position: relative'></svg>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='columns: 2'> + <svg id='svgroot' style='position: relative'></svg> + </div> + )HTML"); PaintLayer* svgroot = GetPaintLayerByElementId("svgroot"); EXPECT_FALSE(svgroot->SupportsSubsequenceCaching()); } TEST_P(PaintLayerTest, HasDescendantWithClipPath) { - SetBodyInnerHTML( - "<div id='parent' style='position:relative'>" - " <div id='clip-path' style='clip-path: circle(50px at 0 100px)'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position:relative'> + <div id='clip-path' style='clip-path: circle(50px at 0 100px)'> + </div> + </div> + )HTML"); PaintLayer* parent = GetPaintLayerByElementId("parent"); PaintLayer* clip_path = GetPaintLayerByElementId("clip-path"); @@ -386,11 +402,12 @@ TEST_P(PaintLayerTest, HasVisibleDescendant) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='invisible' style='position:relative'>" - " <div id='visible' style='visibility: visible; position: relative'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='invisible' style='position:relative'> + <div id='visible' style='visibility: visible; position: relative'> + </div> + </div> + )HTML"); PaintLayer* invisible = GetPaintLayerByElementId("invisible"); PaintLayer* visible = GetPaintLayerByElementId("visible"); @@ -403,11 +420,12 @@ TEST_P(PaintLayerTest, Has3DTransformedDescendant) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='parent' style='position:relative; z-index: 0'>" - " <div id='child' style='transform: translateZ(1px)'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position:relative; z-index: 0'> + <div id='child' style='transform: translateZ(1px)'> + </div> + </div> + )HTML"); PaintLayer* parent = GetPaintLayerByElementId("parent"); PaintLayer* child = GetPaintLayerByElementId("child"); @@ -417,11 +435,12 @@ TEST_P(PaintLayerTest, Has3DTransformedDescendantChangeStyle) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='parent' style='position:relative; z-index: 0'>" - " <div id='child' style='position:relative '>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position:relative; z-index: 0'> + <div id='child' style='position:relative '> + </div> + </div> + )HTML"); PaintLayer* parent = GetPaintLayerByElementId("parent"); PaintLayer* child = GetPaintLayerByElementId("child"); @@ -438,11 +457,12 @@ TEST_P(PaintLayerTest, Has3DTransformedDescendantNotStacking) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='parent' style='position:relative;'>" - " <div id='child' style='transform: translateZ(1px)'>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position:relative;'> + <div id='child' style='transform: translateZ(1px)'> + </div> + </div> + )HTML"); PaintLayer* parent = GetPaintLayerByElementId("parent"); PaintLayer* child = GetPaintLayerByElementId("child"); @@ -454,13 +474,14 @@ TEST_P(PaintLayerTest, Has3DTransformedGrandchildWithPreserve3d) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='parent' style='position:relative; z-index: 0'>" - " <div id='child' style='transform-style: preserve-3d'>" - " <div id='grandchild' style='transform: translateZ(1px)'>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent' style='position:relative; z-index: 0'> + <div id='child' style='transform-style: preserve-3d'> + <div id='grandchild' style='transform: translateZ(1px)'> + </div> + </div> + </div> + )HTML"); PaintLayer* parent = GetPaintLayerByElementId("parent"); PaintLayer* child = GetPaintLayerByElementId("child"); PaintLayer* grandchild = GetPaintLayerByElementId("grandchild"); @@ -472,15 +493,17 @@ TEST_P(PaintLayerTest, DescendantDependentFlagsStopsAtThrottledFrames) { EnableCompositing(); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='transform' style='transform: translate3d(4px, 5px, 6px);'>" - "</div>" - "<iframe id='iframe' sandbox></iframe>"); - SetChildFrameHTML( - "<style>body { margin: 0; }</style>" - "<div id='iframeTransform'" - " style='transform: translate3d(4px, 5px, 6px);'/>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='transform' style='transform: translate3d(4px, 5px, 6px);'> + </div> + <iframe id='iframe' sandbox></iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='iframeTransform' + style='transform: translate3d(4px, 5px, 6px);'/> + )HTML"); // Move the child frame offscreen so it becomes available for throttling. auto* iframe = ToHTMLIFrameElement(GetDocument().getElementById("iframe")); @@ -533,16 +556,17 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - SetBodyInnerHTML( - "<style>* { margin: 0 } ::-webkit-scrollbar { display: none }</style>" - "<div id='scroller' style='overflow: scroll; width: 50px; height: 50px'>" - " <div style='height: 400px'>" - " <div id='content-layer' style='position: relative; height: 10px;" - " top: 30px; background: blue'>" - " <div id='content' style='height: 5px; background: yellow'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>* { margin: 0 } ::-webkit-scrollbar { display: none }</style> + <div id='scroller' style='overflow: scroll; width: 50px; height: 50px'> + <div style='height: 400px'> + <div id='content-layer' style='position: relative; height: 10px; + top: 30px; background: blue'> + <div id='content' style='height: 5px; background: yellow'></div> + </div> + </div> + </div> + )HTML"); LayoutBox* scroller = ToLayoutBox(GetLayoutObjectByElementId("scroller")); LayoutObject* content_layer = GetLayoutObjectByElementId("content-layer"); @@ -561,17 +585,18 @@ TEST_P(PaintLayerTest, PaintInvalidationOnCompositedScroll) { EnableCompositing(); - SetBodyInnerHTML( - "<style>* { margin: 0 } ::-webkit-scrollbar { display: none }</style>" - "<div id='scroller' style='overflow: scroll; width: 50px; height: 50px;" - " will-change: transform'>" - " <div style='height: 400px'>" - " <div id='content-layer' style='position: relative; height: 10px;" - " top: 30px; background: blue'>" - " <div id='content' style='height: 5px; background: yellow'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>* { margin: 0 } ::-webkit-scrollbar { display: none }</style> + <div id='scroller' style='overflow: scroll; width: 50px; height: 50px; + will-change: transform'> + <div style='height: 400px'> + <div id='content-layer' style='position: relative; height: 10px; + top: 30px; background: blue'> + <div id='content' style='height: 5px; background: yellow'></div> + </div> + </div> + </div> + )HTML"); LayoutBox* scroller = ToLayoutBox(GetLayoutObjectByElementId("scroller")); LayoutObject* content_layer = GetLayoutObjectByElementId("content-layer"); @@ -590,15 +615,16 @@ TEST_P(PaintLayerTest, CompositingContainerStackedFloatUnderStackingInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9'>" - " <div id='target' style='float: right; position: relative'></div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9'> + <div id='target' style='float: right; position: relative'></div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer()); @@ -614,15 +640,16 @@ TEST_P(PaintLayerTest, CompositingContainerStackedFloatUnderStackingCompositedInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9; will-change: transform'>" - " <div id='target' style='float: right; position: relative'></div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9; will-change: transform'> + <div id='target' style='float: right; position: relative'></div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); PaintLayer* span = GetPaintLayerByElementId("span"); @@ -638,15 +665,16 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedFloatUnderStackingInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9'>" - " <div id='target' style='float: right; overflow: hidden'></div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9'> + <div id='target' style='float: right; overflow: hidden'></div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); EXPECT_EQ(GetPaintLayerByElementId("containingBlock"), @@ -663,15 +691,16 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedFloatUnderStackingCompositedInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9; will-change: transform'>" - " <div id='target' style='float: right; overflow: hidden'></div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9; will-change: transform'> + <div id='target' style='float: right; overflow: hidden'></div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); EXPECT_EQ(GetPaintLayerByElementId("containingBlock"), @@ -688,17 +717,18 @@ TEST_P(PaintLayerTest, CompositingContainerStackedUnderFloatUnderStackingInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9'>" - " <div style='float: right'>" - " <div id='target' style='position: relative'></div>" - " </div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9'> + <div style='float: right'> + <div id='target' style='position: relative'></div> + </div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer()); @@ -714,17 +744,18 @@ TEST_P(PaintLayerTest, CompositingContainerStackedUnderFloatUnderStackingCompositedInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9; will-change: transform'>" - " <div style='float: right'>" - " <div id='target' style='position: relative'></div>" - " </div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9; will-change: transform'> + <div style='float: right'> + <div id='target' style='position: relative'></div> + </div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); PaintLayer* span = GetPaintLayerByElementId("span"); @@ -741,17 +772,18 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedUnderFloatUnderStackingInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9'>" - " <div style='float: right'>" - " <div id='target' style='overflow: hidden'></div>" - " </div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9'> + <div style='float: right'> + <div id='target' style='overflow: hidden'></div> + </div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); EXPECT_EQ(GetPaintLayerByElementId("containingBlock"), @@ -768,17 +800,18 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedUnderFloatUnderStackingCompositedInline) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <span id='span' style='opacity: 0.9; will-change: transform'>" - " <div style='float: right'>" - " <div id='target' style='overflow: hidden'></div>" - " </div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <span id='span' style='opacity: 0.9; will-change: transform'> + <div style='float: right'> + <div id='target' style='overflow: hidden'></div> + </div> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); EXPECT_EQ(GetPaintLayerByElementId("containingBlock"), @@ -793,19 +826,20 @@ } TEST_P(PaintLayerTest, FloatLayerAndAbsoluteUnderInlineLayer) { - SetBodyInnerHTML( - "<div id='container' style='position: absolute; top: 20px; left: 20px'>" - " <div style='margin: 33px'>" - " <span id='span' style='position: relative; top: 100px; left: 100px'>" - " <div id='floating'" - " style='float: left; position: relative; top: 50px; left: 50px'>" - " </div>" - " <div id='absolute'" - " style='position: absolute; top: 50px; left: 50px'>" - " </div>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: absolute; top: 20px; left: 20px'> + <div style='margin: 33px'> + <span id='span' style='position: relative; top: 100px; left: 100px'> + <div id='floating' + style='float: left; position: relative; top: 50px; left: 50px'> + </div> + <div id='absolute' + style='position: absolute; top: 50px; left: 50px'> + </div> + </span> + </div> + </div> + )HTML"); PaintLayer* floating = GetPaintLayerByElementId("floating"); PaintLayer* absolute = GetPaintLayerByElementId("absolute"); @@ -832,15 +866,16 @@ } TEST_P(PaintLayerTest, FloatLayerUnderInlineLayerScrolled) { - SetBodyInnerHTML( - "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>" - " <span id='span' style='position: relative; top: 100px; left: 100px'>" - " <div id='floating'" - " style='float: left; position: relative; top: 50px; left: 50px'>" - " </div>" - " </span>" - " <div style='height: 1000px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='overflow: scroll; width: 50px; height: 50px'> + <span id='span' style='position: relative; top: 100px; left: 100px'> + <div id='floating' + style='float: left; position: relative; top: 50px; left: 50px'> + </div> + </span> + <div style='height: 1000px'></div> + </div> + )HTML"); PaintLayer* floating = GetPaintLayerByElementId("floating"); PaintLayer* span = GetPaintLayerByElementId("span"); @@ -862,15 +897,16 @@ } TEST_P(PaintLayerTest, FloatLayerUnderBlockUnderInlineLayer) { - SetBodyInnerHTML( - "<style>body {margin: 0}</style>" - "<span id='span' style='position: relative; top: 100px; left: 100px'>" - " <div style='display: inline-block; margin: 33px'>" - " <div id='floating'" - " style='float: left; position: relative; top: 50px; left: 50px'>" - " </div>" - " </div>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <style>body {margin: 0}</style> + <span id='span' style='position: relative; top: 100px; left: 100px'> + <div style='display: inline-block; margin: 33px'> + <div id='floating' + style='float: left; position: relative; top: 50px; left: 50px'> + </div> + </div> + </span> + )HTML"); PaintLayer* floating = GetPaintLayerByElementId("floating"); PaintLayer* span = GetPaintLayerByElementId("span"); @@ -886,15 +922,16 @@ } TEST_P(PaintLayerTest, FloatLayerUnderFloatUnderInlineLayer) { - SetBodyInnerHTML( - "<style>body {margin: 0}</style>" - "<span id='span' style='position: relative; top: 100px; left: 100px'>" - " <div style='float: left; margin: 33px'>" - " <div id='floating'" - " style='float: left; position: relative; top: 50px; left: 50px'>" - " </div>" - " </div>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <style>body {margin: 0}</style> + <span id='span' style='position: relative; top: 100px; left: 100px'> + <div style='float: left; margin: 33px'> + <div id='floating' + style='float: left; position: relative; top: 50px; left: 50px'> + </div> + </div> + </span> + )HTML"); PaintLayer* floating = GetPaintLayerByElementId("floating"); PaintLayer* span = GetPaintLayerByElementId("span"); @@ -910,16 +947,17 @@ } TEST_P(PaintLayerTest, FloatLayerUnderFloatLayerUnderInlineLayer) { - SetBodyInnerHTML( - "<style>body {margin: 0}</style>" - "<span id='span' style='position: relative; top: 100px; left: 100px'>" - " <div id='floatingParent'" - " style='float: left; position: relative; margin: 33px'>" - " <div id='floating'" - " style='float: left; position: relative; top: 50px; left: 50px'>" - " </div>" - " </div>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <style>body {margin: 0}</style> + <span id='span' style='position: relative; top: 100px; left: 100px'> + <div id='floatingParent' + style='float: left; position: relative; margin: 33px'> + <div id='floating' + style='float: left; position: relative; top: 50px; left: 50px'> + </div> + </div> + </span> + )HTML"); PaintLayer* floating = GetPaintLayerByElementId("floating"); PaintLayer* floating_parent = GetPaintLayerByElementId("floatingParent"); @@ -941,16 +979,17 @@ } TEST_P(PaintLayerTest, LayerUnderFloatUnderInlineLayer) { - SetBodyInnerHTML( - "<style>body {margin: 0}</style>" - "<span id='span' style='position: relative; top: 100px; left: 100px'>" - " <div style='float: left; margin: 33px'>" - " <div>" - " <div id='child' style='position: relative; top: 50px; left: 50px'>" - " </div>" - " </div>" - " </div>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <style>body {margin: 0}</style> + <span id='span' style='position: relative; top: 100px; left: 100px'> + <div style='float: left; margin: 33px'> + <div> + <div id='child' style='position: relative; top: 50px; left: 50px'> + </div> + </div> + </div> + </span> + )HTML"); PaintLayer* child = GetPaintLayerByElementId("child"); PaintLayer* span = GetPaintLayerByElementId("span"); @@ -967,17 +1006,18 @@ TEST_P(PaintLayerTest, CompositingContainerFloatingIframe) { EnableCompositing(); - SetBodyInnerHTML( - "<div id='compositedContainer' style='position: relative;" - " will-change: transform'>" - " <div id='containingBlock' style='position: relative; z-index: 0'>" - " <div style='backface-visibility: hidden'></div>" - " <span id='span'" - " style='clip-path: polygon(0px 15px, 0px 54px, 100px 0px)'>" - " <iframe srcdoc='foo' id='target' style='float: right'></iframe>" - " </span>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='compositedContainer' style='position: relative; + will-change: transform'> + <div id='containingBlock' style='position: relative; z-index: 0'> + <div style='backface-visibility: hidden'></div> + <span id='span' + style='clip-path: polygon(0px 15px, 0px 54px, 100px 0px)'> + <iframe srcdoc='foo' id='target' style='float: right'></iframe> + </span> + </div> + </div> + )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); @@ -998,12 +1038,13 @@ } TEST_P(PaintLayerTest, CompositingContainerSelfPaintingNonStackedFloat) { - SetBodyInnerHTML( - "<div id='container' style='position: relative'>" - " <span id='span' style='opacity: 0.9'>" - " <div id='target' style='columns: 1; float: left'></div>" - " </span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: relative'> + <span id='span' style='opacity: 0.9'> + <div id='target' style='columns: 1; float: left'></div> + </span> + </div> + )HTML"); // The target layer is self-painting, but not stacked. PaintLayer* target = GetPaintLayerByElementId("target"); @@ -1017,17 +1058,18 @@ } TEST_P(PaintLayerTest, ColumnSpanLayerUnderExtraLayerScrolled) { - SetBodyInnerHTML( - "<div id='columns' style='overflow: hidden; width: 80px; height: 80px; " - " columns: 2; column-gap: 0'>" - " <div id='extraLayer'" - " style='position: relative; top: 100px; left: 100px'>" - " <div id='spanner' style='column-span: all; position: relative; " - " top: 50px; left: 50px'>" - " </div>" - " </div>" - " <div style='height: 1000px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='columns' style='overflow: hidden; width: 80px; height: 80px; + columns: 2; column-gap: 0'> + <div id='extraLayer' + style='position: relative; top: 100px; left: 100px'> + <div id='spanner' style='column-span: all; position: relative; + top: 50px; left: 50px'> + </div> + </div> + <div style='height: 1000px'></div> + </div> + )HTML"); PaintLayer* spanner = GetPaintLayerByElementId("spanner"); PaintLayer* extra_layer = GetPaintLayerByElementId("extraLayer"); @@ -1068,12 +1110,13 @@ } TEST_P(PaintLayerTest, NeedsRepaintOnSelfPaintingStatusChange) { - SetBodyInnerHTML( - "<span id='span' style='opacity: 0.1'>" - " <div id='target' style='overflow: hidden; float: left;" - " column-width: 10px'>" - " </div>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <span id='span' style='opacity: 0.1'> + <div id='target' style='overflow: hidden; float: left; + column-width: 10px'> + </div> + </span> + )HTML"); auto* span_layer = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"))->Layer();
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp index bc247cdc..555a933 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -279,13 +279,14 @@ } TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRL) { - SetBodyInnerHTML( - "<style>::-webkit-scrollbar {width: 15px; height: 15px}</style>" - "<div id='scroller'" - " style='width: 100px; height: 100px; overflow: scroll; " - " writing-mode: vertical-rl; border: 10px solid blue'>" - " <div style='width: 400px; height: 400px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>::-webkit-scrollbar {width: 15px; height: 15px}</style> + <div id='scroller' + style='width: 100px; height: 100px; overflow: scroll; + writing-mode: vertical-rl; border: 10px solid blue'> + <div style='width: 400px; height: 400px'></div> + </div> + )HTML"); const auto* properties = PaintPropertiesForElement("scroller"); const auto* overflow_clip = properties->OverflowClip(); @@ -309,13 +310,14 @@ } TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollRTL) { - SetBodyInnerHTML( - "<style>::-webkit-scrollbar {width: 15px; height: 15px}</style>" - "<div id='scroller'" - " style='width: 100px; height: 100px; overflow: scroll; " - " direction: rtl; border: 10px solid blue'>" - " <div style='width: 400px; height: 400px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>::-webkit-scrollbar {width: 15px; height: 15px}</style> + <div id='scroller' + style='width: 100px; height: 100px; overflow: scroll; + direction: rtl; border: 10px solid blue'> + <div style='width: 400px; height: 400px'></div> + </div> + )HTML"); const auto* properties = PaintPropertiesForElement("scroller"); const auto* overflow_clip = properties->OverflowClip(); @@ -363,25 +365,26 @@ } TEST_P(PaintPropertyTreeBuilderTest, Perspective) { - SetBodyInnerHTML( - "<style>" - " #perspective {" - " position: absolute;" - " left: 50px;" - " top: 100px;" - " width: 400px;" - " height: 300px;" - " perspective: 100px;" - " }" - " #inner {" - " transform: translateZ(0);" - " width: 100px;" - " height: 200px;" - " }" - "</style>" - "<div id='perspective'>" - " <div id='inner'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #perspective { + position: absolute; + left: 50px; + top: 100px; + width: 400px; + height: 300px; + perspective: 100px; + } + #inner { + transform: translateZ(0); + width: 100px; + height: 200px; + } + </style> + <div id='perspective'> + <div id='inner'></div> + </div> + )HTML"); Element* perspective = GetDocument().getElementById("perspective"); const ObjectPaintProperties* perspective_properties = perspective->GetLayoutObject() @@ -430,12 +433,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, Transform) { - SetBodyInnerHTML( - "<style> body { margin: 0 } </style>" - "<div id='transform' style='margin-left: 50px; margin-top: 100px;" - " width: 400px; height: 300px;" - " transform: translate3d(123px, 456px, 789px)'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0 } </style> + <div id='transform' style='margin-left: 50px; margin-top: 100px; + width: 400px; height: 300px; + transform: translate3d(123px, 456px, 789px)'> + </div> + )HTML"); Element* transform = GetDocument().getElementById("transform"); const ObjectPaintProperties* transform_properties = @@ -480,14 +484,15 @@ } TEST_P(PaintPropertyTreeBuilderTest, Preserve3D3DTransformedDescendant) { - SetBodyInnerHTML( - "<style> body { margin: 0 } </style>" - "<div id='preserve' style='transform-style: preserve-3d'>" - "<div id='transform' style='margin-left: 50px; margin-top: 100px;" - " width: 400px; height: 300px;" - " transform: translate3d(123px, 456px, 789px)'>" - "</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0 } </style> + <div id='preserve' style='transform-style: preserve-3d'> + <div id='transform' style='margin-left: 50px; margin-top: 100px; + width: 400px; height: 300px; + transform: translate3d(123px, 456px, 789px)'> + </div> + </div> + )HTML"); Element* preserve = GetDocument().getElementById("preserve"); const ObjectPaintProperties* preserve_properties = @@ -498,14 +503,15 @@ } TEST_P(PaintPropertyTreeBuilderTest, Perspective3DTransformedDescendant) { - SetBodyInnerHTML( - "<style> body { margin: 0 } </style>" - "<div id='perspective' style='perspective: 800px;'>" - "<div id='transform' style='margin-left: 50px; margin-top: 100px;" - " width: 400px; height: 300px;" - " transform: translate3d(123px, 456px, 789px)'>" - "</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0 } </style> + <div id='perspective' style='perspective: 800px;'> + <div id='transform' style='margin-left: 50px; margin-top: 100px; + width: 400px; height: 300px; + transform: translate3d(123px, 456px, 789px)'> + </div> + </div> + )HTML"); Element* perspective = GetDocument().getElementById("perspective"); const ObjectPaintProperties* perspective_properties = @@ -539,12 +545,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, WillChangeTransform) { - SetBodyInnerHTML( - "<style> body { margin: 0 } </style>" - "<div id='transform' style='margin-left: 50px; margin-top: 100px;" - " width: 400px; height: 300px;" - " will-change: transform'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0 } </style> + <div id='transform' style='margin-left: 50px; margin-top: 100px; + width: 400px; height: 300px; + will-change: transform'> + </div> + )HTML"); Element* transform = GetDocument().getElementById("transform"); const ObjectPaintProperties* transform_properties = @@ -583,12 +590,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, WillChangeContents) { - SetBodyInnerHTML( - "<style> body { margin: 0 } </style>" - "<div id='transform' style='margin-left: 50px; margin-top: 100px;" - " width: 400px; height: 300px;" - " will-change: transform, contents'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0 } </style> + <div id='transform' style='margin-left: 50px; margin-top: 100px; + width: 400px; height: 300px; + will-change: transform, contents'> + </div> + )HTML"); Element* transform = GetDocument().getElementById("transform"); EXPECT_EQ(nullptr, @@ -614,17 +622,18 @@ } TEST_P(PaintPropertyTreeBuilderTest, NestedOpacityEffect) { - SetBodyInnerHTML( - "<div id='nodeWithoutOpacity' style='width: 100px; height: 200px'>" - " <div id='childWithOpacity'" - " style='opacity: 0.5; width: 50px; height: 60px;'>" - " <div id='grandChildWithoutOpacity'" - " style='width: 20px; height: 30px'>" - " <div id='greatGrandChildWithOpacity'" - " style='opacity: 0.2; width: 10px; height: 15px'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='nodeWithoutOpacity' style='width: 100px; height: 200px'> + <div id='childWithOpacity' + style='opacity: 0.5; width: 50px; height: 60px;'> + <div id='grandChildWithoutOpacity' + style='width: 20px; height: 30px'> + <div id='greatGrandChildWithOpacity' + style='opacity: 0.2; width: 10px; height: 15px'></div> + </div> + </div> + </div> + )HTML"); LayoutObject* node_without_opacity = GetLayoutObjectByElementId("nodeWithoutOpacity"); @@ -669,29 +678,30 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformNodeDoesNotAffectEffectNodes) { - SetBodyInnerHTML( - "<style>" - " #nodeWithOpacity {" - " opacity: 0.6;" - " width: 100px;" - " height: 200px;" - " }" - " #childWithTransform {" - " transform: translate3d(10px, 10px, 0px);" - " width: 50px;" - " height: 60px;" - " }" - " #grandChildWithOpacity {" - " opacity: 0.4;" - " width: 20px;" - " height: 30px;" - " }" - "</style>" - "<div id='nodeWithOpacity'>" - " <div id='childWithTransform'>" - " <div id='grandChildWithOpacity'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #nodeWithOpacity { + opacity: 0.6; + width: 100px; + height: 200px; + } + #childWithTransform { + transform: translate3d(10px, 10px, 0px); + width: 50px; + height: 60px; + } + #grandChildWithOpacity { + opacity: 0.4; + width: 20px; + height: 30px; + } + </style> + <div id='nodeWithOpacity'> + <div id='childWithTransform'> + <div id='grandChildWithOpacity'></div> + </div> + </div> + )HTML"); LayoutObject* node_with_opacity = GetLayoutObjectByElementId("nodeWithOpacity"); @@ -729,15 +739,16 @@ } TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossStackingContext) { - SetBodyInnerHTML( - "<div id='nodeWithOpacity'" - " style='opacity: 0.6; width: 100px; height: 200px'>" - " <div id='childWithStackingContext'" - " style='position:absolute; width: 50px; height: 60px;'>" - " <div id='grandChildWithOpacity'" - " style='opacity: 0.4; width: 20px; height: 30px'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='nodeWithOpacity' + style='opacity: 0.6; width: 100px; height: 200px'> + <div id='childWithStackingContext' + style='position:absolute; width: 50px; height: 60px;'> + <div id='grandChildWithOpacity' + style='opacity: 0.4; width: 20px; height: 30px'></div> + </div> + </div> + )HTML"); LayoutObject* node_with_opacity = GetLayoutObjectByElementId("nodeWithOpacity"); @@ -775,16 +786,17 @@ } TEST_P(PaintPropertyTreeBuilderTest, EffectNodesInSVG) { - SetBodyInnerHTML( - "<svg id='svgRoot'>" - " <g id='groupWithOpacity' opacity='0.6'>" - " <rect id='rectWithoutOpacity' />" - " <rect id='rectWithOpacity' opacity='0.4' />" - " <text id='textWithOpacity' opacity='0.2'>" - " <tspan id='tspanWithOpacity' opacity='0.1' />" - " </text>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svgRoot'> + <g id='groupWithOpacity' opacity='0.6'> + <rect id='rectWithoutOpacity' /> + <rect id='rectWithOpacity' opacity='0.4' /> + <text id='textWithOpacity' opacity='0.2'> + <tspan id='tspanWithOpacity' opacity='0.1' /> + </text> + </g> + </svg> + )HTML"); LayoutObject* group_with_opacity = GetLayoutObjectByElementId("groupWithOpacity"); const ObjectPaintProperties* group_with_opacity_properties = @@ -832,12 +844,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossHTMLSVGBoundary) { - SetBodyInnerHTML( - "<div id='divWithOpacity' style='opacity: 0.2;'>" - " <svg id='svgRootWithOpacity' style='opacity: 0.3;'>" - " <rect id='rectWithOpacity' opacity='0.4' />" - " </svg>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='divWithOpacity' style='opacity: 0.2;'> + <svg id='svgRootWithOpacity' style='opacity: 0.3;'> + <rect id='rectWithOpacity' opacity='0.4' /> + </svg> + </div> + )HTML"); LayoutObject& div_with_opacity = *GetLayoutObjectByElementId("divWithOpacity"); @@ -867,14 +880,15 @@ } TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossSVGHTMLBoundary) { - SetBodyInnerHTML( - "<svg id='svgRootWithOpacity' style='opacity: 0.3;'>" - " <foreignObject id='foreignObjectWithOpacity' opacity='0.4'>" - " <body>" - " <span id='spanWithOpacity' style='opacity: 0.5'/>" - " </body>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svgRootWithOpacity' style='opacity: 0.3;'> + <foreignObject id='foreignObjectWithOpacity' opacity='0.4'> + <body> + <span id='spanWithOpacity' style='opacity: 0.5'/> + </body> + </foreignObject> + </svg> + )HTML"); LayoutObject& svg_root_with_opacity = *GetLayoutObjectByElementId("svgRootWithOpacity"); @@ -907,26 +921,27 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInSVG) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0px;" - " }" - " svg {" - " margin-left: 50px;" - " transform: translate3d(1px, 2px, 3px);" - " position: absolute;" - " left: 20px;" - " top: 25px;" - " }" - " rect {" - " transform: translate(100px, 100px) rotate(45deg);" - " transform-origin: 50px 25px;" - " }" - "</style>" - "<svg id='svgRootWith3dTransform' width='100px' height='100px'>" - " <rect id='rectWith2dTransform' width='100px' height='100px' />" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0px; + } + svg { + margin-left: 50px; + transform: translate3d(1px, 2px, 3px); + position: absolute; + left: 20px; + top: 25px; + } + rect { + transform: translate(100px, 100px) rotate(45deg); + transform-origin: 50px 25px; + } + </style> + <svg id='svgRootWith3dTransform' width='100px' height='100px'> + <rect id='rectWith2dTransform' width='100px' height='100px' /> + </svg> + )HTML"); LayoutObject& svg_root_with3d_transform = *GetDocument() @@ -965,26 +980,27 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGViewBoxTransform) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0px;" - " }" - " #svgWithViewBox {" - " transform: translate3d(1px, 2px, 3px);" - " position: absolute;" - " width: 100px;" - " height: 100px;" - " }" - " #rect {" - " transform: translate(100px, 100px);" - " width: 100px;" - " height: 100px;" - " }" - "</style>" - "<svg id='svgWithViewBox' viewBox='50 50 100 100'>" - " <rect id='rect' />" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0px; + } + #svgWithViewBox { + transform: translate3d(1px, 2px, 3px); + position: absolute; + width: 100px; + height: 100px; + } + #rect { + transform: translate(100px, 100px); + width: 100px; + height: 100px; + } + </style> + <svg id='svgWithViewBox' viewBox='50 50 100 100'> + <rect id='rect' /> + </svg> + )HTML"); LayoutObject& svg_with_view_box = *GetLayoutObjectByElementId("svgWithViewBox"); @@ -1009,17 +1025,18 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGRootPaintOffsetTransformNode) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0px; }" - " #svg {" - " margin-left: 50px;" - " margin-top: 25px;" - " width: 100px;" - " height: 100px;" - " }" - "</style>" - "<svg id='svg' />"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0px; } + #svg { + margin-left: 50px; + margin-top: 25px; + width: 100px; + height: 100px; + } + </style> + <svg id='svg' /> + )HTML"); LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = @@ -1034,19 +1051,20 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGRootLocalToBorderBoxTransformNode) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0px; }" - " svg {" - " margin-left: 2px;" - " margin-top: 3px;" - " transform: translate(5px, 7px);" - " border: 11px solid green;" - " }" - "</style>" - "<svg id='svg' width='100px' height='100px' viewBox='0 0 13 13'>" - " <rect id='rect' transform='translate(17 19)' />" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0px; } + svg { + margin-left: 2px; + margin-top: 3px; + transform: translate(5px, 7px); + border: 11px solid green; + } + </style> + <svg id='svg' width='100px' height='100px' viewBox='0 0 13 13'> + <rect id='rect' transform='translate(17 19)' /> + </svg> + )HTML"); LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = @@ -1074,14 +1092,15 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGNestedViewboxTransforms) { - SetBodyInnerHTML( - "<style>body { margin: 0px; } </style>" - "<svg id='svg' width='100px' height='100px' viewBox='0 0 50 50'" - " style='transform: translate(11px, 11px);'>" - " <svg id='nestedSvg' width='50px' height='50px' viewBox='0 0 5 5'>" - " <rect id='rect' transform='translate(13 13)' />" - " </svg>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0px; } </style> + <svg id='svg' width='100px' height='100px' viewBox='0 0 50 50' + style='transform: translate(11px, 11px);'> + <svg id='nestedSvg' width='50px' height='50px' viewBox='0 0 5 5'> + <rect id='rect' transform='translate(13 13)' /> + </svg> + </svg> + )HTML"); LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = @@ -1110,17 +1129,18 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSVGHTMLBoundary) { - SetBodyInnerHTML( - "<style> body { margin: 0px; } </style>" - "<svg id='svgWithTransform'" - " style='transform: translate3d(1px, 2px, 3px);'>" - " <foreignObject>" - " <body>" - " <div id='divWithTransform'" - " style='transform: translate3d(3px, 4px, 5px);'></div>" - " </body>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0px; } </style> + <svg id='svgWithTransform' + style='transform: translate3d(1px, 2px, 3px);'> + <foreignObject> + <body> + <div id='divWithTransform' + style='transform: translate3d(3px, 4px, 5px);'></div> + </body> + </foreignObject> + </svg> + )HTML"); LayoutObject& svg_with_transform = *GetLayoutObjectByElementId("svgWithTransform"); @@ -1141,15 +1161,16 @@ } TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetTranslationSVGHTMLBoundary) { - SetBodyInnerHTML( - "<svg id='svg'" - " <foreignObject>" - " <body>" - " <div id='divWithTransform'" - " style='transform: translate3d(3px, 4px, 5px);'></div>" - " </body>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg' + <foreignObject> + <body> + <div id='divWithTransform' + style='transform: translate3d(3px, 4px, 5px);'></div> + </body> + </foreignObject> + </svg> + )HTML"); LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = @@ -1174,16 +1195,17 @@ TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetTranslationSVGHTMLBoundaryMulticol) { - SetBodyInnerHTML( - "<svg id='svg'>" - " <foreignObject>" - " <body>" - " <div id='divWithColumns' style='columns: 2'>" - " <div style='width: 5px; height: 5px; background: blue'>" - " </div>" - " </body>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg'> + <foreignObject> + <body> + <div id='divWithColumns' style='columns: 2'> + <div style='width: 5px; height: 5px; background: blue'> + </div> + </body> + </foreignObject> + </svg> + )HTML"); LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = @@ -1198,18 +1220,19 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedTransformAncestorAcrossSVGHTMLBoundary) { - SetBodyInnerHTML( - "<style> body { margin: 0px; } </style>" - "<svg id='svg' style='transform: translate3d(1px, 2px, 3px);'>" - " <g id='container' transform='translate(20 30)'>" - " <foreignObject>" - " <body>" - " <div id='fixed'" - " style='position: fixed; left: 200px; top: 150px;'></div>" - " </body>" - " </foreignObject>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> body { margin: 0px; } </style> + <svg id='svg' style='transform: translate3d(1px, 2px, 3px);'> + <g id='container' transform='translate(20 30)'> + <foreignObject> + <body> + <div id='fixed' + style='position: fixed; left: 200px; top: 150px;'></div> + </body> + </foreignObject> + </g> + </svg> + )HTML"); LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = @@ -1236,19 +1259,20 @@ } TEST_P(PaintPropertyTreeBuilderTest, ControlClip) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0;" - " }" - " input {" - " border-radius: 0;" - " border-width: 5px;" - " padding: 0;" - " }" - "</style>" - "<input id='button' type='button'" - " style='width:345px; height:123px' value='some text'/>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0; + } + input { + border-radius: 0; + border-width: 5px; + padding: 0; + } + </style> + <input id='button' type='button' + style='width:345px; height:123px' value='some text'/> + )HTML"); LayoutObject& button = *GetLayoutObjectByElementId("button"); const ObjectPaintProperties* button_properties = @@ -1266,17 +1290,18 @@ } TEST_P(PaintPropertyTreeBuilderTest, ControlClipInsideForeignObject) { - SetBodyInnerHTML( - "<div style='column-count:2;'>" - " <div style='columns: 2'>" - " <svg style='width: 500px; height: 500px;'>" - " <foreignObject>" - " <input id='button' style='width:345px; height:123px'" - " value='some text'/>" - " </foreignObject>" - " </svg>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='column-count:2;'> + <div style='columns: 2'> + <svg style='width: 500px; height: 500px;'> + <foreignObject> + <input id='button' style='width:345px; height:123px' + value='some text'/> + </foreignObject> + </svg> + </div> + </div> + )HTML"); LayoutObject& button = *GetLayoutObjectByElementId("button"); const ObjectPaintProperties* button_properties = @@ -1291,23 +1316,24 @@ } TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0px;" - " }" - " #div {" - " border-radius: 12px 34px 56px 78px;" - " border-top: 45px solid;" - " border-right: 50px solid;" - " border-bottom: 55px solid;" - " border-left: 60px solid;" - " width: 500px;" - " height: 400px;" - " overflow: scroll;" - " }" - "</style>" - "<div id='div'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0px; + } + #div { + border-radius: 12px 34px 56px 78px; + border-top: 45px solid; + border-right: 50px solid; + border-bottom: 55px solid; + border-left: 60px solid; + width: 500px; + height: 400px; + overflow: scroll; + } + </style> + <div id='div'></div> + )HTML"); LayoutObject& div = *GetLayoutObjectByElementId("div"); const ObjectPaintProperties* div_properties = @@ -1348,26 +1374,28 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " #divWithTransform {" - " transform: translate3d(1px, 2px, 3px);" - " }" - "</style>" - "<div id='divWithTransform'>" - " <iframe style='border: 7px solid black'></iframe>" - "</div>"); - SetChildFrameHTML( - "<style>" - " body { margin: 0; }" - " #innerDivWithTransform {" - " transform: translate3d(4px, 5px, 6px);" - " width: 100px;" - " height: 200px;" - " }" - "</style>" - "<div id='innerDivWithTransform'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #divWithTransform { + transform: translate3d(1px, 2px, 3px); + } + </style> + <div id='divWithTransform'> + <iframe style='border: 7px solid black'></iframe> + </div> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + body { margin: 0; } + #innerDivWithTransform { + transform: translate3d(4px, 5px, 6px); + width: 100px; + height: 200px; + } + </style> + <div id='innerDivWithTransform'></div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); frame_view->UpdateAllLifecyclePhases(); @@ -1417,31 +1445,33 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInTransformedSubframes) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " #divWithTransform {" - " transform: translate3d(1px, 2px, 3px);" - " }" - " iframe {" - " transform: translate3d(4px, 5px, 6px);" - " border: 42px solid;" - " margin: 7px;" - " }" - "</style>" - "<div id='divWithTransform'>" - " <iframe></iframe>" - "</div>"); - SetChildFrameHTML( - "<style>" - " body { margin: 31px; }" - " #transform {" - " transform: translate3d(7px, 8px, 9px);" - " width: 100px;" - " height: 200px;" - " }" - "</style>" - "<div id='transform'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #divWithTransform { + transform: translate3d(1px, 2px, 3px); + } + iframe { + transform: translate3d(4px, 5px, 6px); + border: 42px solid; + margin: 7px; + } + </style> + <div id='divWithTransform'> + <iframe></iframe> + </div> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + body { margin: 31px; } + #transform { + transform: translate3d(7px, 8px, 9px); + width: 100px; + height: 200px; + } + </style> + <div id='transform'></div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); frame_view->UpdateAllLifecyclePhases(); @@ -1498,13 +1528,14 @@ // This test verifies the tree builder correctly computes and records the // property tree context for a (pseudo) stacking context that is scrolled by a // containing block that is not one of the painting ancestors. - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='scroller' style='overflow:scroll; width:400px; height:300px;'>" - " <div id='child'" - " style='position:relative; width:100px; height: 200px;'></div>" - " <div style='height:10000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='scroller' style='overflow:scroll; width:400px; height:300px;'> + <div id='child' + style='position:relative; width:100px; height: 200px;'></div> + <div style='height:10000px;'></div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* scroller = GetLayoutObjectByElementId("scroller"); @@ -1539,25 +1570,26 @@ // painting ancestor that is not its containing block (thus should not be // scrolled by it). - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " #scroller {" - " overflow:scroll;" - " opacity:0.5;" - " }" - " #child {" - " position:absolute;" - " left:0;" - " top:0;" - " width: 100px;" - " height: 200px;" - " }" - "</style>" - "<div id='scroller'>" - " <div id='child'></div>" - " <div id='forceScroll' style='height:10000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #scroller { + overflow:scroll; + opacity:0.5; + } + #child { + position:absolute; + left:0; + top:0; + width: 100px; + height: 200px; + } + </style> + <div id='scroller'> + <div id='child'></div> + <div id='forceScroll' style='height:10000px;'></div> + </div> + )HTML"); auto& scroller = *GetLayoutObjectByElementId("scroller"); const ObjectPaintProperties* scroller_properties = @@ -1586,32 +1618,33 @@ // This test verifies that the border box space of a table cell is being // correctly computed. Table cells have weird location adjustment in our // layout/paint implementation. - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0;" - " }" - " table {" - " border-spacing: 0;" - " margin: 20px;" - " padding: 40px;" - " border: 10px solid black;" - " }" - " td {" - " width: 100px;" - " height: 100px;" - " padding: 0;" - " }" - " #target {" - " position: relative;" - " width: 100px;" - " height: 100px;" - " }" - "</style>" - "<table>" - " <tr><td></td><td></td></tr>" - " <tr><td></td><td><div id='target'></div></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0; + } + table { + border-spacing: 0; + margin: 20px; + padding: 40px; + border: 10px solid black; + } + td { + width: 100px; + height: 100px; + padding: 0; + } + #target { + position: relative; + width: 100px; + height: 100px; + } + </style> + <table> + <tr><td></td><td></td></tr> + <tr><td></td><td><div id='target'></div></td></tr> + </table> + )HTML"); LayoutObject& target = *GetLayoutObjectByElementId("target"); EXPECT_EQ(LayoutPoint(170, 170), target.FirstFragment().PaintOffset()); @@ -1627,25 +1660,26 @@ // This test verifies that clip tree hierarchy being generated correctly for // the hard case such that a fixed position element getting clipped by an // absolute position CSS clip. - SetBodyInnerHTML( - "<style>" - " #clip {" - " position: absolute;" - " left: 123px;" - " top: 456px;" - " clip: rect(10px, 80px, 70px, 40px);" - " width: 100px;" - " height: 100px;" - " }" - " #fixed {" - " position: fixed;" - " left: 654px;" - " top: 321px;" - " width: 10px;" - " height: 20px" - " }" - "</style>" - "<div id='clip'><div id='fixed'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #clip { + position: absolute; + left: 123px; + top: 456px; + clip: rect(10px, 80px, 70px, 40px); + width: 100px; + height: 100px; + } + #fixed { + position: fixed; + left: 654px; + top: 321px; + width: 10px; + height: 20px + } + </style> + <div id='clip'><div id='fixed'></div></div> + )HTML"); LayoutRect local_clip_rect(40, 10, 40, 60); LayoutRect absolute_clip_rect = local_clip_rect; absolute_clip_rect.Move(123, 456); @@ -1685,25 +1719,26 @@ // This test verifies that clip tree hierarchy being generated correctly for // the hard case such that a fixed position element getting clipped by an // absolute position CSS clip. - SetBodyInnerHTML( - "<style>" - " #clip {" - " position: absolute;" - " left: 123px;" - " top: 456px;" - " clip: rect(10px, 80px, 70px, 40px);" - " width: 100px;" - " height: 100px;" - " }" - " #absolute {" - " position: absolute;" - " left: 654px;" - " top: 321px;" - " width: 10px;" - " heght: 20px" - " }" - "</style>" - "<div id='clip'><div id='absolute'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #clip { + position: absolute; + left: 123px; + top: 456px; + clip: rect(10px, 80px, 70px, 40px); + width: 100px; + height: 100px; + } + #absolute { + position: absolute; + left: 654px; + top: 321px; + width: 10px; + heght: 20px + } + </style> + <div id='clip'><div id='absolute'></div></div> + )HTML"); LayoutRect local_clip_rect(40, 10, 40, 60); LayoutRect absolute_clip_rect = local_clip_rect; @@ -1748,32 +1783,33 @@ // This test is similar to CSSClipFixedPositionDescendant above, except that // now we have a parent overflow clip that should be escaped by the fixed // descendant. - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0;" - " }" - " #overflow {" - " position: relative;" - " width: 50px;" - " height: 50px;" - " overflow: scroll;" - " }" - " #clip {" - " position: absolute;" - " left: 123px;" - " top: 456px;" - " clip: rect(10px, 80px, 70px, 40px);" - " width: 100px;" - " height: 100px;" - " }" - " #fixed {" - " position: fixed;" - " left: 654px;" - " top: 321px;" - " }" - "</style>" - "<div id='overflow'><div id='clip'><div id='fixed'></div></div></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0; + } + #overflow { + position: relative; + width: 50px; + height: 50px; + overflow: scroll; + } + #clip { + position: absolute; + left: 123px; + top: 456px; + clip: rect(10px, 80px, 70px, 40px); + width: 100px; + height: 100px; + } + #fixed { + position: fixed; + left: 654px; + top: 321px; + } + </style> + <div id='overflow'><div id='clip'><div id='fixed'></div></div></div> + )HTML"); LayoutRect local_clip_rect(40, 10, 40, 60); LayoutRect absolute_clip_rect = local_clip_rect; absolute_clip_rect.Move(123, 456); @@ -1826,20 +1862,21 @@ } TEST_P(PaintPropertyTreeBuilderTest, ColumnSpannerUnderRelativePositioned) { - SetBodyInnerHTML( - "<style>" - " #spanner {" - " column-span: all;" - " opacity: 0.5;" - " width: 100px;" - " height: 100px;" - " }" - "</style>" - "<div style='columns: 3; position: absolute; top: 44px; left: 55px;'>" - " <div style='position: relative; top: 100px; left: 100px'>" - " <div id='spanner'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #spanner { + column-span: all; + opacity: 0.5; + width: 100px; + height: 100px; + } + </style> + <div style='columns: 3; position: absolute; top: 44px; left: 55px;'> + <div style='position: relative; top: 100px; left: 100px'> + <div id='spanner'></div> + </div> + </div> + )HTML"); LayoutObject* spanner = GetLayoutObjectByElementId("spanner"); EXPECT_EQ(LayoutPoint(55, 44), spanner->FirstFragment().PaintOffset()); @@ -1848,26 +1885,27 @@ } TEST_P(PaintPropertyTreeBuilderTest, FractionalPaintOffset) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " div { position: absolute; }" - " #a {" - " width: 70px;" - " height: 70px;" - " left: 0.1px;" - " top: 0.3px;" - " }" - " #b {" - " width: 40px;" - " height: 40px;" - " left: 0.5px;" - " top: 11.1px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + div { position: absolute; } + #a { + width: 70px; + height: 70px; + left: 0.1px; + top: 0.3px; + } + #b { + width: 40px; + height: 40px; + left: 0.5px; + top: 11.1px; + } + </style> + <div id='a'> + <div id='b'></div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -1887,33 +1925,34 @@ } TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetWithBasicPixelSnapping) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " div { position: relative; }" - " #a {" - " width: 70px;" - " height: 70px;" - " left: 0.3px;" - " top: 0.3px;" - " }" - " #b {" - " width: 40px;" - " height: 40px;" - " transform: translateZ(0);" - " }" - " #c {" - " width: 40px;" - " height: 40px;" - " left: 0.1px;" - " top: 0.1px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'>" - " <div id='c'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + div { position: relative; } + #a { + width: 70px; + height: 70px; + left: 0.3px; + top: 0.3px; + } + #b { + width: 40px; + height: 40px; + transform: translateZ(0); + } + #c { + width: 40px; + height: 40px; + left: 0.1px; + top: 0.1px; + } + </style> + <div id='a'> + <div id='b'> + <div id='c'></div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* b = GetLayoutObjectByElementId("b"); @@ -1944,33 +1983,34 @@ TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingThroughTransform) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " div { position: relative; }" - " #a {" - " width: 70px;" - " height: 70px;" - " left: 0.7px;" - " top: 0.7px;" - " }" - " #b {" - " width: 40px;" - " height: 40px;" - " transform: translateZ(0);" - " }" - " #c {" - " width: 40px;" - " height: 40px;" - " left: 0.7px;" - " top: 0.7px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'>" - " <div id='c'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + div { position: relative; } + #a { + width: 70px; + height: 70px; + left: 0.7px; + top: 0.7px; + } + #b { + width: 40px; + height: 40px; + transform: translateZ(0); + } + #c { + width: 40px; + height: 40px; + left: 0.7px; + top: 0.7px; + } + </style> + <div id='a'> + <div id='b'> + <div id='c'></div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* b = GetLayoutObjectByElementId("b"); @@ -2005,34 +2045,35 @@ TEST_P(PaintPropertyTreeBuilderTest, NonTranslationTransformShouldResetSubpixelPaintOffset) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " div { position: relative; }" - " #a {" - " width: 70px;" - " height: 70px;" - " left: 0.9px;" - " top: 0.9px;" - " }" - " #b {" - " width: 40px;" - " height: 40px;" - " transform: scale(10);" - " transform-origin: 0 0;" - " }" - " #c {" - " width: 40px;" - " height: 40px;" - " left: 0.6px;" - " top: 0.6px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'>" - " <div id='c'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + div { position: relative; } + #a { + width: 70px; + height: 70px; + left: 0.9px; + top: 0.9px; + } + #b { + width: 40px; + height: 40px; + transform: scale(10); + transform-origin: 0 0; + } + #c { + width: 40px; + height: 40px; + left: 0.6px; + top: 0.6px; + } + </style> + <div id='a'> + <div id='b'> + <div id='c'></div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* b = GetLayoutObjectByElementId("b"); @@ -2067,40 +2108,41 @@ TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingThroughMultipleTransforms) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " div { position: relative; }" - " #a {" - " width: 70px;" - " height: 70px;" - " left: 0.7px;" - " top: 0.7px;" - " }" - " #b {" - " width: 40px;" - " height: 40px;" - " transform: translate3d(5px, 7px, 0);" - " }" - " #c {" - " width: 40px;" - " height: 40px;" - " transform: translate3d(11px, 13px, 0);" - " }" - " #d {" - " width: 40px;" - " height: 40px;" - " left: 0.7px;" - " top: 0.7px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'>" - " <div id='c'>" - " <div id='d'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + div { position: relative; } + #a { + width: 70px; + height: 70px; + left: 0.7px; + top: 0.7px; + } + #b { + width: 40px; + height: 40px; + transform: translate3d(5px, 7px, 0); + } + #c { + width: 40px; + height: 40px; + transform: translate3d(11px, 13px, 0); + } + #d { + width: 40px; + height: 40px; + left: 0.7px; + top: 0.7px; + } + </style> + <div id='a'> + <div id='b'> + <div id='c'> + <div id='d'></div> + </div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* b = GetLayoutObjectByElementId("b"); @@ -2150,40 +2192,41 @@ } TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingWithFixedPos) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " #a {" - " width: 70px;" - " height: 70px;" - " left: 0.7px;" - " position: relative;" - " }" - " #b {" - " width: 40px;" - " height: 40px;" - " transform: translateZ(0);" - " position: relative;" - " }" - " #fixed {" - " width: 40px;" - " height: 40px;" - " position: fixed;" - " }" - " #d {" - " width: 40px;" - " height: 40px;" - " left: 0.7px;" - " position: relative;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'>" - " <div id='fixed'>" - " <div id='d'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #a { + width: 70px; + height: 70px; + left: 0.7px; + position: relative; + } + #b { + width: 40px; + height: 40px; + transform: translateZ(0); + position: relative; + } + #fixed { + width: 40px; + height: 40px; + position: fixed; + } + #d { + width: 40px; + height: 40px; + left: 0.7px; + position: relative; + } + </style> + <div id='a'> + <div id='b'> + <div id='fixed'> + <div id='d'></div> + </div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* b = GetLayoutObjectByElementId("b"); @@ -2223,17 +2266,18 @@ } TEST_P(PaintPropertyTreeBuilderTest, SvgPixelSnappingShouldResetPaintOffset) { - SetBodyInnerHTML( - "<style>" - " #svg {" - " position: relative;" - " left: 0.1px;" - " transform: matrix(1, 0, 0, 1, 0, 0);" - " }" - "</style>" - "<svg id='svg'>" - " <rect id='rect' transform='translate(1, 1)'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> + #svg { + position: relative; + left: 0.1px; + transform: matrix(1, 0, 0, 1, 0, 0); + } + </style> + <svg id='svg'> + <rect id='rect' transform='translate(1, 1)'/> + </svg> + )HTML"); LayoutObject& svg_with_transform = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_with_transform_properties = @@ -2258,13 +2302,14 @@ } TEST_P(PaintPropertyTreeBuilderTest, SvgRootAndForeignObjectPixelSnapping) { - SetBodyInnerHTML( - "<svg id=svg style='position: relative; left: 0.6px; top: 0.3px'>" - " <foreignObject id=foreign x='3.5' y='5.4' transform='translate(1, 1)'>" - " <div id=div style='position: absolute; left: 5.6px; top: 7.3px'>" - " </div>" - " </foreignObject>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id=svg style='position: relative; left: 0.6px; top: 0.3px'> + <foreignObject id=foreign x='3.5' y='5.4' transform='translate(1, 1)'> + <div id=div style='position: absolute; left: 5.6px; top: 7.3px'> + </div> + </foreignObject> + </svg> + )HTML"); const auto* svg = GetLayoutObjectByElementId("svg"); const auto* svg_properties = svg->FirstFragment().PaintProperties(); @@ -2305,13 +2350,14 @@ } TEST_P(PaintPropertyTreeBuilderTest, Preserve3DCreatesSharedRenderingContext) { - SetBodyInnerHTML( - "<div style='transform-style: preserve-3d'>" - " <div id='a'" - " style='transform: translateZ(0); width: 30px; height: 40px'></div>" - " <div id='b'" - " style='transform: translateZ(0); width: 20px; height: 10px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform-style: preserve-3d'> + <div id='a' style='transform: translateZ(0); width: 30px; height: 40px'> + </div> + <div id='b' style='transform: translateZ(0); width: 20px; height: 10px'> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2333,24 +2379,25 @@ } TEST_P(PaintPropertyTreeBuilderTest, FlatTransformStyleEndsRenderingContext) { - SetBodyInnerHTML( - "<style>" - " #a {" - " transform: translateZ(0);" - " width: 30px;" - " height: 40px;" - " }" - " #b {" - " transform: translateZ(0);" - " width: 10px;" - " height: 20px;" - " }" - "</style>" - "<div style='transform-style: preserve-3d'>" - " <div id='a'>" - " <div id='b'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #a { + transform: translateZ(0); + width: 30px; + height: 40px; + } + #b { + transform: translateZ(0); + width: 10px; + height: 20px; + } + </style> + <div style='transform-style: preserve-3d'> + <div id='a'> + <div id='b'></div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2374,17 +2421,17 @@ } TEST_P(PaintPropertyTreeBuilderTest, NestedRenderingContexts) { - SetBodyInnerHTML( - "<div style='transform-style: preserve-3d'>" - " <div id='a'" - " style='transform: translateZ(0); width: 50px; height: 60px'>" - " <div" - " style='transform-style: preserve-3d; width: 30px; height: 40px'>" - " <div id='b'" - " style='transform: translateZ(0); width: 10px; height: 20px'>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='transform-style: preserve-3d'> + <div id='a' style='transform: translateZ(0); width: 50px; height: 60px'> + <div style='transform-style: preserve-3d; width: 30px; height: 40px'> + <div id='b' + style='transform: translateZ(0); width: 10px; height: 20px'> + </div> + </div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2435,23 +2482,24 @@ } TEST_P(PaintPropertyTreeBuilderTest, FlatTransformStylePropagatesToChildren) { - SetBodyInnerHTML( - "<style>" - " #a {" - " transform: translateZ(0);" - " transform-style: flat;" - " width: 30px;" - " height: 40px;" - " }" - " #b {" - " transform: translateZ(0);" - " width: 10px;" - " height: 10px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #a { + transform: translateZ(0); + transform-style: flat; + width: 30px; + height: 40px; + } + #b { + transform: translateZ(0); + width: 10px; + height: 10px; + } + </style> + <div id='a'> + <div id='b'></div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2473,23 +2521,24 @@ TEST_P(PaintPropertyTreeBuilderTest, Preserve3DTransformStylePropagatesToChildren) { - SetBodyInnerHTML( - "<style>" - " #a {" - " transform: translateZ(0);" - " transform-style: preserve-3d;" - " width: 30px;" - " height: 40px;" - " }" - " #b {" - " transform: translateZ(0);" - " width: 10px;" - " height: 10px;" - " }" - "</style>" - "<div id='a'>" - " <div id='b'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #a { + transform: translateZ(0); + transform-style: preserve-3d; + width: 30px; + height: 40px; + } + #b { + transform: translateZ(0); + width: 10px; + height: 10px; + } + </style> + <div id='a'> + <div id='b'></div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2513,12 +2562,12 @@ // It's necessary to make nodes from the one that applies perspective to // ones that combine with it preserve 3D. Otherwise, the perspective doesn't // do anything. - SetBodyInnerHTML( - "<div id='a'" - " style='perspective: 800px; width: 30px; height: 40px'>" - " <div id='b'" - " style='transform: translateZ(0); width: 10px; height: 20px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='a' style='perspective: 800px; width: 30px; height: 40px'> + <div id='b' + style='transform: translateZ(0); width: 10px; height: 20px'></div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2544,12 +2593,12 @@ // It's necessary to make nodes from the one that applies perspective to // ones that combine with it preserve 3D. Otherwise, the perspective doesn't // do anything. - SetBodyInnerHTML( - "<div id='a'" - " style='perspective: 800px; width: 30px; height: 40px'>" - " <div id='b'" - " style='transform: translateZ(0); width: 10px; height: 20px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='a' style='perspective: 800px; width: 30px; height: 40px'> + <div id='b' + style='transform: translateZ(0); width: 10px; height: 20px'></div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); LayoutObject* a = GetLayoutObjectByElementId("a"); @@ -2571,16 +2620,17 @@ } TEST_P(PaintPropertyTreeBuilderTest, CachedProperties) { - SetBodyInnerHTML( - "<style>body { margin: 0 }</style>" - "<div id='a' style='transform: translate(33px, 44px); width: 50px; " - " height: 60px'>" - " <div id='b' style='transform: translate(55px, 66px); width: 30px; " - " height: 40px'>" - " <div id='c' style='transform: translate(77px, 88px); width: 10px; " - " height: 20px'>C<div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0 }</style> + <div id='a' style='transform: translate(33px, 44px); width: 50px; + height: 60px'> + <div id='b' style='transform: translate(55px, 66px); width: 30px; + height: 40px'> + <div id='c' style='transform: translate(77px, 88px); width: 10px; + height: 20px'>C<div> + </div> + </div> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); Element* a = GetDocument().getElementById("a"); @@ -2701,13 +2751,14 @@ // This test verifies the tree builder correctly computes and records the // property tree context for a (pseudo) stacking context that is scrolled by a // containing block that is not one of the painting ancestors. - SetBodyInnerHTML( - "<style>body { margin: 20px 30px; }</style>" - "<div id='clipper'" - " style='overflow: hidden; width: 400px; height: 300px;'>" - " <div id='child'" - " style='position: relative; width: 500px; height: 600px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 20px 30px; }</style> + <div id='clipper' + style='overflow: hidden; width: 400px; height: 300px;'> + <div id='child' + style='position: relative; width: 500px; height: 600px;'></div> + </div> + )HTML"); LayoutBoxModelObject* clipper = ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); @@ -2750,13 +2801,14 @@ } TEST_P(PaintPropertyTreeBuilderTest, ContainsPaintContentsTreeState) { - SetBodyInnerHTML( - "<style>body { margin: 20px 30px; }</style>" - "<div id='clipper'" - " style='contain: paint; width: 300px; height: 200px;'>" - " <div id='child'" - " style='position: relative; width: 400px; height: 500px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 20px 30px; }</style> + <div id='clipper' + style='contain: paint; width: 300px; height: 200px;'> + <div id='child' + style='position: relative; width: 400px; height: 500px;'></div> + </div> + )HTML"); LayoutBoxModelObject* clipper = ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); @@ -2802,14 +2854,15 @@ // This test verifies the tree builder correctly computes and records the // property tree context for a (pseudo) stacking context that is scrolled by a // containing block that is not one of the painting ancestors. - SetBodyInnerHTML( - "<style>body { margin: 20px 30px; }</style>" - "<div id='clipper' style='overflow:scroll; width:400px; height:300px;'>" - " <div id='child'" - " style='position:relative; width:500px; height: 600px;'></div>" - " <div style='width: 200px; height: 10000px'></div>" - "</div>" - "<div id='forceScroll' style='height: 4000px;'></div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 20px 30px; }</style> + <div id='clipper' style='overflow:scroll; width:400px; height:300px;'> + <div id='child' + style='position:relative; width:500px; height: 600px;'></div> + <div style='width: 200px; height: 10000px'></div> + </div> + <div id='forceScroll' style='height: 4000px;'></div> + )HTML"); Element* clipper_element = GetDocument().getElementById("clipper"); clipper_element->scrollTo(1, 2); @@ -2859,30 +2912,31 @@ } TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollWithRoundedRect) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " ::-webkit-scrollbar {" - " width: 13px;" - " height: 13px;" - " }" - " #roundedBox {" - " width: 200px;" - " height: 200px;" - " border-radius: 100px;" - " background-color: red;" - " border: 50px solid green;" - " overflow: scroll;" - " }" - " #roundedBoxChild {" - " width: 200px;" - " height: 200px;" - " background-color: orange;" - " }" - "</style>" - "<div id='roundedBox'>" - " <div id='roundedBoxChild'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + ::-webkit-scrollbar { + width: 13px; + height: 13px; + } + #roundedBox { + width: 200px; + height: 200px; + border-radius: 100px; + background-color: red; + border: 50px solid green; + overflow: scroll; + } + #roundedBoxChild { + width: 200px; + height: 200px; + background-color: orange; + } + </style> + <div id='roundedBox'> + <div id='roundedBoxChild'></div> + </div> + )HTML"); LayoutObject& rounded_box = *GetLayoutObjectByElementId("roundedBox"); const ObjectPaintProperties* rounded_box_properties = @@ -2906,13 +2960,14 @@ // This test verifies the tree builder correctly computes and records the // property tree context for a (pseudo) stacking context that is scrolled by a // containing block that is not one of the painting ancestors. - SetBodyInnerHTML( - "<style>body { margin: 20px 30px; }</style>" - "<div id='clipper' style='position: absolute; clip: rect(10px, 80px, " - "70px, 40px); width:300px; height:200px;'>" - " <div id='child' style='position:relative; width:400px; height: " - "500px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 20px 30px; }</style> + <div id='clipper' style='position: absolute; + clip: rect(10px, 80px, 70px, 40px); width:300px; height:200px;'> + <div id='child' style='position:relative; width:400px; height: 500px;'> + </div> + </div> + )HTML"); LayoutBoxModelObject* clipper = ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); @@ -2944,22 +2999,23 @@ TEST_P(PaintPropertyTreeBuilderTest, SvgLocalToBorderBoxTransformContentsTreeState) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 20px 30px;" - " }" - " svg {" - " position: absolute;" - " }" - " rect {" - " transform: translate(100px, 100px);" - " }" - "</style>" - "<svg id='svgWithViewBox' width='100px' height='100px' viewBox='50 50 " - "100 100'>" - " <rect id='rect' width='100px' height='100px' />" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 20px 30px; + } + svg { + position: absolute; + } + rect { + transform: translate(100px, 100px); + } + </style> + <svg id='svgWithViewBox' width='100px' height='100px' + viewBox='50 50 100 100'> + <rect id='rect' width='100px' height='100px' /> + </svg> + )HTML"); LayoutObject& svg_with_view_box = *GetLayoutObjectByElementId("svgWithViewBox"); @@ -2987,23 +3043,24 @@ } TEST_P(PaintPropertyTreeBuilderTest, OverflowHiddenScrollProperties) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0px;" - " }" - " #overflowHidden {" - " overflow: hidden;" - " width: 5px;" - " height: 3px;" - " }" - " .forceScroll {" - " height: 79px;" - " }" - "</style>" - "<div id='overflowHidden'>" - " <div class='forceScroll'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0px; + } + #overflowHidden { + overflow: hidden; + width: 5px; + height: 3px; + } + .forceScroll { + height: 79px; + } + </style> + <div id='overflowHidden'> + <div class='forceScroll'></div> + </div> + )HTML"); Element* overflow_hidden = GetDocument().getElementById("overflowHidden"); overflow_hidden->setScrollTop(37); @@ -3024,19 +3081,20 @@ } TEST_P(PaintPropertyTreeBuilderTest, FrameOverflowHiddenScrollProperties) { - SetBodyInnerHTML( - "<style>" - " html {" - " margin: 0px;" - " overflow: hidden;" - " width: 300px;" - " height: 300px;" - " }" - " .forceScroll {" - " height: 5000px;" - " }" - "</style>" - "<div class='forceScroll'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + html { + margin: 0px; + overflow: hidden; + width: 300px; + height: 300px; + } + .forceScroll { + height: 5000px; + } + </style> + <div class='forceScroll'></div> + )HTML"); GetDocument().domWindow()->scrollTo(0, 37); @@ -3051,31 +3109,32 @@ } TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) { - SetBodyInnerHTML( - "<style>" - " * {" - " margin: 0px;" - " }" - " #overflowA {" - " overflow: scroll;" - " width: 5px;" - " height: 3px;" - " }" - " #overflowB {" - " overflow: scroll;" - " width: 9px;" - " height: 7px;" - " }" - " .forceScroll {" - " height: 100px;" - " }" - "</style>" - "<div id='overflowA'>" - " <div id='overflowB'>" - " <div class='forceScroll'></div>" - " </div>" - " <div class='forceScroll'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { + margin: 0px; + } + #overflowA { + overflow: scroll; + width: 5px; + height: 3px; + } + #overflowB { + overflow: scroll; + width: 9px; + height: 7px; + } + .forceScroll { + height: 100px; + } + </style> + <div id='overflowA'> + <div id='overflowB'> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + </div> + )HTML"); Element* overflow_a = GetDocument().getElementById("overflowA"); overflow_a->setScrollTop(37); @@ -3118,46 +3177,47 @@ } TEST_P(PaintPropertyTreeBuilderTest, PositionedScrollerIsNotNested) { - SetBodyInnerHTML( - "<style>" - " * {" - " margin: 0px;" - " }" - " #overflow {" - " overflow: scroll;" - " width: 5px;" - " height: 3px;" - " }" - " #absposOverflow {" - " position: absolute;" - " top: 0;" - " left: 0;" - " overflow: scroll;" - " width: 9px;" - " height: 7px;" - " }" - " #fixedOverflow {" - " position: fixed;" - " top: 0;" - " left: 0;" - " overflow: scroll;" - " width: 13px;" - " height: 11px;" - " }" - " .forceScroll {" - " height: 4000px;" - " }" - "</style>" - "<div id='overflow'>" - " <div id='absposOverflow'>" - " <div class='forceScroll'></div>" - " </div>" - " <div id='fixedOverflow'>" - " <div class='forceScroll'></div>" - " </div>" - " <div class='forceScroll'></div>" - "</div>" - "<div class='forceScroll'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { + margin: 0px; + } + #overflow { + overflow: scroll; + width: 5px; + height: 3px; + } + #absposOverflow { + position: absolute; + top: 0; + left: 0; + overflow: scroll; + width: 9px; + height: 7px; + } + #fixedOverflow { + position: fixed; + top: 0; + left: 0; + overflow: scroll; + width: 13px; + height: 11px; + } + .forceScroll { + height: 4000px; + } + </style> + <div id='overflow'> + <div id='absposOverflow'> + <div class='forceScroll'></div> + </div> + <div id='fixedOverflow'> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + )HTML"); Element* overflow = GetDocument().getElementById("overflow"); overflow->setScrollTop(37); @@ -3216,37 +3276,38 @@ } TEST_P(PaintPropertyTreeBuilderTest, NestedPositionedScrollProperties) { - SetBodyInnerHTML( - "<style>" - " * {" - " margin: 0px;" - " }" - " #overflowA {" - " position: absolute;" - " top: 7px;" - " left: 11px;" - " overflow: scroll;" - " width: 20px;" - " height: 20px;" - " }" - " #overflowB {" - " position: absolute;" - " top: 1px;" - " left: 3px;" - " overflow: scroll;" - " width: 5px;" - " height: 3px;" - " }" - " .forceScroll {" - " height: 100px;" - " }" - "</style>" - "<div id='overflowA'>" - " <div id='overflowB'>" - " <div class='forceScroll'></div>" - " </div>" - " <div class='forceScroll'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { + margin: 0px; + } + #overflowA { + position: absolute; + top: 7px; + left: 11px; + overflow: scroll; + width: 20px; + height: 20px; + } + #overflowB { + position: absolute; + top: 1px; + left: 3px; + overflow: scroll; + width: 5px; + height: 3px; + } + .forceScroll { + height: 100px; + } + </style> + <div id='overflowA'> + <div id='overflowB'> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + </div> + )HTML"); Element* overflow_a = GetDocument().getElementById("overflowA"); overflow_a->setScrollTop(37); @@ -3289,10 +3350,11 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGRootClip) { - SetBodyInnerHTML( - "<svg id='svg' width='100px' height='100px'>" - " <rect width='200' height='200' fill='red' />" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg' width='100px' height='100px'> + <rect width='200' height='200' fill='red' /> + </svg> + )HTML"); const ClipPaintPropertyNode* clip = GetLayoutObjectByElementId("svg") ->FirstFragment() @@ -3309,11 +3371,12 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGRootNoClip) { - SetBodyInnerHTML( - "<svg id='svg' xmlns='http://www.w3.org/2000/svg' width='100px' " - "height='100px' style='overflow: visible'>" - " <rect width='200' height='200' fill='red' />" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg' xmlns='http://www.w3.org/2000/svg' width='100px' + height='100px' style='overflow: visible'> + <rect width='200' height='200' fill='red' /> + </svg> + )HTML"); EXPECT_FALSE(GetLayoutObjectByElementId("svg") ->FirstFragment() @@ -3322,27 +3385,28 @@ } TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithoutScrolling) { - SetBodyInnerHTML( - "<style>" - " #overflow {" - " overflow: scroll;" - " width: 100px;" - " height: 100px;" - " }" - " .backgroundAttachmentFixed {" - " background-image: url('foo');" - " background-attachment: fixed;" - " width: 10px;" - " height: 10px;" - " }" - " .forceScroll {" - " height: 4000px;" - " }" - "</style>" - "<div id='overflow'>" - " <div class='backgroundAttachmentFixed'></div>" - "</div>" - "<div class='forceScroll'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #overflow { + overflow: scroll; + width: 100px; + height: 100px; + } + .backgroundAttachmentFixed { + background-image: url('foo'); + background-attachment: fixed; + width: 10px; + height: 10px; + } + .forceScroll { + height: 4000px; + } + </style> + <div id='overflow'> + <div class='backgroundAttachmentFixed'></div> + </div> + <div class='forceScroll'></div> + )HTML"); Element* overflow = GetDocument().getElementById("overflow"); EXPECT_TRUE(FrameScroll()->HasBackgroundAttachmentFixedDescendants()); // No scroll node is needed. @@ -3373,15 +3437,15 @@ } TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumnScrolled) { - SetBodyInnerHTML( - "<!doctype HTML>" - "<div style='columns: 1;'>" - " <div id=scroller style='height: 400px; width: 400px; overflow: " - "auto;'>" - " <div style='width: 50px; height: 1000px; background: lightgray'>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <!doctype HTML> + <div style='columns: 1;'> + <div id=scroller style='height: 400px; width: 400px; overflow: auto;'> + <div style='width: 50px; height: 1000px; background: lightgray'> + </div> + </div> + </div> + )HTML"); LayoutObject* scroller = GetLayoutObjectByElementId("scroller"); ToLayoutBoxModelObject(scroller)->Layer()->GetScrollableArea()->ScrollBy( @@ -3397,12 +3461,13 @@ TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetUnderMulticolumnScrollFixedPos) { - SetBodyInnerHTML( - "<div id=fixed style='position: fixed; columns: 2'>" - " <div style='width: 50px; height: 20px; background: lightblue'></div>" - " <div style='width: 50px; height: 20px; background: lightgray'></div>" - "</div>" - "<div style='height: 2000px'></div>"); + SetBodyInnerHTML(R"HTML( + <div id=fixed style='position: fixed; columns: 2'> + <div style='width: 50px; height: 20px; background: lightblue'></div> + <div style='width: 50px; height: 20px; background: lightgray'></div> + </div> + <div style='height: 2000px'></div> + )HTML"); LayoutObject* fixed = GetLayoutObjectByElementId("fixed"); LayoutObject* multicol_container = fixed->SlowFirstChild(); @@ -3428,25 +3493,26 @@ } TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumn) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " .space { height: 30px; }" - " .abs { position: absolute; width: 20px; height: 20px; }" - "</style>" - "<div style='columns:2; width: 200px; column-gap: 0'>" - " <div id=relpos style='position: relative'>" - " <div id=space1 class=space></div>" - " <div id=space2 class=space></div>" - " <div id=spanner style='column-span: all'>" - " <div id=normal style='height: 50px'></div>" - " <div id=top-left class=abs style='top: 0; left: 0'></div>" - " <div id=bottom-right class=abs style='bottom: 0; right: 0'></div>" - " </div>" - " <div id=space3 class=space></div>" - " <div id=space4 class=space></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + .space { height: 30px; } + .abs { position: absolute; width: 20px; height: 20px; } + </style> + <div style='columns:2; width: 200px; column-gap: 0'> + <div id=relpos style='position: relative'> + <div id=space1 class=space></div> + <div id=space2 class=space></div> + <div id=spanner style='column-span: all'> + <div id=normal style='height: 50px'></div> + <div id=top-left class=abs style='top: 0; left: 0'></div> + <div id=bottom-right class=abs style='bottom: 0; right: 0'></div> + </div> + <div id=space3 class=space></div> + <div id=space4 class=space></div> + </div> + </div> + )HTML"); LayoutObject* relpos = GetLayoutObjectByElementId("relpos"); EXPECT_EQ(4u, NumFragments(relpos)); @@ -3568,25 +3634,27 @@ // spanner with absolute-position children. TEST_P(PaintPropertyTreeBuilderTest, MultiColumnInlineRelativeAndSpannerAndAbsPos) { - SetBodyInnerHTML( - "<div style='columns:2; width: 200px; column-gap: 0'>" - " <span style='position: relative'>" - " <span id=spanner style='column-span: all'>" - " <div id=absolute style='position: absolute'>absolute</div>" - " </span>" - " </span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='columns:2; width: 200px; column-gap: 0'> + <span style='position: relative'> + <span id=spanner style='column-span: all'> + <div id=absolute style='position: absolute'>absolute</div> + </span> + </span> + </div> + )HTML"); // The "spanner" isn't a real spanner because it's an inline. EXPECT_FALSE(GetLayoutObjectByElementId("spanner")->IsColumnSpanAll()); - SetBodyInnerHTML( - "<div style='columns:2; width: 200px; column-gap: 0'>" - " <span style='position: relative'>" - " <div id=spanner style='column-span: all'>" - " <div id=absolute style='position: absolute'>absolute</div>" - " </div>" - " </span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='columns:2; width: 200px; column-gap: 0'> + <span style='position: relative'> + <div id=spanner style='column-span: all'> + <div id=absolute style='position: absolute'>absolute</div> + </div> + </span> + </div> + )HTML"); // There should be anonymous block created containing the inline "relative", // serving as the container of "absolute". EXPECT_TRUE( @@ -3620,12 +3688,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, FilterReparentClips) { - SetBodyInnerHTML( - "<div id='clip' style='overflow:hidden;'>" - " <div id='filter' style='filter:opacity(0.5); height:1000px;'>" - " <div id='child' style='position:fixed;'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='clip' style='overflow:hidden;'> + <div id='filter' style='filter:opacity(0.5); height:1000px;'> + <div id='child' style='position:fixed;'></div> + </div> + </div> + )HTML"); const ObjectPaintProperties* clip_properties = GetLayoutObjectByElementId("clip")->FirstFragment().PaintProperties(); const ObjectPaintProperties* filter_properties = @@ -3650,24 +3719,25 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformOriginWithAndWithoutTransform) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " div {" - " width: 400px;" - " height: 100px;" - " }" - " #transform {" - " transform: translate(100px, 200px);" - " transform-origin: 75% 75% 0;" - " }" - " #willChange {" - " will-change: opacity;" - " transform-origin: 75% 75% 0;" - " }" - "</style>" - "<div id='transform'></div>" - "<div id='willChange'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + div { + width: 400px; + height: 100px; + } + #transform { + transform: translate(100px, 200px); + transform-origin: 75% 75% 0; + } + #willChange { + will-change: opacity; + transform-origin: 75% 75% 0; + } + </style> + <div id='transform'></div> + <div id='willChange'></div> + )HTML"); auto* transform = GetLayoutObjectByElementId("transform"); EXPECT_EQ( @@ -3690,27 +3760,28 @@ } TEST_P(PaintPropertyTreeBuilderTest, TransformOriginWithAndWithoutMotionPath) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " div {" - " width: 100px;" - " height: 100px;" - " }" - " #motionPath {" - " position: absolute;" - " offset-path: path('M0 0 L 200 400');" - " offset-distance: 50%;" - " offset-rotate: 0deg;" - " transform-origin: 50% 50% 0;" - " }" - " #willChange {" - " will-change: opacity;" - " transform-origin: 50% 50% 0;" - " }" - "</style>" - "<div id='motionPath'></div>" - "<div id='willChange'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + div { + width: 100px; + height: 100px; + } + #motionPath { + position: absolute; + offset-path: path('M0 0 L 200 400'); + offset-distance: 50%; + offset-rotate: 0deg; + transform-origin: 50% 50% 0; + } + #willChange { + will-change: opacity; + transform-origin: 50% 50% 0; + } + </style> + <div id='motionPath'></div> + <div id='willChange'></div> + )HTML"); auto* motion_path = GetLayoutObjectByElementId("motionPath"); EXPECT_EQ( @@ -3733,15 +3804,16 @@ } TEST_P(PaintPropertyTreeBuilderTest, ChangePositionUpdateDescendantProperties) { - SetBodyInnerHTML( - "<style>" - " * { margin: 0; }" - " #ancestor { position: absolute; overflow: hidden }" - " #descendant { position: absolute }" - "</style>" - "<div id='ancestor'>" - " <div id='descendant'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + * { margin: 0; } + #ancestor { position: absolute; overflow: hidden } + #descendant { position: absolute } + </style> + <div id='ancestor'> + <div id='descendant'></div> + </div> + )HTML"); LayoutObject* ancestor = GetLayoutObjectByElementId("ancestor"); LayoutObject* descendant = GetLayoutObjectByElementId("descendant"); @@ -3799,15 +3871,16 @@ } TEST_P(PaintPropertyTreeBuilderTest, FloatUnderInline) { - SetBodyInnerHTML( - "<div style='position: absolute; top: 55px; left: 66px'>" - " <span id='span'" - " style='position: relative; top: 100px; left: 200px; opacity: 0.5'>" - " <div id='target'" - " style='overflow: hidden; float: left; width: 3px; height: 4px'>" - " </div>" - " </span>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div style='position: absolute; top: 55px; left: 66px'> + <span id='span' + style='position: relative; top: 100px; left: 200px; opacity: 0.5'> + <div id='target' + style='overflow: hidden; float: left; width: 3px; height: 4px'> + </div> + </span> + </div> + )HTML"); LayoutObject* span = GetLayoutObjectByElementId("span"); const auto* effect = span->FirstFragment().PaintProperties()->Effect(); @@ -3825,10 +3898,11 @@ } TEST_P(PaintPropertyTreeBuilderTest, ScrollNodeHasCompositorElementId) { - SetBodyInnerHTML( - "<div id='target' style='overflow: auto; width: 100px; height: 100px'>" - " <div style='width: 200px; height: 200px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='overflow: auto; width: 100px; height: 100px'> + <div style='width: 200px; height: 200px'></div> + </div> + )HTML"); const ObjectPaintProperties* properties = PaintPropertiesForElement("target"); // The scroll translation node should not have the element id as it should be @@ -3840,12 +3914,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, OverflowClipSubpixelPosition) { - SetBodyInnerHTML( - "<style>body { margin: 20px 30px; }</style>" - "<div id='clipper'" - " style='position: relative; overflow: hidden; " - " width: 400px; height: 300px; left: 1.5px'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 20px 30px; }</style> + <div id='clipper' + style='position: relative; overflow: hidden; + width: 400px; height: 300px; left: 1.5px'> + </div> + )HTML"); LayoutBoxModelObject* clipper = ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); @@ -3859,11 +3934,12 @@ } TEST_P(PaintPropertyTreeBuilderTest, MaskSimple) { - SetBodyInnerHTML( - "<div id='target' style='width:300px; height:200px; " - "-webkit-mask:linear-gradient(red,red)'>" - " Lorem ipsum" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='width:300px; height:200px; + -webkit-mask:linear-gradient(red,red)'> + Lorem ipsum + </div> + )HTML"); const ObjectPaintProperties* properties = PaintPropertiesForElement("target"); const ClipPaintPropertyNode* output_clip = properties->MaskClip(); @@ -3890,12 +3966,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, MaskWithOutset) { - SetBodyInnerHTML( - "<div id='target' style='width:300px; height:200px; " - "-webkit-mask-box-image-source:linear-gradient(red,red);" - "-webkit-mask-box-image-outset:10px 20px;'>" - " Lorem ipsum" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='width:300px; height:200px; + -webkit-mask-box-image-source:linear-gradient(red,red); + -webkit-mask-box-image-outset:10px 20px;'> + Lorem ipsum + </div> + )HTML"); const ObjectPaintProperties* properties = PaintPropertiesForElement("target"); const ClipPaintPropertyNode* output_clip = properties->MaskClip(); @@ -3924,15 +4001,17 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskEscapeClip) { // This test verifies an abs-pos element still escape the scroll of a // static-pos ancestor, but gets clipped due to the presence of a mask. - SetBodyInnerHTML( - "<div id='scroll' style='width:300px; height:200px; overflow:scroll;'>" - " <div id='target' style='width:200px; height:300px; " - "-webkit-mask:linear-gradient(red,red); border:10px dashed black; " - "overflow:hidden;'>" - " <div id='absolute' style='position:absolute; left:0; top:0;'>Lorem " - "ipsum</div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='scroll' style='width:300px; height:200px; overflow:scroll;'> + <div id='target' style='width:200px; height:300px; + -webkit-mask:linear-gradient(red,red); border:10px dashed black; + overflow:hidden;'> + <div id='absolute' style='position:absolute; left:0; top:0;'> + Lorem ipsum + </div> + </div> + </div> + )HTML"); const ObjectPaintProperties* target_properties = PaintPropertiesForElement("target"); @@ -3996,16 +4075,17 @@ // This test verifies CSS mask applied on an inline element is clipped to // the line box of the said element. In this test the masked element has // only one box, and one of the child element overflows the box. - SetBodyInnerHTML( - "<style>* { font-family:Ahem; font-size:16px; }</style>" - "Lorem" - "<span id='target' style='-webkit-mask:linear-gradient(red,red);'>" - " ipsum" - " <span id='overflowing' style='position:relative; font-size:32px;'>" - " dolor" - " </span>" - " sit amet," - "</span>"); + SetBodyInnerHTML(R"HTML( + <style>* { font-family:Ahem; font-size:16px; }</style> + Lorem + <span id='target' style='-webkit-mask:linear-gradient(red,red);'> + ipsum + <span id='overflowing' style='position:relative; font-size:32px;'> + dolor + </span> + sit amet, + </span> + )HTML"); const ObjectPaintProperties* properties = PaintPropertiesForElement("target"); const ClipPaintPropertyNode* output_clip = properties->MaskClip(); @@ -4016,7 +4096,7 @@ ->LocalBorderBoxProperties() ->Clip()); EXPECT_EQ(FrameContentClip(), output_clip->Parent()); - EXPECT_EQ(FloatRoundedRect(88, 21, 448, 16), output_clip->ClipRect()); + EXPECT_EQ(FloatRoundedRect(104, 21, 432, 16), output_clip->ClipRect()); EXPECT_EQ(properties->Effect(), target->FirstFragment() .GetRarePaintData() @@ -4042,22 +4122,23 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGResource) { - SetBodyInnerHTML( - "<svg id='svg' xmlns='http://www.w3.org/2000/svg' >" - " <g transform='scale(1000)'>" - " <marker id='markerMiddle' markerWidth='2' markerHeight='2' refX='5' " - " refY='5' markerUnits='strokeWidth'>" - " <g id='transformInsideMarker' transform='scale(4)'>" - " <circle cx='5' cy='5' r='7' fill='green'/>" - " </g>" - " </marker>" - " </g>" - " <g id='transformOutsidePath' transform='scale(2)'>" - " <path d='M 130 135 L 180 135 L 180 185' " - " marker-mid='url(#markerMiddle)' fill='none' stroke-width='8px' " - " stroke='black'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg' xmlns='http://www.w3.org/2000/svg' > + <g transform='scale(1000)'> + <marker id='markerMiddle' markerWidth='2' markerHeight='2' refX='5' + refY='5' markerUnits='strokeWidth'> + <g id='transformInsideMarker' transform='scale(4)'> + <circle cx='5' cy='5' r='7' fill='green'/> + </g> + </marker> + </g> + <g id='transformOutsidePath' transform='scale(2)'> + <path d='M 130 135 L 180 135 L 180 185' + marker-mid='url(#markerMiddle)' fill='none' stroke-width='8px' + stroke='black'/> + </g> + </svg> + )HTML"); const ObjectPaintProperties* transform_inside_marker_properties = PaintPropertiesForElement("transformInsideMarker"); @@ -4077,19 +4158,20 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGHiddenResource) { - SetBodyInnerHTML( - "<svg id='svg' xmlns='http://www.w3.org/2000/svg' >" - " <g transform='scale(1000)'>" - " <symbol id='symbol'>" - " <g id='transformInsideSymbol' transform='scale(4)'>" - " <circle cx='5' cy='5' r='7' fill='green'/>" - " </g>" - " </symbol>" - " </g>" - " <g id='transformOutsideUse' transform='scale(2)'>" - " <use x='25' y='25' width='400' height='400' xlink:href='#symbol'/>" - " </g>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svg' xmlns='http://www.w3.org/2000/svg' > + <g transform='scale(1000)'> + <symbol id='symbol'> + <g id='transformInsideSymbol' transform='scale(4)'> + <circle cx='5' cy='5' r='7' fill='green'/> + </g> + </symbol> + </g> + <g id='transformOutsideUse' transform='scale(2)'> + <use x='25' y='25' width='400' height='400' xlink:href='#symbol'/> + </g> + </svg> + )HTML"); const ObjectPaintProperties* transform_inside_symbol_properties = PaintPropertiesForElement("transformInsideSymbol"); @@ -4109,12 +4191,13 @@ } TEST_P(PaintPropertyTreeBuilderTest, SVGRootBlending) { - SetBodyInnerHTML( - "<svg id='svgroot' 'width=100' height='100'" - " style='position: relative; z-index: 0'>" - " <rect width='100' height='100' fill='#00FF00'" - " style='mix-blend-mode: difference'/>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg id='svgroot' 'width=100' height='100' + style='position: relative; z-index: 0'> + <rect width='100' height='100' fill='#00FF00' + style='mix-blend-mode: difference'/> + </svg> + )HTML"); LayoutObject& svg_root = *GetLayoutObjectByElementId("svgroot"); const ObjectPaintProperties* svg_root_properties = @@ -4125,25 +4208,26 @@ } TEST_P(PaintPropertyTreeBuilderTest, ScrollBoundsOffset) { - SetBodyInnerHTML( - "<style>" - " body {" - " margin: 0px;" - " }" - " #scroller {" - " overflow-y: scroll;" - " width: 100px;" - " height: 100px;" - " margin-left: 7px;" - " margin-top: 11px;" - " }" - " .forceScroll {" - " height: 200px;" - " }" - "</style>" - "<div id='scroller'>" - " <div class='forceScroll'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { + margin: 0px; + } + #scroller { + overflow-y: scroll; + width: 100px; + height: 100px; + margin-left: 7px; + margin-top: 11px; + } + .forceScroll { + height: 200px; + } + </style> + <div id='scroller'> + <div class='forceScroll'></div> + </div> + )HTML"); Element* scroller = GetDocument().getElementById("scroller"); scroller->setScrollTop(42);
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp index 7d5f7e8bd..a5d72b4a1 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
@@ -121,10 +121,11 @@ } TEST_P(PaintPropertyTreePrinterTest, SimpleScrollTreePath) { - SetBodyInnerHTML( - "<div id='scroll' style='overflow: scroll; height: 100px;'>" - " <div id='forceScroll' style='height: 4000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='scroll' style='overflow: scroll; height: 100px;'> + <div id='forceScroll' style='height: 4000px;'></div> + </div> + )HTML"); LayoutObject* scroll_object = GetDocument().getElementById("scroll")->GetLayoutObject(); const auto* scroll_object_properties =
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp index 6a78a16..78834d0 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -19,22 +19,23 @@ TEST_P(PaintPropertyTreeUpdateTest, ThreadedScrollingDisabledMainThreadScrollReason) { - SetBodyInnerHTML( - "<style>" - " #overflowA {" - " position: absolute;" - " overflow: scroll;" - " width: 20px;" - " height: 20px;" - " }" - " .forceScroll {" - " height: 4000px;" - " }" - "</style>" - "<div id='overflowA'>" - " <div class='forceScroll'></div>" - "</div>" - "<div class='forceScroll'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #overflowA { + position: absolute; + overflow: scroll; + width: 20px; + height: 20px; + } + .forceScroll { + height: 4000px; + } + </style> + <div id='overflowA'> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + )HTML"); Element* overflow_a = GetDocument().getElementById("overflowA"); EXPECT_FALSE(FrameScroll()->ThreadedScrollingDisabled()); EXPECT_FALSE(overflow_a->GetLayoutObject() @@ -61,35 +62,36 @@ TEST_P(PaintPropertyTreeUpdateTest, BackgroundAttachmentFixedMainThreadScrollReasonsWithNestedScrollers) { - SetBodyInnerHTML( - "<style>" - " #overflowA {" - " position: absolute;" - " overflow: scroll;" - " width: 20px;" - " height: 20px;" - " }" - " #overflowB {" - " position: absolute;" - " overflow: scroll;" - " width: 5px;" - " height: 3px;" - " }" - " .backgroundAttachmentFixed {" - " background-image: url('foo');" - " background-attachment: fixed;" - " }" - " .forceScroll {" - " height: 4000px;" - " }" - "</style>" - "<div id='overflowA'>" - " <div id='overflowB' class='backgroundAttachmentFixed'>" - " <div class='forceScroll'></div>" - " </div>" - " <div class='forceScroll'></div>" - "</div>" - "<div class='forceScroll'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #overflowA { + position: absolute; + overflow: scroll; + width: 20px; + height: 20px; + } + #overflowB { + position: absolute; + overflow: scroll; + width: 5px; + height: 3px; + } + .backgroundAttachmentFixed { + background-image: url('foo'); + background-attachment: fixed; + } + .forceScroll { + height: 4000px; + } + </style> + <div id='overflowA'> + <div id='overflowB' class='backgroundAttachmentFixed'> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + )HTML"); Element* overflow_a = GetDocument().getElementById("overflowA"); Element* overflow_b = GetDocument().getElementById("overflowB"); @@ -143,17 +145,18 @@ } TEST_P(PaintPropertyTreeUpdateTest, ParentFrameMainThreadScrollReasons) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " .fixedBackground {" - " background-image: url('foo');" - " background-attachment: fixed;" - " }" - "</style>" - "<iframe></iframe>" - "<div id='fixedBackground' class='fixedBackground'></div>" - "<div id='forceScroll' style='height: 8888px;'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + .fixedBackground { + background-image: url('foo'); + background-attachment: fixed; + } + </style> + <iframe></iframe> + <div id='fixedBackground' class='fixedBackground'></div> + <div id='forceScroll' style='height: 8888px;'></div> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; }</style>" "<div id='forceScroll' style='height: 8888px;'></div>"); @@ -178,20 +181,22 @@ } TEST_P(PaintPropertyTreeUpdateTest, ChildFrameMainThreadScrollReasons) { - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<iframe></iframe>" - "<div id='forceScroll' style='height: 8888px;'></div>"); - SetChildFrameHTML( - "<style>" - " body { margin: 0; }" - " .fixedBackground {" - " background-image: url('foo');" - " background-attachment: fixed;" - " }" - "</style>" - "<div id='fixedBackground' class='fixedBackground'></div>" - "<div id='forceScroll' style='height: 8888px;'></div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <iframe></iframe> + <div id='forceScroll' style='height: 8888px;'></div> + )HTML"); + SetChildFrameHTML(R"HTML( + <style> + body { margin: 0; } + .fixedBackground { + background-image: url('foo'); + background-attachment: fixed; + } + </style> + <div id='fixedBackground' class='fixedBackground'></div> + <div id='forceScroll' style='height: 8888px;'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); LocalFrameView* parent = GetDocument().View(); @@ -215,35 +220,36 @@ TEST_P(PaintPropertyTreeUpdateTest, BackgroundAttachmentFixedMainThreadScrollReasonsWithFixedScroller) { - SetBodyInnerHTML( - "<style>" - " #overflowA {" - " position: absolute;" - " overflow: scroll;" - " width: 20px;" - " height: 20px;" - " }" - " #overflowB {" - " position: fixed;" - " overflow: scroll;" - " width: 5px;" - " height: 3px;" - " }" - " .backgroundAttachmentFixed {" - " background-image: url('foo');" - " background-attachment: fixed;" - " }" - " .forceScroll {" - " height: 4000px;" - " }" - "</style>" - "<div id='overflowA'>" - " <div id='overflowB' class='backgroundAttachmentFixed'>" - " <div class='forceScroll'></div>" - " </div>" - " <div class='forceScroll'></div>" - "</div>" - "<div class='forceScroll'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #overflowA { + position: absolute; + overflow: scroll; + width: 20px; + height: 20px; + } + #overflowB { + position: fixed; + overflow: scroll; + width: 5px; + height: 3px; + } + .backgroundAttachmentFixed { + background-image: url('foo'); + background-attachment: fixed; + } + .forceScroll { + height: 4000px; + } + </style> + <div id='overflowA'> + <div id='overflowB' class='backgroundAttachmentFixed'> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + </div> + <div class='forceScroll'></div> + )HTML"); Element* overflow_a = GetDocument().getElementById("overflowA"); Element* overflow_b = GetDocument().getElementById("overflowB"); @@ -295,11 +301,12 @@ } TEST_P(PaintPropertyTreeUpdateTest, DescendantNeedsUpdateAcrossFrames) { - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='divWithTransform' style='transform: translate3d(1px,2px,3px);'>" - " <iframe style='border: 7px solid black'></iframe>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='divWithTransform' style='transform: translate3d(1px,2px,3px);'> + <iframe style='border: 7px solid black'></iframe> + </div> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; }</style><div id='transform' style='transform: " "translate3d(4px, 5px, 6px); width: 100px; height: 200px'></div>"); @@ -369,15 +376,17 @@ // testing with real frame viewport intersection observer. This one tests // paint property update with or without AllowThrottlingScope. TEST_P(PaintPropertyTreeUpdateTest, BuildingStopsAtThrottledFrames) { - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='transform' style='transform: translate3d(4px, 5px, 6px);'>" - "</div>" - "<iframe id='iframe' sandbox></iframe>"); - SetChildFrameHTML( - "<style>body { margin: 0; }</style>" - "<div id='iframeTransform'" - " style='transform: translate3d(4px, 5px, 6px);'/>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='transform' style='transform: translate3d(4px, 5px, 6px);'> + </div> + <iframe id='iframe' sandbox></iframe> + )HTML"); + SetChildFrameHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='iframeTransform' + style='transform: translate3d(4px, 5px, 6px);'/> + )HTML"); // Move the child frame offscreen so it becomes available for throttling. auto* iframe = ToHTMLIFrameElement(GetDocument().getElementById("iframe")); @@ -445,12 +454,13 @@ } TEST_P(PaintPropertyTreeUpdateTest, ClipChangesUpdateOverflowClip) { - SetBodyInnerHTML( - "<style>" - " body { margin:0 }" - " #div { overflow:hidden; height:0px; }" - "</style>" - "<div id='div'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin:0 } + #div { overflow:hidden; height:0px; } + </style> + <div id='div'></div> + )HTML"); auto* div = GetDocument().getElementById("div"); div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:7px;"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -512,12 +522,13 @@ } TEST_P(PaintPropertyTreeUpdateTest, ContainPaintChangesUpdateOverflowClip) { - SetBodyInnerHTML( - "<style>" - " body { margin:0 }" - " #div { will-change:transform; width:7px; height:6px; }" - "</style>" - "<div id='div' style='contain:paint;'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin:0 } + #div { will-change:transform; width:7px; height:6px; } + </style> + <div id='div' style='contain:paint;'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); auto* div = GetDocument().getElementById("div"); auto* properties = @@ -547,11 +558,12 @@ // Disabled due to stale scrollsOverflow values, see: https://crbug.com/675296. TEST_P(PaintPropertyTreeUpdateTest, DISABLED_FrameVisibilityChangeUpdatesProperties) { - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div id='iframeContainer'>" - " <iframe id='iframe' style='width: 100px; height: 100px;'></iframe>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div id='iframeContainer'> + <iframe id='iframe' style='width: 100px; height: 100px;'></iframe> + </div> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; }</style>" "<div id='forceScroll' style='height: 3000px;'></div>"); @@ -641,19 +653,20 @@ } TEST_P(PaintPropertyTreeUpdateTest, PerspectiveOriginUpdatesOnSizeChanges) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " #perspective {" - " position: absolute;" - " perspective: 100px;" - " width: 100px;" - " perspective-origin: 50% 50% 0;" - " }" - "</style>" - "<div id='perspective'>" - " <div id='contents'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + #perspective { + position: absolute; + perspective: 100px; + width: 100px; + perspective-origin: 50% 50% 0; + } + </style> + <div id='perspective'> + <div id='contents'></div> + </div> + )HTML"); auto* perspective = GetLayoutObjectByElementId("perspective"); EXPECT_EQ( @@ -675,16 +688,17 @@ } TEST_P(PaintPropertyTreeUpdateTest, TransformUpdatesOnRelativeLengthChanges) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " #transform {" - " transform: translate3d(50%, 50%, 0);" - " width: 100px;" - " height: 200px;" - " }" - "</style>" - "<div id='transform'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + #transform { + transform: translate3d(50%, 50%, 0); + width: 100px; + height: 200px; + } + </style> + <div id='transform'></div> + )HTML"); auto* transform = GetDocument().getElementById("transform"); auto* transform_object = transform->GetLayoutObject(); @@ -704,22 +718,23 @@ } TEST_P(PaintPropertyTreeUpdateTest, CSSClipDependingOnSize) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " #outer {" - " position: absolute;" - " width: 100px; height: 100px; top: 50px; left: 50px;" - " }" - " #clip {" - " position: absolute;" - " clip: rect(auto auto auto -5px);" - " top: 0; left: 0; right: 0; bottom: 0;" - " }" - "</style>" - "<div id='outer'>" - " <div id='clip'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + #outer { + position: absolute; + width: 100px; height: 100px; top: 50px; left: 50px; + } + #clip { + position: absolute; + clip: rect(auto auto auto -5px); + top: 0; left: 0; right: 0; bottom: 0; + } + </style> + <div id='outer'> + <div id='clip'></div> + </div> + )HTML"); auto* outer = GetDocument().getElementById("outer"); auto* clip = GetLayoutObjectByElementId("clip"); @@ -735,11 +750,12 @@ } TEST_P(PaintPropertyTreeUpdateTest, ScrollBoundsChange) { - SetBodyInnerHTML( - "<div id='container'" - " style='width: 100px; height: 100px; overflow: scroll'>" - " <div id='content' style='width: 200px; height: 200px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' + style='width: 100px; height: 100px; overflow: scroll'> + <div id='content' style='width: 200px; height: 200px'></div> + </div> + )HTML"); auto* container = GetLayoutObjectByElementId("container"); auto* scroll_node = container->FirstFragment() @@ -761,12 +777,13 @@ } TEST_P(PaintPropertyTreeUpdateTest, ScrollbarWidthChange) { - SetBodyInnerHTML( - "<style>::-webkit-scrollbar {width: 20px; height: 20px}</style>" - "<div id='container'" - " style='width: 100px; height: 100px; overflow: scroll'>" - " <div id='content' style='width: 200px; height: 200px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>::-webkit-scrollbar {width: 20px; height: 20px}</style> + <div id='container' + style='width: 100px; height: 100px; overflow: scroll'> + <div id='content' style='width: 200px; height: 200px'></div> + </div> + )HTML"); auto* container = GetLayoutObjectByElementId("container"); auto* overflow_clip = @@ -784,10 +801,11 @@ } TEST_P(PaintPropertyTreeUpdateTest, Preserve3DChange) { - SetBodyInnerHTML( - "<div id='parent'>" - " <div id='child' style='transform: translate3D(1px, 2px, 3px)'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='parent'> + <div id='child' style='transform: translate3D(1px, 2px, 3px)'></div> + </div> + )HTML"); auto* child = GetLayoutObjectByElementId("child"); auto* transform = child->FirstFragment().PaintProperties()->Transform(); @@ -801,11 +819,12 @@ } TEST_P(PaintPropertyTreeUpdateTest, MenuListControlClipChange) { - SetBodyInnerHTML( - "<select id='select' style='white-space: normal'>" - " <option></option>" - " <option>bar</option>" - "</select>"); + SetBodyInnerHTML(R"HTML( + <select id='select' style='white-space: normal'> + <option></option> + <option>bar</option> + </select> + )HTML"); auto* select = GetLayoutObjectByElementId("select"); EXPECT_NE(nullptr, select->FirstFragment().PaintProperties()->OverflowClip()); @@ -817,11 +836,12 @@ } TEST_P(PaintPropertyTreeUpdateTest, BoxAddRemoveMask) { - SetBodyInnerHTML( - "<style>#target {width: 100px; height: 100px}</style>" - "<div id='target'>" - " <div style='width:500px; height:500px; background:green;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>#target {width: 100px; height: 100px}</style> + <div id='target'> + <div style='width:500px; height:500px; background:green;'></div> + </div> + )HTML"); EXPECT_EQ(nullptr, PaintPropertiesForElement("target")); @@ -844,17 +864,18 @@ } TEST_P(PaintPropertyTreeUpdateTest, MaskClipNodeBoxSizeChange) { - SetBodyInnerHTML( - "<style>" - "#target {" - " width: 100px;" - " height: 100px;" - " -webkit-mask: linear-gradient(red, blue);" - "}" - "</style>" - "<div id='target'>" - " <div style='width:500px; height:500px; background:green;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #target { + width: 100px; + height: 100px; + -webkit-mask: linear-gradient(red, blue); + } + </style> + <div id='target'> + <div style='width:500px; height:500px; background:green;'></div> + </div> + )HTML"); const auto* properties = PaintPropertiesForElement("target"); ASSERT_NE(nullptr, properties); @@ -895,10 +916,11 @@ } TEST_P(PaintPropertyTreeUpdateTest, MaskClipNodeInlineBoundsChange) { - SetBodyInnerHTML( - "<span id='target' style='-webkit-mask: linear-gradient(red, blue)'>" - " <img id='img' style='width: 50px'>" - "</span>"); + SetBodyInnerHTML(R"HTML( + <span id='target' style='-webkit-mask: linear-gradient(red, blue)'> + <img id='img' style='width: 50px'> + </span> + )HTML"); const auto* properties = PaintPropertiesForElement("target"); ASSERT_NE(nullptr, properties); @@ -915,15 +937,16 @@ } TEST_P(PaintPropertyTreeUpdateTest, AddRemoveSVGMask) { - SetBodyInnerHTML( - "<svg width='200' height='200'>" - " <rect id='rect' x='0' y='100' width='100' height='100' fill='blue'/>" - " <defs>" - " <mask id='mask' x='0' y='0' width='100' height='200'>" - " <rect width='100' height='200' fill='red'/>" - " </mask>" - " </defs>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg width='200' height='200'> + <rect id='rect' x='0' y='100' width='100' height='100' fill='blue'/> + <defs> + <mask id='mask' x='0' y='0' width='100' height='200'> + <rect width='100' height='200' fill='red'/> + </mask> + </defs> + </svg> + )HTML"); EXPECT_EQ(nullptr, PaintPropertiesForElement("rect")); @@ -943,17 +966,18 @@ } TEST_P(PaintPropertyTreeUpdateTest, SVGMaskTargetBoundsChange) { - SetBodyInnerHTML( - "<svg width='500' height='500'>" - " <g id='target' mask='url(#mask)'>" - " <rect id='rect' x='0' y='50' width='50' height='100' fill='blue'/>" - " </g>" - " <defs>" - " <mask id='mask' x='0' y='0' width='100' height='200'>" - " <rect width='100' height='200' fill='red'/>" - " </mask>" - " </defs>" - "</svg>"); + SetBodyInnerHTML(R"HTML( + <svg width='500' height='500'> + <g id='target' mask='url(#mask)'> + <rect id='rect' x='0' y='50' width='50' height='100' fill='blue'/> + </g> + <defs> + <mask id='mask' x='0' y='0' width='100' height='200'> + <rect width='100' height='200' fill='red'/> + </mask> + </defs> + </svg> + )HTML"); const auto* properties = PaintPropertiesForElement("target"); ASSERT_NE(nullptr, properties);
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp index df87c9d..896a00869 100644 --- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp +++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp
@@ -73,13 +73,14 @@ ::testing::ValuesIn(kDefaultPaintTestConfigurations)); TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithBorderInvalidation) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " #transformed { transform: translate(100px, 100px); }" - " .border { border: 10px solid black; }" - "</style>" - "<div id='transformed'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #transformed { transform: translate(100px, 100px); } + .border { border: 10px solid black; } + </style> + <div id='transformed'></div> + )HTML"); auto* transformed_element = GetDocument().getElementById("transformed"); const auto* transformed_properties = @@ -114,13 +115,14 @@ } TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithCSSTransformInvalidation) { - SetBodyInnerHTML( - "<style>" - " .transformA { transform: translate(100px, 100px); }" - " .transformB { transform: translate(200px, 200px); }" - " #transformed { will-change: transform; }" - "</style>" - "<div id='transformed' class='transformA'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + .transformA { transform: translate(100px, 100px); } + .transformB { transform: translate(200px, 200px); } + #transformed { will-change: transform; } + </style> + <div id='transformed' class='transformA'></div> + )HTML"); auto* transformed_element = GetDocument().getElementById("transformed"); const auto* transformed_properties = @@ -141,12 +143,13 @@ // In SPv1 mode, we don't need or store property tree nodes for effects. if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) return; - SetBodyInnerHTML( - "<style>" - " .opacityA { opacity: 0.9; }" - " .opacityB { opacity: 0.4; }" - "</style>" - "<div id='transparent' class='opacityA'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + .opacityA { opacity: 0.9; } + .opacityB { opacity: 0.4; } + </style> + <div id='transparent' class='opacityA'></div> + )HTML"); auto* transparent_element = GetDocument().getElementById("transparent"); const auto* transparent_properties = @@ -162,16 +165,17 @@ } TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChange) { - SetBodyInnerHTML( - "<style>" - " .clip { overflow: hidden }" - "</style>" - "<div id='parent' style='transform: translateZ(0); width: 100px;" - " height: 100px;'>" - " <div id='child' style='isolation: isolate'>" - " content" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .clip { overflow: hidden } + </style> + <div id='parent' style='transform: translateZ(0); width: 100px; + height: 100px;'> + <div id='child' style='isolation: isolate'> + content + </div> + </div> + )HTML"); auto* parent = GetDocument().getElementById("parent"); auto* child = GetDocument().getElementById("child"); @@ -187,16 +191,17 @@ } TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChange2DTransform) { - SetBodyInnerHTML( - "<style>" - " .clip { overflow: hidden }" - "</style>" - "<div id='parent' style='transform: translateX(0); width: 100px;" - " height: 100px;'>" - " <div id='child' style='isolation: isolate'>" - " content" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .clip { overflow: hidden } + </style> + <div id='parent' style='transform: translateX(0); width: 100px; + height: 100px;'> + <div id='child' style='isolation: isolate'> + content + </div> + </div> + )HTML"); auto* parent = GetDocument().getElementById("parent"); auto* child = GetDocument().getElementById("child"); @@ -212,17 +217,18 @@ } TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChangePosAbs) { - SetBodyInnerHTML( - "<style>" - " .clip { overflow: hidden }" - "</style>" - "<div id='parent' style='transform: translateZ(0); width: 100px;" - " height: 100px; position: absolute'>" - " <div id='child' style='overflow: hidden; position: relative;" - " z-index: 0; width: 50px; height: 50px'>" - " content" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .clip { overflow: hidden } + </style> + <div id='parent' style='transform: translateZ(0); width: 100px; + height: 100px; position: absolute'> + <div id='child' style='overflow: hidden; position: relative; + z-index: 0; width: 50px; height: 50px'> + content + </div> + </div> + )HTML"); auto* parent = GetDocument().getElementById("parent"); auto* child = GetDocument().getElementById("child"); @@ -240,17 +246,18 @@ } TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChangePosFixed) { - SetBodyInnerHTML( - "<style>" - " .clip { overflow: hidden }" - "</style>" - "<div id='parent' style='transform: translateZ(0); width: 100px;" - " height: 100px; trans'>" - " <div id='child' style='overflow: hidden; z-index: 0;" - " position: absolute; width: 50px; height: 50px'>" - " content" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .clip { overflow: hidden } + </style> + <div id='parent' style='transform: translateZ(0); width: 100px; + height: 100px; trans'> + <div id='child' style='overflow: hidden; z-index: 0; + position: absolute; width: 50px; height: 50px'> + content + </div> + </div> + )HTML"); auto* parent = GetDocument().getElementById("parent"); auto* child = GetDocument().getElementById("child"); @@ -268,19 +275,20 @@ } TEST_P(PrePaintTreeWalkTest, VisualRectClipForceSubtree) { - SetBodyInnerHTML( - "<style>" - " #parent { height: 75px; position: relative; width: 100px; }" - "</style>" - "<div id='parent' style='height: 100px;'>" - " <div id='child' style='overflow: hidden; width: 100%; height: 100%; " - " position: relative'>" - " <div>" - " <div id='grandchild' style='width: 50px; height: 200px; '>" - " </div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #parent { height: 75px; position: relative; width: 100px; } + </style> + <div id='parent' style='height: 100px;'> + <div id='child' style='overflow: hidden; width: 100%; height: 100%; + position: relative'> + <div> + <div id='grandchild' style='width: 50px; height: 200px; '> + </div> + </div> + </div> + </div> + )HTML"); auto* grandchild = GetLayoutObjectByElementId("grandchild"); @@ -296,17 +304,18 @@ } TEST_P(PrePaintTreeWalkTest, ClipChangeHasRadius) { - SetBodyInnerHTML( - "<style>" - " #target {" - " position: absolute;" - " z-index: 0;" - " overflow: hidden;" - " width: 50px;" - " height: 50px;" - " }" - "</style>" - "<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <style> + #target { + position: absolute; + z-index: 0; + overflow: hidden; + width: 50px; + height: 50px; + } + </style> + <div id='target'></div> + )HTML"); auto* target = GetDocument().getElementById("target"); auto* target_object = ToLayoutBoxModelObject(target->GetLayoutObject());
diff --git a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp index b69479f..d384e0bc 100644 --- a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
@@ -19,16 +19,17 @@ ::testing::Values(0, kRootLayerScrolling)); TEST_P(TablePainterTest, Background) { - SetBodyInnerHTML( - "<style>" - " td { width: 200px; height: 200px; padding: 0; border: none; }" - " tr { background-color: blue; }" - " table { border: none; border-spacing: 0 }" - "</style>" - "<table>" - " <tr id='row1'><td></td></tr>" - " <tr id='row2'><td></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + td { width: 200px; height: 200px; padding: 0; border: none; } + tr { background-color: blue; } + table { border: none; border-spacing: 0 } + </style> + <table> + <tr id='row1'><td></td></tr> + <tr id='row2'><td></td></tr> + </table> + )HTML"); LayoutObject& row1 = *GetLayoutObjectByElementId("row1"); LayoutObject& row2 = *GetLayoutObjectByElementId("row2"); @@ -64,19 +65,20 @@ } TEST_P(TablePainterTest, BackgroundWithCellSpacing) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0; }" - " td { width: 200px; height: 150px; border: 0; background-color: green; " - " }" - " tr { background-color: blue; }" - " table { border: none; border-spacing: 100px; border-collapse: " - "separate; }" - "</style>" - "<table>" - " <tr id='row1'><td id='cell1'></td></tr>" - " <tr id='row2'><td id='cell2'></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + td { width: 200px; height: 150px; border: 0; background-color: green; + } + tr { background-color: blue; } + table { border: none; border-spacing: 100px; border-collapse: + separate; } + </style> + <table> + <tr id='row1'><td id='cell1'></td></tr> + <tr id='row2'><td id='cell2'></td></tr> + </table> + )HTML"); LayoutObject& row1 = *GetLayoutObjectByElementId("row1"); LayoutObject& row2 = *GetLayoutObjectByElementId("row2"); @@ -128,18 +130,19 @@ } TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " td { width: 200px; height: 200px; border: 0; background-color: green; " - "}" - " tr { background-color: blue; opacity: 0.5; }" - " table { border: none; border-spacing: 100px; border-collapse: " - "separate; }" - "</style>" - "<table>" - " <tr id='row'><td id='cell1'><td id='cell2'></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + td { width: 200px; height: 200px; border: 0; background-color: green; + } + tr { background-color: blue; opacity: 0.5; } + table { border: none; border-spacing: 100px; border-collapse: + separate; } + </style> + <table> + <tr id='row'><td id='cell1'><td id='cell2'></td></tr> + </table> + )HTML"); LayoutObject& cell1 = *GetLayoutObjectByElementId("cell1"); LayoutObject& cell2 = *GetLayoutObjectByElementId("cell2"); @@ -193,16 +196,17 @@ } TEST_P(TablePainterTest, CollapsedBorderAndOverflow) { - SetBodyInnerHTML( - "<style>" - " body { margin: 0 }" - " td { width: 100px; height: 100px; border: 100px solid blue; outline: " - "100px solid yellow; background: green; }" - " table { margin: 100px; border-collapse: collapse; }" - "</style>" - "<table>" - " <tr><td id='cell'></td></tr>" - "</table>"); + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0 } + td { width: 100px; height: 100px; border: 100px solid blue; outline: + 100px solid yellow; background: green; } + table { margin: 100px; border-collapse: collapse; } + </style> + <table> + <tr><td id='cell'></td></tr> + </table> + )HTML"); auto& cell = *ToLayoutTableCell(GetLayoutObjectByElementId("cell"));
diff --git a/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp b/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp index a321fa81..3af7d92e 100644 --- a/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
@@ -30,17 +30,18 @@ Settings* settings = GetDocument().GetFrame()->GetSettings(); settings->SetPreferCompositingToLCDTextEnabled(true); } - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { display: none; }" - " body {" - " margin: 0;" - " width: 1200px;" - " height: 900px;" - " background: radial-gradient(" - " circle at 100px 100px, blue, transparent 200px) fixed;" - " }" - "</style>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { display: none; } + body { + margin: 0; + width: 1200px; + height: 900px; + background: radial-gradient( + circle at 100px 100px, blue, transparent 200px) fixed; + } + </style> + )HTML"); LocalFrameView* frame_view = GetDocument().View(); ScrollableArea* layout_viewport = frame_view->LayoutViewportScrollableArea();
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp index 8824f05..fb229c2 100644 --- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
@@ -187,10 +187,11 @@ } TEST_P(CompositedLayerMappingTest, VerticalRightLeftWritingModeDocument) { - SetBodyInnerHTML( - "<style>html,body { margin: 0px } html { -webkit-writing-mode: " - "vertical-rl}</style> <div id='target' style='width: 10000px; height: " - "200px;'></div>"); + SetBodyInnerHTML(R"HTML( + <style>html,body { margin: 0px } html { -webkit-writing-mode: + vertical-rl}</style> <div id='target' style='width: 10000px; height: + 200px;'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); GetDocument().View()->LayoutViewportScrollableArea()->SetScrollOffset( @@ -243,34 +244,35 @@ // It's rotated 90 degrees about the X axis, which means its visual content // rect is empty, and so the interest rect is the default (0, 0, 4000, 4000) // intersected with the layer bounds. - SetBodyInnerHTML( - "<style>" - " .container {" - " height: 1080px;" - " width: 1920px;" - " transform: scale(0.0859375);" - " transform-origin: 0 0 0;" - " background:blue;" - " }" - " .wrapper {" - " height: 92px;" - " width: 165px;" - " overflow: hidden;" - " }" - " .posabs {" - " position: absolute;" - " width: 300px;" - " height: 300px;" - " top: 5000px;" - " }" - "</style>" - "<div class='wrapper'>" - " <div id='target' class='container'>" - " <div class='posabs'></div>" - " <div id='target' style='will-change: transform' " - "class='posabs'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .container { + height: 1080px; + width: 1920px; + transform: scale(0.0859375); + transform-origin: 0 0 0; + background:blue; + } + .wrapper { + height: 92px; + width: 165px; + overflow: hidden; + } + .posabs { + position: absolute; + width: 300px; + height: 300px; + top: 5000px; + } + </style> + <div class='wrapper'> + <div id='target' class='container'> + <div class='posabs'></div> + <div id='target' style='will-change: transform' + class='posabs'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("target"); @@ -358,10 +360,11 @@ } TEST_P(CompositedLayerMappingTest, LayerOffscreenInterestRect) { - SetBodyInnerHTML( - "<div id='target' style='width: 200px; height: 200px; will-change: " - "transform; position: absolute; top: 9000px; left: 0px;'>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='width: 200px; height: 200px; will-change: + transform; position: absolute; top: 9000px; left: 0px;'> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("target"); @@ -374,11 +377,12 @@ } TEST_P(CompositedLayerMappingTest, ScrollingLayerInterestRect) { - SetBodyInnerHTML( - "<style>div::-webkit-scrollbar{ width: 5px; }</style>" - "<div id='target' style='width: 200px; height: 200px; will-change: " - "transform; overflow: scroll'>" - "<div style='width: 100px; height: 10000px'></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>div::-webkit-scrollbar{ width: 5px; }</style> + <div id='target' style='width: 200px; height: 200px; will-change: + transform; overflow: scroll'> + <div style='width: 100px; height: 10000px'></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("target"); @@ -392,10 +396,11 @@ } TEST_P(CompositedLayerMappingTest, ClippedBigLayer) { - SetBodyInnerHTML( - "<div style='width: 1px; height: 1px; overflow: hidden'>" - "<div id='target' style='width: 10000px; height: 10000px; will-change: " - "transform'></div></div>"); + SetBodyInnerHTML(R"HTML( + <div style='width: 1px; height: 1px; overflow: hidden'> + <div id='target' style='width: 10000px; height: 10000px; will-change: + transform'></div></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("target"); @@ -447,11 +452,12 @@ } TEST_P(CompositedLayerMappingTest, ScrollContentsFlattenForScroller) { - SetBodyInnerHTML( - "<style>div::-webkit-scrollbar{ width: 5px; }</style>" - "<div id='scroller' style='width: 100px; height: 100px; overflow: " - "scroll; will-change: transform'>" - "<div style='width: 1000px; height: 1000px;'>Foo</div>Foo</div>"); + SetBodyInnerHTML(R"HTML( + <style>div::-webkit-scrollbar{ width: 5px; }</style> + <div id='scroller' style='width: 100px; height: 100px; overflow: + scroll; will-change: transform'> + <div style='width: 1000px; height: 1000px;'>Foo</div>Foo</div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("scroller"); @@ -554,12 +560,13 @@ } TEST_P(CompositedLayerMappingTest, InterestRectChangeOnViewportScroll) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { width: 0; height: 0; }" - " body { margin: 0; }" - "</style>" - "<div id='div' style='width: 100px; height: 10000px'>Text</div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { width: 0; height: 0; } + body { margin: 0; } + </style> + <div id='div' style='width: 100px; height: 10000px'>Text</div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); GraphicsLayer* root_scrolling_layer = @@ -615,12 +622,13 @@ } TEST_P(CompositedLayerMappingTest, InterestRectChangeOnShrunkenViewport) { - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { width: 0; height: 0; }" - " body { margin: 0; }" - "</style>" - "<div id='div' style='width: 100px; height: 10000px'>Text</div>"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { width: 0; height: 0; } + body { margin: 0; } + </style> + <div id='div' style='width: 100px; height: 10000px'>Text</div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); GraphicsLayer* root_scrolling_layer = @@ -641,15 +649,16 @@ GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { width: 0; height: 0; }" - " body { margin: 0; }" - "</style>" - "<div id='scroller' style='width: 400px; height: 400px; overflow: " - "scroll'>" - " <div id='content' style='width: 100px; height: 10000px'>Text</div>" - "</div"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { width: 0; height: 0; } + body { margin: 0; } + </style> + <div id='scroller' style='width: 400px; height: 400px; overflow: + scroll'> + <div id='content' style='width: 100px; height: 10000px'>Text</div> + </div + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scroller = GetDocument().getElementById("scroller"); @@ -696,15 +705,16 @@ GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { width: 0; height: 0; }" - " body { margin: 0; }" - "</style>" - "<div id='scroller' style='width: 400px; height: 400px; overflow: " - "scroll'>" - " <div id='content' style='width: 100px; height: 10000px'>Text</div>" - "</div"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { width: 0; height: 0; } + body { margin: 0; } + </style> + <div id='scroller' style='width: 400px; height: 400px; overflow: + scroll'> + <div id='content' style='width: 100px; height: 10000px'>Text</div> + </div + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scroller = GetDocument().getElementById("scroller"); @@ -731,14 +741,15 @@ TEST_P(CompositedLayerMappingTest, InterestRectOfSquashingLayerWithNegativeOverflow) { - SetBodyInnerHTML( - "<style>body { margin: 0; font-size: 16px; }</style>" - "<div style='position: absolute; top: -500px; width: 200px; height: " - "700px; will-change: transform'></div>" - "<div id='squashed' style='position: absolute; top: 190px;'>" - " <div id='inside' style='width: 100px; height: 100px; text-indent: " - "-10000px'>text</div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; font-size: 16px; }</style> + <div style='position: absolute; top: -500px; width: 200px; height: + 700px; will-change: transform'></div> + <div id='squashed' style='position: absolute; top: 190px;'> + <div id='inside' style='width: 100px; height: 100px; text-indent: + -10000px'>text</div> + </div> + )HTML"); EXPECT_EQ(GetDocument() .getElementById("inside") @@ -790,12 +801,13 @@ TEST_P(CompositedLayerMappingTest, InterestRectOfIframeInScrolledDiv) { GetDocument().SetBaseURLOverride(KURL("http://test.com")); - SetBodyInnerHTML( - "<style>body { margin: 0; }</style>" - "<div style='width: 200; height: 8000px'></div>" - "<iframe src='http://test.com' width='500' height='500' " - "frameBorder='0'>" - "</iframe>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; }</style> + <div style='width: 200; height: 8000px'></div> + <iframe src='http://test.com' width='500' height='500' + frameBorder='0'> + </iframe> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; } #target { width: 200px; height: 200px; " "will-change: transform}</style><div id=target></div>"); @@ -818,12 +830,13 @@ GetDocument().SetBaseURLOverride(KURL("http://test.com")); GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<style>body { margin: 0; } ::-webkit-scrollbar { display: none; " - "}</style>" - "<iframe src='http://test.com' width='500' height='500' " - "frameBorder='0'>" - "</iframe>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; } ::-webkit-scrollbar { display: none; + }</style> + <iframe src='http://test.com' width='500' height='500' + frameBorder='0'> + </iframe> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; } #target { width: 200px; " "height: 8000px;}</style><div id=target></div>"); @@ -850,12 +863,13 @@ true); // Set a 10px border in order to have a contentBoxOffset for the iframe // element. - SetBodyInnerHTML( - "<style>body { margin: 0; } #frame { border: 10px solid black; } " - "::-webkit-scrollbar { display: none; }</style>" - "<iframe src='http://test.com' width='500' height='500' " - "frameBorder='0'>" - "</iframe>"); + SetBodyInnerHTML(R"HTML( + <style>body { margin: 0; } #frame { border: 10px solid black; } + ::-webkit-scrollbar { display: none; }</style> + <iframe src='http://test.com' width='500' height='500' + frameBorder='0'> + </iframe> + )HTML"); SetChildFrameHTML( "<style>body { margin: 0; } #target { width: 200px; " "height: 8000px;}</style> <div id=target></div>"); @@ -882,15 +896,16 @@ ScrollingContentsAndForegroundLayerPaintingPhase) { GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<div id='container' style='position: relative; z-index: 1; overflow: " - "scroll; width: 300px; height: 300px'>" - " <div id='negative-composited-child' style='background-color: red; " - "width: 1px; height: 1px; position: absolute; backface-visibility: " - "hidden; z-index: -1'></div>" - " <div style='background-color: blue; width: 2000px; height: 2000px; " - "position: relative; top: 10px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='position: relative; z-index: 1; overflow: + scroll; width: 300px; height: 300px'> + <div id='negative-composited-child' style='background-color: red; + width: 1px; height: 1px; position: absolute; backface-visibility: + hidden; z-index: -1'></div> + <div style='background-color: blue; width: 2000px; height: 2000px; + position: relative; top: 10px'></div> + </div> + )HTML"); CompositedLayerMapping* mapping = ToLayoutBlock(GetLayoutObjectByElementId("container")) @@ -931,16 +946,17 @@ TEST_P(CompositedLayerMappingTest, DecorationOutlineLayerOnlyCreatedInCompositedScrolling) { - SetBodyInnerHTML( - "<style>" - "#target { overflow: scroll; height: 200px; width: 200px; will-change: " - "transform; background: white local content-box; " - "outline: 1px solid blue; outline-offset: -2px;}" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"parent\">" - " <div id=\"target\"><div id=\"scrolled\"></div></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #target { overflow: scroll; height: 200px; width: 200px; will-change: + transform; background: white local content-box; + outline: 1px solid blue; outline-offset: -2px;} + #scrolled { height: 300px; } + </style> + <div id="parent"> + <div id="target"><div id="scrolled"></div></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* element = GetDocument().getElementById("target"); @@ -968,15 +984,16 @@ TEST_P(CompositedLayerMappingTest, DecorationOutlineLayerCreatedAndDestroyedInCompositedScrolling) { - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: scroll; height: 200px; width: 200px; background: " - "white local content-box; outline: 1px solid blue; contain: paint; }" - "#scrolled { height: 300px; }" - "</style>" - "<div id=\"parent\">" - " <div id=\"scroller\"><div id=\"scrolled\"></div></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; height: 200px; width: 200px; background: + white local content-box; outline: 1px solid blue; contain: paint; } + #scrolled { height: 300px; } + </style> + <div id="parent"> + <div id="scroller"><div id="scrolled"></div></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scroller = GetDocument().getElementById("scroller"); @@ -1013,12 +1030,13 @@ BackgroundPaintedIntoGraphicsLayerIfNotCompositedScrolling) { GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<div id='container' style='overflow: scroll; width: 300px; height: " - "300px; border-radius: 5px; background: white; will-change: transform;'>" - " <div style='background-color: blue; width: 2000px; height: " - "2000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='container' style='overflow: scroll; width: 300px; height: + 300px; border-radius: 5px; background: white; will-change: transform;'> + <div style='background-color: blue; width: 2000px; height: + 2000px;'></div> + </div> + )HTML"); PaintLayer* layer = ToLayoutBlock(GetLayoutObjectByElementId("container"))->Layer(); @@ -1120,14 +1138,15 @@ } TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerUpdates) { - SetBodyInnerHTML( - "<style>" - " #ancestor { width: 100px; height: 100px; overflow: hidden; }" - " #child { width: 120px; height: 120px; background-color: green; }" - "</style>" - "<div id='ancestor'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #ancestor { width: 100px; height: 100px; overflow: hidden; } + #child { width: 120px; height: 120px; background-color: green; } + </style> + <div id='ancestor'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ancestor = GetDocument().getElementById("ancestor"); @@ -1199,18 +1218,19 @@ } TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerSiblingUpdates) { - SetBodyInnerHTML( - "<style>" - " #ancestor { width: 200px; height: 200px; overflow: hidden; }" - " #child1 { width: 10px;; height: 260px; position: relative; " - " left: 0px; top: -30px; background-color: green; }" - " #child2 { width: 10px;; height: 260px; position: relative; " - " left: 190px; top: -260px; background-color: green; }" - "</style>" - "<div id='ancestor'>" - " <div id='child1'></div>" - " <div id='child2'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #ancestor { width: 200px; height: 200px; overflow: hidden; } + #child1 { width: 10px;; height: 260px; position: relative; + left: 0px; top: -30px; background-color: green; } + #child2 { width: 10px;; height: 260px; position: relative; + left: 190px; top: -260px; background-color: green; } + </style> + <div id='ancestor'> + <div id='child1'></div> + <div id='child2'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ancestor = GetDocument().getElementById("ancestor"); @@ -1334,19 +1354,20 @@ } TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerGrandchildUpdates) { - SetBodyInnerHTML( - "<style>" - " #ancestor { width: 200px; height: 200px; overflow: hidden; }" - " #child { width: 10px;; height: 260px; position: relative; " - " left: 0px; top: -30px; background-color: green; }" - " #grandchild { width: 10px;; height: 260px; position: relative; " - " left: 190px; top: -30px; background-color: green; }" - "</style>" - "<div id='ancestor'>" - " <div id='child'>" - " <div id='grandchild'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #ancestor { width: 200px; height: 200px; overflow: hidden; } + #child { width: 10px;; height: 260px; position: relative; + left: 0px; top: -30px; background-color: green; } + #grandchild { width: 10px;; height: 260px; position: relative; + left: 190px; top: -30px; background-color: green; } + </style> + <div id='ancestor'> + <div id='child'> + <div id='grandchild'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ancestor = GetDocument().getElementById("ancestor"); @@ -1448,19 +1469,20 @@ TEST_P(CompositedLayerMappingTest, AncestorClipMaskRequiredByBorderRadius) { // Verify that we create the mask layer when the child is contained within // the rectangular clip but not contained within the rounded rect clip. - SetBodyInnerHTML( - "<style>" - " #ancestor {" - " width: 100px; height: 100px; overflow: hidden; border-radius: 20px;" - " }" - " #child { position: relative; left: 2px; top: 2px; width: 96px;" - " height: 96px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='ancestor'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #ancestor { + width: 100px; height: 100px; overflow: hidden; border-radius: 20px; + } + #child { position: relative; left: 2px; top: 2px; width: 96px; + height: 96px; background-color: green; + will-change: transform; + } + </style> + <div id='ancestor'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ancestor = GetDocument().getElementById("ancestor"); @@ -1490,24 +1512,25 @@ AncestorClipMaskNotRequiredByNestedBorderRadius) { // This case has the child within all ancestors and does not require a // mask. - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; border-radius: 10px; overflow: hidden;" - " }" - " #child { position: relative; left: 10px; top: 10px; width: 100px;" - " height: 100px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; border-radius: 10px; overflow: hidden; + } + #child { position: relative; left: 10px; top: 10px; width: 100px; + height: 100px; background-color: green; + will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1527,24 +1550,25 @@ AncestorClipMaskRequiredByParentBorderRadius) { // This case has the child within the grandparent but not the parent, and does // require a mask so that the parent will clip the corners. - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; border-radius: 10px; overflow: hidden;" - " }" - " #child { position: relative; left: 1px; top: 1px; width: 118px;" - " height: 118px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; border-radius: 10px; overflow: hidden; + } + #child { position: relative; left: 1px; top: 1px; width: 118px; + height: 118px; background-color: green; + will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1568,24 +1592,25 @@ AncestorClipMaskNotRequiredByParentBorderRadius) { // This case has the child within the grandparent but not the parent, and does // not require a mask because the parent does not have border radius - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden;" - " }" - " #child { position: relative; left: -10px; top: -10px; width: 140px;" - " height: 140px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; + } + #child { position: relative; left: -10px; top: -10px; width: 140px; + height: 140px; background-color: green; + will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1607,24 +1632,25 @@ // the parent, and requires a mask to clip to the grandparent. Although in // an optimized world we would not need this because the parent clips out // the child before it is clipped by the grandparent. - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden;" - " }" - " #child { position: relative; left: -10px; top: -10px; width: 180px;" - " height: 180px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; + } + #child { position: relative; left: -10px; top: -10px; width: 180px; + height: 180px; background-color: green; + will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1647,24 +1673,25 @@ TEST_P(CompositedLayerMappingTest, AncestorClipMaskRequiredByGrandparentBorderRadius2) { // Similar to the previous case, but here we really do need the mask. - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 40px; top: 40px; width: 180px;" - " height: 180px; overflow: hidden;" - " }" - " #child { position: relative; left: -10px; top: -10px; width: 180px;" - " height: 180px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 40px; top: 40px; width: 180px; + height: 180px; overflow: hidden; + } + #child { position: relative; left: -10px; top: -10px; width: 180px; + height: 180px; background-color: green; + will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1688,19 +1715,20 @@ AncestorClipMaskNotRequiredByBorderRadiusInside) { // Verify that we do not create the mask layer when the child is contained // within the rounded rect clip. - SetBodyInnerHTML( - "<style>" - " #ancestor {" - " width: 100px; height: 100px; overflow: hidden; border-radius: 5px;" - " }" - " #child { position: relative; left: 10px; top: 10px; width: 80px;" - " height: 80px; background-color: green;" - " will-change: transform;" - " }" - "</style>" - "<div id='ancestor'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #ancestor { + width: 100px; height: 100px; overflow: hidden; border-radius: 5px; + } + #child { position: relative; left: 10px; top: 10px; width: 80px; + height: 80px; background-color: green; + will-change: transform; + } + </style> + <div id='ancestor'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ancestor = GetDocument().getElementById("ancestor"); @@ -1730,19 +1758,20 @@ AncestorClipMaskNotRequiredByBorderRadiusOutside) { // Verify that we do not create the mask layer when the child is outside // the ancestors rectangular clip. - SetBodyInnerHTML( - "<style>" - " #ancestor {" - " width: 100px; height: 100px; overflow: hidden; border-radius: 5px;" - " }" - " #child { position: relative; left: 110px; top: 10px; width: 80px;" - " height: 80px; background-color: green;" - " will-change: transform;" - "}" - "</style>" - "<div id='ancestor'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #ancestor { + width: 100px; height: 100px; overflow: hidden; border-radius: 5px; + } + #child { position: relative; left: 110px; top: 10px; width: 80px; + height: 80px; background-color: green; + will-change: transform; + } + </style> + <div id='ancestor'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* ancestor = GetDocument().getElementById("ancestor"); @@ -1772,20 +1801,21 @@ // Verify that we include the mask when the untransformed child does not // intersect the border radius but the transformed child does. Here the // child is inside the parent and scaled to expand to be clipped. - SetBodyInnerHTML( - "<style>" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden; border-radius: 10px" - " }" - " #child { position: relative; left: 32px; top: 32px; width: 56px;" - " height: 56px; background-color: green;" - " transform: scale3d(2, 2, 1);" - " will-change: transform;" - " }" - "</style>" - "<div id='parent'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; border-radius: 10px + } + #child { position: relative; left: 32px; top: 32px; width: 56px; + height: 56px; background-color: green; + transform: scale3d(2, 2, 1); + will-change: transform; + } + </style> + <div id='parent'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1806,20 +1836,21 @@ // intersect the border radius but the transformed child does not. Here the // child is bigger than the parent and scaled down such that it does not // need a mask. - SetBodyInnerHTML( - "<style>" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden; border-radius: 10px" - " }" - " #child { position: relative; left: -10px; top: -10px; width: 140px;" - " height: 140px; background-color: green;" - " transform: scale3d(0.5, 0.5, 1);" - " will-change: transform;" - " }" - "</style>" - "<div id='parent'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; border-radius: 10px + } + #child { position: relative; left: -10px; top: -10px; width: 140px; + height: 140px; background-color: green; + transform: scale3d(0.5, 0.5, 1); + will-change: transform; + } + </style> + <div id='parent'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1839,20 +1870,21 @@ // Verify that we include the mask when the untransformed child does not // intersect the border radius but the transformed child does. Here the // child is outside the parent and translated to be clipped. - SetBodyInnerHTML( - "<style>" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden; border-radius: 10px" - " }" - " #child { position: relative; left: 140px; top: 140px; width: 100px;" - " height: 100px; background-color: green;" - " transform: translate(-120px, -120px);" - " will-change: transform;" - " }" - "</style>" - "<div id='parent'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; border-radius: 10px + } + #child { position: relative; left: 140px; top: 140px; width: 100px; + height: 100px; background-color: green; + transform: translate(-120px, -120px); + will-change: transform; + } + </style> + <div id='parent'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1873,20 +1905,21 @@ // Verify that we exclude the mask when the untransformed child does // intersect the border radius but the transformed child does not. Here the // child is inside the parent and translated outside. - SetBodyInnerHTML( - "<style>" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden; border-radius: 10px" - " }" - " #child { position: relative; left: 15px; top: 15px; width: 100px;" - " height: 100px; background-color: green;" - " transform: translate(110px, 110px);" - " will-change: transform;" - " }" - "</style>" - "<div id='parent'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; border-radius: 10px + } + #child { position: relative; left: 15px; top: 15px; width: 100px; + height: 100px; background-color: green; + transform: translate(110px, 110px); + will-change: transform; + } + </style> + <div id='parent'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1907,20 +1940,21 @@ // intersect the border radius but the transformed child does. Here the // child is just within the mask-not-required area but when rotated requires // a mask. - SetBodyInnerHTML( - "<style>" - " #parent { position: relative; left: 40px; top: 40px; width: 120px;" - " height: 120px; overflow: hidden; border-radius: 10px" - " }" - " #child { position: relative; left: 11px; top: 11px; width: 98px;" - " height: 98px; background-color: green;" - " transform: rotate3d(0, 0, 1, 5deg);" - " will-change: transform;" - " }" - "</style>" - "<div id='parent'>" - " <div id='child'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #parent { position: relative; left: 40px; top: 40px; width: 120px; + height: 120px; overflow: hidden; border-radius: 10px + } + #child { position: relative; left: 11px; top: 11px; width: 98px; + height: 98px; background-color: green; + transform: rotate3d(0, 0, 1, 5deg); + will-change: transform; + } + </style> + <div id='parent'> + <div id='child'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -1942,23 +1976,24 @@ // in principle not need a mask, but does because we cannot efficiently // check the bounds of the composited descendant for intersection with the // border. - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 30px; top: 30px; width: 140px;" - " height: 140px; overflow: hidden; will-change: transform;" - " }" - " #child { position: relative; left: 10px; top: 10px; width: 120px;" - " height: 120px; will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 30px; top: 30px; width: 140px; + height: 140px; overflow: hidden; will-change: transform; + } + #child { position: relative; left: 10px; top: 10px; width: 120px; + height: 120px; will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'></div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* parent = GetDocument().getElementById("parent"); @@ -1980,28 +2015,29 @@ // the parent, and does not itself require a mask to clip to the grandparent. // But the child has it's own composited child, so we force the mask in case // the child's child needs it. - SetBodyInnerHTML( - "<style>" - " #grandparent {" - " width: 200px; height: 200px; overflow: hidden; border-radius: 25px;" - " }" - " #parent { position: relative; left: 30px; top: 30px; width: 140px;" - " height: 140px; overflow: hidden;" - " }" - " #child { position: relative; left: 10px; top: 10px; width: 120px;" - " height: 120px; will-change: transform;" - " }" - " #grandchild { position: relative; left: 10px; top: 10px; width: 200px;" - " height: 200px; will-change: transform;" - " }" - "</style>" - "<div id='grandparent'>" - " <div id='parent'>" - " <div id='child'>" - " <div id='grandchild'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #grandparent { + width: 200px; height: 200px; overflow: hidden; border-radius: 25px; + } + #parent { position: relative; left: 30px; top: 30px; width: 140px; + height: 140px; overflow: hidden; + } + #child { position: relative; left: 10px; top: 10px; width: 120px; + height: 120px; will-change: transform; + } + #grandchild { position: relative; left: 10px; top: 10px; width: 200px; + height: 200px; will-change: transform; + } + </style> + <div id='grandparent'> + <div id='parent'> + <div id='child'> + <div id='grandchild'></div> + </div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* child = GetDocument().getElementById("child"); @@ -2022,38 +2058,39 @@ // When a node with inline transform has siblings with border radius and // composited children, those siblings must not be squashed because it // prevents application of a border radius clip mask. - SetBodyInnerHTML( - "<style>" - " .precursor {" - " width: 100px;" - " height: 40px;" - " }" - " .container {" - " position: relative;" - " top: 20px;" - " width: 100px;" - " height: 40px;" - " border: 1px solid black;" - " border-radius: 10px;" - " overflow: hidden;" - " }" - " .contents {" - " height: 200px;" - " width: 200px;" - " position: relative;" - " top: -10px;" - " left: -10px;" - " }" - "</style>" - "<div id='precursor' class='precursor'" - " style='transform: translateZ(0);'>" - "</div>" - "<div id='container1' class='container'>" - " <div id='contents1' class='contents'></div>" - "</div>" - "<div id='container2' class='container'>" - " <div id='contents2' class='contents'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .precursor { + width: 100px; + height: 40px; + } + .container { + position: relative; + top: 20px; + width: 100px; + height: 40px; + border: 1px solid black; + border-radius: 10px; + overflow: hidden; + } + .contents { + height: 200px; + width: 200px; + position: relative; + top: -10px; + left: -10px; + } + </style> + <div id='precursor' class='precursor' + style='transform: translateZ(0);'> + </div> + <div id='container1' class='container'> + <div id='contents1' class='contents'></div> + </div> + <div id='container2' class='container'> + <div id='contents2' class='contents'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* first_child = GetDocument().getElementById("contents1"); @@ -2082,18 +2119,19 @@ } TEST_P(CompositedLayerMappingTest, StickyPositionMainThreadOffset) { - SetBodyInnerHTML( - "<style>.composited { backface-visibility: hidden; }" - "#scroller { overflow: auto; height: 200px; width: 200px; }" - ".container { height: 500px; }" - ".innerPadding { height: 10px; }" - "#sticky { position: sticky; top: 25px; height: 50px; }</style>" - "<div id='scroller' class='composited'>" - " <div class='composited container'>" - " <div class='composited container'>" - " <div class='innerPadding'></div>" - " <div id='sticky' class='composited'></div>" - " </div></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>.composited { backface-visibility: hidden; } + #scroller { overflow: auto; height: 200px; width: 200px; } + .container { height: 500px; } + .innerPadding { height: 10px; } + #sticky { position: sticky; top: 25px; height: 50px; }</style> + <div id='scroller' class='composited'> + <div class='composited container'> + <div class='composited container'> + <div class='innerPadding'></div> + <div id='sticky' class='composited'></div> + </div></div></div> + )HTML"); PaintLayer* sticky_layer = ToLayoutBox(GetLayoutObjectByElementId("sticky"))->Layer(); @@ -2116,20 +2154,21 @@ } TEST_P(CompositedLayerMappingTest, StickyPositionNotSquashed) { - SetBodyInnerHTML( - "<style>" - "#scroller { overflow: auto; height: 200px; }" - "#sticky1, #sticky2, #sticky3 {position: sticky; top: 0; width: 50px;" - " height: 50px; background: rgba(0, 128, 0, 0.5);}" - "#sticky1 {backface-visibility: hidden;}" - ".spacer {height: 2000px;}" - "</style>" - "<div id='scroller'>" - " <div id='sticky1'></div>" - " <div id='sticky2'></div>" - " <div id='sticky3'></div>" - " <div class='spacer'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: auto; height: 200px; } + #sticky1, #sticky2, #sticky3 {position: sticky; top: 0; width: 50px; + height: 50px; background: rgba(0, 128, 0, 0.5);} + #sticky1 {backface-visibility: hidden;} + .spacer {height: 2000px;} + </style> + <div id='scroller'> + <div id='sticky1'></div> + <div id='sticky2'></div> + <div id='sticky3'></div> + <div class='spacer'></div> + </div> + )HTML"); PaintLayer* sticky1 = ToLayoutBlock(GetLayoutObjectByElementId("sticky1"))->Layer(); @@ -2158,19 +2197,20 @@ TEST_P(CompositedLayerMappingTest, LayerPositionForStickyElementInCompositedScroller) { - SetBodyInnerHTML( - "<style>" - " .scroller { overflow: scroll; width: 200px; height: 600px; }" - " .composited { will-change:transform; }" - " .perspective { perspective: 150px; }" - " .box { position: sticky; width: 185px; height: 50px; top: 0px; }" - " .container { width: 100%; height: 1000px; }" - "</style>" - "<div id='scroller' class='composited scroller'>" - " <div class='composited container'>" - " <div id='sticky' class='perspective box'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .scroller { overflow: scroll; width: 200px; height: 600px; } + .composited { will-change:transform; } + .perspective { perspective: 150px; } + .box { position: sticky; width: 185px; height: 50px; top: 0px; } + .container { width: 100%; height: 1000px; } + </style> + <div id='scroller' class='composited scroller'> + <div class='composited container'> + <div id='sticky' class='perspective box'></div> + </div> + </div> + )HTML"); LayoutBoxModelObject* sticky = ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky")); @@ -2209,18 +2249,19 @@ TEST_P(CompositedLayerMappingTest, LayerPositionForStickyElementInNonCompositedScroller) { - SetBodyInnerHTML( - "<style>" - " .scroller { overflow: scroll; width: 200px; height: 600px; }" - " .composited { will-change:transform; }" - " .box { position: sticky; width: 185px; height: 50px; top: 0px; }" - " .container { width: 100%; height: 1000px; }" - "</style>" - "<div id='scroller' class='scroller'>" - " <div class='composited container'>" - " <div id='sticky' class='box'></div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .scroller { overflow: scroll; width: 200px; height: 600px; } + .composited { will-change:transform; } + .box { position: sticky; width: 185px; height: 50px; top: 0px; } + .container { width: 100%; height: 1000px; } + </style> + <div id='scroller' class='scroller'> + <div class='composited container'> + <div id='sticky' class='box'></div> + </div> + </div> + )HTML"); CompositedLayerMapping* mapping = ToLayoutBlock(GetLayoutObjectByElementId("sticky")) @@ -2245,10 +2286,11 @@ TransformedRasterizationDisallowedForDirectReasons) { // This test verifies layers with direct compositing reasons won't have // transformed rasterization, i.e. should raster in local space. - SetBodyInnerHTML( - "<div id='target1' style='transform:translateZ(0);'>foo</div>" - "<div id='target2' style='will-change:opacity;'>bar</div>" - "<div id='target3' style='backface-visibility:hidden;'>ham</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target1' style='transform:translateZ(0);'>foo</div> + <div id='target2' style='will-change:opacity;'>bar</div> + <div id='target3' style='backface-visibility:hidden;'>ham</div> + )HTML"); { LayoutObject* target = GetLayoutObjectByElementId("target1"); @@ -2286,12 +2328,13 @@ // This test verifies we allow layers that are indirectly composited due to // an inline transform (but no direct reason otherwise) to raster in the // device space for higher quality. - SetBodyInnerHTML( - "<div style='will-change:transform; width:500px; " - "height:20px;'>composited</div>" - "<div id='target' style='transform:translate(1.5px,-10.5px); " - "width:500px; height:20px;'>indirectly composited due to inline " - "transform</div>"); + SetBodyInnerHTML(R"HTML( + <div style='will-change:transform; width:500px; + height:20px;'>composited</div> + <div id='target' style='transform:translate(1.5px,-10.5px); + width:500px; height:20px;'>indirectly composited due to inline + transform</div> + )HTML"); LayoutObject* target = GetLayoutObjectByElementId("target"); ASSERT_TRUE(target && target->IsBox()); @@ -2307,16 +2350,17 @@ // element is promoted for another reason we do remove its composited sticky // constraint as it doesn't need to move on the compositor. TEST_P(CompositedLayerMappingTest, CompositedStickyConstraintRemovedAndAdded) { - SetBodyInnerHTML( - "<style>" - ".scroller { overflow: auto; height: 200px; }" - ".sticky { position: sticky; top: 0; width: 10px; height: 10px; }" - ".composited { will-change: transform; }" - "</style>" - "<div class='composited scroller'>" - " <div id='sticky' class='composited sticky'></div>" - " <div id='spacer' style='height: 2000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .scroller { overflow: auto; height: 200px; } + .sticky { position: sticky; top: 0; width: 10px; height: 10px; } + .composited { will-change: transform; } + </style> + <div class='composited scroller'> + <div id='sticky' class='composited sticky'></div> + <div id='spacer' style='height: 2000px;'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); PaintLayer* sticky_layer = ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky"))->Layer(); @@ -2355,21 +2399,22 @@ TEST_P(CompositedLayerMappingTest, ScrollingContainerBoundsChange) { GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( true); - SetBodyInnerHTML( - "<style>" - " ::-webkit-scrollbar { width: 0; height: 0; }" - " body { margin: 0; }" - " #scroller { overflow-y: scroll; }" - " #content {" - " width: 100px;" - " height: 100px;" - " margin-top: 50px;" - " margin-bottom: -50px;" - " }" - "</style>" - "<div id='scroller'>" - " <div id='content'></div>" - "</div"); + SetBodyInnerHTML(R"HTML( + <style> + ::-webkit-scrollbar { width: 0; height: 0; } + body { margin: 0; } + #scroller { overflow-y: scroll; } + #content { + width: 100px; + height: 100px; + margin-top: 50px; + margin-bottom: -50px; + } + </style> + <div id='scroller'> + <div id='content'></div> + </div + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* scrollerElement = GetDocument().getElementById("scroller"); @@ -2414,12 +2459,13 @@ } TEST_P(CompositedLayerMappingTest, ScrollingLayerBackgroundColor) { - SetBodyInnerHTML( - "<style>.color {background-color: blue}</style>" - "<div id='target' style='width: 100px; height: 100px;" - " overflow: scroll; will-change: transform'>" - " <div style='height: 200px'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>.color {background-color: blue}</style> + <div id='target' style='width: 100px; height: 100px; + overflow: scroll; will-change: transform'> + <div style='height: 200px'></div> + </div> + )HTML"); auto* target = GetDocument().getElementById("target"); auto* mapping = ToLayoutBoxModelObject(target->GetLayoutObject()) @@ -2441,10 +2487,11 @@ TEST_P(CompositedLayerMappingTest, ClipPathNoChildContainmentLayer) { // This test verifies only the presence of clip path does not induce child // containment layer. - SetBodyInnerHTML( - "<div id='target' style='width:100px; height:100px; clip-path:circle();'>" - " <div style='will-change:transform; width:200px; height:200px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='width:100px; height:100px; clip-path:circle();'> + <div style='will-change:transform; width:200px; height:200px;'></div> + </div> + )HTML"); auto* mapping = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target")) ->Layer() ->GetCompositedLayerMapping(); @@ -2454,13 +2501,14 @@ TEST_P(CompositedLayerMappingTest, ForegroundLayerSizing) { // This test verifies the foreground layer is sized to the clip rect. - SetBodyInnerHTML( - "<div id='target' style='position:relative; z-index:0; width:100px; " - "height:100px; border:10px solid black; overflow:hidden;'>" - " <div style='width:200px; height:200px; background:green;'></div>" - " <div style='position:relative; z-index:-1; " - "will-change:transform;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='position:relative; z-index:0; width:100px; + height:100px; border:10px solid black; overflow:hidden;'> + <div style='width:200px; height:200px; background:green;'></div> + <div style='position:relative; z-index:-1; + will-change:transform;'></div> + </div> + )HTML"); auto* mapping = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target")) ->Layer() ->GetCompositedLayerMapping();
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdaterTest.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdaterTest.cpp index c893d73..71169f8 100644 --- a/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdaterTest.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdaterTest.cpp
@@ -25,14 +25,15 @@ // making them positioned), and the previous ancestor overflow must change // from being scrollable to non-scrollable (achieved by setting its overflow // property to visible at the same time as we change the inner scroller.) - SetBodyInnerHTML( - "<style>#outerScroller { position: relative; overflow: scroll; " - "height: 500px; width: 100px; }" - "#innerScroller { position: relative; height: 100px; }" - "#sticky { position: sticky; top: 0; height: 50px; width: 50px; }" - "#padding { height: 200px; }</style>" - "<div id='outerScroller'><div id='innerScroller'><div id='sticky'></div>" - "<div id='padding'></div></div></div>"); + SetBodyInnerHTML(R"HTML( + <style>#outerScroller { position: relative; overflow: scroll; + height: 500px; width: 100px; } + #innerScroller { position: relative; height: 100px; } + #sticky { position: sticky; top: 0; height: 50px; width: 50px; } + #padding { height: 200px; }</style> + <div id='outerScroller'><div id='innerScroller'><div id='sticky'></div> + <div id='padding'></div></div></div> + )HTML"); LayoutBoxModelObject* outer_scroller = ToLayoutBoxModelObject(GetLayoutObjectByElementId("outerScroller"));
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingReasonFinderTest.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingReasonFinderTest.cpp index 827f0c17..c1476e1 100644 --- a/third_party/WebKit/Source/core/paint/compositing/CompositingReasonFinderTest.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/CompositingReasonFinderTest.cpp
@@ -29,15 +29,16 @@ TEST_F(CompositingReasonFinderTest, PromoteOpaqueFixedPosition) { ScopedCompositeFixedPositionForTest composite_fixed_position(true); - SetBodyInnerHTML( - "<div id='translucent' style='width: 20px; height: 20px; position: " - "fixed; top: 100px; left: 100px;'></div>" - "<div id='opaque' style='width: 20px; height: 20px; position: fixed; " - "top: 100px; left: 200px; background: white;'></div>" - "<div id='opaque-with-shadow' style='width: 20px; height: 20px; " - "position: fixed; top: 100px; left: 300px; background: white; " - "box-shadow: 10px 10px 5px #888888;'></div>" - "<div id='spacer' style='height: 2000px'></div>"); + SetBodyInnerHTML(R"HTML( + <div id='translucent' style='width: 20px; height: 20px; position: + fixed; top: 100px; left: 100px;'></div> + <div id='opaque' style='width: 20px; height: 20px; position: fixed; + top: 100px; left: 200px; background: white;'></div> + <div id='opaque-with-shadow' style='width: 20px; height: 20px; + position: fixed; top: 100px; left: 300px; background: white; + box-shadow: 10px 10px 5px #888888;'></div> + <div id='spacer' style='height: 2000px'></div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -62,16 +63,17 @@ } TEST_F(CompositingReasonFinderTest, OnlyAnchoredStickyPositionPromoted) { - SetBodyInnerHTML( - "<style>" - ".scroller {contain: paint; width: 400px; height: 400px; overflow: auto; " - "will-change: transform;}" - ".sticky { position: sticky; width: 10px; height: 10px;}</style>" - "<div class='scroller'>" - " <div id='sticky-top' class='sticky' style='top: 0px;'></div>" - " <div id='sticky-no-anchor' class='sticky'></div>" - " <div style='height: 2000px;'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + .scroller {contain: paint; width: 400px; height: 400px; overflow: auto; + will-change: transform;} + .sticky { position: sticky; width: 10px; height: 10px;}</style> + <div class='scroller'> + <div id='sticky-top' class='sticky' style='top: 0px;'></div> + <div id='sticky-no-anchor' class='sticky'></div> + <div style='height: 2000px;'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_EQ(kPaintsIntoOwnBacking, @@ -85,18 +87,19 @@ } TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) { - SetBodyInnerHTML( - "<style>.scroller {width: 400px; height: 400px; overflow: auto; " - "will-change: transform;}" - ".sticky { position: sticky; top: 0; width: 10px; height: 10px;}" - "</style>" - "<div class='scroller'>" - " <div id='sticky-scrolling' class='sticky'></div>" - " <div style='height: 2000px;'></div>" - "</div>" - "<div class='scroller'>" - " <div id='sticky-no-scrolling' class='sticky'></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>.scroller {width: 400px; height: 400px; overflow: auto; + will-change: transform;} + .sticky { position: sticky; top: 0; width: 10px; height: 10px;} + </style> + <div class='scroller'> + <div id='sticky-scrolling' class='sticky'></div> + <div style='height: 2000px;'></div> + </div> + <div class='scroller'> + <div id='sticky-no-scrolling' class='sticky'></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_EQ( @@ -117,16 +120,17 @@ TEST_F(CompositingReasonFinderTest, OnlyNonTransformedFixedLayersPromoted) { ScopedCompositeFixedPositionForTest composite_fixed_position(true); - SetBodyInnerHTML( - "<style>" - "#fixed { position: fixed; height: 200px; width: 200px; background: " - "white; top: 0; }" - "#spacer { height: 3000px; }" - "</style>" - "<div id=\"parent\">" - " <div id=\"fixed\"></div>" - " <div id=\"spacer\"></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #fixed { position: fixed; height: 200px; width: 200px; background: + white; top: 0; } + #spacer { height: 3000px; } + </style> + <div id="parent"> + <div id="fixed"></div> + <div id="spacer"></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -166,16 +170,17 @@ TEST_F(CompositingReasonFinderTest, OnlyOpaqueFixedLayersPromoted) { ScopedCompositeFixedPositionForTest composite_fixed_position(true); - SetBodyInnerHTML( - "<style>" - "#fixed { position: fixed; height: 200px; width: 200px; background: " - "white; top: 0}" - "#spacer { height: 3000px; }" - "</style>" - "<div id=\"parent\">" - " <div id=\"fixed\"></div>" - " <div id=\"spacer\"></div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style> + #fixed { position: fixed; height: 200px; width: 200px; background: + white; top: 0} + #spacer { height: 3000px; } + </style> + <div id="parent"> + <div id="fixed"></div> + <div id="spacer"></div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled()); @@ -324,19 +329,20 @@ TEST_F(CompositingReasonFinderTest, CompositeNestedSticky) { ScopedCompositeFixedPositionForTest composite_fixed_position(true); - SetBodyInnerHTML( - "<style>.scroller { overflow: scroll; height: 200px; width: 100px; }" - ".container { height: 500px; }" - ".opaque { background-color: white; contain: paint; }" - "#outerSticky { height: 50px; position: sticky; top: 0px; }" - "#innerSticky { height: 20px; position: sticky; top: 25px; }</style>" - "<div class='scroller'>" - " <div class='container'>" - " <div id='outerSticky' class='opaque'>" - " <div id='innerSticky' class='opaque'></div>" - " </div>" - " </div>" - "</div>"); + SetBodyInnerHTML(R"HTML( + <style>.scroller { overflow: scroll; height: 200px; width: 100px; } + .container { height: 500px; } + .opaque { background-color: white; contain: paint; } + #outerSticky { height: 50px; position: sticky; top: 0px; } + #innerSticky { height: 20px; position: sticky; top: 25px; }</style> + <div class='scroller'> + <div class='container'> + <div id='outerSticky' class='opaque'> + <div id='innerSticky' class='opaque'></div> + </div> + </div> + </div> + )HTML"); GetDocument().View()->UpdateAllLifecyclePhases(); Element* outer_sticky = GetDocument().getElementById("outerSticky");
diff --git a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositorTest.cpp b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositorTest.cpp index 4a3b3a99..25da82e 100644 --- a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositorTest.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositorTest.cpp
@@ -46,11 +46,12 @@ TEST_F(PaintLayerCompositorTest, CompositingInputsCleanDoesNotTriggerAnimations) { - SetBodyInnerHTML( - "<style>@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }" - ".animate { animation: fadeOut 2s; }</style>" - "<div id='box'></div>" - "<div id='otherBox'></div>"); + SetBodyInnerHTML(R"HTML( + <style>@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } + .animate { animation: fadeOut 2s; }</style> + <div id='box'></div> + <div id='otherBox'></div> + )HTML"); Element* box = GetDocument().getElementById("box"); Element* otherBox = GetDocument().getElementById("otherBox");
diff --git a/third_party/WebKit/Source/core/resize_observer/ResizeObserverTest.cpp b/third_party/WebKit/Source/core/resize_observer/ResizeObserverTest.cpp index 36f659b8..bbd702bc 100644 --- a/third_party/WebKit/Source/core/resize_observer/ResizeObserverTest.cpp +++ b/third_party/WebKit/Source/core/resize_observer/ResizeObserverTest.cpp
@@ -60,11 +60,12 @@ LoadURL("https://example.com/"); main_resource.Start(); - main_resource.Write( - "<div id='domTarget' style='width:100px;height:100px'>yo</div>" - "<svg height='200' width='200'>" - "<circle id='svgTarget' cx='100' cy='100' r='100'/>" - "</svg>"); + main_resource.Write(R"HTML( + <div id='domTarget' style='width:100px;height:100px'>yo</div> + <svg height='200' width='200'> + <circle id='svgTarget' cx='100' cy='100' r='100'/> + </svg> + )HTML"); main_resource.Finish(); ResizeObserver::Delegate* delegate =
diff --git a/third_party/WebKit/Source/core/scheduler/FrameSchedulerTest.cpp b/third_party/WebKit/Source/core/scheduler/FrameSchedulerTest.cpp index d2e0158e..ede4c53c 100644 --- a/third_party/WebKit/Source/core/scheduler/FrameSchedulerTest.cpp +++ b/third_party/WebKit/Source/core/scheduler/FrameSchedulerTest.cpp
@@ -17,11 +17,12 @@ TEST_F(WebFrameSchedulerFrameTypeTest, GetFrameType) { SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<!DOCTYPE HTML>" - "<body>" - "<iframe src=\"about:blank\"></iframe>" - "</body>"); + main_resource.Complete(R"HTML( + <!DOCTYPE HTML> + <body> + <iframe src="about:blank"></iframe> + </body> + )HTML"); EXPECT_EQ(WebFrameScheduler::FrameType::kMainFrame, MainFrame().GetFrame()->FrameScheduler()->GetFrameType());
diff --git a/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp b/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp index 5cb2244..a3f3e9f 100644 --- a/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp +++ b/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp
@@ -449,15 +449,16 @@ LoadURL("https://example.com/"); main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>"); - frame_resource.Complete( - "<style>" - "div { " - " width: 100px;" - " height: 100px;" - " background-color: green;" - " transform: translateZ(0);" - "}" - "</style><div></div>"); + frame_resource.Complete(R"HTML( + <style> + div { + width: 100px; + height: 100px; + background-color: green; + transform: translateZ(0); + } + </style><div></div> + )HTML"); // Move the frame offscreen to throttle it. auto* frame_element = @@ -805,11 +806,12 @@ LoadURL("https://example.com/"); main_resource.Complete( "<iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>"); - frame_resource.Complete( - "<script>" - "window.addEventListener('touchstart', function(){}, {passive: false});" - "document.addEventListener('touchstart', function(){}, {passive: false});" - "</script>"); + frame_resource.Complete(R"HTML( + <script> + window.addEventListener('touchstart', function(){}, {passive: false}); + document.addEventListener('touchstart', function(){}, {passive: false}); + </script> + )HTML"); auto* frame_element = ToHTMLIFrameElement(GetDocument().getElementById("frame")); frame_element->setAttribute(styleAttr, "transform: translateY(480px)"); @@ -841,12 +843,13 @@ LoadURL("https://example.com/"); main_resource.Complete( "<iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>"); - frame_resource.Complete( - "<div id=d>touch handler</div>" - "<script>" - "document.querySelector('#d').addEventListener('touchstart', " - "function(){});" - "</script>"); + frame_resource.Complete(R"HTML( + <div id=d>touch handler</div> + <script> + document.querySelector('#d').addEventListener('touchstart', + function(){}); + </script> + )HTML"); auto* frame_element = ToHTMLIFrameElement(GetDocument().getElementById("frame")); frame_element->setAttribute(styleAttr, "transform: translateY(480px)"); @@ -1143,11 +1146,12 @@ SimRequest second_frame_resource("https://thirdparty.com/second.html", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<iframe id=first name=first " - "src='https://thirdparty.com/first.html'></iframe>\n" - "<iframe id=second name=second " - "src='https://thirdparty.com/second.html'></iframe>"); + main_resource.Complete(R"HTML( + <iframe id=first name=first + src='https://thirdparty.com/first.html'></iframe>\n + <iframe id=second name=second + src='https://thirdparty.com/second.html'></iframe> + )HTML"); // The first frame contains just a simple div. This frame will be made // throttled. @@ -1192,10 +1196,11 @@ "<iframe id=frame style=\"position: fixed; top: -10000px\" " "src='https://thirdparty.com/frame.html'></iframe>"); - frame_resource.Complete( - "<script>" - "window.requestAnimationFrame(() => { window.didRaf = true; });" - "</script>"); + frame_resource.Complete(R"HTML( + <script> + window.requestAnimationFrame(() => { window.didRaf = true; }); + </script> + )HTML"); auto* frame_element = ToHTMLIFrameElement(GetDocument().getElementById("frame")); @@ -1328,11 +1333,12 @@ main_resource.Complete( "<iframe sandbox id='frame' src='iframe.html' style='position:relative; " "top:1000px;'></iframe>"); - frame_resource.Complete( - "<div id='scroller' style='overflow:scroll; width:300px; height:200px;'>" - " <div style='height:1000px;'></div>" - " <div id='sibling' style='transform:translateZ(0);'>Foo</div>" - "</div>"); + frame_resource.Complete(R"HTML( + <div id='scroller' style='overflow:scroll; width:300px; height:200px;'> + <div style='height:1000px;'></div> + <div id='sibling' style='transform:translateZ(0);'>Foo</div> + </div> + )HTML"); CompositeFrame(); auto* frame_element =
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp index e8142f4..36dacfc 100644 --- a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp +++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
@@ -95,11 +95,11 @@ } bool StyleFetchedImage::ImageHasRelativeSize() const { - return image_->ImageHasRelativeSize(); + return image_->GetImage()->HasRelativeSize(); } bool StyleFetchedImage::UsesImageContainerSize() const { - return image_->UsesImageContainerSize(); + return image_->GetImage()->UsesContainerSize(); } void StyleFetchedImage::AddClient(ImageResourceObserver* observer) {
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp index dddba2b..2836d64 100644 --- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp +++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
@@ -101,11 +101,11 @@ } bool StyleFetchedImageSet::ImageHasRelativeSize() const { - return best_fit_image_->ImageHasRelativeSize(); + return best_fit_image_->GetImage()->HasRelativeSize(); } bool StyleFetchedImageSet::UsesImageContainerSize() const { - return best_fit_image_->UsesImageContainerSize(); + return best_fit_image_->GetImage()->UsesContainerSize(); } void StyleFetchedImageSet::AddClient(ImageResourceObserver* observer) {
diff --git a/third_party/WebKit/Source/core/svg/SVGLength.cpp b/third_party/WebKit/Source/core/svg/SVGLength.cpp index 09bcce9..a8e4a12 100644 --- a/third_party/WebKit/Source/core/svg/SVGLength.cpp +++ b/third_party/WebKit/Source/core/svg/SVGLength.cpp
@@ -136,7 +136,10 @@ } SVGParsingError SVGLength::SetValueAsString(const String& string) { - if (string.IsEmpty()) { + // TODO(fs): Preferably we wouldn't need to special-case the null + // string (which we'll get for example for removeAttribute.) + // Hopefully work on crbug.com/225807 can help here. + if (string.IsNull()) { value_ = CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kUserUnits); return SVGParseStatus::kNoError;
diff --git a/third_party/WebKit/Source/core/svg/SVGURIReference.cpp b/third_party/WebKit/Source/core/svg/SVGURIReference.cpp index ecedcc1..e5c9e8a 100644 --- a/third_party/WebKit/Source/core/svg/SVGURIReference.cpp +++ b/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
@@ -88,11 +88,10 @@ } AtomicString SVGURLReferenceResolver::FragmentIdentifier() const { - // If this is a "fragment-only" URL, then the reference is always local, so - // just return what's after the '#' as the fragment. - if (is_local_) - return AtomicString(relative_url_.Substring(1)); - return AtomicString(AbsoluteUrl().FragmentIdentifier()); + // Use KURL's FragmentIdentifier to ensure that we're handling the + // fragment in a consistent manner. + return AtomicString( + DecodeURLEscapeSequences(AbsoluteUrl().FragmentIdentifier())); } AtomicString SVGURIReference::FragmentIdentifierFromIRIString(
diff --git a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp index b4ea6fa..3d1e8ac2 100644 --- a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
@@ -305,7 +305,8 @@ Element* SVGUseElement::ResolveTargetElement(ObserveBehavior observe_behavior) { if (!element_url_.HasFragmentIdentifier()) return nullptr; - AtomicString element_identifier(element_url_.FragmentIdentifier()); + AtomicString element_identifier( + DecodeURLEscapeSequences(element_url_.FragmentIdentifier())); if (!IsStructurallyExternal()) { if (observe_behavior == kDontAddObserver) return GetTreeScope().getElementById(element_identifier);
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js index a43d6e6..57a6b42 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -595,12 +595,17 @@ note.classList.add('info-note'); note.title = Common.UIString('Value below was evaluated just now.'); - var section = new ObjectUI.ObjectPropertiesSection(obj, titleElement, this._linkifier); + var section = new ObjectUI.ObjectPropertiesSection( + obj, titleElement, this._linkifier, undefined, undefined, undefined, this._onObjectChange.bind(this)); section.element.classList.add('console-view-object-properties-section'); section.enableContextMenu(); return section.element; } + _onObjectChange() { + // This method is sniffed in tests. + } + /** * @param {!SDK.RemoteObject} func * @param {boolean=} includePreview
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js index 71299468b..7084242 100644 --- a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js +++ b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
@@ -35,15 +35,16 @@ * @param {?string=} emptyPlaceholder * @param {boolean=} ignoreHasOwnProperty * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties + * @param {function()=} onChange */ - constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) { + constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, onChange) { super(); this._object = object; this._editable = true; this.hideOverflow(); this.setFocusable(false); this._objectTreeElement = new ObjectUI.ObjectPropertiesSection.RootElement( - object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties); + object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, onChange); this.appendChild(this._objectTreeElement); if (typeof title === 'string' || !title) { this.titleElement = this.element.createChild('span'); @@ -335,9 +336,10 @@ * @param {!Element} element * @param {boolean} linkify * @param {boolean=} includePreview + * @return {!Promise} */ static formatObjectAsFunction(func, element, linkify, includePreview) { - func.debuggerModel().functionDetailsPromise(func).then(didGetDetails); + return func.debuggerModel().functionDetailsPromise(func).then(didGetDetails); /** * @param {?SDK.DebuggerModel.FunctionDetails} response @@ -411,8 +413,9 @@ * @param {?string=} emptyPlaceholder * @param {boolean=} ignoreHasOwnProperty * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties + * @param {function()=} onChange */ - constructor(object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) { + constructor(object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, onChange) { var contentElement = createElement('content'); super(contentElement); @@ -426,6 +429,7 @@ this.toggleOnClick = true; this.listItemElement.classList.add('object-properties-section-root-element'); this._linkifier = linkifier; + this._onChange = onChange; } /** @@ -434,6 +438,8 @@ onexpand() { if (this.treeOutline) this.treeOutline.element.classList.add('expanded'); + if (this._onChange) + this._onChange(); } /** @@ -442,6 +448,8 @@ oncollapse() { if (this.treeOutline) this.treeOutline.element.classList.remove('expanded'); + if (this._onChange) + this._onChange(); } /** @@ -459,7 +467,7 @@ onpopulate() { ObjectUI.ObjectPropertyTreeElement._populate( this, this._object, !!this.treeOutline._skipProto, this._linkifier, this._emptyPlaceholder, - this._ignoreHasOwnProperty, this._extraProperties); + this._ignoreHasOwnProperty, this._extraProperties, undefined, this._onChange); } }; @@ -470,8 +478,9 @@ /** * @param {!SDK.RemoteObjectProperty} property * @param {!Components.Linkifier=} linkifier + * @param {function()=} onChange */ - constructor(property, linkifier) { + constructor(property, linkifier, onChange) { // Pass an empty title, the title gets made later in onattach. super(); @@ -481,6 +490,7 @@ /** @type {!Array.<!Object>} */ this._highlightChanges = []; this._linkifier = linkifier; + this._onChange = onChange; } /** @@ -492,19 +502,15 @@ * @param {boolean=} flattenProtoChain * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties * @param {!SDK.RemoteObject=} targetValue + * @param {function()=} onChange */ static _populate( - treeElement, - value, - skipProto, - linkifier, - emptyPlaceholder, - flattenProtoChain, - extraProperties, - targetValue) { + treeElement, value, skipProto, linkifier, emptyPlaceholder, flattenProtoChain, extraProperties, targetValue, + onChange) { if (value.arrayLength() > ObjectUI.ObjectPropertiesSection._arrayLoadThreshold) { treeElement.removeChildren(); - ObjectUI.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1, linkifier); + ObjectUI.ArrayGroupingTreeElement._populateArray( + treeElement, value, 0, value.arrayLength() - 1, linkifier, onChange); return; } @@ -514,15 +520,19 @@ */ function callback(properties, internalProperties) { treeElement.removeChildren(); - if (!properties) + if (!properties) { + if (onChange) + onChange(); return; + } extraProperties = extraProperties || []; for (var i = 0; i < extraProperties.length; ++i) properties.push(extraProperties[i]); ObjectUI.ObjectPropertyTreeElement.populateWithProperties( - treeElement, properties, internalProperties, skipProto, targetValue || value, linkifier, emptyPlaceholder); + treeElement, properties, internalProperties, skipProto, targetValue || value, linkifier, emptyPlaceholder, + onChange); } var generatePreview = Runtime.experiments.isEnabled('objectPreviews'); @@ -540,15 +550,10 @@ * @param {?SDK.RemoteObject} value * @param {!Components.Linkifier=} linkifier * @param {?string=} emptyPlaceholder + * @param {function()=} onChange */ static populateWithProperties( - treeNode, - properties, - internalProperties, - skipProto, - value, - linkifier, - emptyPlaceholder) { + treeNode, properties, internalProperties, skipProto, value, linkifier, emptyPlaceholder, onChange) { properties.sort(ObjectUI.ObjectPropertiesSection.CompareProperties); var tailProperties = []; @@ -573,17 +578,17 @@ } var canShowProperty = property.getter || !property.isAccessorProperty(); if (canShowProperty && property.name !== '__proto__') - treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(property, linkifier)); + treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(property, linkifier, onChange)); } for (var i = 0; i < tailProperties.length; ++i) - treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(tailProperties[i], linkifier)); + treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(tailProperties[i], linkifier, onChange)); if (!skipProto && protoProperty) - treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(protoProperty, linkifier)); + treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(protoProperty, linkifier, onChange)); if (internalProperties) { for (var i = 0; i < internalProperties.length; i++) { internalProperties[i].parentObject = value; - var treeElement = new ObjectUI.ObjectPropertyTreeElement(internalProperties[i], linkifier); + var treeElement = new ObjectUI.ObjectPropertyTreeElement(internalProperties[i], linkifier, onChange); if (internalProperties[i].name === '[[Entries]]') { treeElement.setExpandable(true); treeElement.expand(); @@ -593,6 +598,8 @@ } ObjectUI.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(treeNode, emptyPlaceholder); + if (onChange) + onChange(); } /** @@ -683,7 +690,7 @@ var skipProto = this.treeOutline ? this.treeOutline._skipProto : true; var targetValue = this.property.name !== '__proto__' ? propertyValue : this.property.parentObject; ObjectUI.ObjectPropertyTreeElement._populate( - this, propertyValue, skipProto, this._linkifier, undefined, undefined, undefined, targetValue); + this, propertyValue, skipProto, this._linkifier, undefined, undefined, undefined, targetValue, this._onChange); } /** @@ -711,6 +718,8 @@ */ onexpand() { this._showExpandedValueElement(true); + if (this._onChange) + this._onChange(); } /** @@ -718,6 +727,8 @@ */ oncollapse() { this._showExpandedValueElement(false); + if (this._onChange) + this._onChange(); } /** @@ -785,6 +796,8 @@ this.listItemElement.removeChildren(); this.listItemElement.appendChildren(this.nameElement, separatorElement, this.valueElement); + if (this._onChange) + this._onChange(); } _updatePropertyPath() { @@ -906,6 +919,8 @@ if (!expression) { // The property was deleted, so remove this tree element. this.parent.removeChild(this); + if (this._onChange) + this._onChange(); } else { // Call updateSiblings since their value might be based on the value that just changed. var parent = this.parent; @@ -927,6 +942,8 @@ this.update(); this.invalidateChildren(); this._updateExpandable(); + if (this._onChange) + this._onChange(); } _updateExpandable() { @@ -950,8 +967,9 @@ * @param {number} toIndex * @param {number} propertyCount * @param {!Components.Linkifier=} linkifier + * @param {function()=} onChange */ - constructor(object, fromIndex, toIndex, propertyCount, linkifier) { + constructor(object, fromIndex, toIndex, propertyCount, linkifier, onChange) { super(String.sprintf('[%d \u2026 %d]', fromIndex, toIndex), true); this.toggleOnClick = true; this.selectable = false; @@ -961,6 +979,7 @@ this._readOnly = true; this._propertyCount = propertyCount; this._linkifier = linkifier; + this._onChange = onChange; } /** @@ -969,9 +988,10 @@ * @param {number} fromIndex * @param {number} toIndex * @param {!Components.Linkifier=} linkifier + * @param {function()=} onChange */ - static _populateArray(treeNode, object, fromIndex, toIndex, linkifier) { - ObjectUI.ArrayGroupingTreeElement._populateRanges(treeNode, object, fromIndex, toIndex, true, linkifier); + static _populateArray(treeNode, object, fromIndex, toIndex, linkifier, onChange) { + ObjectUI.ArrayGroupingTreeElement._populateRanges(treeNode, object, fromIndex, toIndex, true, linkifier, onChange); } /** @@ -981,9 +1001,10 @@ * @param {number} toIndex * @param {boolean} topLevel * @param {!Components.Linkifier=} linkifier + * @param {function()=} onChange * @this {ObjectUI.ArrayGroupingTreeElement} */ - static _populateRanges(treeNode, object, fromIndex, toIndex, topLevel, linkifier) { + static _populateRanges(treeNode, object, fromIndex, toIndex, topLevel, linkifier, onChange) { object.callFunctionJSON( packRanges, [ @@ -1074,22 +1095,28 @@ return; var ranges = /** @type {!Array.<!Array.<number>>} */ (result.ranges); if (ranges.length === 1) { - ObjectUI.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, ranges[0][0], ranges[0][1], linkifier); + ObjectUI.ArrayGroupingTreeElement._populateAsFragment( + treeNode, object, ranges[0][0], ranges[0][1], linkifier, onChange); } else { for (var i = 0; i < ranges.length; ++i) { var fromIndex = ranges[i][0]; var toIndex = ranges[i][1]; var count = ranges[i][2]; - if (fromIndex === toIndex) - ObjectUI.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, fromIndex, toIndex, linkifier); - else - treeNode.appendChild(new ObjectUI.ArrayGroupingTreeElement(object, fromIndex, toIndex, count, linkifier)); + if (fromIndex === toIndex) { + ObjectUI.ArrayGroupingTreeElement._populateAsFragment( + treeNode, object, fromIndex, toIndex, linkifier, onChange); + } else { + treeNode.appendChild( + new ObjectUI.ArrayGroupingTreeElement(object, fromIndex, toIndex, count, linkifier, onChange)); + } } } if (topLevel) { ObjectUI.ArrayGroupingTreeElement._populateNonIndexProperties( - treeNode, object, result.skipGetOwnPropertyNames, linkifier); + treeNode, object, result.skipGetOwnPropertyNames, linkifier, onChange); } + if (onChange) + onChange(); } } @@ -1099,9 +1126,10 @@ * @param {number} fromIndex * @param {number} toIndex * @param {!Components.Linkifier=} linkifier + * @param {function()=} onChange * @this {ObjectUI.ArrayGroupingTreeElement} */ - static _populateAsFragment(treeNode, object, fromIndex, toIndex, linkifier) { + static _populateAsFragment(treeNode, object, fromIndex, toIndex, linkifier, onChange) { object.callFunction( buildArrayFragment, [{value: fromIndex}, {value: toIndex}, {value: ObjectUI.ArrayGroupingTreeElement._sparseIterationThreshold}], @@ -1153,10 +1181,12 @@ properties.sort(ObjectUI.ObjectPropertiesSection.CompareProperties); for (var i = 0; i < properties.length; ++i) { properties[i].parentObject = this._object; - var childTreeElement = new ObjectUI.ObjectPropertyTreeElement(properties[i], linkifier); + var childTreeElement = new ObjectUI.ObjectPropertyTreeElement(properties[i], linkifier, onChange); childTreeElement._readOnly = true; treeNode.appendChild(childTreeElement); } + if (onChange) + onChange(); } } @@ -1165,9 +1195,10 @@ * @param {!SDK.RemoteObject} object * @param {boolean} skipGetOwnPropertyNames * @param {!Components.Linkifier=} linkifier + * @param {function()=} onChange * @this {ObjectUI.ArrayGroupingTreeElement} */ - static _populateNonIndexProperties(treeNode, object, skipGetOwnPropertyNames, linkifier) { + static _populateNonIndexProperties(treeNode, object, skipGetOwnPropertyNames, linkifier, onChange) { object.callFunction(buildObjectFragment, [{value: skipGetOwnPropertyNames}], processObjectFragment.bind(this)); /** @@ -1214,7 +1245,7 @@ properties.sort(ObjectUI.ObjectPropertiesSection.CompareProperties); for (var i = 0; i < properties.length; ++i) { properties[i].parentObject = this._object; - var childTreeElement = new ObjectUI.ObjectPropertyTreeElement(properties[i], linkifier); + var childTreeElement = new ObjectUI.ObjectPropertyTreeElement(properties[i], linkifier, onChange); childTreeElement._readOnly = true; treeNode.appendChild(childTreeElement); } @@ -1227,11 +1258,11 @@ onpopulate() { if (this._propertyCount >= ObjectUI.ArrayGroupingTreeElement._bucketThreshold) { ObjectUI.ArrayGroupingTreeElement._populateRanges( - this, this._object, this._fromIndex, this._toIndex, false, this._linkifier); + this, this._object, this._fromIndex, this._toIndex, false, this._linkifier, this._onChange); return; } ObjectUI.ArrayGroupingTreeElement._populateAsFragment( - this, this._object, this._fromIndex, this._toIndex, this._linkifier); + this, this._object, this._fromIndex, this._toIndex, this._linkifier, this._onChange); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js b/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js index 0a3ea7f..3cc2b771 100644 --- a/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js
@@ -17,13 +17,9 @@ scriptName: 'formatAsTypeName', scriptId: 'formatAsTypeName', usedHeapSizeDelta: 'skip', - mimeType: 'formatAsTypeName', id: 'formatAsTypeName', timerId: 'formatAsTypeName', - scriptLine: 'formatAsTypeName', layerId: 'formatAsTypeName', - lineNumber: 'formatAsTypeName', - columnNumber: 'formatAsTypeName', frameId: 'formatAsTypeName', frame: 'formatAsTypeName', page: 'formatAsTypeName',
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp index c3d3f67..bf15c1d98 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
@@ -30,7 +30,6 @@ #include "core/dom/AccessibleNode.h" #include "core/dom/Document.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/editing/EditingUtilities.h" #include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameView.h" @@ -87,6 +86,7 @@ #include "modules/permissions/PermissionUtils.h" #include "platform/wtf/PtrUtil.h" #include "platform/wtf/RefPtr.h" +#include "public/platform/TaskType.h" #include "public/platform/modules/permissions/permission.mojom-blink.h" #include "public/platform/modules/permissions/permission_status.mojom-blink.h" #include "public/web/WebFrameClient.h" @@ -105,10 +105,9 @@ document_(document), modification_count_(0), relation_cache_(new AXRelationCache(this)), - notification_post_timer_( - TaskRunnerHelper::Get(TaskType::kUnspecedTimer, &document), - this, - &AXObjectCacheImpl::NotificationPostTimerFired), + notification_post_timer_(document.GetTaskRunner(TaskType::kUnspecedTimer), + this, + &AXObjectCacheImpl::NotificationPostTimerFired), accessibility_event_permission_(mojom::PermissionStatus::ASK), permission_observer_binding_(this) { if (document_->LoadEventFinished())
diff --git a/third_party/WebKit/Source/modules/accessibility/AccessibilityObjectModelTest.cpp b/third_party/WebKit/Source/modules/accessibility/AccessibilityObjectModelTest.cpp index 687c1e7..fc9762f 100644 --- a/third_party/WebKit/Source/modules/accessibility/AccessibilityObjectModelTest.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AccessibilityObjectModelTest.cpp
@@ -197,13 +197,14 @@ TEST_F(AccessibilityObjectModelTest, Grid) { SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<div role=grid id=grid>" - " <div role=row id=row>" - " <div role=gridcell id=cell></div>" - " <div role=gridcell id=cell2></div>" - " </div>" - "</div>"); + main_resource.Complete(R"HTML( + <div role=grid id=grid> + <div role=row id=row> + <div role=gridcell id=cell></div> + <div role=gridcell id=cell2></div> + </div> + </div> + )HTML"); auto* grid = GetDocument().getElementById("grid"); ASSERT_NE(nullptr, grid); @@ -279,19 +280,20 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) { SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<input id=target" - " aria-keyshortcuts=Ctrl+K" - " aria-roledescription=Widget" - " aria-activedescendant=active" - " aria-details=details" - " aria-errormessage=error>" - "<div id=active role=option></div>" - "<div id=active2 role=gridcell></div>" - "<div id=details role=contentinfo></div>" - "<div id=details2 role=form></div>" - "<div id=error role=article>Error</div>" - "<div id=error2 role=banner>Error 2</div>"); + main_resource.Complete(R"HTML( + <input id=target + aria-keyshortcuts=Ctrl+K + aria-roledescription=Widget + aria-activedescendant=active + aria-details=details + aria-errormessage=error> + <div id=active role=option></div> + <div id=active2 role=gridcell></div> + <div id=details role=contentinfo></div> + <div id=details2 role=form></div> + <div id=error role=article>Error</div> + <div id=error2 role=banner>Error 2</div> + )HTML"); auto* target = GetDocument().getElementById("target"); auto* cache = AXObjectCache(); @@ -353,11 +355,12 @@ TEST_F(AccessibilityObjectModelTest, LabeledBy) { SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete( - "<input id=target aria-labelledby='l1 l2'>" - "<label id=l1>Label 1</label>" - "<label id=l2>Label 2</label>" - "<label id=l3>Label 3</label>"); + main_resource.Complete(R"HTML( + <input id=target aria-labelledby='l1 l2'> + <label id=l1>Label 1</label> + <label id=l2>Label 2</label> + <label id=l3>Label 3</label> + )HTML"); auto* target = GetDocument().getElementById("target"); auto* l1 = GetDocument().getElementById("l1");
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h index 22305f4..34021d61 100644 --- a/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h
@@ -250,11 +250,9 @@ virtual void WillDrawImage(CanvasImageSource*) const {} - virtual CanvasColorSpace ColorSpace() const { - return kLegacyCanvasColorSpace; - }; + virtual CanvasColorSpace ColorSpace() const { return kSRGBCanvasColorSpace; }; virtual String ColorSpaceAsString() const { - return kLegacyCanvasColorSpaceName; + return kSRGBCanvasColorSpaceName; } virtual CanvasPixelFormat PixelFormat() const { return kRGBA8CanvasPixelFormat;
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp index cd44f64..69e99ed 100644 --- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
@@ -42,7 +42,6 @@ #include "core/css/StylePropertySet.h" #include "core/css/resolver/StyleResolver.h" #include "core/dom/AXObjectCache.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/events/MouseEvent.h" #include "core/frame/Settings.h" @@ -68,6 +67,7 @@ #include "platform/wtf/text/StringBuilder.h" #include "platform/wtf/typed_arrays/ArrayBufferContents.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "third_party/skia/include/core/SkImageFilter.h" namespace blink { @@ -116,18 +116,15 @@ context_restorable_(true), try_restore_context_attempt_count_(0), dispatch_context_lost_event_timer_( - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, - &canvas->GetDocument()), + canvas->GetDocument().GetTaskRunner(TaskType::kMiscPlatformAPI), this, &CanvasRenderingContext2D::DispatchContextLostEvent), dispatch_context_restored_event_timer_( - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, - &canvas->GetDocument()), + canvas->GetDocument().GetTaskRunner(TaskType::kMiscPlatformAPI), this, &CanvasRenderingContext2D::DispatchContextRestoredEvent), try_restore_context_event_timer_( - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, - &canvas->GetDocument()), + canvas->GetDocument().GetTaskRunner(TaskType::kMiscPlatformAPI), this, &CanvasRenderingContext2D::TryRestoreContextEvent), should_prune_local_font_cache_(false) {
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DAPITest.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DAPITest.cpp index aff68b7..ca616cc 100644 --- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DAPITest.cpp +++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DAPITest.cpp
@@ -295,10 +295,11 @@ } void ResetCanvasForAccessibilityRectTest(Document& document) { - document.documentElement()->SetInnerHTMLFromString( - "<canvas id='canvas' style='position:absolute; top:0px; left:0px; " - "padding:10px; margin:5px;'>" - "<button id='button'></button></canvas>"); + document.documentElement()->SetInnerHTMLFromString(R"HTML( + <canvas id='canvas' style='position:absolute; top:0px; left:0px; + padding:10px; margin:5px;'> + <button id='button'></button></canvas> + )HTML"); document.GetSettings()->SetAccessibilityEnabled(true); HTMLCanvasElement* canvas = ToHTMLCanvasElement(document.getElementById("canvas"));
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DSettings.idl b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DSettings.idl index d953c69..e8fd5d5 100644 --- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DSettings.idl +++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DSettings.idl
@@ -7,10 +7,7 @@ [PermissiveDictionaryConversion] dictionary CanvasRenderingContext2DSettings { boolean alpha = true; - - // TODO(crbug.com/637288): Do we keep "legacy-srgb" as the default? - // Must decide before shipping. - [RuntimeEnabled=ExperimentalCanvasFeatures] CanvasColorSpace colorSpace = "legacy-srgb"; + [RuntimeEnabled=ExperimentalCanvasFeatures] CanvasColorSpace colorSpace = "srgb"; [RuntimeEnabled=ExperimentalCanvasFeatures] CanvasPixelFormat pixelFormat = "8-8-8-8"; };
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp index bb8f35569..dc1b5aa 100644 --- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -815,7 +815,7 @@ CreateContext(kOpaque); auto surface = WTF::MakeUnique<RecordingImageBufferSurface>( IntSize(10, 10), RecordingImageBufferSurface::kAllowFallback, - CanvasColorParams(kLegacyCanvasColorSpace, kRGBA8CanvasPixelFormat, + CanvasColorParams(kSRGBCanvasColorSpace, kRGBA8CanvasPixelFormat, kOpaque)); auto* surface_ptr = surface.get(); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface));
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp index fe1cbf8..f0f166e3 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
@@ -30,7 +30,6 @@ #include "core/dom/DOMException.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/html/media/HTMLMediaElement.h" #include "core/typed_arrays/DOMArrayBuffer.h" #include "modules/encryptedmedia/ContentDecryptionModuleResultPromise.h" @@ -42,6 +41,7 @@ #include "platform/bindings/ScriptState.h" #include "platform/bindings/V8ThrowException.h" #include "platform/wtf/RefPtr.h" +#include "public/platform/TaskType.h" #include "public/platform/WebContentDecryptionModule.h" #include "public/platform/WebEncryptedMediaKeyInformation.h" @@ -206,7 +206,7 @@ cdm_(std::move(cdm)), media_element_(nullptr), reserved_for_media_element_(false), - timer_(TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, context), + timer_(context->GetTaskRunner(TaskType::kMiscPlatformAPI), this, &MediaKeys::TimerFired) { DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")";
diff --git a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp index c32affa..ab921e7 100644 --- a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp +++ b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
@@ -39,7 +39,6 @@ #include "bindings/core/v8/serialization/SerializedScriptValueFactory.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/events/MessageEvent.h" #include "core/frame/LocalDOMWindow.h" @@ -57,6 +56,7 @@ #include "platform/network/http_names.h" #include "platform/weborigin/SecurityOrigin.h" #include "platform/wtf/text/StringBuilder.h" +#include "public/platform/TaskType.h" #include "public/platform/WebURLRequest.h" namespace blink { @@ -71,7 +71,7 @@ current_url_(url), with_credentials_(event_source_init.withCredentials()), state_(kConnecting), - connect_timer_(TaskRunnerHelper::Get(TaskType::kRemoteEvent, context), + connect_timer_(context->GetTaskRunner(TaskType::kRemoteEvent), this, &EventSource::ConnectTimerFired), reconnect_delay_(kDefaultReconnectDelay) {}
diff --git a/third_party/WebKit/Source/modules/fetch/BytesConsumer.cpp b/third_party/WebKit/Source/modules/fetch/BytesConsumer.cpp index 208614ac..d7ec227c 100644 --- a/third_party/WebKit/Source/modules/fetch/BytesConsumer.cpp +++ b/third_party/WebKit/Source/modules/fetch/BytesConsumer.cpp
@@ -7,13 +7,13 @@ #include <string.h> #include <algorithm> #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "modules/fetch/BlobBytesConsumer.h" #include "platform/WebTaskRunner.h" #include "platform/blob/BlobData.h" #include "platform/wtf/Functional.h" #include "platform/wtf/RefPtr.h" #include "platform/wtf/debug/Alias.h" +#include "public/platform/TaskType.h" #include "v8/include/v8.h" namespace blink { @@ -195,7 +195,7 @@ } if (chunks_.IsEmpty() && tee_->GetPublicState() == PublicState::kClosed) { // All data has been consumed. - TaskRunnerHelper::Get(TaskType::kNetworking, execution_context_) + execution_context_->GetTaskRunner(TaskType::kNetworking) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&Destination::Close, WrapPersistent(this))); }
diff --git a/third_party/WebKit/Source/modules/fetch/BytesConsumerForDataConsumerHandle.cpp b/third_party/WebKit/Source/modules/fetch/BytesConsumerForDataConsumerHandle.cpp index b755c64..7cce0c4 100644 --- a/third_party/WebKit/Source/modules/fetch/BytesConsumerForDataConsumerHandle.cpp +++ b/third_party/WebKit/Source/modules/fetch/BytesConsumerForDataConsumerHandle.cpp
@@ -5,9 +5,9 @@ #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "platform/WebTaskRunner.h" #include "platform/wtf/Functional.h" +#include "public/platform/TaskType.h" #include "public/platform/WebTraceLocation.h" #include <algorithm> @@ -69,7 +69,7 @@ } if (has_pending_notification_) { has_pending_notification_ = false; - TaskRunnerHelper::Get(TaskType::kNetworking, execution_context_) + execution_context_->GetTaskRunner(TaskType::kNetworking) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&BytesConsumerForDataConsumerHandle::Notify, WrapPersistent(this)));
diff --git a/third_party/WebKit/Source/modules/fetch/BytesConsumerTestUtil.cpp b/third_party/WebKit/Source/modules/fetch/BytesConsumerTestUtil.cpp index 2cb05eb..0a40017 100644 --- a/third_party/WebKit/Source/modules/fetch/BytesConsumerTestUtil.cpp +++ b/third_party/WebKit/Source/modules/fetch/BytesConsumerTestUtil.cpp
@@ -5,11 +5,11 @@ #include "modules/fetch/BytesConsumerTestUtil.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "platform/WebTaskRunner.h" #include "platform/testing/UnitTestHelpers.h" #include "platform/wtf/Assertions.h" #include "platform/wtf/Functional.h" +#include "public/platform/TaskType.h" namespace blink { @@ -74,7 +74,7 @@ case Command::kWait: commands_.pop_front(); state_ = InternalState::kWaiting; - TaskRunnerHelper::Get(TaskType::kNetworking, execution_context_) + execution_context_->GetTaskRunner(TaskType::kNetworking) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&ReplayingBytesConsumer::NotifyAsReadable, WrapPersistent(this), notification_token_));
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp index 2258640..731a488 100644 --- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp +++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp
@@ -213,7 +213,7 @@ std::unique_ptr<int> identifier = WTF::MakeUnique<int>(0); probe::AsyncTaskScheduled(execution_context, TaskNameForInstrumentation(), identifier.get()); - TaskRunnerHelper::Get(TaskType::kFileReading, execution_context) + execution_context->GetTaskRunner(TaskType::kFileReading) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&RunCallback, WrapWeakPersistent(execution_context), WTF::Passed(std::move(task)),
diff --git a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp index d52f221..2d57722 100644 --- a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp +++ b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
@@ -33,7 +33,6 @@ #include <memory> #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/fileapi/FileError.h" #include "core/frame/LocalFrame.h" #include "core/workers/WorkerGlobalScope.h" @@ -42,6 +41,7 @@ #include "platform/ContentSettingCallbacks.h" #include "platform/wtf/Functional.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/WebFileSystem.h" namespace blink { @@ -130,7 +130,7 @@ void LocalFileSystem::FileSystemNotAvailable(ExecutionContext* context, CallbackWrapper* callbacks) { - TaskRunnerHelper::Get(TaskType::kFileReading, context) + context->GetTaskRunner(TaskType::kFileReading) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&ReportFailure, WTF::Passed(callbacks->Release()), FileError::kAbortErr)); @@ -138,7 +138,7 @@ void LocalFileSystem::FileSystemNotAllowedInternal(ExecutionContext* context, CallbackWrapper* callbacks) { - TaskRunnerHelper::Get(TaskType::kFileReading, context) + context->GetTaskRunner(TaskType::kFileReading) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&ReportFailure, WTF::Passed(callbacks->Release()), FileError::kAbortErr));
diff --git a/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp b/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp index 92da6a36..a810efd6 100644 --- a/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp +++ b/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp
@@ -4,12 +4,12 @@ #include "modules/geolocation/GeoNotifier.h" -#include "core/dom/TaskRunnerHelper.h" #include "modules/geolocation/Geolocation.h" #include "modules/geolocation/PositionError.h" #include "modules/geolocation/PositionOptions.h" #include "platform/Histogram.h" #include "platform/wtf/Assertions.h" +#include "public/platform/TaskType.h" namespace blink { @@ -21,10 +21,10 @@ success_callback_(success_callback), error_callback_(error_callback), options_(options), - timer_(TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, - geolocation->GetDocument()), - this, - &GeoNotifier::TimerFired), + timer_( + geolocation->GetDocument()->GetTaskRunner(TaskType::kMiscPlatformAPI), + this, + &GeoNotifier::TimerFired), use_cached_position_(false) { DCHECK(geolocation_); DCHECK(success_callback_);
diff --git a/third_party/WebKit/Source/modules/indexeddb/docs/idb_data_path.md b/third_party/WebKit/Source/modules/indexeddb/docs/idb_data_path.md index 3f94274..b19a7f5b 100644 --- a/third_party/WebKit/Source/modules/indexeddb/docs/idb_data_path.md +++ b/third_party/WebKit/Source/modules/indexeddb/docs/idb_data_path.md
@@ -43,9 +43,18 @@ Blink's implementation of the specification is responsible for converting between [V8](https://developers.google.com/v8/) values and the byte sequences in IndexedDB's backing store. The implementation is in `SerializedScriptValue` -(SSV), which delegates to `v8::ValueSerializer`. A serialized value handled by -the backing store is essentially a data buffer that stores a sequence of bytes, -and a list (technically, an ordered set) of Blobs. +(SSV), which delegates to `v8::ValueSerializer` and `v8::ValueDeserializer`. A +serialized value handled by the backing store is essentially a data buffer that +stores a sequence of bytes, and a list (technically, an ordered set) of Blobs. + +While V8 drives the serialization process, Blink implements the serialization of +objects not covered by the JavaScript specification, such as `Blob` and +`ImageData`. This is accomplished by having V8 expose the interfaces +`v8::ValueSerializer::Delegate` and `v8::ValueDeserializer::Delegate`, which are +implemented by Blink. The canonical example methods of these interfaces are +`v8::ValueSerializer::Delegate::WriteHostObject()` and +`v8::ValueDeserializer::Delegate::ReadHostObject()`, which are used to +completely delegate the serialization of a V8 object to Blink. Changes to the IndexedDB serialization format are delicate because our backing store does not have any form of data migration. Once written to the backing @@ -71,10 +80,10 @@ * The SerializedScriptValue code is tightly coupled with v8::ValueSerializer. For this reason, SSV should not host logic that might - later be moved to the browser process. Such moves are bound to be difficult, - because operating on V8 values (in the manner required by the serialization - specification) requires a V8 execution context, which can only be hosted in a - renderer process. + later be moved to the browser process (e.g., to the IndexedDB backing store). + Such moves are bound to be difficult, because operating on V8 values (in the + manner required by the serialization specification) requires a V8 execution + context, which can only be hosted in a renderer process. * The SerializedScriptValue API, which is synchronous, is incompatible with reading Blobs (or any sort of files), which must be done asynchronously. All the information needed by SSV deserialization must be fetched before the
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp index 695ee9f..e930338 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -31,7 +31,6 @@ #include "core/dom/MutationObserverInit.h" #include "core/dom/MutationRecord.h" #include "core/dom/ShadowRoot.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/events/KeyboardEvent.h" #include "core/events/PointerEvent.h" #include "core/frame/DOMVisualViewport.h" @@ -79,6 +78,7 @@ #include "modules/remoteplayback/RemotePlayback.h" #include "platform/EventDispatchForbiddenScope.h" #include "platform/runtime_enabled_features.h" +#include "public/platform/TaskType.h" #include "public/platform/WebSize.h" namespace blink { @@ -115,6 +115,8 @@ constexpr int kModernControlsAudioButtonPadding = 20; constexpr int kModernControlsVideoButtonPadding = 26; +const char kShowDefaultPosterCSSClass[] = "use-default-poster"; + bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element) { // Unconditionally allow the user to exit fullscreen if we are in it // now. Especially on android, when we might not yet know if @@ -306,8 +308,7 @@ orientation_lock_delegate_(nullptr), rotate_to_fullscreen_delegate_(nullptr), hide_media_controls_timer_( - TaskRunnerHelper::Get(TaskType::kUnspecedTimer, - &media_element.GetDocument()), + media_element.GetDocument().GetTaskRunner(TaskType::kUnspecedTimer), this, &MediaControlsImpl::HideMediaControlsTimerFired), hide_timer_behavior_flags_(kIgnoreNone), @@ -317,8 +318,7 @@ media_element.GetDocument(), new MediaControlsResizeObserverDelegate(this))), element_size_changed_timer_( - TaskRunnerHelper::Get(TaskType::kUnspecedTimer, - &media_element.GetDocument()), + media_element.GetDocument().GetTaskRunner(TaskType::kUnspecedTimer), this, &MediaControlsImpl::ElementSizeChangedTimerFired), keep_showing_until_timer_fires_(false) { @@ -558,7 +558,17 @@ } void MediaControlsImpl::UpdateCSSClassFromState() { - const char* classes = kStateCSSClasses[State()]; + StringBuilder builder; + builder.Append(kStateCSSClasses[State()]); + + if (MediaElement().IsHTMLVideoElement() && + !VideoElement().HasAvailableVideoFrame() && + VideoElement().PosterImageURL().IsEmpty()) { + builder.Append(" "); + builder.Append(kShowDefaultPosterCSSClass); + } + + const AtomicString& classes = builder.ToAtomicString(); if (getAttribute("class") != classes) setAttribute("class", classes); } @@ -1528,6 +1538,15 @@ MediaControlOverflowMenuListElement::kTimeToAction); } +void MediaControlsImpl::OnLoadedData() { + UpdateCSSClassFromState(); +} + +HTMLVideoElement& MediaControlsImpl::VideoElement() { + DCHECK(MediaElement().IsHTMLVideoElement()); + return *ToHTMLVideoElement(&MediaElement()); +} + void MediaControlsImpl::Trace(blink::Visitor* visitor) { visitor->Trace(element_mutation_callback_); visitor->Trace(resize_observer_);
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h index 9d7a4be0..6df3062a 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
@@ -36,6 +36,7 @@ namespace blink { class Event; +class HTMLVideoElement; class MediaControlsMediaEventListener; class MediaControlsOrientationLockDelegate; class MediaControlsRotateToFullscreenDelegate; @@ -162,6 +163,10 @@ // Update the CSS class when we think the state has updated. void UpdateCSSClassFromState(); + // Get the HTMLVideoElement that the controls are attached to. The caller must + // check that the element is a video element first. + HTMLVideoElement& VideoElement(); + // Track the state of the controls. enum ControlsState { // There is no video source. @@ -259,6 +264,7 @@ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); } void OnWaiting(); void OnLoadingProgress(); + void OnLoadedData(); // Media control elements. Member<MediaControlOverlayEnclosureElement> overlay_enclosure_;
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsMediaEventListener.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsMediaEventListener.cpp index c4a8c7f..f4f1189 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsMediaEventListener.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsMediaEventListener.cpp
@@ -40,6 +40,7 @@ GetMediaElement().addEventListener(EventTypeNames::keyup, this, false); GetMediaElement().addEventListener(EventTypeNames::waiting, this, false); GetMediaElement().addEventListener(EventTypeNames::progress, this, false); + GetMediaElement().addEventListener(EventTypeNames::loadeddata, this, false); // Listen to two different fullscreen events in order to make sure the new and // old APIs are handled. @@ -172,6 +173,10 @@ media_controls_->OnLoadingProgress(); return; } + if (event->type() == EventTypeNames::loadeddata) { + media_controls_->OnLoadedData(); + return; + } // Fullscreen handling. if (event->type() == EventTypeNames::fullscreenchange ||
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp index 9ef6eac..c9b9af7 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp
@@ -5,7 +5,6 @@ #include "modules/media_controls/MediaControlsOrientationLockDelegate.h" #include "build/build_config.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/frame/LocalDOMWindow.h" #include "core/frame/Screen.h" @@ -20,6 +19,7 @@ #include "platform/runtime_enabled_features.h" #include "platform/wtf/Functional.h" #include "platform/wtf/MathExtras.h" +#include "public/platform/TaskType.h" #include "public/platform/WebScreenInfo.h" #include "public/platform/modules/screen_orientation/WebLockOrientationCallback.h" @@ -449,7 +449,8 @@ // is avoided by delaying unlocking long enough to ensure that Android has // detected the orientation change. lock_to_any_task_ = - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, &GetDocument()) + GetDocument() + .GetTaskRunner(TaskType::kMediaElementEvent) ->PostDelayedCancellableTask( BLINK_FROM_HERE, // Conceptually, this callback will unlock the screen orientation,
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverflowMenuListElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverflowMenuListElement.cpp index 77a753f..0ab8627 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverflowMenuListElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverflowMenuListElement.cpp
@@ -4,7 +4,6 @@ #include "modules/media_controls/elements/MediaControlOverflowMenuListElement.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "modules/media_controls/MediaControlsImpl.h" #include "platform/Histogram.h" @@ -58,7 +57,8 @@ // is not needed. DCHECK(!current_task_handle_.IsActive()); current_task_handle_ = - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, &GetDocument()) + GetDocument() + .GetTaskRunner(TaskType::kMediaElementEvent) ->PostCancellableTask( BLINK_FROM_HERE, WTF::Bind(
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPanelElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPanelElement.cpp index 54d02153..38c2885 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPanelElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPanelElement.cpp
@@ -4,11 +4,11 @@ #include "modules/media_controls/elements/MediaControlPanelElement.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/html/media/HTMLMediaElement.h" #include "modules/media_controls/MediaControlsImpl.h" #include "modules/media_controls/elements/MediaControlElementsHelper.h" +#include "public/platform/TaskType.h" namespace blink { @@ -22,10 +22,10 @@ MediaControlPanelElement::MediaControlPanelElement( MediaControlsImpl& media_controls) : MediaControlDivElement(media_controls, kMediaControlsPanel), - transition_timer_(TaskRunnerHelper::Get(TaskType::kUnspecedTimer, - &media_controls.GetDocument()), - this, - &MediaControlPanelElement::TransitionTimerFired) { + transition_timer_( + media_controls.GetDocument().GetTaskRunner(TaskType::kUnspecedTimer), + this, + &MediaControlPanelElement::TransitionTimerFired) { SetShadowPseudoId(AtomicString("-webkit-media-controls-panel")); }
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css index aed3e98..4127ce88 100644 --- a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css +++ b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
@@ -490,3 +490,17 @@ audio::-internal-media-controls-overflow-button { flex: 0 0 32px; } + +/** + * Preload state + */ + +.use-default-poster { + background: #F1F3F4; +} + +.state-no-source input[pseudo="-webkit-media-controls-overlay-play-button" i], +.use-default-poster div[pseudo="-internal-media-controls-button-panel" i], +.use-default-poster input[pseudo="-webkit-media-controls-timeline" i] { + display: none; +}
diff --git a/third_party/WebKit/Source/modules/mediacapturefromelement/TimedCanvasDrawListener.cpp b/third_party/WebKit/Source/modules/mediacapturefromelement/TimedCanvasDrawListener.cpp index 3cd8bc0..e9c175d 100644 --- a/third_party/WebKit/Source/modules/mediacapturefromelement/TimedCanvasDrawListener.cpp +++ b/third_party/WebKit/Source/modules/mediacapturefromelement/TimedCanvasDrawListener.cpp
@@ -5,7 +5,8 @@ #include "modules/mediacapturefromelement/TimedCanvasDrawListener.h" #include <memory> -#include "core/dom/TaskRunnerHelper.h" +#include "core/dom/ExecutionContext.h" +#include "public/platform/TaskType.h" #include "third_party/skia/include/core/SkImage.h" namespace blink { @@ -16,10 +17,9 @@ ExecutionContext* context) : CanvasDrawListener(std::move(handler)), frame_interval_(1 / frame_rate), - request_frame_timer_( - TaskRunnerHelper::Get(TaskType::kUnthrottled, context), - this, - &TimedCanvasDrawListener::RequestFrameTimerFired) {} + request_frame_timer_(context->GetTaskRunner(TaskType::kUnthrottled), + this, + &TimedCanvasDrawListener::RequestFrameTimerFired) {} TimedCanvasDrawListener::~TimedCanvasDrawListener() {}
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp index 907a63d7..8fd9303 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp
@@ -28,13 +28,13 @@ #include "bindings/core/v8/ExceptionState.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/Deprecation.h" #include "modules/mediastream/MediaStreamRegistry.h" #include "modules/mediastream/MediaStreamTrackEvent.h" #include "platform/bindings/ScriptState.h" #include "platform/mediastream/MediaStreamCenter.h" #include "platform/mediastream/MediaStreamSource.h" +#include "public/platform/TaskType.h" namespace blink { @@ -110,7 +110,7 @@ : ContextClient(context), descriptor_(stream_descriptor), scheduled_event_timer_( - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, context), + context->GetTaskRunner(TaskType::kMediaElementEvent), this, &MediaStream::ScheduledEventTimerFired) { descriptor_->SetClient(this); @@ -145,7 +145,7 @@ : ContextClient(context), descriptor_(stream_descriptor), scheduled_event_timer_( - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, context), + context->GetTaskRunner(TaskType::kMediaElementEvent), this, &MediaStream::ScheduledEventTimerFired) { descriptor_->SetClient(this); @@ -176,7 +176,7 @@ const MediaStreamTrackVector& video_tracks) : ContextClient(context), scheduled_event_timer_( - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, context), + context->GetTaskRunner(TaskType::kMediaElementEvent), this, &MediaStream::ScheduledEventTimerFired) { MediaStreamComponentVector audio_components;
diff --git a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp index 41393acc..28da9f56 100644 --- a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp +++ b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
@@ -7,11 +7,11 @@ #include <algorithm> #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "modules/EventTargetModules.h" #include "platform/runtime_enabled_features.h" #include "platform/wtf/text/WTFString.h" +#include "public/platform/TaskType.h" namespace blink { @@ -208,8 +208,7 @@ DCHECK(!connection_observer_handle_); connection_observer_handle_ = GetNetworkStateNotifier().AddConnectionObserver( - this, TaskRunnerHelper::Get(TaskType::kNetworking, - GetExecutionContext())); + this, GetExecutionContext()->GetTaskRunner(TaskType::kNetworking)); } }
diff --git a/third_party/WebKit/Source/modules/notifications/Notification.cpp b/third_party/WebKit/Source/modules/notifications/Notification.cpp index 08d04e4e..7c9932e 100644 --- a/third_party/WebKit/Source/modules/notifications/Notification.cpp +++ b/third_party/WebKit/Source/modules/notifications/Notification.cpp
@@ -37,7 +37,6 @@ #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" #include "core/dom/ScopedWindowFocusAllowedIndicator.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/UserGestureIndicator.h" #include "core/dom/events/Event.h" #include "core/frame/Deprecation.h" @@ -57,6 +56,7 @@ #include "platform/wtf/Assertions.h" #include "platform/wtf/Functional.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/WebSecurityOrigin.h" #include "public/platform/modules/notifications/WebNotificationAction.h" #include "public/platform/modules/notifications/WebNotificationConstants.h" @@ -204,7 +204,8 @@ // Schedule the "close" event to be fired for non-persistent notifications. // Persistent notifications won't get such events for programmatic closes. if (type_ == Type::kNonPersistent) { - TaskRunnerHelper::Get(TaskType::kUserInteraction, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kUserInteraction) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&Notification::DispatchCloseEvent, WrapPersistent(this))); state_ = State::kClosing;
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp index 36ced0a4..ae25652 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -16,7 +16,6 @@ #include "core/dom/DOMException.h" #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/dom/events/EventQueue.h" #include "core/event_type_names.h" @@ -49,6 +48,7 @@ #include "platform/weborigin/KURL.h" #include "platform/wtf/HashSet.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/WebTraceLocation.h" #include "services/service_manager/public/cpp/interface_provider.h" @@ -1052,7 +1052,7 @@ options_(options), client_binding_(this), complete_timer_( - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, execution_context), + execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI), this, &PaymentRequest::OnCompleteTimeout) { if (!GetExecutionContext()->IsSecureContext()) { @@ -1127,28 +1127,38 @@ } shipping_address_ = new PaymentAddress(std::move(address)); + PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create( GetExecutionContext(), EventTypeNames::shippingaddresschange); event->SetTarget(this); event->SetPaymentDetailsUpdater(this); - bool success = GetExecutionContext()->GetEventQueue()->EnqueueEvent( - BLINK_FROM_HERE, event); - DCHECK(success); - ALLOW_UNUSED_LOCAL(success); + DispatchEvent(event); + if (!event->is_waiting_for_update()) { + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, kWarningMessageLevel, + "No updateWith() call in 'shippingaddresschange' event handler. User " + "may see outdated line items and total.")); + payment_provider_->NoUpdatedPaymentDetails(); + } } void PaymentRequest::OnShippingOptionChange(const String& shipping_option_id) { DCHECK(show_resolver_); DCHECK(!complete_resolver_); shipping_option_ = shipping_option_id; + PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create( GetExecutionContext(), EventTypeNames::shippingoptionchange); event->SetTarget(this); event->SetPaymentDetailsUpdater(this); - bool success = GetExecutionContext()->GetEventQueue()->EnqueueEvent( - BLINK_FROM_HERE, event); - DCHECK(success); - ALLOW_UNUSED_LOCAL(success); + DispatchEvent(event); + if (!event->is_waiting_for_update()) { + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, kWarningMessageLevel, + "No updateWith() call in 'shippingoptionchange' event handler. User " + "may see outdated line items and total.")); + payment_provider_->NoUpdatedPaymentDetails(); + } } void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp index ba005a2..91e2d545 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp
@@ -10,9 +10,9 @@ #include "core/dom/DOMException.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "modules/payments/PaymentUpdater.h" #include "platform/wtf/text/WTFString.h" +#include "public/platform/TaskType.h" #include "public/platform/WebTraceLocation.h" namespace blink { @@ -96,8 +96,6 @@ void PaymentRequestUpdateEvent::SetPaymentDetailsUpdater( PaymentUpdater* updater) { - DCHECK(!abort_timer_.IsActive()); - abort_timer_.StartOneShot(kAbortTimeout, BLINK_FROM_HERE); updater_ = updater; } @@ -124,6 +122,9 @@ stopImmediatePropagation(); wait_for_update_ = true; + DCHECK(!abort_timer_.IsActive()); + abort_timer_.StartOneShot(kAbortTimeout, BLINK_FROM_HERE); + promise.Then( UpdatePaymentDetailsFunction::CreateFunction(script_state, this), UpdatePaymentDetailsErrorFunction::CreateFunction(script_state, this)); @@ -162,10 +163,9 @@ const PaymentRequestUpdateEventInit& init) : Event(type, init), wait_for_update_(false), - abort_timer_( - TaskRunnerHelper::Get(TaskType::kUserInteraction, execution_context), - this, - &PaymentRequestUpdateEvent::OnUpdateEventTimeout) {} + abort_timer_(execution_context->GetTaskRunner(TaskType::kUserInteraction), + this, + &PaymentRequestUpdateEvent::OnUpdateEventTimeout) {} void PaymentRequestUpdateEvent::OnUpdateEventTimeout(TimerBase*) { OnUpdatePaymentDetailsFailure("Timed out waiting for a response to a '" +
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h index 2ad79784..dbae308 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h
@@ -37,6 +37,8 @@ void updateWith(ScriptState*, ScriptPromise, ExceptionState&); + bool is_waiting_for_update() const { return wait_for_update_; } + // PaymentUpdater: void OnUpdatePaymentDetails(const ScriptValue& details_script_value) override; void OnUpdatePaymentDetailsFailure(const String& error) override; @@ -52,8 +54,10 @@ void OnUpdateEventTimeout(TimerBase*); - Member<PaymentUpdater> updater_; + // True after event.updateWith() was called. bool wait_for_update_; + + Member<PaymentUpdater> updater_; TaskRunnerTimer<PaymentRequestUpdateEvent> abort_timer_; };
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDTMFSender.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCDTMFSender.cpp index 79d4704..ae7e304 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCDTMFSender.cpp +++ b/third_party/WebKit/Source/modules/peerconnection/RTCDTMFSender.cpp
@@ -30,10 +30,10 @@ #include "bindings/core/v8/ExceptionState.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "modules/mediastream/MediaStreamTrack.h" #include "modules/peerconnection/RTCDTMFToneChangeEvent.h" #include "platform/wtf/PtrUtil.h" +#include "public/platform/TaskType.h" #include "public/platform/WebMediaStreamTrack.h" #include "public/platform/WebRTCDTMFSenderHandler.h" #include "public/platform/WebRTCPeerConnectionHandler.h" @@ -73,10 +73,9 @@ inter_tone_gap_(kDefaultInterToneGapMs), handler_(std::move(handler)), stopped_(false), - scheduled_event_timer_( - TaskRunnerHelper::Get(TaskType::kNetworking, context), - this, - &RTCDTMFSender::ScheduledEventTimerFired) { + scheduled_event_timer_(context->GetTaskRunner(TaskType::kNetworking), + this, + &RTCDTMFSender::ScheduledEventTimerFired) { handler_->SetClient(this); }
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.cpp index 465cefb..45fb0a6 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.cpp +++ b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.cpp
@@ -29,13 +29,13 @@ #include "bindings/core/v8/ExceptionState.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/events/MessageEvent.h" #include "core/fileapi/Blob.h" #include "core/typed_arrays/DOMArrayBuffer.h" #include "core/typed_arrays/DOMArrayBufferView.h" #include "modules/peerconnection/RTCPeerConnection.h" #include "platform/wtf/PtrUtil.h" +#include "public/platform/TaskType.h" #include "public/platform/WebRTCPeerConnectionHandler.h" namespace blink { @@ -90,10 +90,9 @@ handler_(std::move(handler)), ready_state_(kReadyStateConnecting), binary_type_(kBinaryTypeArrayBuffer), - scheduled_event_timer_( - TaskRunnerHelper::Get(TaskType::kNetworking, context), - this, - &RTCDataChannel::ScheduledEventTimerFired), + scheduled_event_timer_(context->GetTaskRunner(TaskType::kNetworking), + this, + &RTCDataChannel::ScheduledEventTimerFired), buffered_amount_low_threshold_(0U), stopped_(false) { handler_->SetClient(this);
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp index e97c03b2..1392599a 100644 --- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp +++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
@@ -8,7 +8,6 @@ #include "bindings/core/v8/ScriptPromiseResolver.h" #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/events/MessageEvent.h" #include "core/fileapi/FileReaderLoader.h" @@ -27,6 +26,7 @@ #include "modules/presentation/PresentationRequest.h" #include "platform/wtf/Assertions.h" #include "platform/wtf/text/AtomicString.h" +#include "public/platform/TaskType.h" namespace blink { @@ -257,7 +257,8 @@ // Fire onconnectionavailable event asynchronously. auto* event = PresentationConnectionAvailableEvent::Create( EventTypeNames::connectionavailable, connection); - TaskRunnerHelper::Get(TaskType::kPresentation, request->GetExecutionContext()) + request->GetExecutionContext() + ->GetTaskRunner(TaskType::kPresentation) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&PresentationConnection::DispatchEventAsync, WrapPersistent(request), WrapPersistent(event))); @@ -640,7 +641,8 @@ } void PresentationConnection::DispatchStateChangeEvent(Event* event) { - TaskRunnerHelper::Get(TaskType::kPresentation, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kPresentation) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&PresentationConnection::DispatchEventAsync, WrapPersistent(this), WrapPersistent(event)));
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp index 4258ce3..a380ae6 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
@@ -8,7 +8,6 @@ #include "bindings/modules/v8/v8_remote_playback_availability_callback.h" #include "core/dom/DOMException.h" #include "core/dom/Document.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/html/media/HTMLMediaElement.h" #include "core/html/media/HTMLVideoElement.h" @@ -20,6 +19,7 @@ #include "modules/remoteplayback/RemotePlaybackConnectionCallbacks.h" #include "platform/MemoryCoordinator.h" #include "platform/wtf/text/Base64.h" +#include "public/platform/TaskType.h" #include "public/platform/modules/presentation/WebPresentationClient.h" #include "public/platform/modules/presentation/WebPresentationError.h" #include "public/platform/modules/presentation/WebPresentationInfo.h" @@ -248,7 +248,8 @@ std::unique_ptr<int> task_id = WTF::MakeUnique<int>(0); probe::AsyncTaskScheduled(GetExecutionContext(), "promptCancelled", task_id.get()); - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kMediaElementEvent) ->PostTask(BLINK_FROM_HERE, WTF::Bind(RunRemotePlaybackTask, WrapPersistent(GetExecutionContext()), @@ -285,7 +286,8 @@ std::unique_ptr<int> task_id = WTF::MakeUnique<int>(0); probe::AsyncTaskScheduled(GetExecutionContext(), "watchAvailabilityCallback", task_id.get()); - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kMediaElementEvent) ->PostTask(BLINK_FROM_HERE, WTF::Bind(RunRemotePlaybackTask, WrapPersistent(GetExecutionContext()),
diff --git a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp index 2b95b18..fe9e13f2 100644 --- a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp +++ b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp
@@ -7,7 +7,6 @@ #include <memory> #include <utility> #include "core/dom/Document.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/dom/events/Event.h" #include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameView.h" @@ -17,6 +16,7 @@ #include "modules/screen_orientation/ScreenOrientationDispatcher.h" #include "platform/LayoutTestSupport.h" #include "platform/ScopedOrientationChangeIndicator.h" +#include "public/platform/TaskType.h" #include "public/platform/WebScreenInfo.h" #include "public/platform/modules/screen_orientation/WebScreenOrientationClient.h" @@ -45,7 +45,7 @@ PlatformEventController(frame.GetDocument()), client_(client), dispatch_event_timer_( - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, &frame), + frame.GetTaskRunner(TaskType::kMiscPlatformAPI), this, &ScreenOrientationControllerImpl::DispatchEventTimerFired) {}
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp index eddfe41..f383d91 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp +++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -6,13 +6,13 @@ #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/inspector/ConsoleMessage.h" #include "core/timing/DOMWindowPerformance.h" #include "core/timing/Performance.h" #include "modules/sensor/SensorErrorEvent.h" #include "modules/sensor/SensorProviderProxy.h" #include "platform/LayoutTestSupport.h" +#include "public/platform/TaskType.h" #include "services/device/public/cpp/generic_sensor/sensor_traits.h" #include "services/device/public/interfaces/sensor.mojom-blink.h" @@ -200,12 +200,14 @@ // possible modifications of SensorProxy::observers_ container // while it is being iterated through. pending_reading_notification_ = - TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kSensor) ->PostCancellableTask(BLINK_FROM_HERE, std::move(sensor_reading_changed)); } else { pending_reading_notification_ = - TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kSensor) ->PostDelayedCancellableTask( BLINK_FROM_HERE, std::move(sensor_reading_changed), WTF::TimeDelta::FromSecondsD(waitingTime)); @@ -231,7 +233,8 @@ return; pending_activated_notification_ = - TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kSensor) ->PostCancellableTask( BLINK_FROM_HERE, WTF::Bind(&Sensor::NotifyActivated, WrapWeakPersistent(this))); @@ -309,7 +312,8 @@ auto error = DOMException::Create(code, sanitized_message, unsanitized_message); pending_error_notification_ = - TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kSensor) ->PostCancellableTask( BLINK_FROM_HERE, WTF::Bind(&Sensor::NotifyError, WrapWeakPersistent(this), @@ -331,7 +335,8 @@ // right away. DCHECK(!pending_reading_notification_.IsActive()); pending_reading_notification_ = - TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kSensor) ->PostCancellableTask( BLINK_FROM_HERE, WTF::Bind(&Sensor::NotifyReading, WrapWeakPersistent(this)));
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp index 32787147..409fe08 100644 --- a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp +++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
@@ -4,12 +4,12 @@ #include "modules/sensor/SensorProxy.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/LocalFrame.h" #include "core/page/FocusController.h" #include "modules/sensor/SensorProviderProxy.h" #include "platform/mojo/MojoHelper.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "services/device/public/cpp/generic_sensor/sensor_traits.h" namespace blink { @@ -27,10 +27,10 @@ client_binding_(this), state_(SensorProxy::kUninitialized), suspended_(false), - polling_timer_(TaskRunnerHelper::Get(TaskType::kSensor, - provider->GetSupplementable()), - this, - &SensorProxy::OnPollingTimer) {} + polling_timer_( + provider->GetSupplementable()->GetTaskRunner(TaskType::kSensor), + this, + &SensorProxy::OnPollingTimer) {} SensorProxy::~SensorProxy() {}
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp index 9338f58..ab2b0d8 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp
@@ -7,7 +7,6 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8BindingForCore.h" #include "core/dom/Document.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/DOMWindow.h" #include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameClient.h" @@ -19,6 +18,7 @@ #include "platform/scheduler/child/web_scheduler.h" #include "platform/wtf/PtrUtil.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/modules/serviceworker/service_worker_error_type.mojom-blink.h" namespace blink { @@ -33,13 +33,15 @@ void OnSuccess( std::unique_ptr<WebServiceWorkerRegistration::Handle> handle) override { - TaskRunnerHelper::Get(TaskType::kUnthrottled, &owner_->GetDocument()) + owner_->GetDocument() + .GetTaskRunner(TaskType::kUnthrottled) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&LinkLoaderClient::LinkLoaded, owner_)); } void OnError(const WebServiceWorkerError& error) override { - TaskRunnerHelper::Get(TaskType::kUnthrottled, &owner_->GetDocument()) + owner_->GetDocument() + .GetTaskRunner(TaskType::kUnthrottled) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&LinkLoaderClient::LinkLoadingErrored, owner_)); }
diff --git a/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp b/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp index 21b83a9..58f9c2f 100644 --- a/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp +++ b/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp
@@ -25,8 +25,9 @@ #include "modules/speech/testing/PlatformSpeechSynthesizerMock.h" -#include "core/dom/TaskRunnerHelper.h" +#include "core/dom/ExecutionContext.h" #include "platform/speech/PlatformSpeechSynthesisUtterance.h" +#include "public/platform/TaskType.h" namespace blink { @@ -45,11 +46,11 @@ ExecutionContext* context) : PlatformSpeechSynthesizer(client), speaking_error_occurred_timer_( - TaskRunnerHelper::Get(TaskType::kUnspecedTimer, context), + context->GetTaskRunner(TaskType::kUnspecedTimer), this, &PlatformSpeechSynthesizerMock::SpeakingErrorOccurred), speaking_finished_timer_( - TaskRunnerHelper::Get(TaskType::kUnspecedTimer, context), + context->GetTaskRunner(TaskType::kUnspecedTimer), this, &PlatformSpeechSynthesizerMock::SpeakingFinished) {}
diff --git a/third_party/WebKit/Source/modules/vibration/VibrationController.cpp b/third_party/WebKit/Source/modules/vibration/VibrationController.cpp index 156260b9..36a2e1b 100644 --- a/third_party/WebKit/Source/modules/vibration/VibrationController.cpp +++ b/third_party/WebKit/Source/modules/vibration/VibrationController.cpp
@@ -21,12 +21,12 @@ #include "bindings/modules/v8/unsigned_long_or_unsigned_long_sequence.h" #include "core/dom/Document.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/LocalFrame.h" #include "core/frame/Navigator.h" #include "core/page/Page.h" #include "platform/mojo/MojoHelper.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "services/service_manager/public/cpp/interface_provider.h" // Maximum number of entries in a vibration pattern. @@ -78,10 +78,10 @@ VibrationController::VibrationController(LocalFrame& frame) : ContextLifecycleObserver(frame.GetDocument()), PageVisibilityObserver(frame.GetDocument()->GetPage()), - timer_do_vibrate_(TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, - frame.GetDocument()), - this, - &VibrationController::DoVibrate), + timer_do_vibrate_( + frame.GetDocument()->GetTaskRunner(TaskType::kMiscPlatformAPI), + this, + &VibrationController::DoVibrate), is_running_(false), is_calling_cancel_(false), is_calling_vibrate_(false) {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp index f90d6e9..7de83c0 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp
@@ -231,16 +231,16 @@ void AudioScheduledSourceHandler::Finish() { FinishWithoutOnEnded(); - if (Context()->GetExecutionContext()) { - task_runner_->PostTask( - BLINK_FROM_HERE, - CrossThreadBind(&AudioScheduledSourceHandler::NotifyEnded, - WrapRefCounted(this))); - } + task_runner_->PostTask( + BLINK_FROM_HERE, + CrossThreadBind(&AudioScheduledSourceHandler::NotifyEnded, + WrapRefCounted(this))); } void AudioScheduledSourceHandler::NotifyEnded() { DCHECK(IsMainThread()); + if (!Context() || !Context()->GetExecutionContext()) + return; if (GetNode()) GetNode()->DispatchEvent(Event::Create(EventTypeNames::ended)); }
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp index fd065912..26718cb5 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
@@ -34,7 +34,6 @@ #include "core/dom/DOMException.h" #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/Settings.h" #include "core/html/media/AutoplayPolicy.h" #include "core/html/media/HTMLMediaElement.h" @@ -79,6 +78,7 @@ #include "platform/bindings/ScriptState.h" #include "platform/wtf/text/WTFString.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" namespace blink { @@ -699,7 +699,8 @@ // Notify context that state changed if (GetExecutionContext()) - TaskRunnerHelper::Get(TaskType::kMediaElementEvent, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kMediaElementEvent) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&BaseAudioContext::NotifyStateChange, WrapPersistent(this)));
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp index f6a9ba0..27a74eb 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp
@@ -203,12 +203,10 @@ // Print a CORS message, but just once for each change in the current // media element source, and only if we have a document to print to. maybe_print_cors_message_ = false; - if (Context()->GetExecutionContext()) { - task_runner_->PostTask( - BLINK_FROM_HERE, - CrossThreadBind(&MediaElementAudioSourceHandler::PrintCORSMessage, - WrapRefCounted(this), current_src_string_)); - } + task_runner_->PostTask( + BLINK_FROM_HERE, + CrossThreadBind(&MediaElementAudioSourceHandler::PrintCORSMessage, + WrapRefCounted(this), current_src_string_)); } output_bus->Zero(); }
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp index 5a860b6f..8dfb7e7a 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
@@ -254,30 +254,26 @@ DCHECK(!IsMainThread()); // The actual rendering has been suspended. Notify the context. - if (Context()->GetExecutionContext()) { - task_runner_->PostTask( - BLINK_FROM_HERE, - CrossThreadBind(&OfflineAudioDestinationHandler::NotifySuspend, - WrapRefCounted(this), Context()->CurrentSampleFrame())); - } + task_runner_->PostTask( + BLINK_FROM_HERE, + CrossThreadBind(&OfflineAudioDestinationHandler::NotifySuspend, + WrapRefCounted(this), Context()->CurrentSampleFrame())); } void OfflineAudioDestinationHandler::FinishOfflineRendering() { DCHECK(!IsMainThread()); // The actual rendering has been completed. Notify the context. - if (Context()->GetExecutionContext()) { - task_runner_->PostTask( - BLINK_FROM_HERE, - CrossThreadBind(&OfflineAudioDestinationHandler::NotifyComplete, - WrapRefCounted(this))); - } + task_runner_->PostTask( + BLINK_FROM_HERE, + CrossThreadBind(&OfflineAudioDestinationHandler::NotifyComplete, + WrapRefCounted(this))); } void OfflineAudioDestinationHandler::NotifySuspend(size_t frame) { DCHECK(IsMainThread()); - if (Context()) + if (Context() && Context()->GetExecutionContext()) Context()->ResolveSuspendOnMainThread(frame); } @@ -288,7 +284,7 @@ render_thread_.reset(); // The OfflineAudioContext might be gone. - if (Context()) + if (Context() && Context()->GetExecutionContext()) Context()->FireCompletionEvent(); }
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp index c3da1e691..043962ac 100644 --- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp
@@ -213,7 +213,7 @@ // We're late in handling the previous request. The main thread must be // very busy. The best we can do is clear out the buffer ourself here. output_buffer->Zero(); - } else if (Context()->GetExecutionContext()) { + } else { // With the realtime context, execute the script code asynchronously // and do not wait. if (Context()->HasRealtimeConstraint()) { @@ -249,6 +249,9 @@ void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) { DCHECK(IsMainThread()); + if (!Context() || !Context()->GetExecutionContext()) + return; + DCHECK_LT(double_buffer_index, 2u); if (double_buffer_index > 1) return; @@ -260,7 +263,7 @@ return; // Avoid firing the event if the document has already gone away. - if (GetNode() && Context() && Context()->GetExecutionContext()) { + if (GetNode()) { // This synchronizes with process(). MutexLocker process_locker(process_event_lock_); @@ -282,6 +285,9 @@ WaitableEvent* waitable_event) { DCHECK(IsMainThread()); + if (!Context() || !Context()->GetExecutionContext()) + return; + DCHECK_LT(double_buffer_index, 2u); if (double_buffer_index > 1) { waitable_event->Signal(); @@ -296,7 +302,7 @@ return; } - if (GetNode() && Context() && Context()->GetExecutionContext()) { + if (GetNode()) { // We do not need a process lock here because the offline render thread // is locked by the waitable event. double playback_time = (Context()->CurrentSampleFrame() + buffer_size_) /
diff --git a/third_party/WebKit/Source/modules/webdatabase/Database.cpp b/third_party/WebKit/Source/modules/webdatabase/Database.cpp index 27070fa..0d49d228 100644 --- a/third_party/WebKit/Source/modules/webdatabase/Database.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/Database.cpp
@@ -29,7 +29,6 @@ #include "bindings/modules/v8/v8_database_callback.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/html/VoidCallback.h" #include "core/inspector/ConsoleMessage.h" #include "core/probe/CoreProbes.h" @@ -57,6 +56,7 @@ #include "platform/wtf/Atomics.h" #include "platform/wtf/CurrentTime.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/WebDatabaseObserver.h" #include "public/platform/WebSecurityOrigin.h" @@ -263,7 +263,7 @@ DCHECK(database_context_->GetDatabaseThread()); DCHECK(database_context_->IsContextThread()); database_task_runner_ = - TaskRunnerHelper::Get(TaskType::kDatabaseAccess, GetExecutionContext()); + GetExecutionContext()->GetTaskRunner(TaskType::kDatabaseAccess); } Database::~Database() { @@ -310,7 +310,8 @@ << "Scheduling DatabaseCreationCallbackTask for database " << this; probe::AsyncTaskScheduled(GetExecutionContext(), "openDatabase", creation_callback_); - TaskRunnerHelper::Get(TaskType::kDatabaseAccess, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kDatabaseAccess) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&Database::RunCreationCallback, WrapPersistent(this))); } else {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp b/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp index 98f62d8..f2d1db3 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp
@@ -4,10 +4,10 @@ #include "modules/webgl/WebGLQuery.h" -#include "core/dom/TaskRunnerHelper.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "modules/webgl/WebGL2RenderingContextBase.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" namespace blink { @@ -21,8 +21,8 @@ can_update_availability_(false), query_result_available_(false), query_result_(0), - task_runner_(TaskRunnerHelper::Get(TaskType::kUnthrottled, - &ctx->canvas()->GetDocument())) { + task_runner_( + ctx->canvas()->GetDocument().GetTaskRunner(TaskType::kUnthrottled)) { GLuint query; ctx->ContextGL()->GenQueriesEXT(1, &query); SetObject(query);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index f6bc474f..613bf5f8 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -33,7 +33,6 @@ #include "bindings/modules/v8/html_canvas_element_or_offscreen_canvas.h" #include "build/build_config.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameClient.h" #include "core/frame/Settings.h" @@ -107,6 +106,7 @@ #include "platform/wtf/text/StringUTF8Adaptor.h" #include "platform/wtf/typed_arrays/ArrayBufferContents.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "skia/ext/texture_handle.h" namespace blink { @@ -983,8 +983,7 @@ unsigned version) : WebGLRenderingContextBase( host, - TaskRunnerHelper::Get(TaskType::kWebGL, - host->GetTopExecutionContext()), + host->GetTopExecutionContext()->GetTaskRunner(TaskType::kWebGL), std::move(context_provider), requested_attributes, version) {}
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.cpp b/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.cpp index 01b2767..22457c61 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.cpp
@@ -4,10 +4,10 @@ #include "modules/webgl/WebGLTimerQueryEXT.h" -#include "core/dom/TaskRunnerHelper.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "modules/webgl/WebGLRenderingContextBase.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" namespace blink { @@ -22,8 +22,8 @@ can_update_availability_(false), query_result_available_(false), query_result_(0), - task_runner_(TaskRunnerHelper::Get(TaskType::kUnthrottled, - &ctx->canvas()->GetDocument())) { + task_runner_( + ctx->canvas()->GetDocument().GetTaskRunner(TaskType::kUnthrottled)) { Context()->ContextGL()->GenQueriesEXT(1, &query_id_); }
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp b/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp index 299d9d1..e1ad33bd 100644 --- a/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp +++ b/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp
@@ -33,10 +33,10 @@ #include "bindings/core/v8/ScriptPromise.h" #include "core/dom/DOMException.h" #include "core/dom/Document.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/frame/UseCounter.h" #include "modules/webmidi/MIDIAccess.h" #include "modules/webmidi/MIDIConnectionEvent.h" +#include "public/platform/TaskType.h" using midi::mojom::PortState; @@ -103,7 +103,8 @@ return Accept(script_state); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kMiscPlatformAPI) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&MIDIPort::OpenAsynchronously, WrapPersistent(this), WrapPersistent(resolver))); @@ -114,7 +115,8 @@ void MIDIPort::open() { if (connection_ == kConnectionStateOpen || running_open_count_) return; - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kMiscPlatformAPI) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&MIDIPort::OpenAsynchronously, WrapPersistent(this), nullptr)); running_open_count_++; @@ -125,7 +127,8 @@ return Accept(script_state); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); - TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, GetExecutionContext()) + GetExecutionContext() + ->GetTaskRunner(TaskType::kMiscPlatformAPI) ->PostTask(BLINK_FROM_HERE, WTF::Bind(&MIDIPort::CloseAsynchronously, WrapPersistent(this), WrapPersistent(resolver)));
diff --git a/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp b/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp index 8ab15a4..8e73a053 100644 --- a/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp +++ b/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp
@@ -38,7 +38,6 @@ #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" #include "core/dom/SecurityContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/events/MessageEvent.h" #include "core/fileapi/Blob.h" #include "core/frame/LocalDOMWindow.h" @@ -61,6 +60,7 @@ #include "platform/wtf/text/CString.h" #include "platform/wtf/text/StringBuilder.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/WebInsecureRequestPolicy.h" static const size_t kMaxByteSizeForHistogram = 100 * 1000 * 1000; @@ -71,10 +71,10 @@ DOMWebSocket::EventQueue::EventQueue(EventTarget* target) : state_(kActive), target_(target), - resume_timer_(TaskRunnerHelper::Get(TaskType::kWebSocket, - target->GetExecutionContext()), - this, - &EventQueue::ResumeTimerFired) {} + resume_timer_( + target->GetExecutionContext()->GetTaskRunner(TaskType::kWebSocket), + this, + &EventQueue::ResumeTimerFired) {} DOMWebSocket::EventQueue::~EventQueue() { ContextDestroyed(); @@ -231,7 +231,7 @@ extensions_(""), event_queue_(EventQueue::Create(this)), buffered_amount_consume_timer_( - TaskRunnerHelper::Get(TaskType::kWebSocket, context), + context->GetTaskRunner(TaskType::kWebSocket), this, &DOMWebSocket::ReflectBufferedAmountConsumption) {}
diff --git a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp index 39d9c0c6..4e987ff 100644 --- a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp +++ b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp
@@ -31,7 +31,6 @@ #include "modules/websockets/DocumentWebSocketChannel.h" #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/fileapi/FileReaderLoader.h" #include "core/fileapi/FileReaderLoaderClient.h" #include "core/frame/LocalFrame.h" @@ -61,6 +60,7 @@ #include "platform/wtf/Functional.h" #include "platform/wtf/PtrUtil.h" #include "public/platform/Platform.h" +#include "public/platform/TaskType.h" #include "public/platform/WebSocketHandshakeThrottle.h" #include "public/platform/WebTraceLocation.h" #include "public/platform/WebURL.h" @@ -237,7 +237,8 @@ // failure blocks the worker thread which should be avoided. Note that // returning "true" just indicates that this was not a mixed content error. if (ShouldDisallowConnection(url)) { - TaskRunnerHelper::Get(TaskType::kNetworking, GetDocument()) + GetDocument() + ->GetTaskRunner(TaskType::kNetworking) ->PostTask( BLINK_FROM_HERE, WTF::Bind(&DocumentWebSocketChannel::TearDownFailedConnection, @@ -246,13 +247,13 @@ } handle_->Initialize(std::move(socket_ptr)); - handle_->Connect( - url, protocols, loading_context_->GetFetchContext()->GetSecurityOrigin(), - loading_context_->GetFetchContext()->GetSiteForCookies(), - loading_context_->GetExecutionContext()->UserAgent(), this, - TaskRunnerHelper::Get(TaskType::kNetworking, - loading_context_->GetExecutionContext()) - .get()); + handle_->Connect(url, protocols, + loading_context_->GetFetchContext()->GetSecurityOrigin(), + loading_context_->GetFetchContext()->GetSiteForCookies(), + loading_context_->GetExecutionContext()->UserAgent(), this, + loading_context_->GetExecutionContext() + ->GetTaskRunner(TaskType::kNetworking) + .get()); // TODO(ricea): Maybe lookup GetDocument()->GetFrame() less often? if (handshake_throttle_ && GetDocument() && GetDocument()->GetFrame() &&
diff --git a/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp index 81af944..414f22b9 100644 --- a/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp +++ b/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
@@ -32,7 +32,6 @@ #include <memory> #include "core/dom/ExecutionContext.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/fileapi/Blob.h" #include "core/loader/ThreadableLoadingContext.h" #include "core/typed_arrays/DOMArrayBuffer.h" @@ -48,6 +47,7 @@ #include "platform/wtf/text/CString.h" #include "platform/wtf/text/WTFString.h" #include "public/platform/InterfaceProvider.h" +#include "public/platform/TaskType.h" namespace blink { @@ -405,7 +405,7 @@ // content check must synchronously be conducted. WebSocketChannelSyncHelper sync_helper; scoped_refptr<WebTaskRunner> worker_networking_task_runner = - TaskRunnerHelper::Get(TaskType::kNetworking, worker_global_scope_.Get()); + worker_global_scope_->GetTaskRunner(TaskType::kNetworking); WorkerThread* worker_thread = worker_global_scope_->GetThread(); // Dedicated workers are a special case as they always have an associated
diff --git a/third_party/WebKit/Source/platform/blob/BlobData.cpp b/third_party/WebKit/Source/platform/blob/BlobData.cpp index 769f60a..9286607 100644 --- a/third_party/WebKit/Source/platform/blob/BlobData.cpp +++ b/third_party/WebKit/Source/platform/blob/BlobData.cpp
@@ -400,7 +400,8 @@ size_(size), is_single_unknown_size_file_(false) { if (RuntimeEnabledFeatures::MojoBlobsEnabled()) { - SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Storage.Blob.GetBlobFromUUIDTime"); + SCOPED_BLINK_UMA_HISTOGRAM_TIMER_THREAD_SAFE( + "Storage.Blob.GetBlobFromUUIDTime"); // TODO(mek): Going through InterfaceProvider to get a BlobRegistryPtr // ends up going through the main thread. Ideally workers wouldn't need // to do that.
diff --git a/third_party/WebKit/Source/platform/fonts/FontSelector.h b/third_party/WebKit/Source/platform/fonts/FontSelector.h index 87d6d52..c3c58c77 100644 --- a/third_party/WebKit/Source/platform/fonts/FontSelector.h +++ b/third_party/WebKit/Source/platform/fonts/FontSelector.h
@@ -38,6 +38,7 @@ class ExecutionContext; class FontData; class FontDescription; +class FontFaceCache; class FontSelectorClient; class GenericFontFamilySettings; @@ -67,6 +68,12 @@ virtual ExecutionContext* GetExecutionContext() const = 0; + virtual FontFaceCache* GetFontFaceCache() = 0; + + virtual bool IsPlatformFamilyMatchAvailable( + const FontDescription&, + const AtomicString& passed_family) = 0; + protected: static AtomicString FamilyNameFromSettings( const GenericFontFamilySettings&,
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp index c103027..8adb90bc 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -418,6 +418,11 @@ sk_sp<SkImage> skia_image = image->PaintImageForCurrentFrame().GetSkImage(); + // This check should not be necessary, it is a speculative fix for + // crbug.com/759412 + if (!skia_image || !skia_image->getTexture()) + return false; + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) { if (PrepareGpuMemoryBufferMailboxFromImage(skia_image.get(), mailbox_info, out_mailbox)) @@ -808,9 +813,9 @@ if (have_recorded_draw_commands_ && GetOrCreateSurface()) { TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly"); - // For legacy canvases, transform all input colors and images to the target - // space using a SkCreateColorSpaceXformCanvas. This ensures blending will - // be done using target space pixel values. + // For legacy and sRGB canvases, transform all input colors and images to + // the target space using a SkCreateColorSpaceXformCanvas. This ensures + // blending will be done using target space pixel values. SkCanvas* canvas = GetOrCreateSurface()->getCanvas(); std::unique_ptr<PaintCanvas> color_transform_canvas = color_params_.WrapCanvas(canvas); @@ -975,6 +980,7 @@ { sk_sp<SkImage> skImage = image->PaintImageForCurrentFrame().GetSkImage(); + DCHECK(skImage->isTextureBacked()); // Early exit if canvas was not drawn to since last prepareMailbox. GLenum filter = GetGLFilter(); if (skImage->uniqueID() == last_image_id_ && filter == last_filter_)
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp index d9e3290..8aaec48b5e 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp +++ b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp
@@ -16,7 +16,6 @@ gfx::ColorSpace::PrimaryID GetPrimaryID(CanvasColorSpace color_space) { gfx::ColorSpace::PrimaryID primary_id = gfx::ColorSpace::PrimaryID::BT709; switch (color_space) { - case kLegacyCanvasColorSpace: case kSRGBCanvasColorSpace: primary_id = gfx::ColorSpace::PrimaryID::BT709; break; @@ -42,7 +41,7 @@ opacity_mode_(opacity_mode) {} CanvasColorParams::CanvasColorParams(const SkImageInfo& info) { - color_space_ = kLegacyCanvasColorSpace; + color_space_ = kSRGBCanvasColorSpace; pixel_format_ = kRGBA8CanvasPixelFormat; // When there is no color space information, the SkImage is in legacy mode and // the color type is kN32_SkColorType (which translates to kRGBA8 canvas pixel @@ -80,9 +79,8 @@ } bool CanvasColorParams::NeedsSkColorSpaceXformCanvas() const { - return color_space_ == kLegacyCanvasColorSpace || - (color_space_ == kSRGBCanvasColorSpace && - pixel_format_ == kRGBA8CanvasPixelFormat); + return color_space_ == kSRGBCanvasColorSpace && + pixel_format_ == kRGBA8CanvasPixelFormat; } std::unique_ptr<cc::PaintCanvas> CanvasColorParams::WrapCanvas( @@ -161,7 +159,6 @@ SkColorSpace::Gamut gamut = SkColorSpace::kSRGB_Gamut; SkColorSpace::RenderTargetGamma gamma = SkColorSpace::kSRGB_RenderTargetGamma; switch (color_space_) { - case kLegacyCanvasColorSpace: case kSRGBCanvasColorSpace: if (pixel_format_ == kF16CanvasPixelFormat) gamma = SkColorSpace::kLinear_RenderTargetGamma;
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h index 8819398..4804183 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h +++ b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h
@@ -23,7 +23,6 @@ namespace blink { enum CanvasColorSpace { - kLegacyCanvasColorSpace, kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace, @@ -59,7 +58,9 @@ bool NeedsColorConversion(const CanvasColorParams&) const; // The SkColorSpace to use in the SkImageInfo for allocated SkSurfaces. This - // is nullptr in legacy rendering mode. + // is nullptr in legacy rendering mode and when the surface is supposed to be + // in sRGB (for which we wrap the canvas into a PaintCanvas along with an + // SkColorSpaceXformCanvas). sk_sp<SkColorSpace> GetSkColorSpaceForSkSurfaces() const; // Wraps an SkCanvas into a PaintCanvas, along with an SkColorSpaceXformCanvas @@ -82,7 +83,7 @@ const SkSurfaceProps* GetSkSurfaceProps() const; private: - CanvasColorSpace color_space_ = kLegacyCanvasColorSpace; + CanvasColorSpace color_space_ = kSRGBCanvasColorSpace; CanvasPixelFormat pixel_format_ = kRGBA8CanvasPixelFormat; OpacityMode opacity_mode_ = kNonOpaque; };
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h index 2ad9576d..5d59cbd6 100644 --- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h +++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
@@ -46,7 +46,7 @@ UnacceleratedImageBufferSurface( const IntSize&, ImageInitializationMode = kInitializeImagePixels, - const CanvasColorParams& = CanvasColorParams(kLegacyCanvasColorSpace, + const CanvasColorParams& = CanvasColorParams(kSRGBCanvasColorSpace, kRGBA8CanvasPixelFormat, kNonOpaque)); ~UnacceleratedImageBufferSurface() override;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc index 92685ac..d918f88 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
@@ -17,8 +17,9 @@ namespace scheduler { scoped_refptr<WebTaskRunnerImpl> WebTaskRunnerImpl::Create( - scoped_refptr<TaskQueue> task_queue) { - return WTF::AdoptRef(new WebTaskRunnerImpl(std::move(task_queue))); + scoped_refptr<TaskQueue> task_queue, + base::Optional<TaskType> task_type) { + return WTF::AdoptRef(new WebTaskRunnerImpl(std::move(task_queue), task_type)); } bool WebTaskRunnerImpl::RunsTasksInCurrentSequence() { @@ -34,8 +35,9 @@ static_cast<double>(base::Time::kMicrosecondsPerSecond); } -WebTaskRunnerImpl::WebTaskRunnerImpl(scoped_refptr<TaskQueue> task_queue) - : task_queue_(std::move(task_queue)) {} +WebTaskRunnerImpl::WebTaskRunnerImpl(scoped_refptr<TaskQueue> task_queue, + base::Optional<TaskType> task_type) + : task_queue_(std::move(task_queue)), task_type_(task_type) {} WebTaskRunnerImpl::~WebTaskRunnerImpl() {} @@ -56,9 +58,8 @@ bool WebTaskRunnerImpl::PostDelayedTask(const base::Location& location, base::OnceClosure task, base::TimeDelta delay) { - // TODO(hajimehoshi): Give an appropriate task type - return task_queue_->PostTaskWithMetadata( - TaskQueue::PostedTask(std::move(task), location, delay)); + return task_queue_->PostTaskWithMetadata(TaskQueue::PostedTask( + std::move(task), location, delay, base::Nestable::kNestable, task_type_)); } } // namespace scheduler
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h index 1bd2819a..0fac5c3 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
@@ -10,9 +10,11 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/optional.h" #include "base/time/time.h" #include "platform/PlatformExport.h" #include "platform/WebTaskRunner.h" +#include "public/platform/TaskType.h" namespace blink { namespace scheduler { @@ -21,7 +23,8 @@ class PLATFORM_EXPORT WebTaskRunnerImpl : public WebTaskRunner { public: static scoped_refptr<WebTaskRunnerImpl> Create( - scoped_refptr<TaskQueue> task_queue); + scoped_refptr<TaskQueue> task_queue, + base::Optional<TaskType> task_type = base::nullopt); // WebTaskRunner implementation: bool RunsTasksInCurrentSequence() override; @@ -38,12 +41,14 @@ base::TimeDelta) override; private: - explicit WebTaskRunnerImpl(scoped_refptr<TaskQueue> task_queue); + WebTaskRunnerImpl(scoped_refptr<TaskQueue> task_queue, + base::Optional<TaskType> task_type); ~WebTaskRunnerImpl() override; base::TimeTicks Now() const; scoped_refptr<TaskQueue> task_queue_; + base::Optional<TaskType> task_type_; DISALLOW_COPY_AND_ASSIGN(WebTaskRunnerImpl); };
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc index 15fa4d8..00e99ae 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc
@@ -60,7 +60,7 @@ // TODO(nhiroki): Identify which tasks can be throttled / suspendable and // move them into other task runners. See also comments in // Get(LocalFrame). (https://crbug.com/670534) - return WebTaskRunnerImpl::Create(task_queue_); + return WebTaskRunnerImpl::Create(task_queue_, type); } NOTREACHED(); return nullptr;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc index 6f10c8fc..f2b9f50 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -707,6 +707,16 @@ &RendererSchedulerImpl::UseCaseToString); } + static scoped_refptr<TaskQueue> ThrottableTaskQueue( + WebFrameSchedulerImpl* scheduler) { + return scheduler->ThrottleableTaskQueue(); + } + + static scoped_refptr<TaskQueue> LoadingTaskQueue( + WebFrameSchedulerImpl* scheduler) { + return scheduler->LoadingTaskQueue(); + } + std::unique_ptr<base::SimpleTestTickClock> clock_; TaskQueue::Task fake_task_; scoped_refptr<MainThreadTaskQueue> fake_queue_; @@ -3828,10 +3838,7 @@ web_view_scheduler->CreateWebFrameSchedulerImpl( nullptr, WebFrameScheduler::FrameType::kSubframe); - scoped_refptr<WebTaskRunner> timer_wtr = - web_frame_scheduler->ThrottleableTaskRunner(); - TaskQueue* timer_tq = - static_cast<WebTaskRunnerImpl*>(timer_wtr.get())->GetTaskQueue(); + TaskQueue* timer_tq = ThrottableTaskQueue(web_frame_scheduler.get()).get(); web_frame_scheduler->SetCrossOrigin(true); web_frame_scheduler->SetFrameVisible(false); @@ -3892,8 +3899,7 @@ scheduler_->TimerTaskQueue()->PostTask(FROM_HERE, base::Bind(NullTask)); - web_frame_scheduler->LoadingTaskRunner() - ->ToSingleThreadTaskRunner() + LoadingTaskQueue(web_frame_scheduler.get()) ->PostDelayedTask(FROM_HERE, base::Bind(NullTask), TimeDelta::FromMilliseconds(10));
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index 4565ef3..cb00a4c 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -217,12 +217,12 @@ // TODO(haraken): Optimize the mapping from TaskTypes to task runners. switch (type) { case TaskType::kJavascriptTimer: - return ThrottleableTaskRunner(); + return WebTaskRunnerImpl::Create(ThrottleableTaskQueue(), type); case TaskType::kUnspecedLoading: case TaskType::kNetworking: - return LoadingTaskRunner(); + return WebTaskRunnerImpl::Create(LoadingTaskQueue(), type); case TaskType::kNetworkingControl: - return LoadingControlTaskRunner(); + return WebTaskRunnerImpl::Create(LoadingControlTaskQueue(), type); // Throttling following tasks may break existing web pages, so tentatively // these are unthrottled. // TODO(nhiroki): Throttle them again after we're convinced that it's safe @@ -246,7 +246,7 @@ case TaskType::kUnspecedTimer: case TaskType::kMiscPlatformAPI: // TODO(altimin): Move appropriate tasks to throttleable task queue. - return DeferrableTaskRunner(); + return WebTaskRunnerImpl::Create(DeferrableTaskQueue(), type); // PostedMessage can be used for navigation, so we shouldn't defer it // when expecting a user gesture. case TaskType::kPostedMessage: @@ -255,15 +255,15 @@ // Media events should not be deferred to ensure that media playback is // smooth. case TaskType::kMediaElementEvent: - return PausableTaskRunner(); + return WebTaskRunnerImpl::Create(PausableTaskQueue(), type); case TaskType::kUnthrottled: - return UnpausableTaskRunner(); + return WebTaskRunnerImpl::Create(UnpausableTaskQueue(), type); } NOTREACHED(); return nullptr; } -scoped_refptr<blink::WebTaskRunner> WebFrameSchedulerImpl::LoadingTaskRunner() { +scoped_refptr<TaskQueue> WebFrameSchedulerImpl::LoadingTaskQueue() { DCHECK(parent_web_view_scheduler_); if (!loading_task_queue_) { loading_task_queue_ = renderer_scheduler_->NewLoadingTaskQueue( @@ -274,11 +274,10 @@ loading_task_queue_->CreateQueueEnabledVoter(); loading_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); } - return WebTaskRunnerImpl::Create(loading_task_queue_); + return loading_task_queue_; } -scoped_refptr<blink::WebTaskRunner> -WebFrameSchedulerImpl::LoadingControlTaskRunner() { +scoped_refptr<TaskQueue> WebFrameSchedulerImpl::LoadingControlTaskQueue() { DCHECK(parent_web_view_scheduler_); if (!loading_control_task_queue_) { loading_control_task_queue_ = renderer_scheduler_->NewLoadingTaskQueue( @@ -289,11 +288,10 @@ loading_control_task_queue_->CreateQueueEnabledVoter(); loading_control_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); } - return WebTaskRunnerImpl::Create(loading_control_task_queue_); + return loading_control_task_queue_; } -scoped_refptr<blink::WebTaskRunner> -WebFrameSchedulerImpl::ThrottleableTaskRunner() { +scoped_refptr<TaskQueue> WebFrameSchedulerImpl::ThrottleableTaskQueue() { DCHECK(parent_web_view_scheduler_); if (!throttleable_task_queue_) { throttleable_task_queue_ = renderer_scheduler_->NewTaskQueue( @@ -322,11 +320,10 @@ throttleable_task_queue_.get()); } } - return WebTaskRunnerImpl::Create(throttleable_task_queue_); + return throttleable_task_queue_; } -scoped_refptr<blink::WebTaskRunner> -WebFrameSchedulerImpl::DeferrableTaskRunner() { +scoped_refptr<TaskQueue> WebFrameSchedulerImpl::DeferrableTaskQueue() { DCHECK(parent_web_view_scheduler_); if (!deferrable_task_queue_) { deferrable_task_queue_ = renderer_scheduler_->NewTaskQueue( @@ -341,11 +338,10 @@ deferrable_task_queue_->CreateQueueEnabledVoter(); deferrable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); } - return WebTaskRunnerImpl::Create(deferrable_task_queue_); + return deferrable_task_queue_; } -scoped_refptr<blink::WebTaskRunner> -WebFrameSchedulerImpl::PausableTaskRunner() { +scoped_refptr<TaskQueue> WebFrameSchedulerImpl::PausableTaskQueue() { DCHECK(parent_web_view_scheduler_); if (!pausable_task_queue_) { pausable_task_queue_ = renderer_scheduler_->NewTaskQueue( @@ -359,11 +355,10 @@ pausable_task_queue_->CreateQueueEnabledVoter(); pausable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); } - return WebTaskRunnerImpl::Create(pausable_task_queue_); + return pausable_task_queue_; } -scoped_refptr<blink::WebTaskRunner> -WebFrameSchedulerImpl::UnpausableTaskRunner() { +scoped_refptr<TaskQueue> WebFrameSchedulerImpl::UnpausableTaskQueue() { DCHECK(parent_web_view_scheduler_); if (!unpausable_task_queue_) { unpausable_task_queue_ = renderer_scheduler_->NewTaskQueue( @@ -372,7 +367,7 @@ unpausable_task_queue_->SetBlameContext(blame_context_); unpausable_task_queue_->SetFrameScheduler(this); } - return WebTaskRunnerImpl::Create(unpausable_task_queue_); + return unpausable_task_queue_; } blink::WebViewScheduler* WebFrameSchedulerImpl::GetWebViewScheduler() {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h index 7c729df1..858764e 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h
@@ -32,6 +32,18 @@ class TaskQueue; class WebViewSchedulerImpl; +namespace renderer_scheduler_impl_unittest { +class RendererSchedulerImplTest; +} + +namespace web_frame_scheduler_impl_unittest { +class WebFrameSchedulerImplTest; +} + +namespace web_view_scheduler_impl_unittest { +class WebViewSchedulerImplTest; +} + class PLATFORM_EXPORT WebFrameSchedulerImpl : public WebFrameScheduler { public: WebFrameSchedulerImpl(RendererSchedulerImpl* renderer_scheduler, @@ -70,18 +82,11 @@ void OnTraceLogEnabled(); - // TODO(hajimehoshi): Some tests like RendererSchedulerImplTest depends on - // these functions. These are public or a lot of FORWARD_DECLARE_TEST and - // FRIEND_TEST_ALL_PREFIXES would be required. Fix the tests not to use these. - scoped_refptr<WebTaskRunner> LoadingTaskRunner(); - scoped_refptr<WebTaskRunner> LoadingControlTaskRunner(); - scoped_refptr<WebTaskRunner> ThrottleableTaskRunner(); - scoped_refptr<WebTaskRunner> DeferrableTaskRunner(); - scoped_refptr<WebTaskRunner> PausableTaskRunner(); - scoped_refptr<WebTaskRunner> UnpausableTaskRunner(); - private: friend class WebViewSchedulerImpl; + friend class renderer_scheduler_impl_unittest::RendererSchedulerImplTest; + friend class web_frame_scheduler_impl_unittest::WebFrameSchedulerImplTest; + friend class web_view_scheduler_impl_unittest::WebViewSchedulerImplTest; class ActiveConnectionHandleImpl : public ActiveConnectionHandle { public: @@ -105,6 +110,13 @@ void DidOpenActiveConnection(); void DidCloseActiveConnection(); + scoped_refptr<TaskQueue> LoadingTaskQueue(); + scoped_refptr<TaskQueue> LoadingControlTaskQueue(); + scoped_refptr<TaskQueue> ThrottleableTaskQueue(); + scoped_refptr<TaskQueue> DeferrableTaskQueue(); + scoped_refptr<TaskQueue> PausableTaskQueue(); + scoped_refptr<TaskQueue> UnpausableTaskQueue(); + base::WeakPtr<WebFrameSchedulerImpl> AsWeakPtr(); scoped_refptr<MainThreadTaskQueue> loading_task_queue_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc index e2241ce..3865384 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
@@ -50,6 +50,27 @@ scheduler_.reset(); } + protected: + scoped_refptr<TaskQueue> ThrottleableTaskQueue() { + return web_frame_scheduler_->ThrottleableTaskQueue(); + } + + scoped_refptr<TaskQueue> LoadingTaskQueue() { + return web_frame_scheduler_->LoadingTaskQueue(); + } + + scoped_refptr<TaskQueue> DeferrableTaskQueue() { + return web_frame_scheduler_->DeferrableTaskQueue(); + } + + scoped_refptr<TaskQueue> PausableTaskQueue() { + return web_frame_scheduler_->PausableTaskQueue(); + } + + scoped_refptr<TaskQueue> UnpausableTaskQueue() { + return web_frame_scheduler_->UnpausableTaskQueue(); + } + std::unique_ptr<base::SimpleTestTickClock> clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; scoped_refptr<SchedulerTqmDelegate> delegate_; @@ -95,21 +116,20 @@ size_t stopped_count_; }; -void RunRepeatingTask(scoped_refptr<WebTaskRunner> task_runner, int* run_count); +void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count); -WTF::Closure MakeRepeatingTask(scoped_refptr<blink::WebTaskRunner> task_runner, - int* run_count) { - return WTF::Bind(&RunRepeatingTask, WTF::Passed(std::move(task_runner)), - WTF::Unretained(run_count)); +base::Closure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, + int* run_count) { + return base::Bind(&RunRepeatingTask, base::Passed(std::move(task_queue)), + base::Unretained(run_count)); } -void RunRepeatingTask(scoped_refptr<WebTaskRunner> task_runner, - int* run_count) { +void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count) { ++*run_count; - WebTaskRunner* task_runner_ptr = task_runner.get(); - task_runner_ptr->PostDelayedTask( - BLINK_FROM_HERE, MakeRepeatingTask(std::move(task_runner), run_count), + TaskQueue* task_queue_ptr = task_queue.get(); + task_queue_ptr->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(std::move(task_queue), run_count), TimeDelta::FromMilliseconds(1)); } @@ -124,10 +144,8 @@ timer_throttling_for_hidden_frames(true); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -140,10 +158,8 @@ web_view_scheduler_->SetPageVisible(false); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -156,10 +172,8 @@ web_frame_scheduler_->SetFrameVisible(false); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -173,10 +187,8 @@ web_frame_scheduler_->SetCrossOrigin(true); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -190,10 +202,8 @@ web_frame_scheduler_->SetCrossOrigin(true); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -206,10 +216,8 @@ web_view_scheduler_->SetPageVisible(false); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -224,10 +232,8 @@ web_frame_scheduler_->SetCrossOrigin(true); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -236,16 +242,21 @@ TEST_F(WebFrameSchedulerImplTest, PauseAndResume) { int counter = 0; - web_frame_scheduler_->LoadingTaskRunner()->PostTask( - BLINK_FROM_HERE, WTF::Bind(&IncrementCounter, WTF::Unretained(&counter))); - web_frame_scheduler_->ThrottleableTaskRunner()->PostTask( - BLINK_FROM_HERE, WTF::Bind(&IncrementCounter, WTF::Unretained(&counter))); - web_frame_scheduler_->DeferrableTaskRunner()->PostTask( - BLINK_FROM_HERE, WTF::Bind(&IncrementCounter, WTF::Unretained(&counter))); - web_frame_scheduler_->PausableTaskRunner()->PostTask( - BLINK_FROM_HERE, WTF::Bind(&IncrementCounter, WTF::Unretained(&counter))); - web_frame_scheduler_->UnpausableTaskRunner()->PostTask( - BLINK_FROM_HERE, WTF::Bind(&IncrementCounter, WTF::Unretained(&counter))); + LoadingTaskQueue()->PostTask( + BLINK_FROM_HERE, + base::Bind(&IncrementCounter, base::Unretained(&counter))); + ThrottleableTaskQueue()->PostTask( + BLINK_FROM_HERE, + base::Bind(&IncrementCounter, base::Unretained(&counter))); + DeferrableTaskQueue()->PostTask( + BLINK_FROM_HERE, + base::Bind(&IncrementCounter, base::Unretained(&counter))); + PausableTaskQueue()->PostTask( + BLINK_FROM_HERE, + base::Bind(&IncrementCounter, base::Unretained(&counter))); + UnpausableTaskQueue()->PostTask( + BLINK_FROM_HERE, + base::Bind(&IncrementCounter, base::Unretained(&counter))); web_frame_scheduler_->SetPaused(true);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc index b0b19fe..30599322 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
@@ -60,6 +60,28 @@ virtual bool DisableBackgroundTimerThrottling() const { return false; } + protected: + static scoped_refptr<TaskQueue> ThrottleableTaskQueueForScheduler( + WebFrameSchedulerImpl* scheduler) { + return scheduler->ThrottleableTaskQueue(); + } + + scoped_refptr<WebTaskRunner> ThrottleableTaskRunner() { + return WebTaskRunnerImpl::Create(ThrottleableTaskQueue()); + } + + scoped_refptr<WebTaskRunner> LoadingTaskRunner() { + return WebTaskRunnerImpl::Create(LoadingTaskQueue()); + } + + scoped_refptr<TaskQueue> ThrottleableTaskQueue() { + return web_frame_scheduler_->ThrottleableTaskQueue(); + } + + scoped_refptr<TaskQueue> LoadingTaskQueue() { + return web_frame_scheduler_->LoadingTaskQueue(); + } + std::unique_ptr<base::SimpleTestTickClock> clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; scoped_refptr<SchedulerTqmDelegate> delegate_; @@ -89,21 +111,19 @@ namespace { -void RunRepeatingTask(scoped_refptr<blink::WebTaskRunner> task_runner, - int* run_count); +void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count); -WTF::Closure MakeRepeatingTask(scoped_refptr<blink::WebTaskRunner> task_runner, - int* run_count) { - return WTF::Bind(&RunRepeatingTask, WTF::Passed(std::move(task_runner)), - WTF::Unretained(run_count)); +base::Closure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, + int* run_count) { + return base::Bind(&RunRepeatingTask, base::Passed(std::move(task_queue)), + base::Unretained(run_count)); } -void RunRepeatingTask(scoped_refptr<blink::WebTaskRunner> task_runner, - int* run_count) { +void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count) { ++*run_count; - blink::WebTaskRunner* task_runner_ptr = task_runner.get(); - task_runner_ptr->PostDelayedTask( - BLINK_FROM_HERE, MakeRepeatingTask(std::move(task_runner), run_count), + TaskQueue* task_queue_ptr = task_queue.get(); + task_queue_ptr->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(std::move(task_queue_ptr), run_count), TimeDelta::FromMilliseconds(1)); } @@ -113,10 +133,8 @@ web_view_scheduler_->SetPageVisible(true); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -128,10 +146,8 @@ web_view_scheduler_->SetPageVisible(false); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -152,9 +168,8 @@ web_view_scheduler_->SetPageVisible(false); int run_count = 0; - web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->LoadingTaskRunner(), &run_count), + LoadingTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(LoadingTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -173,16 +188,15 @@ int run_count1 = 0; int run_count2 = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count1), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count1), TimeDelta::FromMilliseconds(1)); - web_frame_scheduler2->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler2->ThrottleableTaskRunner(), - &run_count2), - TimeDelta::FromMilliseconds(1)); + ThrottleableTaskQueueForScheduler(web_frame_scheduler2.get()) + ->PostDelayedTask(BLINK_FROM_HERE, + MakeRepeatingTask(ThrottleableTaskQueueForScheduler( + web_frame_scheduler2.get()), + &run_count2), + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count1); @@ -191,23 +205,22 @@ namespace { -void RunVirtualTimeRecorderTask( - base::SimpleTestTickClock* clock, - scoped_refptr<blink::WebTaskRunner> web_task_runner, - std::vector<base::TimeTicks>* out_real_times, - std::vector<size_t>* out_virtual_times_ms) { +void RunVirtualTimeRecorderTask(base::SimpleTestTickClock* clock, + scoped_refptr<WebTaskRunner> task_runner, + std::vector<base::TimeTicks>* out_real_times, + std::vector<size_t>* out_virtual_times_ms) { out_real_times->push_back(clock->NowTicks()); out_virtual_times_ms->push_back( - web_task_runner->MonotonicallyIncreasingVirtualTimeSeconds() * 1000.0); + task_runner->MonotonicallyIncreasingVirtualTimeSeconds() * 1000.0); } WTF::Closure MakeVirtualTimeRecorderTask( base::SimpleTestTickClock* clock, - scoped_refptr<blink::WebTaskRunner> web_task_runner, + scoped_refptr<WebTaskRunner> task_runner, std::vector<base::TimeTicks>* out_real_times, std::vector<size_t>* out_virtual_times_ms) { return WTF::Bind(&RunVirtualTimeRecorderTask, WTF::Unretained(clock), - WTF::Passed(std::move(web_task_runner)), + WTF::Passed(std::move(task_runner)), WTF::Unretained(out_real_times), WTF::Unretained(out_virtual_times_ms)); } @@ -218,31 +231,27 @@ std::vector<size_t> virtual_times_ms; base::TimeTicks initial_real_time = scheduler_->tick_clock()->NowTicks(); size_t initial_virtual_time_ms = - web_frame_scheduler_->ThrottleableTaskRunner() - ->MonotonicallyIncreasingVirtualTimeSeconds() * + ThrottleableTaskRunner()->MonotonicallyIncreasingVirtualTimeSeconds() * 1000.0; web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(2)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(20)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(200)); mock_task_runner_->RunUntilIdle(); @@ -259,30 +268,26 @@ std::vector<size_t> virtual_times_ms; base::TimeTicks initial_real_time = scheduler_->tick_clock()->NowTicks(); size_t initial_virtual_time_ms = - web_frame_scheduler_->ThrottleableTaskRunner() - ->MonotonicallyIncreasingVirtualTimeSeconds() * + ThrottleableTaskRunner()->MonotonicallyIncreasingVirtualTimeSeconds() * 1000.0; web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( + LoadingTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask(clock_.get(), - web_frame_scheduler_->LoadingTaskRunner(), + MakeVirtualTimeRecorderTask(clock_.get(), LoadingTaskRunner(), &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(2)); - web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( + LoadingTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask(clock_.get(), - web_frame_scheduler_->LoadingTaskRunner(), + MakeVirtualTimeRecorderTask(clock_.get(), LoadingTaskRunner(), &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(20)); - web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( + LoadingTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask(clock_.get(), - web_frame_scheduler_->LoadingTaskRunner(), + MakeVirtualTimeRecorderTask(clock_.get(), LoadingTaskRunner(), &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(200)); @@ -302,10 +307,8 @@ base::TimeTicks initial_real_time = scheduler_->tick_clock()->NowTicks(); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunTasksWhile(mock_task_runner_->TaskRunCountBelow(2000)); @@ -324,12 +327,12 @@ } void DelayedRunOrderTask(int index, - scoped_refptr<blink::WebTaskRunner> task_runner, + scoped_refptr<TaskQueue> task_queue, std::vector<int>* out_run_order) { out_run_order->push_back(index); - task_runner->PostTask( + task_queue->PostTask( BLINK_FROM_HERE, - WTF::Bind(&RunOrderTask, index + 1, WTF::Unretained(out_run_order))); + base::Bind(&RunOrderTask, index + 1, base::Unretained(out_run_order))); } } @@ -339,22 +342,20 @@ web_view_scheduler_->SetVirtualTimePolicy(VirtualTimePolicy::PAUSE); web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler_->ThrottleableTaskRunner()->PostTask( + ThrottleableTaskQueue()->PostTask( BLINK_FROM_HERE, - WTF::Bind(&RunOrderTask, 0, WTF::Unretained(&run_order))); + base::Bind(&RunOrderTask, 0, base::Unretained(&run_order))); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(&DelayedRunOrderTask, 1, - WTF::Passed(web_frame_scheduler_->ThrottleableTaskRunner()), - WTF::Unretained(&run_order)), + base::Bind(&DelayedRunOrderTask, 1, base::Passed(ThrottleableTaskQueue()), + base::Unretained(&run_order)), TimeDelta::FromMilliseconds(2)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(&DelayedRunOrderTask, 3, - WTF::Passed(web_frame_scheduler_->ThrottleableTaskRunner()), - WTF::Unretained(&run_order)), + base::Bind(&DelayedRunOrderTask, 3, base::Passed(ThrottleableTaskQueue()), + base::Unretained(&run_order)), TimeDelta::FromMilliseconds(4)); mock_task_runner_->RunUntilIdle(); @@ -369,22 +370,20 @@ web_view_scheduler_->SetVirtualTimePolicy(VirtualTimePolicy::ADVANCE); web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler_->ThrottleableTaskRunner()->PostTask( + ThrottleableTaskQueue()->PostTask( BLINK_FROM_HERE, - WTF::Bind(&RunOrderTask, 0, WTF::Unretained(&run_order))); + base::Bind(&RunOrderTask, 0, base::Unretained(&run_order))); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(&DelayedRunOrderTask, 1, - WTF::Passed(web_frame_scheduler_->ThrottleableTaskRunner()), - WTF::Unretained(&run_order)), + base::Bind(&DelayedRunOrderTask, 1, base::Passed(ThrottleableTaskQueue()), + base::Unretained(&run_order)), TimeDelta::FromMilliseconds(2)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(&DelayedRunOrderTask, 3, - WTF::Passed(web_frame_scheduler_->ThrottleableTaskRunner()), - WTF::Unretained(&run_order)), + base::Bind(&DelayedRunOrderTask, 3, base::Passed(ThrottleableTaskQueue()), + base::Unretained(&run_order)), TimeDelta::FromMilliseconds(4)); mock_task_runner_->RunUntilIdle(); @@ -406,10 +405,8 @@ web_view_scheduler_->SetPageVisible(false); int run_count = 0; - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - MakeRepeatingTask(web_frame_scheduler_->ThrottleableTaskRunner(), - &run_count), + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -426,9 +423,11 @@ web_view_scheduler_->CreateWebFrameSchedulerImpl( nullptr, WebFrameScheduler::FrameType::kSubframe); - web_frame_scheduler->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, WTF::Bind(&RunOrderTask, 1, WTF::Unretained(&run_order)), - TimeDelta::FromMilliseconds(1)); + ThrottleableTaskQueueForScheduler(web_frame_scheduler.get()) + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&RunOrderTask, 1, base::Unretained(&run_order)), + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilIdle(); EXPECT_TRUE(run_order.empty()); @@ -442,8 +441,8 @@ namespace { template <typename T> -WTF::Closure MakeDeletionTask(T* obj) { - return WTF::Bind([](T* obj) { delete obj; }, WTF::Unretained(obj)); +base::Closure MakeDeletionTask(T* obj) { + return base::Bind([](T* obj) { delete obj; }, base::Unretained(obj)); } } // namespace @@ -455,15 +454,16 @@ ->CreateWebFrameSchedulerImpl( nullptr, WebFrameScheduler::FrameType::kSubframe) .release(); - web_frame_scheduler->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, MakeDeletionTask(web_frame_scheduler), - TimeDelta::FromMilliseconds(1)); + ThrottleableTaskQueueForScheduler(web_frame_scheduler) + ->PostDelayedTask(BLINK_FROM_HERE, + MakeDeletionTask(web_frame_scheduler), + TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilIdle(); } TEST_F(WebViewSchedulerImplTest, DeleteWebViewScheduler_InTask) { - web_frame_scheduler_->ThrottleableTaskRunner()->PostTask( + ThrottleableTaskQueue()->PostTask( BLINK_FROM_HERE, MakeDeletionTask(web_view_scheduler_.release())); mock_task_runner_->RunUntilIdle(); } @@ -476,20 +476,20 @@ ->CreateWebFrameSchedulerImpl(nullptr, WebFrameScheduler::FrameType::kSubframe) .release(); - scoped_refptr<blink::WebTaskRunner> timer_task_runner = - web_frame_scheduler->ThrottleableTaskRunner(); + scoped_refptr<TaskQueue> timer_task_queue = + ThrottleableTaskQueueForScheduler(web_frame_scheduler); int run_count = 0; - timer_task_runner->PostDelayedTask( - BLINK_FROM_HERE, MakeRepeatingTask(timer_task_runner, &run_count), + timer_task_queue->PostDelayedTask( + BLINK_FROM_HERE, MakeRepeatingTask(timer_task_queue, &run_count), TimeDelta::FromMilliseconds(1)); // Note this will run at time t = 10s since we start at time t = 5000us, and // it will prevent further tasks from running (i.e. the RepeatingTask) by // deleting the WebFrameScheduler. - timer_task_runner->PostDelayedTask(BLINK_FROM_HERE, - MakeDeletionTask(web_frame_scheduler), - TimeDelta::FromMilliseconds(9990)); + timer_task_queue->PostDelayedTask(BLINK_FROM_HERE, + MakeDeletionTask(web_frame_scheduler), + TimeDelta::FromMilliseconds(9990)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(100)); EXPECT_EQ(10, run_count); @@ -594,9 +594,9 @@ web_view_scheduler_->SetVirtualTimePolicy(VirtualTimePolicy::PAUSE); web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler->ThrottleableTaskRunner()->PostTask( - BLINK_FROM_HERE, - WTF::Bind(&RunOrderTask, 1, WTF::Unretained(&run_order))); + ThrottleableTaskQueueForScheduler(web_frame_scheduler.get()) + ->PostTask(BLINK_FROM_HERE, + base::Bind(&RunOrderTask, 1, base::Unretained(&run_order))); mock_task_runner_->RunUntilIdle(); EXPECT_TRUE(run_order.empty()); @@ -612,38 +612,33 @@ std::vector<size_t> virtual_times_ms; base::TimeTicks initial_real_time = scheduler_->tick_clock()->NowTicks(); size_t initial_virtual_time_ms = - web_frame_scheduler_->ThrottleableTaskRunner() - ->MonotonicallyIncreasingVirtualTimeSeconds() * + ThrottleableTaskRunner()->MonotonicallyIncreasingVirtualTimeSeconds() * 1000.0; web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(1)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(2)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(5)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + ThrottleableTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - MakeVirtualTimeRecorderTask( - clock_.get(), web_frame_scheduler_->ThrottleableTaskRunner(), - &real_times, &virtual_times_ms), + MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(), + &real_times, &virtual_times_ms), TimeDelta::FromMilliseconds(7)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -698,14 +693,14 @@ web_view_scheduler_->AddVirtualTimeObserver(&mock_observer); web_view_scheduler_->EnableVirtualTime(); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, WTF::Bind(&NopTask), TimeDelta::FromMilliseconds(200)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&NopTask), TimeDelta::FromMilliseconds(200)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, WTF::Bind(&NopTask), TimeDelta::FromMilliseconds(20)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&NopTask), TimeDelta::FromMilliseconds(20)); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, WTF::Bind(&NopTask), TimeDelta::FromMilliseconds(2)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&NopTask), TimeDelta::FromMilliseconds(2)); web_view_scheduler_->GrantVirtualTimeBudget( base::TimeDelta::FromMilliseconds(1000), @@ -725,15 +720,15 @@ } namespace { -void RepostingTask(scoped_refptr<WebTaskRunner> task_runner, +void RepostingTask(scoped_refptr<TaskQueue> task_queue, int max_count, int* count) { if (++(*count) >= max_count) return; - task_runner->PostTask(BLINK_FROM_HERE, - WTF::Bind(&RepostingTask, task_runner, max_count, - WTF::Unretained(count))); + task_queue->PostTask(BLINK_FROM_HERE, + base::Bind(&RepostingTask, task_queue, max_count, + base::Unretained(count))); } void DelayedTask(int* count_in, int* count_out) { @@ -749,11 +744,11 @@ int count = 0; int delayed_task_run_at_count = 0; - RepostingTask(web_frame_scheduler_->ThrottleableTaskRunner(), 1000, &count); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + RepostingTask(ThrottleableTaskQueue(), 1000, &count); + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(DelayedTask, WTF::Unretained(&count), - WTF::Unretained(&delayed_task_run_at_count)), + base::Bind(DelayedTask, base::Unretained(&count), + base::Unretained(&delayed_task_run_at_count)), base::TimeDelta::FromMilliseconds(10)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -780,11 +775,11 @@ int count = 0; int delayed_task_run_at_count = 0; - RepostingTask(web_frame_scheduler_->ThrottleableTaskRunner(), 1000, &count); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + RepostingTask(ThrottleableTaskQueue(), 1000, &count); + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(DelayedTask, WTF::Unretained(&count), - WTF::Unretained(&delayed_task_run_at_count)), + base::Bind(DelayedTask, WTF::Unretained(&count), + WTF::Unretained(&delayed_task_run_at_count)), base::TimeDelta::FromMilliseconds(10)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -808,11 +803,11 @@ int count = 0; int delayed_task_run_at_count = 0; - RepostingTask(web_frame_scheduler_->ThrottleableTaskRunner(), 1000, &count); - web_frame_scheduler_->ThrottleableTaskRunner()->PostDelayedTask( + RepostingTask(ThrottleableTaskQueue(), 1000, &count); + ThrottleableTaskQueue()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(DelayedTask, WTF::Unretained(&count), - WTF::Unretained(&delayed_task_run_at_count)), + base::Bind(DelayedTask, WTF::Unretained(&count), + WTF::Unretained(&delayed_task_run_at_count)), base::TimeDelta::FromMilliseconds(10)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -879,18 +874,12 @@ mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(2500)); - web_frame_scheduler_->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() - ->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - TimeDelta::FromMilliseconds(1)); - web_frame_scheduler_->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() - ->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - TimeDelta::FromMilliseconds(1)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(3500)); @@ -905,18 +894,12 @@ web_view_scheduler_->SetPageVisible(false); - web_frame_scheduler_->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() - ->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - TimeDelta::FromMicroseconds(1)); - web_frame_scheduler_->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() - ->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - TimeDelta::FromMicroseconds(1)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMicroseconds(1)); + ThrottleableTaskQueue()->PostDelayedTask( + BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMicroseconds(1)); mock_task_runner_->RunUntilIdle(); @@ -955,8 +938,7 @@ base::TimeDelta::FromMilliseconds(20500)); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler1->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() + ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get()) ->PostDelayedTask( BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), @@ -978,8 +960,7 @@ websocket_connection = web_frame_scheduler1->OnActiveConnectionCreated(); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler1->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() + ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get()) ->PostDelayedTask( BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), @@ -1000,8 +981,7 @@ run_times.clear(); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler2->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() + ThrottleableTaskQueueForScheduler(web_frame_scheduler2.get()) ->PostDelayedTask( BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), @@ -1027,8 +1007,7 @@ base::TimeDelta::FromMilliseconds(70500)); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler1->ThrottleableTaskRunner() - ->ToSingleThreadTaskRunner() + ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get()) ->PostDelayedTask( BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
diff --git a/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp index 762dde0f..55859d8f 100644 --- a/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp +++ b/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp
@@ -53,11 +53,18 @@ unsigned Version() const override { return 0; } void FontCacheInvalidated() override {} void ReportNotDefGlyph() const override {} - ExecutionContext* GetExecutionContext() const { return nullptr; } + ExecutionContext* GetExecutionContext() const override { return nullptr; } + FontFaceCache* GetFontFaceCache() override { return nullptr; } void RegisterForInvalidationCallbacks(FontSelectorClient*) override {} void UnregisterForInvalidationCallbacks(FontSelectorClient*) override {} + bool IsPlatformFamilyMatchAvailable( + const FontDescription&, + const AtomicString& passed_family) override { + return false; + } + private: TestFontSelector(scoped_refptr<FontCustomPlatformData> custom_platform_data) : custom_platform_data_(std::move(custom_platform_data)) {
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp b/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp index be2765c..39ba1bf 100644 --- a/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp +++ b/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
@@ -23,6 +23,7 @@ #include "platform/text/TextBreakIterator.h" +#include "build/build_config.h" #include "platform/text/Character.h" #include "platform/wtf/ASCIICType.h" #include "platform/wtf/StdLibExtras.h" @@ -31,6 +32,18 @@ #include <unicode/uchar.h> #include <unicode/uvernum.h> +#if defined(OS_ANDROID) +// Investigate crash on Android crbug.com/756624 +// TODO(kojii): Remove this when investigation is done. +#include "base/strings/stringprintf.h" +#include "platform/wtf/debug/CrashLogging.h" +#define SET_CRASH_KEY 1 + +using WTF::debug::ScopedCrashKey; + +const char kCrashKey[] = "break_iterator"; +#endif + namespace blink { unsigned NumGraphemeClusters(const String& string) { @@ -259,6 +272,11 @@ inline int LazyLineBreakIterator::NextBreakablePosition( int pos, const CharacterType* str) const { +#if defined(SET_CRASH_KEY) + ScopedCrashKey crash_key(kCrashKey, + base::StringPrintf("%d %d %p", lineBreakType, pos, + static_cast<const void*>(str))); +#endif int len = static_cast<int>(string_.length()); int next_break = -1; @@ -268,7 +286,8 @@ ULineBreak last_line_break; if (lineBreakType == LineBreakType::kBreakAll) last_line_break = LineBreakPropertyValue(last_last_ch, last_ch); - unsigned prior_context_length = PriorContextLength(); + const unsigned prior_context_length = PriorContextLength(); + TextBreakIterator* break_iterator = nullptr; CharacterType ch; bool is_space; for (int i = pos; i < len; @@ -319,8 +338,16 @@ // Don't break if positioned at start of primary context and there is no // prior context. if (i || prior_context_length) { - TextBreakIterator* break_iterator = Get(prior_context_length); + if (!break_iterator) { +#if defined(SET_CRASH_KEY) + ScopedCrashKey crash_key(kCrashKey, "Get"); +#endif + break_iterator = Get(prior_context_length); + } if (break_iterator) { +#if defined(SET_CRASH_KEY) + ScopedCrashKey crash_key(kCrashKey, "following"); +#endif next_break = break_iterator->following(i - 1 + prior_context_length); if (next_break >= 0) { @@ -371,6 +398,10 @@ template <LineBreakType lineBreakType> inline int LazyLineBreakIterator::NextBreakablePosition(int pos) const { +#if defined(SET_CRASH_KEY) + ScopedCrashKey crash_key(kCrashKey, + base::StringPrintf("%d %d", lineBreakType, pos)); +#endif if (UNLIKELY(string_.IsNull())) return 0; if (string_.Is8Bit()) {
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py index b1dc727..1e3526a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py
@@ -194,7 +194,7 @@ def normpath(self, path): return os.path.normpath(path) - def open_binary_tempfile(self, suffix): + def open_binary_tempfile(self, suffix=''): """Create, open, and return a binary temp file. Returns a tuple of the file and the name.""" temp_fd, temp_name = tempfile.mkstemp(suffix) f = os.fdopen(temp_fd, 'wb') @@ -215,6 +215,12 @@ with file(path, 'wb') as f: f.write(contents) + def open_text_tempfile(self, suffix=''): + """Create, open, and return a text temp file. Returns a tuple of the file and the name.""" + _, temp_name = tempfile.mkstemp(suffix) + f = codecs.open(temp_name, 'w', 'utf8') + return f, temp_name + def open_text_file_for_reading(self, path): # Note: There appears to be an issue with the returned file objects # not being seekable. See
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py index 34f87e6..2fc74d5 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py
@@ -337,6 +337,10 @@ self.files[path] = contents self.written_files[path] = contents + def open_text_tempfile(self, suffix=''): + path = self.mktemp(suffix) + return (WritableTextFileObject(self, path), path) + def open_text_file_for_reading(self, path): if self.files[path] is None: self._raise_not_found(path)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list.py index 8560f8e..735781f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list.py
@@ -40,7 +40,9 @@ class BuilderList(object): def __init__(self, builders_dict): - """The given dictionary maps builder names to dicts with the keys: + """Creates and validates a builders list. + + The given dictionary maps builder names to dicts with the keys: "port_name": A fully qualified port name. "specifiers": A two-item list: [version specifier, build type specifier]. Valid values for the version specifier can be found in @@ -53,6 +55,9 @@ properties to that class. """ self._builders = builders_dict + for builder in builders_dict: + assert 'port_name' in builders_dict[builder] + assert len(builders_dict[builder]['specifiers']) == 2 @staticmethod def load_default_builder_list(filesystem): @@ -80,6 +85,9 @@ def specifiers_for_builder(self, builder_name): return self._builders[builder_name]['specifiers'] + def platform_specifier_for_builder(self, builder_name): + return self.specifiers_for_builder(builder_name)[0] + def builder_name_for_port_name(self, target_port_name): """Returns a builder name for the given port name.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list_unittest.py index 1bfcf8cd..44af2a21 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/builder_list_unittest.py
@@ -44,6 +44,12 @@ 'Try B': {'port_name': 'port-b', 'specifiers': ['B', 'Release'], 'is_try_builder': True}, }) + def test_constructor_validates_list(self): + with self.assertRaises(AssertionError): + BuilderList({'Blink A': {}}) + with self.assertRaises(AssertionError): + BuilderList({'Blink A': {'port_name': 'port-a', 'specifiers': []}}) + def test_all_builder_names(self): builders = self.sample_builder_list() self.assertEqual(['Blink A', 'Blink B', 'Blink B (dbg)', 'Blink C (dbg)', 'Try A', 'Try B'], builders.all_builder_names()) @@ -68,6 +74,10 @@ builders = self.sample_builder_list() self.assertEqual(['B', 'Release'], builders.specifiers_for_builder('Blink B')) + def test_platform_specifier_for_builder(self): + builders = self.sample_builder_list() + self.assertEqual('B', builders.platform_specifier_for_builder('Blink B')) + def test_port_name_for_builder_name_with_missing_builder(self): builders = self.sample_builder_list() with self.assertRaises(KeyError):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/layout_package/bot_test_expectations_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/layout_package/bot_test_expectations_unittest.py index 9bd666be..27aac27 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/layout_package/bot_test_expectations_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/layout_package/bot_test_expectations_unittest.py
@@ -37,7 +37,7 @@ def fake_builder_list(self): return BuilderList({ - 'Dummy builder name': {'port_name': 'dummy-port', 'specifiers': []}, + 'Dummy builder name': {'port_name': 'dummy-port', 'specifiers': ['dummy', 'release']}, }) def fake_results_json_for_builder(self, builder):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index e5480548..8bab466a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -433,17 +433,24 @@ directory_owners = self.get_directory_owners() description = self._cl_description(directory_owners) sheriff_email = self.tbr_reviewer() + + temp_file, temp_path = self.fs.open_text_tempfile() + temp_file.write(description) + temp_file.close() + self.git_cl.run([ 'upload', '-f', '--gerrit', - '-m', description, + '--message-file', temp_path, '--tbrs', sheriff_email, # Note: we used to CC all the directory owners, but have stopped # in search of a better notification mechanism. (crbug.com/765334) '--cc', 'robertma@chromium.org', ]) + self.fs.remove(temp_path) + def get_directory_owners(self): """Returns a mapping of email addresses to owners of changed tests.""" _log.info('Gathering directory owners emails to CC.')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py index b7819e56..2e88d6f6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
@@ -370,37 +370,47 @@ """Returns a list of Port objects for all try builders.""" return [self.host.port_factory.get_from_builder_name(name) for name in self._get_try_bots()] - @staticmethod - def simplify_specifiers(specifiers, configuration_specifier_macros): - """Converts some collection of specifiers to an equivalent and maybe shorter list. + def simplify_specifiers(self, specifiers, specifier_macros): + """Simplifies the specifier part of an expectation line if possible. - The input strings are all case-insensitive, but the strings in the - return value will all be capitalized. + "Simplifying" means finding the shortest list of platform specifiers + that is equivalent to the given list of specifiers. This can be done + because there are "macro specifiers" that stand in for multiple version + specifiers, and an empty list stands in for "all platforms". Args: - specifiers: A collection of lower-case specifiers. - configuration_specifier_macros: A dict mapping "macros" for - groups of specifiers to lists of specific specifiers. In - practice, this is a dict mapping operating systems to - supported versions, e.g. {"win": ["win7", "win10"]}. + specifiers: A collection of specifiers (case insensitive). + specifier_macros: A dict mapping "macros" for groups of specifiers + to lists of version specifiers. e.g. {"win": ["win7", "win10"]}. + If there are versions in this dict for that have no corresponding + try bots, they are ignored. Returns: - A shortened list of specifiers. For example, ["win7", "win10"] - would be converted to ["Win"]. If the given list covers all - supported platforms, then an empty list is returned. - This list will be sorted and have capitalized specifier strings. + A shortened list of specifiers (capitalized). For example, ["win7", + "win10"] would be converted to ["Win"]. If the given list covers + all supported platforms, then an empty list is returned. """ - specifiers = {specifier.lower() for specifier in specifiers} - for macro_specifier, version_specifiers in configuration_specifier_macros.iteritems(): - macro_specifier = macro_specifier.lower() - version_specifiers = {specifier.lower() for specifier in version_specifiers} - if version_specifiers.issubset(specifiers): - specifiers -= version_specifiers - specifiers.add(macro_specifier) - if specifiers == {macro.lower() for macro in configuration_specifier_macros.keys()}: + specifiers = {s.lower() for s in specifiers} + covered_by_try_bots = self._platform_specifiers_covered_by_try_bots() + for macro, versions in specifier_macros.iteritems(): + macro = macro.lower() + + # Only consider version specifiers that have corresponding try bots. + versions = {s.lower() for s in versions if s.lower() in covered_by_try_bots} + if versions <= specifiers: + specifiers -= versions + specifiers.add(macro) + if specifiers == {macro.lower() for macro in specifier_macros}: return [] return sorted(specifier.capitalize() for specifier in specifiers) + def _platform_specifiers_covered_by_try_bots(self): + all_platform_specifiers = set() + for builder_name in self._get_try_bots(): + all_platform_specifiers.add( + self.host.builders.platform_specifier_for_builder(builder_name).lower()) + return frozenset(all_platform_specifiers) + def write_to_test_expectations(self, line_list): """Writes the given lines to the TestExpectations file.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py index 9304d35..da20181 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
@@ -343,17 +343,31 @@ ['Mac10.10', 'Win7', 'Win10'], 'external/wpt/test.html')) def test_simplify_specifiers(self): + host = self.mock_host() + updater = WPTExpectationsUpdater(host) macros = { 'mac': ['Mac10.10', 'mac10.11'], 'win': ['Win7', 'win10'], 'Linux': ['Trusty'], } - self.assertEqual(WPTExpectationsUpdater.simplify_specifiers(['mac10.10', 'mac10.11'], macros), ['Mac']) - self.assertEqual(WPTExpectationsUpdater.simplify_specifiers(['Mac10.10', 'Mac10.11', 'Trusty'], macros), ['Linux', 'Mac']) - self.assertEqual( - WPTExpectationsUpdater.simplify_specifiers(['Mac10.10', 'Mac10.11', 'Trusty', 'Win7', 'Win10'], macros), []) - self.assertEqual(WPTExpectationsUpdater.simplify_specifiers(['a', 'b', 'c'], {}), ['A', 'B', 'C']) - self.assertEqual(WPTExpectationsUpdater.simplify_specifiers(['Mac', 'Win', 'Linux'], macros), []) + self.assertEqual(updater.simplify_specifiers(['mac10.10', 'mac10.11'], macros), ['Mac']) + self.assertEqual(updater.simplify_specifiers(['Mac10.10', 'Mac10.11', 'Trusty'], macros), ['Linux', 'Mac']) + self.assertEqual(updater.simplify_specifiers(['Mac10.10', 'Mac10.11', 'Trusty', 'Win7', 'Win10'], macros), []) + self.assertEqual(updater.simplify_specifiers(['Mac', 'Win', 'Linux'], macros), []) + + def test_simplify_specifiers_uses_specifiers_in_builder_list(self): + # Even if there are extra specifiers in the macro dictionary, we can simplify specifier + # lists if they contain all of the specifiers the are represented in the builder list. + # This way specifier simplification can still be done while a new platform is being added. + host = self.mock_host() + updater = WPTExpectationsUpdater(host) + macros = { + 'mac': ['Mac10.10', 'mac10.11', 'mac10.14'], + 'win': ['Win7', 'win10'], + 'Linux': ['Trusty'], + } + self.assertEqual(updater.simplify_specifiers(['mac10.10', 'mac10.11'], macros), ['Mac']) + self.assertEqual(updater.simplify_specifiers(['Mac10.10', 'Mac10.11', 'Trusty', 'Win7', 'Win10'], macros), []) def test_specifier_part_with_skipped_test(self): host = self.mock_host()
diff --git a/third_party/WebKit/public/platform/modules/payments/payment_request.mojom b/third_party/WebKit/public/platform/modules/payments/payment_request.mojom index eddb3dc0c3..9020239 100644 --- a/third_party/WebKit/public/platform/modules/payments/payment_request.mojom +++ b/third_party/WebKit/public/platform/modules/payments/payment_request.mojom
@@ -224,13 +224,31 @@ }; interface PaymentRequest { + // Instantiates the renderer-browser connection with the information from the + // JavaScript constructor of PaymentRequest. Init(PaymentRequestClient client, array<PaymentMethodData> method_data, PaymentDetails details, PaymentOptions options); + + // Shows the user interface with the payment details. Show(); + + // Updates the payment details in response to new shipping address or shipping + // option. UpdateWith(PaymentDetails details); + + // Called when the merchant received a new shipping address or shipping + // option, but did not update the payment details in response. + NoUpdatedPaymentDetails(); + + // Requests to abort the checkout in process, for example because the item + // went out of stock. Abort(); + + // Closes the payment user interface. Complete(PaymentComplete result); + + // Queries whether the user has a form of payment on file. CanMakePayment(); };
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom b/third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom index 7af56743..fd62ca4 100644 --- a/third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom +++ b/third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom
@@ -83,8 +83,20 @@ // ServiceWorkerRegistration JavaScript object. The browser uses it to talk with // the corresponding impl of ServiceWorkerRegistration in the renderer. interface ServiceWorkerRegistrationObject { + // Sets changed service worker objects for this registration object. + // |changed_mask| indicates which objects of {|installing|,|waiting|,|active|} + // have changed. See ChangedVersionAttributesMask in service_worker_types.h + // for details. + // Changed objects always have non-null value, which may be invalid value + // describing that the object does not exist any more. + // Unchanged ones always have null value. + // TODO(leonhsl): Use mojofied ChangedVersionAttributesMask directly instead + // of an int32 for |changed_mask|. + SetVersionAttributes(int32 changed_mask, + ServiceWorkerObjectInfo? installing, + ServiceWorkerObjectInfo? waiting, + ServiceWorkerObjectInfo? active); + // TODO(leonhsl): Implement all methods. - // SetVersionAttributes(int32 changed_mask, - // ServiceWorkerVersionAttributes attrs); // UpdateFound(); };
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index a995172..0068fb7 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -42,13 +42,11 @@ _MAX_SAME_NAME_ALIAS_COUNT = 40 # 50kb is basically negligable. -def _OpenMaybeGz(path, mode=None): +def _OpenMaybeGz(path): """Calls `gzip.open()` if |path| ends in ".gz", otherwise calls `open()`.""" if path.endswith('.gz'): - if mode and 'w' in mode: - return gzip.GzipFile(path, mode, 1) - return gzip.open(path, mode) - return open(path, mode or 'r') + return gzip.open(path, 'rb') + return open(path, 'rb') def _StripLinkerAddedSymbolPrefixes(raw_symbols): @@ -390,7 +388,7 @@ logging.debug('Created %d string literal symbols', sum(len(x) for x in ret)) logging.debug('Sorting string literals') for symbols in ret: - symbols.sort(key=lambda x: x.address) + symbols.sort(key=lambda x: (x.address, -x.size)) logging.debug('Deduping string literals') num_removed = 0
diff --git a/tools/binary_size/libsupersize/file_format.py b/tools/binary_size/libsupersize/file_format.py index a262c9ab..cb055c7 100644 --- a/tools/binary_size/libsupersize/file_format.py +++ b/tools/binary_size/libsupersize/file_format.py
@@ -6,6 +6,7 @@ import cStringIO import calendar +import contextlib import datetime import gzip import json @@ -187,10 +188,18 @@ size_path=size_path) +@contextlib.contextmanager +def _OpenGzipForWrite(path): + # Open in a way that doesn't set any gzip header fields. + with open(path, 'wb') as f: + with gzip.GzipFile(filename='', mode='wb', fileobj=f, mtime=0) as fz: + yield fz + + def SaveSizeInfo(size_info, path): """Saves |size_info| to |path}.""" if os.environ.get('SUPERSIZE_MEASURE_GZIP') == '1': - with gzip.open(path, 'wb') as f: + with _OpenGzipForWrite(path) as f: _SaveSizeInfoToFile(size_info, f) else: # It is seconds faster to do gzip in a separate step. 6s -> 3.5s. @@ -199,7 +208,7 @@ logging.debug('Serialization complete. Gzipping...') stringio.seek(0) - with gzip.open(path, 'wb') as f: + with _OpenGzipForWrite(path) as f: shutil.copyfileobj(stringio, f)
diff --git a/tools/chrome_proxy/webdriver/video.py b/tools/chrome_proxy/webdriver/video.py index 4c552029..9858b0a0 100644 --- a/tools/chrome_proxy/webdriver/video.py +++ b/tools/chrome_proxy/webdriver/video.py
@@ -9,11 +9,19 @@ from common import IntegrationTest from common import ParseFlags from decorators import Slow +from decorators import ChromeVersionEqualOrAfterM from selenium.webdriver.common.by import By class Video(IntegrationTest): + # Returns the ofcl value in chrome-proxy header. + def getChromeProxyOFCL(self, response): + self.assertIn('chrome-proxy', response.response_headers) + chrome_proxy_header = response.response_headers['chrome-proxy'] + self.assertIn('ofcl=', chrome_proxy_header) + return chrome_proxy_header.split('ofcl=', 1)[1].split(',', 1)[0] + # Check videos are proxied. def testCheckVideoHasViaHeader(self): with TestDriver() as t: @@ -47,6 +55,70 @@ self.assertHasChromeProxyViaHeader(response) self.assertTrue(saw_video_response, 'No video request seen in test!') + @ChromeVersionEqualOrAfterM(64) + def testRangeRequest(self): + with TestDriver() as t: + t.AddChromeArg('--enable-spdy-proxy-auth') + t.LoadURL('http://check.googlezip.net/connect') + time.sleep(2) # wait for page load + initial_ocl_histogram_count = t.GetHistogram( + 'Net.HttpOriginalContentLengthWithValidOCL')['count'] + initial_ocl_histogram_sum = t.GetHistogram( + 'Net.HttpOriginalContentLengthWithValidOCL')['sum'] + t.ExecuteJavascript( + 'var xhr = new XMLHttpRequest();' + 'xhr.open("GET", "/metrics/local.png", false);' + 'xhr.setRequestHeader("Range", "bytes=0-200");' + 'xhr.send();' + 'return;' + ) + saw_range_response = False + for response in t.GetHTTPResponses(): + self.assertHasChromeProxyViaHeader(response) + if response.response_headers['status']=='206': + saw_range_response = True + self.assertEqual('201', response.response_headers['content-length']) + content_range = response.response_headers['content-range'] + self.assertTrue(content_range.startswith('bytes 0-200/')) + compressed_full_content_length = int(content_range.split('/')[1]) + ofcl = int(self.getChromeProxyOFCL(response)) + # ofcl should be same as compressed full content length, since no + # compression for XHR. + self.assertEqual(ofcl, compressed_full_content_length) + # One new entry should be added to HttpOriginalContentLengthWithValidOCL + # histogram and that should match expected OCL which is + # compression_ratio * 201 bytes. + self.assertEqual(1, t.GetHistogram( + 'Net.HttpOriginalContentLengthWithValidOCL')['count'] + - initial_ocl_histogram_count) + self.assertEqual(t.GetHistogram( + 'Net.HttpOriginalContentLengthWithValidOCL')['sum'] + - initial_ocl_histogram_sum, + ofcl/compressed_full_content_length*201) + self.assertTrue(saw_range_response, 'No range request was seen in test!') + + @ChromeVersionEqualOrAfterM(64) + def testRangeRequestInVideo(self): + with TestDriver() as t: + t.AddChromeArg('--enable-spdy-proxy-auth') + t.LoadURL( + 'http://check.googlezip.net/cacheable/video/buck_bunny_tiny.html') + # Wait for the video to finish playing, plus some headroom. + time.sleep(5) + responses = t.GetHTTPResponses() + self.assertEquals(2, len(responses)) + saw_range_response = False + for response in responses: + self.assertHasChromeProxyViaHeader(response) + if response.response_headers['status']=='206': + saw_range_response = True + content_range = response.response_headers['content-range'] + compressed_full_content_length = int(content_range.split('/')[1]) + ofcl = int(self.getChromeProxyOFCL(response)) + # ofcl should be greater than the compressed full content length. + self.assertTrue(ofcl > compressed_full_content_length) + self.assertTrue(saw_range_response, 'No range request was seen in test!') + # Check the compressed video has the same frame count, width, height, and # duration as uncompressed. @Slow
diff --git a/tools/cygprofile/orderfile_generator.py b/tools/cygprofile/orderfile_generator_backend.py similarity index 98% rename from tools/cygprofile/orderfile_generator.py rename to tools/cygprofile/orderfile_generator_backend.py index 8addc06..37cb1da1 100755 --- a/tools/cygprofile/orderfile_generator.py +++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -10,7 +10,7 @@ to page in less code during start-up. Example usage: - tools/cygprofile/orderfile_generator.py -l 20 -j 1000 --use-goma \ + tools/cygprofile/orderfile_generator_backend.py -l 20 -j 1000 --use-goma \ --target-arch=arm """ @@ -747,14 +747,14 @@ logging.basicConfig(level=logging.INFO) devil_chromium.Initialize(adb_path=options.adb_path) - orderfile_generator = OrderfileGenerator(options, orderfile_updater_class) + generator = OrderfileGenerator(options, orderfile_updater_class) try: if options.verify: - orderfile_generator._VerifySymbolOrder() + generator._VerifySymbolOrder() else: - return orderfile_generator.Generate() + return generator.Generate() finally: - json_output = json.dumps(orderfile_generator.GetReportingData(), + json_output = json.dumps(generator.GetReportingData(), indent=2) + '\n' if options.json_file: with open(options.json_file, 'w') as f:
diff --git a/tools/cygprofile/orderfile_generator_unittest.py b/tools/cygprofile/orderfile_generator_backend_unittest.py similarity index 83% rename from tools/cygprofile/orderfile_generator_unittest.py rename to tools/cygprofile/orderfile_generator_backend_unittest.py index 07763de..525b9bd 100755 --- a/tools/cygprofile/orderfile_generator_unittest.py +++ b/tools/cygprofile/orderfile_generator_backend_unittest.py
@@ -7,12 +7,12 @@ import tempfile import unittest -import orderfile_generator +import orderfile_generator_backend class TestOrderfileGenerator(unittest.TestCase): def testStepRecorder(self): """Checks that the step recorder records step timings correctly.""" - step_recorder = orderfile_generator.StepRecorder(False) + step_recorder = orderfile_generator_backend.StepRecorder(False) self.assertFalse(step_recorder.ErrorRecorded()) step_recorder.BeginStep('foo') self.assertFalse(step_recorder.ErrorRecorded()) @@ -28,7 +28,7 @@ def testGetFileExtension(self): self.assertEqual('zip', - orderfile_generator._GetFileExtension('/foo/bar/baz.blub.zip')) + orderfile_generator_backend._GetFileExtension('/foo/bar/baz.blub.zip')) def testGenerateHash(self): try: @@ -36,7 +36,7 @@ filename = handle.name handle.write('foo') self.assertEqual('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', - orderfile_generator._GenerateHash(filename)) + orderfile_generator_backend._GenerateHash(filename)) finally: if filename: os.unlink(filename)
diff --git a/tools/gn/xcode_object.cc b/tools/gn/xcode_object.cc index 9d8e791..8a314703 100644 --- a/tools/gn/xcode_object.cc +++ b/tools/gn/xcode_object.cc
@@ -13,8 +13,6 @@ #include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "tools/gn/filesystem_utils.h" -#include "tools/gn/source_file.h" -#include "tools/gn/source_file_type.h" // Helper methods ------------------------------------------------------------- @@ -155,10 +153,9 @@ return ext == "dart"; } -bool IsSourceFileForIndexing(const SourceFile& src) { - const SourceFileType type = GetSourceFileType(src); - return type == SOURCE_C || type == SOURCE_CPP || type == SOURCE_M || - type == SOURCE_MM; +bool IsSourceFileForIndexing(const base::StringPiece& ext) { + return ext == "c" || ext == "cc" || ext == "cpp" || ext == "cxx" || + ext == "m" || ext == "mm"; } void PrintValue(std::ostream& out, IndentRules rules, unsigned value) { @@ -695,7 +692,8 @@ PBXNativeTarget* target) { PBXFileReference* file_reference = sources_->AddSourceFile(navigator_path, source_path); - if (!IsSourceFileForIndexing(SourceFile(source_path))) + base::StringPiece ext = FindExtension(&source_path); + if (!IsSourceFileForIndexing(ext)) return; DCHECK(target);
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index b7225f2..52f1a676 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -10402,6 +10402,23 @@ </description> </action> +<action name="Media.Controls.RemoteSeekBackward"> + <owner>media-dev@chromium.org</owner> + <description> + User seeks the video backward using any controls apart from the media + element itself (aka remote controls: Android wear, headset, notification, + etc). + </description> +</action> + +<action name="Media.Controls.RemoteSeekForward"> + <owner>media-dev@chromium.org</owner> + <description> + User seeks the video forward using any controls apart from the media element + itself (aka remote controls: Android wear, headset, notification, etc). + </description> +</action> + <action name="Media.Controls.ScrubbingBegin"> <owner>mlamouri@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d488a700..34d23f5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -23977,6 +23977,7 @@ <int value="-2097515669" label="disable-cast"/> <int value="-2091404586" label="TabStripKeyboardFocus:enabled"/> <int value="-2090484194" label="ContextualSearchUrlActions:disabled"/> + <int value="-2083998415" label="VrLaunchIntent:enabled"/> <int value="-2083195884" label="enable-firewall-hole-punching"/> <int value="-2082042818" label="AutofillCreditCardLastUsedDateDisplay:enabled"/> @@ -24914,6 +24915,7 @@ <int value="593707592" label="disable-network-portal-notification"/> <int value="596106994" label="CustomFeedbackUi:enabled"/> <int value="598827460" label="enable-roboto-font-ui"/> + <int value="598926697" label="VrLaunchIntent:disabled"/> <int value="600037637" label="AndroidSigninPromos:enabled"/> <int value="602117675" label="NTPBookmarkSuggestions:enabled"/> <int value="603326800" label="UsePasswordSeparatedSigninFlow:enabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d8fc40ec..01f7712e36 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -13496,6 +13496,9 @@ </histogram> <histogram name="DataUse.Sync.Download.Bytes" enum="SyncModelTypes"> + <obsolete> + Deprecated 10/2017. + </obsolete> <owner>amohammadkhan@chromium.org</owner> <owner>bengr@chromium.org</owner> <summary> @@ -13506,6 +13509,9 @@ </histogram> <histogram name="DataUse.Sync.Download.Count" enum="SyncModelTypes"> + <obsolete> + Deprecated 10/2017. + </obsolete> <owner>amohammadkhan@chromium.org</owner> <owner>bengr@chromium.org</owner> <summary> @@ -13516,6 +13522,9 @@ </histogram> <histogram name="DataUse.Sync.ProgressMarker.Bytes" enum="SyncModelTypes"> + <obsolete> + Deprecated 10/2017. + </obsolete> <owner>amohammadkhan@chromium.org</owner> <owner>bengr@chromium.org</owner> <summary> @@ -13526,6 +13535,9 @@ </histogram> <histogram name="DataUse.Sync.Upload.Bytes" enum="SyncModelTypes"> + <obsolete> + Deprecated 10/2017. + </obsolete> <owner>amohammadkhan@chromium.org</owner> <owner>bengr@chromium.org</owner> <summary> @@ -13535,6 +13547,9 @@ </histogram> <histogram name="DataUse.Sync.Upload.Count" enum="SyncModelTypes"> + <obsolete> + Deprecated 10/2017. + </obsolete> <owner>amohammadkhan@chromium.org</owner> <owner>bengr@chromium.org</owner> <summary> @@ -51372,6 +51387,10 @@ </histogram> <histogram name="Notifications.Display" enum="NotifierType"> + <obsolete> + Deprecated October 2017 (fullscreen notifications feature enabled by + default). + </obsolete> <owner>bmalcolm@chromium.org</owner> <summary> Counts the number of times a notification was shown for the various types of @@ -102387,6 +102406,9 @@ </histogram_suffixes> <histogram_suffixes name="NotificationDisplayExperiment" separator="_"> + <obsolete> + Deprecated October 2017 (feature enabled by default). + </obsolete> <suffix name="Fullscreen.Shown" label="A notification sent by a fullscreen app or webpage that is displayed."/>
diff --git a/tools/metrics/histograms/update_policies.py b/tools/metrics/histograms/update_policies.py index ec3487f..267013b 100644 --- a/tools/metrics/histograms/update_policies.py +++ b/tools/metrics/histograms/update_policies.py
@@ -36,22 +36,6 @@ return self.args[0] -def FlattenPolicies(policy_definitions, policy_list): - """Appends a list of policies defined in |policy_definitions| to - |policy_list|, flattening subgroups. - - Args: - policy_definitions: A list of policy definitions and groups, as in - policy_templates.json file. - policy_list: A list that has policy definitions appended to it. - """ - for policy in policy_definitions: - if policy['type'] == 'group': - FlattenPolicies(policy['policies'], policy_list) - else: - policy_list.append(policy) - - def UpdateHistogramDefinitions(policy_templates, doc): """Sets the children of <enum name="EnterprisePolicies" ...> node in |doc| to values generated from policy ids contained in |policy_templates|. @@ -80,8 +64,8 @@ policy_enum_node.appendChild(doc.createComment(comment)) # Add values generated from policy templates. - ordered_policies = [] - FlattenPolicies(policy_templates['policy_definitions'], ordered_policies) + ordered_policies = [x for x in policy_templates['policy_definitions'] + if x['type'] != 'group'] ordered_policies.sort(key=lambda policy: policy['id']) for policy in ordered_policies: node = doc.createElement('int')
diff --git a/tools/perf/chromium.perf.fyi.extras.json b/tools/perf/chromium.perf.fyi.extras.json index f8d35a0f..af852bd 100644 --- a/tools/perf/chromium.perf.fyi.extras.json +++ b/tools/perf/chromium.perf.fyi.extras.json
@@ -85,7 +85,6 @@ "isolated_scripts": [ { "args": [ - "--bot", "swarm823-c4", "--builder", "One Buildbot Step Test Builder", "-v", "--output-format=histograms", @@ -102,7 +101,6 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "swarm823-c4", "pool": "Chrome-perf-fyi" } ], @@ -110,6 +108,14 @@ "hard_timeout": 10800, "ignore_task_failure": false, "io_timeout": 3600 + }, + "trigger_script": { + "script": "//tools/perf/perf_device_trigger.py", + "args": [ + "--bot-id", "swarm823-c4", + "--bot-id", "swarm846-c4", + "--bot-id", "swarm847-c4" + ] } } ]
diff --git a/tools/perf/contrib/vr_benchmarks/shared_android_vr_page_state.py b/tools/perf/contrib/vr_benchmarks/shared_android_vr_page_state.py index fce58d3..363e4f3d 100644 --- a/tools/perf/contrib/vr_benchmarks/shared_android_vr_page_state.py +++ b/tools/perf/contrib/vr_benchmarks/shared_android_vr_page_state.py
@@ -5,30 +5,29 @@ import os from core import path_util path_util.AddAndroidPylibToPath() -from page_sets import android_screen_restoration_shared_state as screen_state from pylib.utils import shared_preference_utils from telemetry.core import android_platform from telemetry.core import platform from telemetry.core import util from telemetry.internal.platform import android_device +from telemetry.page import shared_page_state CARDBOARD_PATH = os.path.join('chrome', 'android', 'shared_preference_files', 'test', 'vr_cardboard_skipdon_setupcomplete.json') -class SharedAndroidVrPageState( - screen_state.AndroidScreenRestorationSharedState): +class SharedAndroidVrPageState(shared_page_state.SharedPageState): """SharedPageState for VR Telemetry tests. - Performs the same functionality as SharedPageState, but with two main + Performs the same functionality as SharedPageState, but with three main differences: 1. It is currently restricted to Android 2. It performs VR-specific setup such as installing and configuring additional APKs that are necessary for testing - - Also ensures that the screen is on before the test starts by inheriting from - AndroidScreenRestorationSharedState. + 3. It cycles the screen off then on before each story, similar to how + AndroidScreenRestorationSharedState ensures that the screen is on. See + _CycleScreen() for an explanation on the reasoning behind this. """ def __init__(self, test, finder_options, story_set): # TODO(bsheedy): See about making this a cross-platform SharedVrPageState - @@ -87,6 +86,10 @@ self._platform.InstallApplication( os.path.join(chromium_root, newest_apk_path)) + def WillRunStory(self, page): + super(SharedAndroidVrPageState, self).WillRunStory(page) + self._CycleScreen() + def TearDownState(self): super(SharedAndroidVrPageState, self).TearDownState() # Re-apply Cardboard as the viewer to leave the device in a consistent @@ -95,6 +98,20 @@ self._ConfigureVrCore(os.path.join(path_util.GetChromiumSrcDir(), CARDBOARD_PATH)) + def _CycleScreen(self): + """Cycles the screen off then on. + + This is because VR test devices are set to have normal screen brightness and + automatically turn off after several minutes instead of the usual approach + of having the screen always on at minimum brightness. This is due to the + motion-to-photon latency test being sensitive to screen brightness, and min + brightness does not work well for it. + + Simply using TurnScreenOn does not actually reset the timer for turning off + the screen, so instead cycle the screen to refresh it periodically. + """ + self.platform.android_action_runner.TurnScreenOff() + self.platform.android_action_runner.TurnScreenOn() @property def platform(self):
diff --git a/tools/perf/contrib/vr_benchmarks/webvr_sample_pages.py b/tools/perf/contrib/vr_benchmarks/webvr_sample_pages.py index 797b8504..9c6ca4e 100644 --- a/tools/perf/contrib/vr_benchmarks/webvr_sample_pages.py +++ b/tools/perf/contrib/vr_benchmarks/webvr_sample_pages.py
@@ -18,6 +18,10 @@ def RunPageInteractions(self, action_runner): action_runner.TapElement(selector='canvas[id="webgl-canvas"]') action_runner.MeasureMemory(True) + # We don't want to be in VR or on a page with a WebGL canvas at the end of + # the test, as this generates unnecessary heat while the trace data is being + # processed, so navigate to a blank page. + action_runner.Navigate("about:blank") class WebVrSamplePageSet(story.StorySet):
diff --git a/tools/perf/page_sets/system_health/expectations.py b/tools/perf/page_sets/system_health/expectations.py index 4931117..e85979e 100644 --- a/tools/perf/page_sets/system_health/expectations.py +++ b/tools/perf/page_sets/system_health/expectations.py
@@ -102,10 +102,6 @@ 'load:tools:drive', [expectations.ANDROID_NEXUS5X, expectations.ANDROID_WEBVIEW], 'crbug.com/738854') - self.DisableStory('browse:shopping:lazada', [expectations.ANDROID_NEXUS5], - 'crbug.com/778108') - self.DisableStory('load:tools:weather', [expectations.ANDROID_NEXUS5], - 'crbug.com/778108') self.DisableStory('long_running:tools:gmail-background', [expectations.ANDROID_SVELTE], 'crbug.com/777355') # TODO(rnephew): This disabling should move to CanRunOnBrowser.
diff --git a/tools/perf/perf_device_trigger.py b/tools/perf/perf_device_trigger.py index 7a32a30..109c9a3 100755 --- a/tools/perf/perf_device_trigger.py +++ b/tools/perf/perf_device_trigger.py
@@ -51,8 +51,8 @@ dash_ind = all_args.index('--') return all_args[:dash_ind] + [ - '--dump_json', temp_file, '--dimension', 'id', bot_id] + all_args[ - dash_ind:] + ['--bot', bot_id] + '--dump-json', temp_file, '--dimension', 'id', bot_id] + all_args[ + dash_ind:] + ['--id', bot_id] def trigger_tasks(args, remaining): @@ -75,8 +75,7 @@ try: args_to_pass = modify_args(remaining[:], bot_id, json_temp) - ret = subprocess.call( - sys.executable, [get_swarming_py_path()] + args_to_pass) + ret = subprocess.call([get_swarming_py_path()] + args_to_pass) if ret: sys.stderr.write('Failed to trigger a task, aborting\n') return ret
diff --git a/tools/perf/perf_device_trigger_unittest.py b/tools/perf/perf_device_trigger_unittest.py index 10df3d5f..99bf350 100644 --- a/tools/perf/perf_device_trigger_unittest.py +++ b/tools/perf/perf_device_trigger_unittest.py
@@ -6,7 +6,6 @@ import os import tempfile import unittest -import sys import mock @@ -40,9 +39,8 @@ called_args, keyword = call_mock.call_args self.assertEqual(keyword, {}) - self.assertEqual(called_args[0], sys.executable) - python_args = called_args[1] - json_ind = python_args.index('--dump_json') + python_args = called_args[0] + json_ind = python_args.index('--dump-json') # Remove --dump_json and its arg python_args.pop(json_ind) temp_json_path = python_args.pop(json_ind) @@ -59,7 +57,7 @@ '/path/to/swarming.py', 'trigger', '--some', '--test', '--dimension', 'id', 'build1', '--', - 'args', '--bot', 'build1']) + 'args', '--id', 'build1']) finally: os.close(temp_fd) os.remove(json_temp)
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc index 4f2058939..47b0f4ab 100644 --- a/ui/accessibility/ax_event_generator.cc +++ b/ui/accessibility/ax_event_generator.cc
@@ -281,6 +281,7 @@ void AXEventGenerator::OnNodeWillBeReparented(AXTree* tree, AXNode* node) { DCHECK_EQ(tree_, tree); + tree_events_.erase(node); } void AXEventGenerator::OnSubtreeWillBeReparented(AXTree* tree, AXNode* node) {
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index 1eec1a5..75e7b64 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h
@@ -117,11 +117,11 @@ // Converts |point| from the root window's coordinate system to the // host window's. - void ConvertDIPToPixels(gfx::Point* point) const; + virtual void ConvertDIPToPixels(gfx::Point* point) const; // Converts |point| from the host window's coordinate system to the // root window's. - void ConvertPixelsToDIP(gfx::Point* point) const; + virtual void ConvertPixelsToDIP(gfx::Point* point) const; // Cursor. // Sets the currently-displayed cursor. If the cursor was previously hidden
diff --git a/ui/display/manager/chromeos/display_configurator.h b/ui/display/manager/chromeos/display_configurator.h index 46744ef..e5a815d 100644 --- a/ui/display/manager/chromeos/display_configurator.h +++ b/ui/display/manager/chromeos/display_configurator.h
@@ -110,6 +110,9 @@ // Called when the hardware mirroring failed. virtual void SetSoftwareMirroring(bool enabled) = 0; + + // Returns true when software mirroring mode is requested, but it does + // not guarantee that the mode is active. virtual bool SoftwareMirroringEnabled() const = 0; };
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc index 89732c2..8b96f5ba 100644 --- a/ui/display/manager/display_manager.cc +++ b/ui/display/manager/display_manager.cc
@@ -194,6 +194,54 @@ return true; } +// Returns a pointer to the ManagedDisplayInfo of the display with |id|, nullptr +// if the corresponding info was not found. +const ManagedDisplayInfo* FindInfoById(const DisplayInfoList& display_info_list, + int64_t id) { + const auto iter = std::find_if( + display_info_list.begin(), display_info_list.end(), + [id](const ManagedDisplayInfo& info) { return info.id() == id; }); + + if (iter == display_info_list.end()) + return nullptr; + + return &(*iter); +} + +// Validates that: +// - All display IDs in the |matrix| are included in the |display_info_list|, +// - All IDs in |display_info_list| exist in the |matrix|, +// - All IDs in the matrix are unique (no repeated IDs). +bool ValidateMatrixForDisplayInfoList( + const DisplayInfoList& display_info_list, + const UnifiedDesktopLayoutMatrix& matrix) { + std::set<int64_t> matrix_ids; + for (const auto& row : matrix) { + for (const auto& id : row) { + if (!matrix_ids.emplace(id).second) { + LOG(ERROR) << "Matrix has a repeated ID: " << id; + return false; + } + + if (!FindInfoById(display_info_list, id)) { + LOG(ERROR) << "Matrix has ID: " << id << " with no corresponding info " + << "in the display info list."; + return false; + } + } + } + + for (const auto& info : display_info_list) { + if (!matrix_ids.count(info.id())) { + LOG(ERROR) << "Display info with ID: " << info.id() << " doesn't exist " + << "in the layout matrix."; + return false; + } + } + + return true; +} + } // namespace DisplayManager::BeginEndNotifier::BeginEndNotifier( @@ -304,21 +352,34 @@ } DisplayIdList DisplayManager::GetCurrentDisplayIdList() const { - if (IsInUnifiedMode()) { + if (IsInUnifiedMode()) return CreateDisplayIdList(software_mirroring_display_list_); - } else if (IsInMirrorMode()) { - if (software_mirroring_enabled()) { - CHECK_EQ(2u, num_connected_displays()); - // This comment is to make it easy to distinguish the crash - // between two checks. - CHECK_EQ(1u, active_display_list_.size()); - } - int64_t ids[] = {active_display_list_[0].id(), mirroring_display_id_}; - return GenerateDisplayIdList(std::begin(ids), std::end(ids)); - } else { - CHECK_LE(2u, active_display_list_.size()); - return CreateDisplayIdList(active_display_list_); + + DisplayIdList display_id_list = CreateDisplayIdList(active_display_list_); + + if (IsInSoftwareMirrorMode()) { + CHECK_EQ(2u, num_connected_displays()); + // This comment is to make it easy to distinguish the crash + // between two checks. + CHECK_EQ(1u, active_display_list_.size()); + + DisplayIdList software_mirroring_display_id_list = + CreateDisplayIdList(software_mirroring_display_list_); + display_id_list.insert(display_id_list.end(), + software_mirroring_display_id_list.begin(), + software_mirroring_display_id_list.end()); + return display_id_list; } + + if (IsInHardwareMirrorMode()) { + display_id_list.insert(display_id_list.end(), + hardware_mirroring_display_id_list_.begin(), + hardware_mirroring_display_id_list_.end()); + return display_id_list; + } + + CHECK_LE(2u, active_display_list_.size()); + return display_id_list; } void DisplayManager::SetLayoutForCurrentDisplays( @@ -666,42 +727,52 @@ << ", [1]=" << updated_displays[1].ToString(); first_display_id_ = updated_displays[0].id(); - std::set<gfx::Point> origins; + std::map<gfx::Point, int64_t> origins; bool internal_display_connected = false; num_connected_displays_ = updated_displays.size(); - mirroring_display_id_ = kInvalidDisplayId; - software_mirroring_display_list_.clear(); + ClearMirroringSourceAndDestination(); DisplayInfoList new_display_info_list; - for (DisplayInfoList::const_iterator iter = updated_displays.begin(); - iter != updated_displays.end(); ++iter) { + for (const auto& display_info : updated_displays) { if (!internal_display_connected) - internal_display_connected = Display::IsInternalDisplayId(iter->id()); + internal_display_connected = + Display::IsInternalDisplayId(display_info.id()); // Mirrored monitors have the same origins. - gfx::Point origin = iter->bounds_in_native().origin(); - if (origins.find(origin) != origins.end()) { - InsertAndUpdateDisplayInfo(*iter); - mirroring_display_id_ = iter->id(); + gfx::Point origin = display_info.bounds_in_native().origin(); + const auto iter = origins.find(origin); + if (iter != origins.end()) { + InsertAndUpdateDisplayInfo(display_info); + if (hardware_mirroring_display_id_list_.empty()) { + // Unlike software mirroring, hardware mirroring has no source and + // target. All mirroring displays scan the same frame buffer. But for + // convenience, we treat the first mirroring display as source. + mirroring_source_id_ = iter->second; + } + // Only keep the first hardware mirroring display in + // |new_display_info_list| because hardware mirroring is not visible for + // display manager and all hardware mirroring displays should be treated + // as one single display from this point. + hardware_mirroring_display_id_list_.emplace_back(display_info.id()); } else { - origins.insert(origin); - new_display_info_list.push_back(*iter); + origins.emplace(origin, display_info.id()); + new_display_info_list.emplace_back(display_info); } - ManagedDisplayMode new_mode(iter->bounds_in_native().size(), - 0.0 /* refresh rate */, false /* interlaced */, - false /* native */, iter->configured_ui_scale(), - iter->device_scale_factor()); + ManagedDisplayMode new_mode( + display_info.bounds_in_native().size(), 0.0 /* refresh rate */, + false /* interlaced */, false /* native */, + display_info.configured_ui_scale(), display_info.device_scale_factor()); const ManagedDisplayInfo::ManagedDisplayModeList& display_modes = - iter->display_modes(); + display_info.display_modes(); // This is empty the displays are initialized from InitFromCommandLine. if (display_modes.empty()) continue; - auto display_modes_iter = FindDisplayMode(*iter, new_mode); + auto display_modes_iter = FindDisplayMode(display_info, new_mode); // Update the actual resolution selected as the resolution request may fail. if (display_modes_iter == display_modes.end()) - display_modes_.erase(iter->id()); - else if (display_modes_.find(iter->id()) != display_modes_.end()) - display_modes_[iter->id()] = *display_modes_iter; + display_modes_.erase(display_info.id()); + else if (display_modes_.find(display_info.id()) != display_modes_.end()) + display_modes_[display_info.id()] = *display_modes_iter; } if (Display::HasInternalDisplay() && !internal_display_connected) { if (display_info_.find(Display::InternalDisplayId()) == @@ -989,7 +1060,47 @@ } bool DisplayManager::IsInMirrorMode() const { - return mirroring_display_id_ != kInvalidDisplayId; + // Either software or hardware mirror mode can be active at the same time. + DCHECK(!IsInSoftwareMirrorMode() || !IsInHardwareMirrorMode()); + return IsInSoftwareMirrorMode() || IsInHardwareMirrorMode(); +} + +bool DisplayManager::IsInSoftwareMirrorMode() const { + if (multi_display_mode_ != MIRRORING || + software_mirroring_display_list_.empty()) { + return false; + } + + // Software mirroring cannot coexist with hardware mirroring. + DCHECK(hardware_mirroring_display_id_list_.empty()); + return true; +} + +bool DisplayManager::IsInHardwareMirrorMode() const { + if (hardware_mirroring_display_id_list_.empty()) + return false; + + // Hardware mirroring is not visible to the display manager, the display mode + // should be EXTENDED. + DCHECK(multi_display_mode_ == EXTENDED); + + // Hardware mirroring cannot coexist with software mirroring. + DCHECK(software_mirroring_display_list_.empty()); + return true; +} + +DisplayIdList DisplayManager::GetMirroringDstDisplayIdList() const { + if (IsInSoftwareMirrorMode()) + return CreateDisplayIdList(software_mirroring_display_list_); + if (IsInHardwareMirrorMode()) + return hardware_mirroring_display_id_list_; + return DisplayIdList(); +} + +void DisplayManager::ClearMirroringSourceAndDestination() { + mirroring_source_id_ = kInvalidDisplayId; + hardware_mirroring_display_id_list_.clear(); + software_mirroring_display_list_.clear(); } void DisplayManager::SetUnifiedDesktopEnabled(bool enable) { @@ -1006,6 +1117,33 @@ !software_mirroring_display_list_.empty(); } +void DisplayManager::SetUnifiedDesktopMatrix( + const UnifiedDesktopLayoutMatrix& matrix) { + current_matrix_ = matrix; + SetDefaultMultiDisplayModeForCurrentDisplays(UNIFIED); +} + +const Display* DisplayManager::GetPrimaryMirroringDisplayForUnifiedDesktop() + const { + if (!IsInUnifiedMode()) + return nullptr; + + return &software_mirroring_display_list_[0]; +} + +int DisplayManager::GetMirroringDisplayRowIndexInUnifiedMatrix( + int64_t display_id) const { + DCHECK(IsInUnifiedMode()); + + return mirroring_display_id_to_unified_matrix_row_.at(display_id); +} + +int DisplayManager::GetUnifiedDesktopRowMaxHeight(int row_index) const { + DCHECK(IsInUnifiedMode()); + + return unified_display_rows_heights_.at(row_index); +} + const ManagedDisplayInfo& DisplayManager::GetDisplayInfo( int64_t display_id) const { DCHECK_NE(kInvalidDisplayId, display_id); @@ -1082,8 +1220,7 @@ host_bounds.bottom() + kVerticalOffsetPx, host_bounds.height()))); } num_connected_displays_ = new_display_info_list.size(); - mirroring_display_id_ = kInvalidDisplayId; - software_mirroring_display_list_.clear(); + ClearMirroringSourceAndDestination(); UpdateDisplaysWith(new_display_info_list); } @@ -1108,7 +1245,7 @@ } bool DisplayManager::SoftwareMirroringEnabled() const { - return software_mirroring_enabled(); + return multi_display_mode_ == MIRRORING; } void DisplayManager::SetTouchCalibrationData( @@ -1186,8 +1323,7 @@ void DisplayManager::SetMultiDisplayMode(MultiDisplayMode mode) { multi_display_mode_ = mode; - mirroring_display_id_ = kInvalidDisplayId; - software_mirroring_display_list_.clear(); + ClearMirroringSourceAndDestination(); } void DisplayManager::ReconfigureDisplays() { @@ -1199,8 +1335,7 @@ } for (const Display& display : software_mirroring_display_list_) display_info_list.push_back(GetDisplayInfo(display.id())); - mirroring_display_id_ = kInvalidDisplayId; - software_mirroring_display_list_.clear(); + ClearMirroringSourceAndDestination(); UpdateDisplaysWith(display_info_list); } @@ -1210,8 +1345,14 @@ return false; display_info_[display_id].SetBounds(new_bounds); // Don't notify observers if the mirrored window has changed. - if (software_mirroring_enabled() && mirroring_display_id_ == display_id) + if (IsInSoftwareMirrorMode() && + std::find_if(software_mirroring_display_list_.begin(), + software_mirroring_display_list_.end(), + [display_id](const Display& display) { + return display.id() == display_id; + }) != software_mirroring_display_list_.end()) { return false; + } // In unified mode then |active_display_list_| won't have a display for // |display_id| but |software_mirroring_display_list_| should. Reconfigure @@ -1307,134 +1448,261 @@ case MIRRORING: { if (display_info_list->size() != 2) return; - bool zero_is_source = - first_display_id_ == (*display_info_list)[0].id() || - Display::IsInternalDisplayId((*display_info_list)[0].id()); - DCHECK_EQ(MIRRORING, multi_display_mode_); - mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); - int64_t display_id = mirroring_display_id_; - auto iter = - std::find_if(display_info_list->begin(), display_info_list->end(), - [display_id](const ManagedDisplayInfo& info) { - return info.id() == display_id; - }); - DCHECK(iter != display_info_list->end()); - - ManagedDisplayInfo info = *iter; - info.SetOverscanInsets(gfx::Insets()); - InsertAndUpdateDisplayInfo(info); - software_mirroring_display_list_.push_back( - CreateMirroringDisplayFromDisplayInfoById(mirroring_display_id_, - gfx::Point(), 1.0f)); - display_info_list->erase(iter); - break; - } - case UNIFIED: { - if (display_info_list->size() == 1) - return; - // TODO(oshima): Currently, all displays are laid out horizontally, - // from left to right. Allow more flexible layouts, such as - // right to left, or vertical layouts. - gfx::Rect unified_bounds; - software_mirroring_display_list_.clear(); - // 1st Pass. Find the max size. - int max_height = std::numeric_limits<int>::min(); - - int default_height = 0; - float default_device_scale_factor = 1.0f; - for (auto& info : *display_info_list) { - max_height = std::max(max_height, info.size_in_pixel().height()); - if (!default_height || Display::IsInternalDisplayId(info.id())) { - default_height = info.size_in_pixel().height(); - default_device_scale_factor = info.device_scale_factor(); + int64_t source_id = kInvalidDisplayId; + if (Display::HasInternalDisplay()) { + // Use the internal display as mirroring source. + source_id = Display::InternalDisplayId(); + auto iter = + std::find_if(display_info_list->begin(), display_info_list->end(), + [source_id](const ManagedDisplayInfo& info) { + return info.id() == source_id; + }); + if (iter == display_info_list->end()) { + // It is possible that internal display is removed (e.g. Use + // Chromebook in Dock mode with two or more external displays). In + // this case, we use the first connected display as mirroring source. + source_id = first_display_id_; } - } - - ManagedDisplayInfo::ManagedDisplayModeList display_mode_list; - std::set<std::pair<float, float>> dsf_scale_list; - - // 2nd Pass. Compute the unified display size. - for (auto& info : *display_info_list) { - InsertAndUpdateDisplayInfo(info); - gfx::Point origin(unified_bounds.right(), 0); - float scale = - info.size_in_pixel().height() / static_cast<float>(max_height); - // The display is scaled to fit the unified desktop size. - Display display = CreateMirroringDisplayFromDisplayInfoById( - info.id(), origin, 1.0f / scale); - unified_bounds.Union(display.bounds()); - - dsf_scale_list.insert( - std::make_pair(info.device_scale_factor(), scale)); - } - - ManagedDisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false); - - ManagedDisplayMode native_mode(unified_bounds.size(), 60.0f, false, true, - 1.0, 1.0); - ManagedDisplayInfo::ManagedDisplayModeList modes = - CreateUnifiedManagedDisplayModeList(native_mode, dsf_scale_list); - - // Find the default mode. - auto iter = std::find_if( - modes.begin(), modes.end(), - [default_height, - default_device_scale_factor](const ManagedDisplayMode& mode) { - return mode.size().height() == default_height && - mode.device_scale_factor() == default_device_scale_factor; - }); - - ManagedDisplayMode dm(*iter); - *iter = ManagedDisplayMode(dm.size(), dm.refresh_rate(), - dm.is_interlaced(), true /* native */, - dm.ui_scale(), dm.device_scale_factor()); - - info.SetManagedDisplayModes(modes); - info.set_device_scale_factor(dm.device_scale_factor()); - info.SetBounds(gfx::Rect(dm.size())); - - // Forget the configured resolution if the original unified - // desktop resolution has changed. - if (display_info_.count(kUnifiedDisplayId) != 0 && - GetMaxNativeSize(display_info_[kUnifiedDisplayId]) != - unified_bounds.size()) { - display_modes_.erase(kUnifiedDisplayId); - } - - // 3rd Pass. Set the selected mode, then recompute the mirroring - // display size. - ManagedDisplayMode mode; - if (GetSelectedModeForDisplayId(kUnifiedDisplayId, &mode) && - FindDisplayMode(info, mode) != info.display_modes().end()) { - info.set_device_scale_factor(mode.device_scale_factor()); - info.SetBounds(gfx::Rect(mode.size())); } else { - display_modes_.erase(kUnifiedDisplayId); + // Use the first connected display as mirroring source + source_id = first_display_id_; } + DCHECK(source_id != kInvalidDisplayId); - int unified_display_height = info.size_in_pixel().height(); - gfx::Point origin; for (auto& info : *display_info_list) { - float display_scale = info.size_in_pixel().height() / - static_cast<float>(unified_display_height); - Display display = CreateMirroringDisplayFromDisplayInfoById( - info.id(), origin, 1.0f / display_scale); - origin.Offset(display.size().width(), 0); - display.UpdateWorkAreaFromInsets(gfx::Insets()); - software_mirroring_display_list_.push_back(display); + if (source_id == info.id()) + continue; + info.SetOverscanInsets(gfx::Insets()); + InsertAndUpdateDisplayInfo(info); + software_mirroring_display_list_.emplace_back( + CreateMirroringDisplayFromDisplayInfoById(info.id(), gfx::Point(), + 1.0f)); } - display_info_list->clear(); - display_info_list->push_back(info); - InsertAndUpdateDisplayInfo(info); + // Remove all destination displays. + display_info_list->erase( + std::remove_if(display_info_list->begin(), display_info_list->end(), + [source_id](const ManagedDisplayInfo& info) { + return info.id() != source_id; + }), + display_info_list->end()); + mirroring_source_id_ = source_id; break; } + case UNIFIED: + CreateUnifiedDesktopDisplayInfo(display_info_list); + break; + case EXTENDED: break; } } +void DisplayManager::CreateUnifiedDesktopDisplayInfo( + DisplayInfoList* display_info_list) { + if (display_info_list->size() == 1) + return; + + if (!ValidateMatrix(current_matrix_) || + !ValidateMatrixForDisplayInfoList(*display_info_list, current_matrix_)) { + // Recreate the default matrix where displays are laid out horizontally from + // left to right. + current_matrix_.clear(); + current_matrix_.resize(1); + for (const auto& info : *display_info_list) + current_matrix_[0].emplace_back(info.id()); + } + + software_mirroring_display_list_.clear(); + mirroring_display_id_to_unified_matrix_row_.clear(); + unified_display_rows_heights_.clear(); + + const size_t num_rows = current_matrix_.size(); + const size_t num_columns = current_matrix_[0].size(); + + // 1 - Find the maximum height per each row. + std::vector<int> rows_max_heights; + rows_max_heights.reserve(num_rows); + for (const auto& row : current_matrix_) { + int max_height = std::numeric_limits<int>::min(); + for (const auto& id : row) { + const ManagedDisplayInfo* info = FindInfoById(*display_info_list, id); + DCHECK(info); + + max_height = std::max(max_height, info->size_in_pixel().height()); + } + rows_max_heights.emplace_back(max_height); + } + + // 2 - Use the maximum height per each row to calculate the scale value for + // each display in each row so that it fits the max row height. Use that + // to calculate the total bounds of each row after all displays has been + // scaled. + + // Holds the scale value of each display in the matrix. + std::vector<std::vector<float>> scales; + scales.resize(num_rows); + + // Holds the total bounds of each row in the matrix. + std::vector<gfx::Rect> rows_bounds; + rows_bounds.reserve(num_rows); + + // Calculate the bounds of each row, and the maximum row width. + int max_total_width = std::numeric_limits<int>::min(); + for (size_t i = 0; i < num_rows; ++i) { + const auto& row = current_matrix_[i]; + const int max_row_height = rows_max_heights[i]; + gfx::Rect this_row_bounds; + scales[i].resize(num_columns); + for (size_t j = 0; j < num_columns; ++j) { + const auto& id = row[j]; + const ManagedDisplayInfo* info = FindInfoById(*display_info_list, id); + DCHECK(info); + + InsertAndUpdateDisplayInfo(*info); + const float scale = + info->size_in_pixel().height() / static_cast<float>(max_row_height); + scales[i][j] = scale; + + const gfx::Point origin(this_row_bounds.right(), 0); + const auto display_bounds = gfx::Rect( + origin, gfx::ScaleToFlooredSize(info->size_in_pixel(), 1.0f / scale)); + this_row_bounds.Union(display_bounds); + } + rows_bounds.emplace_back(this_row_bounds); + max_total_width = std::max(max_total_width, this_row_bounds.width()); + } + + // 3 - Using the maximum row width, adjust the display scales so that each + // row width fits the maximum row width. + for (size_t i = 0; i < num_rows; ++i) { + const auto& row_bound = rows_bounds[i]; + const float scale = row_bound.width() / static_cast<float>(max_total_width); + auto& row_scales = scales[i]; + for (auto& display_scale : row_scales) + display_scale *= scale; + } + + // 4 - Now that we know the final scales, compute the unified display size by + // computing the unified display size of each row and then getting the + // union of all rows. + gfx::Rect unified_bounds; // Will hold the final unified bounds. + std::vector<UnifiedDisplayModeParam> modes_param_list; + modes_param_list.reserve(num_rows * num_columns); + int internal_display_index = -1; + for (size_t i = 0; i < num_rows; ++i) { + const auto& row = current_matrix_[i]; + gfx::Rect row_displays_bounds; + for (size_t j = 0; j < num_columns; ++j) { + const auto& id = row[j]; + if (internal_display_index == -1 && Display::IsInternalDisplayId(id)) + internal_display_index = i * num_columns + j; + + const ManagedDisplayInfo* info = FindInfoById(*display_info_list, id); + DCHECK(info); + + const float scale = scales[i][j]; + const gfx::Point origin(row_displays_bounds.right(), + unified_bounds.bottom()); + // The display is scaled to fit the unified desktop size. + Display display = + CreateMirroringDisplayFromDisplayInfoById(id, origin, 1.0f / scale); + + row_displays_bounds.Union(display.bounds()); + modes_param_list.emplace_back(info->device_scale_factor(), scale, false); + software_mirroring_display_list_.emplace_back(display); + } + + unified_bounds.Union(row_displays_bounds); + } + + // The index of the display that will be used for the default native mode. + const int default_mode_param_index = + internal_display_index != -1 ? internal_display_index : 0; + modes_param_list[default_mode_param_index].is_default_mode = true; + + // 5 - Create the Unified display info and its modes. + ManagedDisplayInfo unified_display_info(kUnifiedDisplayId, "Unified Desktop", + false /* has_overscan */); + ManagedDisplayMode native_mode(unified_bounds.size(), 60.0f, false, true, 1.0, + 1.0); + ManagedDisplayInfo::ManagedDisplayModeList modes = + CreateUnifiedManagedDisplayModeList(native_mode, modes_param_list); + + // Find the default mode. + auto default_mode_iter = + std::find_if(modes.begin(), modes.end(), + [](const ManagedDisplayMode mode) { return mode.native(); }); + DCHECK(default_mode_iter != modes.end()); + + if (default_mode_iter != modes.end()) { + const ManagedDisplayMode& default_mode = *default_mode_iter; + unified_display_info.set_device_scale_factor( + default_mode.device_scale_factor()); + unified_display_info.SetBounds(gfx::Rect(default_mode.size())); + } + + unified_display_info.SetManagedDisplayModes(modes); + + // Forget the configured resolution if the original unified desktop resolution + // has changed. + if (display_info_.count(kUnifiedDisplayId) != 0 && + GetMaxNativeSize(display_info_[kUnifiedDisplayId]) != + unified_bounds.size()) { + display_modes_.erase(kUnifiedDisplayId); + } + + // 6 - Set the selected mode. + ManagedDisplayMode selected_mode; + if (GetSelectedModeForDisplayId(kUnifiedDisplayId, &selected_mode) && + FindDisplayMode(unified_display_info, selected_mode) != + unified_display_info.display_modes().end()) { + unified_display_info.set_device_scale_factor( + selected_mode.device_scale_factor()); + unified_display_info.SetBounds(gfx::Rect(selected_mode.size())); + } else { + display_modes_.erase(kUnifiedDisplayId); + } + + const float unified_bounds_scale_y = + unified_display_info.size_in_pixel().height() / + static_cast<float>(unified_bounds.size().height()); + + // 7 - Now that we know the final unified display bounds, update the displays + // in the |software_mirroring_display_list_| list so that they have the + // correct bounds. + DCHECK_EQ(num_rows * num_columns, software_mirroring_display_list_.size()); + int last_bottom = 0; + for (size_t i = 0; i < num_rows; ++i) { + int last_right = 0; + int max_height = std::numeric_limits<int>::min(); + for (size_t j = 0; j < num_columns; ++j) { + Display& current_display = + software_mirroring_display_list_[i * num_columns + j]; + gfx::SizeF scaled_size(current_display.bounds().size()); + scaled_size.Scale(unified_bounds_scale_y); + const gfx::Point origin(last_right, last_bottom); + current_display.set_bounds( + gfx::Rect(origin, gfx::ToRoundedSize(scaled_size))); + current_display.UpdateWorkAreaFromInsets(gfx::Insets()); + const gfx::Rect display_bounds = current_display.bounds(); + max_height = std::max(max_height, display_bounds.height()); + last_right = display_bounds.right(); + mirroring_display_id_to_unified_matrix_row_[current_display.id()] = i; + } + + unified_display_rows_heights_.emplace_back(max_height); + last_bottom += max_height; + } + + DCHECK_EQ(num_rows, unified_display_rows_heights_.size()); + + display_info_list->clear(); + display_info_list->emplace_back(unified_display_info); + InsertAndUpdateDisplayInfo(unified_display_info); +} + Display* DisplayManager::FindDisplayForId(int64_t id) { auto iter = std::find_if(active_display_list_.begin(), active_display_list_.end(), @@ -1450,10 +1718,11 @@ void DisplayManager::AddMirrorDisplayInfoIfAny( DisplayInfoList* display_info_list) { - if (software_mirroring_enabled() && IsInMirrorMode()) { - display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); - software_mirroring_display_list_.clear(); - } + if (!IsInSoftwareMirrorMode()) + return; + for (const auto& display : software_mirroring_display_list_) + display_info_list->emplace_back(GetDisplayInfo(display.id())); + software_mirroring_display_list_.clear(); } void DisplayManager::InsertAndUpdateDisplayInfo(
diff --git a/ui/display/manager/display_manager.h b/ui/display/manager/display_manager.h index f5d6835..bb2f12e1 100644 --- a/ui/display/manager/display_manager.h +++ b/ui/display/manager/display_manager.h
@@ -26,6 +26,7 @@ #include "ui/display/manager/display_manager_export.h" #include "ui/display/manager/managed_display_info.h" #include "ui/display/types/display_constants.h" +#include "ui/display/unified_desktop_utils.h" #if defined(OS_CHROMEOS) #include "base/optional.h" @@ -289,13 +290,31 @@ // mirrored. size_t num_connected_displays() const { return num_connected_displays_; } - // Returns the mirroring status. + // Returns true if either software or hardware mirror mode is active. bool IsInMirrorMode() const; - int64_t mirroring_display_id() const { return mirroring_display_id_; } + + // Returns true if software mirror mode is active. Note that when + // SoftwareMirroringEnabled() returns true, it only means software mirroring + // mode is requested, but it does not guarantee that the mode is active. The + // mode will be active after UpdateDisplaysWith() is called. + bool IsInSoftwareMirrorMode() const; + + // Returns true if hardware mirror mode is active. + bool IsInHardwareMirrorMode() const; + + int64_t mirroring_source_id() const { return mirroring_source_id_; } + + // Returns a list of mirroring destination display ids. + DisplayIdList GetMirroringDstDisplayIdList() const; + const Displays& software_mirroring_display_list() const { return software_mirroring_display_list_; } + // Remove mirroring source and destination displays, so that they will be + // updated when UpdateDisplaysWith() is called. + void ClearMirroringSourceAndDestination(); + // Sets/gets if the unified desktop feature is enabled. void SetUnifiedDesktopEnabled(bool enabled); bool unified_desktop_enabled() const { return unified_desktop_enabled_; } @@ -303,6 +322,24 @@ // Returns true if it's in unified desktop mode. bool IsInUnifiedMode() const; + // Sets the Unified Desktop layout using the given |matrix| and sets the + // current mode to Unified Desktop. + void SetUnifiedDesktopMatrix(const UnifiedDesktopLayoutMatrix& matrix); + + // In Unified Desktop mode, we consider the first mirroring display to be the + // primary. It's also the top-left display in the layout matrix, and it's + // where the shelf is placed. + // This returns nullptr if we're not in unified desktop mode. + const Display* GetPrimaryMirroringDisplayForUnifiedDesktop() const; + + // Returns the index of the row in the Unified Mode layout matrix which + // contains the display with |display_id|. + int GetMirroringDisplayRowIndexInUnifiedMatrix(int64_t display_id) const; + + // Returns the maximum display height of the row with |row_index| in the + // Unified Mode layout matrix. + int GetUnifiedDesktopRowMaxHeight(int row_index) const; + // Returns the display used for software mirrroring. Returns invalid display // if not found. const Display GetMirroringDisplayById(int64_t id) const; @@ -408,10 +445,6 @@ DISALLOW_COPY_AND_ASSIGN(BeginEndNotifier); }; - bool software_mirroring_enabled() const { - return multi_display_mode_ == MIRRORING; - } - void set_change_display_upon_host_resize(bool value) { change_display_upon_host_resize_ = value; } @@ -420,10 +453,13 @@ // mirror the content is removed from the |display_info_list|. void CreateSoftwareMirroringDisplayInfo(DisplayInfoList* display_info_list); + // Same as above but for Unified Desktop. + void CreateUnifiedDesktopDisplayInfo(DisplayInfoList* display_info_list); + Display* FindDisplayForId(int64_t id); // Add the mirror display's display info if the software based mirroring is in - // use. + // use. This should only be called before UpdateDisplaysWith(). void AddMirrorDisplayInfoIfAny(DisplayInfoList* display_info_list); // Inserts and update the ManagedDisplayInfo according to the overscan state. @@ -475,6 +511,13 @@ std::unique_ptr<DisplayLayout> current_resolved_layout_; + // The matrix that's used to layout the displays in Unified Desktop mode. + UnifiedDesktopLayoutMatrix current_matrix_; + + std::map<int64_t, int> mirroring_display_id_to_unified_matrix_row_; + + std::vector<int> unified_display_rows_heights_; + int64_t first_display_id_ = kInvalidDisplayId; // List of current active displays. @@ -508,14 +551,25 @@ MultiDisplayMode multi_display_mode_ = EXTENDED; MultiDisplayMode current_default_multi_display_mode_ = EXTENDED; - // When mirroring is enabled this is the id of the destination display. - int64_t mirroring_display_id_ = kInvalidDisplayId; + // This is used in two distinct ways: + // 1. The source display id when software mirroring is active. + // 2. There's no source and destination display in hardware mirroring, so we + // treat the first mirroring display id as source id when hardware mirroring + // is active. + int64_t mirroring_source_id_ = kInvalidDisplayId; // This is used in two distinct ways: - // 1. when mirroring is enabled this contains the destination display. + // 1. when software mirroring is active this contains the destination + // displays. // 2. when unified mode is enabled this is the set of physical displays. Displays software_mirroring_display_list_; + // There's no source and destination display in hardware mirroring, so we + // treat the first mirroring display as source and store its id in + // |mirroring_source_id_| and treat the rest of mirroring displays as + // destination and store their ids in this list. + DisplayIdList hardware_mirroring_display_id_list_; + // Cached mirror mode for metrics changed notification. bool mirror_mode_for_metrics_ = false;
diff --git a/ui/display/manager/display_manager_utilities.cc b/ui/display/manager/display_manager_utilities.cc index 4dcaf859..7bb973db 100644 --- a/ui/display/manager/display_manager_utilities.cc +++ b/ui/display/manager/display_manager_utilities.cc
@@ -5,7 +5,6 @@ #include "ui/display/manager/display_manager_utilities.h" #include <algorithm> -#include <vector> #include "base/sys_info.h" #include "ui/display/manager/managed_display_info.h" @@ -115,19 +114,27 @@ return display_mode_list; } +UnifiedDisplayModeParam::UnifiedDisplayModeParam(float dsf, + float scale, + bool is_default) + : device_scale_factor(dsf), + display_bounds_scale(scale), + is_default_mode(is_default) {} + ManagedDisplayInfo::ManagedDisplayModeList CreateUnifiedManagedDisplayModeList( const ManagedDisplayMode& native_mode, - const std::set<std::pair<float, float>>& dsf_scale_list) { + const std::vector<UnifiedDisplayModeParam>& modes_param_list) { ManagedDisplayInfo::ManagedDisplayModeList display_mode_list; + display_mode_list.reserve(modes_param_list.size()); - for (auto& pair : dsf_scale_list) { + for (auto& param : modes_param_list) { gfx::SizeF scaled_size(native_mode.size()); - scaled_size.Scale(pair.second); - ManagedDisplayMode mode( + scaled_size.Scale(param.display_bounds_scale); + display_mode_list.emplace_back( gfx::ToFlooredSize(scaled_size), native_mode.refresh_rate(), - native_mode.is_interlaced(), false /* native */, native_mode.ui_scale(), - pair.first /* device_scale_factor */); - display_mode_list.push_back(mode); + native_mode.is_interlaced(), + param.is_default_mode ? true : false /* native */, + native_mode.ui_scale(), param.device_scale_factor); } // Sort the mode by the size in DIP. std::sort(display_mode_list.begin(), display_mode_list.end(),
diff --git a/ui/display/manager/display_manager_utilities.h b/ui/display/manager/display_manager_utilities.h index d7e71bb..d0cc7ef 100644 --- a/ui/display/manager/display_manager_utilities.h +++ b/ui/display/manager/display_manager_utilities.h
@@ -5,7 +5,7 @@ #ifndef UI_DISPLAY_MANAGER_DISPLAY_MANAGER_UTILITIES_H_ #define UI_DISPLAY_MANAGER_DISPLAY_MANAGER_UTILITIES_H_ -#include <set> +#include <vector> #include "ui/display/display.h" #include "ui/display/display_layout.h" @@ -26,12 +26,24 @@ DISPLAY_MANAGER_EXPORT ManagedDisplayInfo::ManagedDisplayModeList CreateInternalManagedDisplayModeList(const ManagedDisplayMode& native_mode); +// Defines parameters needed to construct a ManagedDisplayMode for Unified +// Desktop. +struct UnifiedDisplayModeParam { + UnifiedDisplayModeParam(float dsf, float scale, bool is_default); + + float device_scale_factor = 1.0f; + + float display_bounds_scale = 1.0f; + + bool is_default_mode = false; +}; + // Creates the display mode list for unified display // based on |native_mode| and |scales|. DISPLAY_MANAGER_EXPORT ManagedDisplayInfo::ManagedDisplayModeList CreateUnifiedManagedDisplayModeList( const ManagedDisplayMode& native_mode, - const std::set<std::pair<float, float>>& dsf_scale_list); + const std::vector<UnifiedDisplayModeParam>& modes_param_list); // Tests if the |info| has display mode that matches |ui_scale|. bool HasDisplayModeForUIScale(const ManagedDisplayInfo& info, float ui_scale);
diff --git a/ui/display/unified_desktop_utils.cc b/ui/display/unified_desktop_utils.cc index 6eeed760..55b7784 100644 --- a/ui/display/unified_desktop_utils.cc +++ b/ui/display/unified_desktop_utils.cc
@@ -166,14 +166,23 @@ return matrix; } -// Validates that the given |matrix| is neither empty nor have holes (empty -// display IDs) in it. +} // namespace + bool ValidateMatrix(const UnifiedDesktopLayoutMatrix& matrix) { if (matrix.empty()) return false; - // No holes are allowed. + const size_t column_count = matrix[0].size(); + if (column_count == 0) + return false; + for (const auto& row : matrix) { + if (row.size() != column_count) { + LOG(ERROR) << "Wrong matrix dimensions. Unequal rows sizes."; + return false; + } + + // No holes or repeated IDs are allowed. for (const auto& id : row) { if (id == display::kInvalidDisplayId) { LOG(ERROR) << "Unified Desktop layout matrix has an empty cell in it."; @@ -185,8 +194,6 @@ return true; } -} // namespace - bool BuildUnifiedDesktopMatrix(const DisplayIdList& ids_list, const DisplayLayout& layout, UnifiedDesktopLayoutMatrix* out_matrix) {
diff --git a/ui/display/unified_desktop_utils.h b/ui/display/unified_desktop_utils.h index 0fa545bc..7c120e0 100644 --- a/ui/display/unified_desktop_utils.h +++ b/ui/display/unified_desktop_utils.h
@@ -17,6 +17,12 @@ // display is desired to be placed in the actual layout. using UnifiedDesktopLayoutMatrix = std::vector<std::vector<int64_t>>; +// Validates that: +// - The matrix is not empty. +// - There are no holes (empty display IDs) in the matrix. +// - All matrix rows have equal non-zero widths. +bool DISPLAY_EXPORT ValidateMatrix(const UnifiedDesktopLayoutMatrix& matrix); + // Validates that the given display |layout| is convertable to a valid Unified // Desktop layout matrix. If yes, then the matrix will be built and filled in // |out_matrix| and true is returned. False is returned and |out_matrix| will be
diff --git a/ui/display/unified_desktop_utils_unittests.cc b/ui/display/unified_desktop_utils_unittests.cc index c594c75d..2ef10ef 100644 --- a/ui/display/unified_desktop_utils_unittests.cc +++ b/ui/display/unified_desktop_utils_unittests.cc
@@ -8,9 +8,28 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display_layout_builder.h" +#include "ui/display/types/display_constants.h" namespace display { +TEST(UnifiedDesktopLayoutTests, ValidateMatrix) { + UnifiedDesktopLayoutMatrix matrix; + + // Empty matrix. + EXPECT_FALSE(ValidateMatrix(matrix)); + + // Matrix with unequal row sizes. + matrix.resize(2); + matrix[0].emplace_back(1); + matrix[0].emplace_back(2); + matrix[1].emplace_back(3); + EXPECT_FALSE(ValidateMatrix(matrix)); + + // Matrix with a hole. + matrix[1].emplace_back(display::kInvalidDisplayId); + EXPECT_FALSE(ValidateMatrix(matrix)); +} + TEST(UnifiedDesktopLayoutTests, PrimaryIdNotInList) { DisplayLayoutBuilder builder(20); builder.AddDisplayPlacement(30, 20, DisplayPlacement::Position::RIGHT, 0);
diff --git a/ui/events/blink/compositor_thread_event_queue.cc b/ui/events/blink/compositor_thread_event_queue.cc index 60b7e16..63c2386a 100644 --- a/ui/events/blink/compositor_thread_event_queue.cc +++ b/ui/events/blink/compositor_thread_event_queue.cc
@@ -44,7 +44,6 @@ DCHECK_LE(last_event->latency_info().trace_id(), new_event->latency_info().trace_id()); LatencyInfo oldest_latency = last_event->latency_info(); - oldest_latency.set_coalesced(); base::TimeTicks oldest_creation_timestamp = last_event->creation_timestamp(); auto combined_original_events = std::make_unique<EventWithCallback::OriginalEventList>(); @@ -63,7 +62,6 @@ DCHECK_LE(second_last_event->latency_info().trace_id(), oldest_latency.trace_id()); oldest_latency = second_last_event->latency_info(); - oldest_latency.set_coalesced(); oldest_creation_timestamp = second_last_event->creation_timestamp(); combined_original_events->splice(combined_original_events->begin(), second_last_event->original_events());
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index 14588f40..ca60dae 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -51,11 +51,11 @@ range_(other.range_), icc_profile_id_(other.icc_profile_id_), icc_profile_sk_color_space_(other.icc_profile_sk_color_space_) { - if (transfer_ == TransferID::CUSTOM) { + if (transfer_ == TransferID::CUSTOM || transfer_ == TransferID::ICC_BASED) { memcpy(custom_transfer_params_, other.custom_transfer_params_, sizeof(custom_transfer_params_)); } - if (primaries_ == PrimaryID::CUSTOM) { + if (primaries_ == PrimaryID::CUSTOM || primaries_ == PrimaryID::ICC_BASED) { memcpy(custom_primary_matrix_, other.custom_primary_matrix_, sizeof(custom_primary_matrix_)); } @@ -96,15 +96,20 @@ ColorSpace result(ColorSpace::PrimaryID::CUSTOM, ColorSpace::TransferID::CUSTOM, ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL); - for (int row = 0; row < 3; ++row) { - for (int col = 0; col < 3; ++col) { - result.custom_primary_matrix_[3 * row + col] = to_XYZD50.get(row, col); - } - } + result.SetCustomPrimaries(to_XYZD50); result.SetCustomTransferFunction(fn); return result; } +void ColorSpace::SetCustomPrimaries(const SkMatrix44& to_XYZD50) { + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + custom_primary_matrix_[3 * row + col] = to_XYZD50.get(row, col); + } + } + primaries_ = PrimaryID::CUSTOM; +} + void ColorSpace::SetCustomTransferFunction(const SkColorSpaceTransferFn& fn) { custom_transfer_params_[0] = fn.fA; custom_transfer_params_[1] = fn.fB; @@ -168,13 +173,13 @@ if (primaries_ != other.primaries_ || transfer_ != other.transfer_ || matrix_ != other.matrix_ || range_ != other.range_) return false; - if (primaries_ == PrimaryID::CUSTOM) { + if (primaries_ == PrimaryID::CUSTOM || primaries_ == PrimaryID::ICC_BASED) { if (memcmp(custom_primary_matrix_, other.custom_primary_matrix_, sizeof(custom_primary_matrix_))) { return false; } } - if (transfer_ == TransferID::CUSTOM) { + if (transfer_ == TransferID::CUSTOM || transfer_ == TransferID::ICC_BASED) { if (memcmp(custom_transfer_params_, other.custom_transfer_params_, sizeof(custom_transfer_params_))) { return false; @@ -202,27 +207,25 @@ transfer_ == TransferID::IEC61966_2_4; } -bool ColorSpace::IsParametric() const { - return primaries_ != PrimaryID::ICC_BASED && - transfer_ != TransferID::ICC_BASED; -} - ColorSpace ColorSpace::GetParametricApproximation() const { - // If this is parametric already, return it directly. - if (IsParametric()) - return *this; - - // Query the ICC profile, if available, for the parametric approximation. - ICCProfile icc_profile; - if (icc_profile_id_ && GetICCProfile(&icc_profile)) { - return icc_profile.GetParametricColorSpace(); - } else { - DLOG(ERROR) - << "Unable to acquire ICC profile for parametric approximation."; + ColorSpace result = *this; + // The parametric approximation will not equal the original color space only + // when the primaries or transfer function of the original color space are not + // parametric (that is, they require the original ICC profile to represent + // them). + if (result.primaries_ == PrimaryID::ICC_BASED || + result.transfer_ == TransferID::ICC_BASED) { + // Ensure that the result not reference the original ICC profile anymore, + // because ICC profile represents a different space from the returned + // approximation. + result.icc_profile_id_ = 0; + result.icc_profile_sk_color_space_ = nullptr; + if (result.primaries_ == PrimaryID::ICC_BASED) + result.primaries_ = PrimaryID::CUSTOM; + if (result.transfer_ == TransferID::ICC_BASED) + result.transfer_ = TransferID::CUSTOM; } - - // Fall back to sRGB if the ICC profile is no longer cached. - return CreateSRGB(); + return result; } bool ColorSpace::operator!=(const ColorSpace& other) const { @@ -246,7 +249,7 @@ return true; if (range_ > other.range_) return false; - if (primaries_ == PrimaryID::CUSTOM) { + if (primaries_ == PrimaryID::CUSTOM || primaries_ == PrimaryID::ICC_BASED) { int primary_result = memcmp(custom_primary_matrix_, other.custom_primary_matrix_, sizeof(custom_primary_matrix_)); @@ -255,7 +258,7 @@ if (primary_result > 0) return false; } - if (transfer_ == TransferID::CUSTOM) { + if (transfer_ == TransferID::CUSTOM || transfer_ == TransferID::ICC_BASED) { int transfer_result = memcmp(custom_transfer_params_, other.custom_transfer_params_, sizeof(custom_transfer_params_)); @@ -272,14 +275,14 @@ (static_cast<size_t>(transfer_) << 8) | (static_cast<size_t>(matrix_) << 16) | (static_cast<size_t>(range_) << 24); - if (primaries_ == PrimaryID::CUSTOM) { + if (primaries_ == PrimaryID::CUSTOM || primaries_ == PrimaryID::ICC_BASED) { const uint32_t* params = reinterpret_cast<const uint32_t*>(custom_primary_matrix_); result ^= params[0]; result ^= params[4]; result ^= params[8]; } - if (transfer_ == TransferID::CUSTOM) { + if (transfer_ == TransferID::CUSTOM || transfer_ == TransferID::ICC_BASED) { const uint32_t* params = reinterpret_cast<const uint32_t*>(custom_transfer_params_); result ^= params[3]; @@ -314,16 +317,17 @@ PRINT_ENUM_CASE(PrimaryID, APPLE_GENERIC_RGB) PRINT_ENUM_CASE(PrimaryID, WIDE_GAMUT_COLOR_SPIN) PRINT_ENUM_CASE(PrimaryID, ICC_BASED) - case PrimaryID::CUSTOM: + PRINT_ENUM_CASE(PrimaryID, CUSTOM) + } + if (primaries_ == PrimaryID::ICC_BASED || primaries_ == PrimaryID::CUSTOM) { + ss << ":["; + for (size_t i = 0; i < 3; ++i) { ss << "["; - for (size_t i = 0; i < 3; ++i) { - ss << "["; - for (size_t j = 0; j < 3; ++j) - ss << custom_primary_matrix_[3 * i + j] << ","; - ss << "],"; - } - ss << "]"; - break; + for (size_t j = 0; j < 3; ++j) + ss << custom_primary_matrix_[3 * i + j] << ","; + ss << "],"; + } + ss << "]"; } ss << ", transfer:"; switch (transfer_) { @@ -350,13 +354,13 @@ PRINT_ENUM_CASE(TransferID, IEC61966_2_1_HDR) PRINT_ENUM_CASE(TransferID, LINEAR_HDR) PRINT_ENUM_CASE(TransferID, ICC_BASED) - case TransferID::CUSTOM: { - SkColorSpaceTransferFn fn; - GetTransferFunction(&fn); - ss << fn.fC << "*x + " << fn.fF << " if x < " << fn.fD << " else ("; - ss << fn.fA << "*x + " << fn.fB << ")**" << fn.fG << " + " << fn.fE; - break; - } + PRINT_ENUM_CASE(TransferID, CUSTOM) + } + if (transfer_ == TransferID::ICC_BASED || transfer_ == TransferID::CUSTOM) { + SkColorSpaceTransferFn fn; + GetTransferFunction(&fn); + ss << ":(" << fn.fC << "*x + " << fn.fF << " if x < " << fn.fD << " else ("; + ss << fn.fA << "*x + " << fn.fB << ")**" << fn.fG << " + " << fn.fE << ")"; } ss << ", matrix:"; switch (matrix_) { @@ -396,15 +400,15 @@ } ColorSpace ColorSpace::GetRasterColorSpace() const { - // Rasterization can only be done into parametric color spaces. - if (!IsParametric()) - return GetParametricApproximation(); // Rasterization doesn't support more than 8 bit unorm values. If the output // space has an extended range, use Display P3 for the rasterization space, // to get a somewhat wider color gamut. if (HasExtendedSkTransferFn()) return CreateDisplayP3D65(); - return *this; + + // Rasterization can only be done into parametric color spaces. Return the + // parametric approximation. + return GetParametricApproximation(); } ColorSpace ColorSpace::GetBlendingColorSpace() const { @@ -416,11 +420,6 @@ } sk_sp<SkColorSpace> ColorSpace::ToSkColorSpace() const { - // If we got a specific SkColorSpace from the ICCProfile that this color space - // was created from, use that. - if (icc_profile_sk_color_space_) - return icc_profile_sk_color_space_; - // Unspecified color spaces correspond to the null SkColorSpace. if (!IsValid()) return nullptr; @@ -435,6 +434,11 @@ return nullptr; } + // If we got a specific SkColorSpace from the ICCProfile that this color space + // was created from, use that. + if (icc_profile_sk_color_space_) + return icc_profile_sk_color_space_; + // Use the named SRGB and linear-SRGB instead of the generic constructors. if (primaries_ == PrimaryID::BT709) { if (transfer_ == TransferID::IEC61966_2_1) @@ -512,10 +516,14 @@ } // If this was created from an ICC profile, retrieve that exact profile. - ICCProfile result; if (ICCProfile::FromId(icc_profile_id_, icc_profile)) return true; + if (primaries_ == PrimaryID::ICC_BASED || + transfer_ == TransferID::ICC_BASED) { + return false; + } + // Otherwise, construct an ICC profile based on the best approximated // primaries and matrix. SkMatrix44 to_XYZD50_matrix; @@ -580,11 +588,11 @@ SkColorSpacePrimaries primaries = {0}; switch (primaries_) { case ColorSpace::PrimaryID::CUSTOM: + case ColorSpace::PrimaryID::ICC_BASED: to_XYZD50->set3x3RowMajorf(custom_primary_matrix_); return; case ColorSpace::PrimaryID::INVALID: - case ColorSpace::PrimaryID::ICC_BASED: to_XYZD50->setIdentity(); return; @@ -751,6 +759,7 @@ switch (transfer_) { case ColorSpace::TransferID::CUSTOM: + case ColorSpace::TransferID::ICC_BASED: fn->fA = custom_transfer_params_[0]; fn->fB = custom_transfer_params_[1]; fn->fC = custom_transfer_params_[2]; @@ -818,7 +827,6 @@ case ColorSpace::TransferID::SMPTEST2084: case ColorSpace::TransferID::SMPTEST2084_NON_HDR: case ColorSpace::TransferID::INVALID: - case ColorSpace::TransferID::ICC_BASED: break; }
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h index 8a514de2..a4757ef3 100644 --- a/ui/gfx/color_space.h +++ b/ui/gfx/color_space.h
@@ -53,7 +53,8 @@ CUSTOM, // For color spaces defined by an ICC profile which cannot be represented // parametrically. Any ColorTransform using this color space will use the - // ICC profile directly to compute a transform LUT. + // ICC profile directly to compute a transform LUT. A parametric + // approximation of these primaries is stored in |custom_primary_matrix_|. ICC_BASED, LAST = ICC_BASED, }; @@ -89,7 +90,8 @@ LINEAR_HDR, // A parametric transfer function defined by |custom_transfer_params_|. CUSTOM, - // See PrimaryID::ICC_BASED. + // See PrimaryID::ICC_BASED. A parametric approximation of the transfer + // function is stored in |custom_transfer_params_|. ICC_BASED, LAST = ICC_BASED, }; @@ -171,9 +173,6 @@ // Returns true if the encoded values can be outside of the 0.0-1.0 range. bool FullRangeEncodedValues() const; - // Returns true if this color space can be represented parametrically. - bool IsParametric() const; - // Return a parametric approximation of this color space (if it is not already // parametric). ColorSpace GetParametricApproximation() const; @@ -208,6 +207,7 @@ void GetRangeAdjustMatrix(SkMatrix44* matrix) const; private: + void SetCustomPrimaries(const SkMatrix44& to_XYZD50); void SetCustomTransferFunction(const SkColorSpaceTransferFn& fn); // Returns true if the transfer function is defined by an @@ -219,12 +219,12 @@ MatrixID matrix_ = MatrixID::INVALID; RangeID range_ = RangeID::INVALID; - // Only used if primaries_ is PrimaryID::CUSTOM. + // Only used if primaries_ is PrimaryID::CUSTOM or PrimaryID::ICC_BASED. float custom_primary_matrix_[9] = {0, 0, 0, 0, 0, 0, 0, 0}; - // Only used if transfer_ is TransferID::CUSTOM. This array consists of the A - // through G entries of the SkColorSpaceTransferFn structure in alphabetical - // order. + // Only used if transfer_ is TransferID::CUSTOM or PrimaryID::ICC_BASED. + // This array consists of the A through G entries of the + // SkColorSpaceTransferFn structure in alphabetical order. float custom_transfer_params_[7] = {0, 0, 0, 0, 0, 0, 0}; // This is used to look up the ICCProfile from which this ColorSpace was
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index 906aded..ab9a4bbf 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -252,8 +252,9 @@ const float kEpsilon = 2.5f / 255.f; ICCProfile icc_profile = ICCProfileForTestingNoAnalyticTrFn(); ColorSpace icc_space = icc_profile.GetColorSpace(); - ColorSpace colorspin = - ICCProfileForTestingColorSpin().GetParametricColorSpace(); + ColorSpace colorspin = ICCProfileForTestingColorSpin() + .GetColorSpace() + .GetParametricApproximation(); ColorTransform::TriStim input_value(0.25f, 0.5f, 0.75f); ColorTransform::TriStim transformed_value = input_value;
diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc index 75fdec5..f26a8181 100644 --- a/ui/gfx/icc_profile.cc +++ b/ui/gfx/icc_profile.cc
@@ -54,17 +54,6 @@ if (!icc_profile->id_) icc_profile->id_ = next_unused_id_++; - // Ensure that GetColorSpace() point back to this ICCProfile. - gfx::ColorSpace& color_space = icc_profile->color_space_; - color_space.icc_profile_id_ = icc_profile->id_; - - // Ensure that the GetParametricColorSpace() point back to this ICCProfile - // only if the parametric version is accurate. - if (color_space.primaries_ != ColorSpace::PrimaryID::ICC_BASED && - color_space.transfer_ != ColorSpace::TransferID::ICC_BASED) { - icc_profile->parametric_color_space_.icc_profile_id_ = icc_profile->id_; - } - Entry entry; entry.icc_profile = *icc_profile; id_to_icc_profile_mru_.Put(icc_profile->id_, entry); @@ -201,76 +190,69 @@ } // namespace -// static -ICCProfile::AnalyzeResult ICCProfile::ExtractColorSpaces( - const std::vector<char>& data, - gfx::ColorSpace* parametric_color_space, - float* parametric_tr_fn_max_error, - sk_sp<SkColorSpace>* useable_sk_color_space) { - // Initialize the output parameters as invalid. - *parametric_color_space = gfx::ColorSpace(); - *parametric_tr_fn_max_error = 0; - *useable_sk_color_space = nullptr; +ICCProfile::AnalyzeResult ICCProfile::Initialize() { + // Start out with no parametric data. + primaries_ = gfx::ColorSpace::PrimaryID::INVALID; + transfer_ = gfx::ColorSpace::TransferID::INVALID; // Parse the profile and attempt to create a SkColorSpaceXform out of it. sk_sp<SkColorSpace> sk_srgb_color_space = SkColorSpace::MakeSRGB(); - sk_sp<SkICC> sk_icc = SkICC::Make(data.data(), data.size()); + sk_sp<SkICC> sk_icc = SkICC::Make(data_.data(), data_.size()); if (!sk_icc) { DLOG(ERROR) << "Failed to parse ICC profile to SkICC."; return kICCFailedToParse; } - sk_sp<SkColorSpace> sk_icc_color_space = - SkColorSpace::MakeICC(data.data(), data.size()); - if (!sk_icc_color_space) { + sk_color_space_ = SkColorSpace::MakeICC(data_.data(), data_.size()); + if (!sk_color_space_) { DLOG(ERROR) << "Failed to parse ICC profile to SkColorSpace."; return kICCFailedToExtractSkColorSpace; } + + // If our SkColorSpace representation is sRGB then return that. + if (SkColorSpace::Equals(sk_srgb_color_space.get(), sk_color_space_.get())) { + primaries_ = gfx::ColorSpace::PrimaryID::BT709; + transfer_ = gfx::ColorSpace::TransferID::IEC61966_2_1; + return kICCExtractedSRGBColorSpace; + } + std::unique_ptr<SkColorSpaceXform> sk_color_space_xform = - SkColorSpaceXform::New(sk_srgb_color_space.get(), - sk_icc_color_space.get()); + SkColorSpaceXform::New(sk_srgb_color_space.get(), sk_color_space_.get()); if (!sk_color_space_xform) { DLOG(ERROR) << "Parsed ICC profile but can't create SkColorSpaceXform."; return kICCFailedToCreateXform; } - // Because this SkColorSpace can be used to construct a transform, mark it - // as "useable". Mark the "best approximation" as sRGB to start. - *useable_sk_color_space = sk_icc_color_space; - *parametric_color_space = ColorSpace::CreateSRGB(); + // Because this SkColorSpace can be used to construct a transform, we can use + // it to create a LUT based color transform, at the very least. If we fail to + // get any better approximation, we'll use sRGB as our approximation. + primaries_ = ColorSpace::PrimaryID::ICC_BASED; + transfer_ = ColorSpace::TransferID::ICC_BASED; + ColorSpace::CreateSRGB().GetPrimaryMatrix(&to_XYZD50_); + ColorSpace::CreateSRGB().GetTransferFunction(&transfer_fn_); - // If our SkColorSpace representation is sRGB then return that. - if (SkColorSpace::Equals(sk_srgb_color_space.get(), - sk_icc_color_space.get())) { - return kICCExtractedSRGBColorSpace; - } - - // A primary matrix is required for our parametric approximation. + // A primary matrix is required for our parametric representations. Use it if + // it exists. SkMatrix44 to_XYZD50_matrix; if (!sk_icc->toXYZD50(&to_XYZD50_matrix)) { DLOG(ERROR) << "Failed to extract ICC profile primary matrix."; return kICCFailedToExtractMatrix; } + primaries_ = ColorSpace::PrimaryID::CUSTOM; + to_XYZD50_ = to_XYZD50_matrix; - // Try to directly extract a numerical transfer function. + // Try to directly extract a numerical transfer function. Use it if it + // exists. SkColorSpaceTransferFn exact_tr_fn; if (sk_icc->isNumericalTransferFn(&exact_tr_fn)) { - *parametric_color_space = - gfx::ColorSpace::CreateCustom(to_XYZD50_matrix, exact_tr_fn); + transfer_ = ColorSpace::TransferID::CUSTOM; + transfer_fn_ = exact_tr_fn; return kICCExtractedMatrixAndAnalyticTrFn; } - // If we fail to get a transfer function, use the sRGB transfer function, - // and return false to indicate that the gfx::ColorSpace isn't accurate, but - // we can construct accurate LUT transforms using the underlying - // SkColorSpace. - *parametric_color_space = gfx::ColorSpace::CreateCustom( - to_XYZD50_matrix, ColorSpace::TransferID::IEC61966_2_1); - // Attempt to fit a parametric transfer function to the table data in the // profile. SkColorSpaceTransferFn approx_tr_fn; - if (!SkApproximateTransferFn(sk_icc, parametric_tr_fn_max_error, - &approx_tr_fn)) { + if (!SkApproximateTransferFn(sk_icc, &transfer_fn_error_, &approx_tr_fn)) { DLOG(ERROR) << "Failed approximate transfer function."; return kICCFailedToConvergeToApproximateTrFn; } @@ -278,16 +260,16 @@ // If this converged, but has too high error, use the sRGB transfer function // from above. const float kMaxError = 2.f / 256.f; - if (*parametric_tr_fn_max_error >= kMaxError) { + if (transfer_fn_error_ >= kMaxError) { DLOG(ERROR) << "Failed to accurately approximate transfer function, error: " - << 256.f * (*parametric_tr_fn_max_error) << "/256"; + << 256.f * transfer_fn_error_ << "/256"; return kICCFailedToApproximateTrFnAccurately; }; // If the error is sufficiently low, declare that the approximation is // accurate. - *parametric_color_space = - gfx::ColorSpace::CreateCustom(to_XYZD50_matrix, approx_tr_fn); + transfer_ = ColorSpace::TransferID::CUSTOM; + transfer_fn_ = approx_tr_fn; return kICCExtractedMatrixAndApproximatedTrFn; } @@ -346,14 +328,28 @@ return data_; } -const ColorSpace& ICCProfile::GetColorSpace() const { +ColorSpace ICCProfile::GetColorSpace() const { g_cache.Get().TouchEntry(*this); - return color_space_; -} -const ColorSpace& ICCProfile::GetParametricColorSpace() const { - g_cache.Get().TouchEntry(*this); - return parametric_color_space_; + ColorSpace color_space; + if (!IsValid()) + return color_space; + color_space.icc_profile_id_ = id_; + color_space.icc_profile_sk_color_space_ = sk_color_space_; + DCHECK(color_space.icc_profile_sk_color_space_); + color_space.matrix_ = ColorSpace::MatrixID::RGB; + color_space.range_ = ColorSpace::RangeID::FULL; + if (primaries_ == ColorSpace::PrimaryID::CUSTOM || + primaries_ == ColorSpace::PrimaryID::ICC_BASED) { + color_space.SetCustomPrimaries(to_XYZD50_); + } + color_space.primaries_ = primaries_; + if (transfer_ == ColorSpace::TransferID::CUSTOM || + transfer_ == ColorSpace::TransferID::ICC_BASED) { + color_space.SetCustomTransferFunction(transfer_fn_); + } + color_space.transfer_ = transfer_; + return color_space; } // static @@ -376,34 +372,7 @@ return; // Parse the ICC profile - sk_sp<SkColorSpace> useable_sk_color_space; - analyze_result_ = - ExtractColorSpaces(data_, ¶metric_color_space_, - ¶metric_tr_fn_error_, &useable_sk_color_space); - switch (analyze_result_) { - case kICCExtractedSRGBColorSpace: - case kICCExtractedMatrixAndAnalyticTrFn: - case kICCExtractedMatrixAndApproximatedTrFn: - // Successfully and accurately extracted color space. - color_space_ = parametric_color_space_; - break; - case kICCFailedToExtractRawTrFn: - case kICCFailedToExtractMatrix: - case kICCFailedToConvergeToApproximateTrFn: - case kICCFailedToApproximateTrFnAccurately: - // Successfully but extracted a color space, but it isn't accurate enough. - color_space_ = ColorSpace(ColorSpace::PrimaryID::ICC_BASED, - ColorSpace::TransferID::ICC_BASED); - color_space_.icc_profile_sk_color_space_ = useable_sk_color_space; - break; - case kICCFailedToParse: - case kICCFailedToExtractSkColorSpace: - case kICCFailedToCreateXform: - // Can't even use this color space as a LUT. - DCHECK(!parametric_color_space_.IsValid()); - color_space_ = parametric_color_space_; - break; - } + analyze_result_ = Initialize(); // Add to the cache. g_cache.Get().InsertAndSetIdIfNeeded(this); @@ -429,7 +398,7 @@ if (nonlinear_fit_converged) { UMA_HISTOGRAM_CUSTOM_COUNTS( "Blink.ColorSpace.Destination.NonlinearFitError", - static_cast<int>(parametric_tr_fn_error_ * 255), 0, 127, 16); + static_cast<int>(transfer_fn_error_ * 255), 0, 127, 16); } }
diff --git a/ui/gfx/icc_profile.h b/ui/gfx/icc_profile.h index bfbdc4e..3c00e76 100644 --- a/ui/gfx/icc_profile.h +++ b/ui/gfx/icc_profile.h
@@ -52,12 +52,7 @@ // Return a ColorSpace that references this ICCProfile. ColorTransforms // created using this ColorSpace will match this ICCProfile precisely. - const ColorSpace& GetColorSpace() const; - - // Return a ColorSpace that is the best parametric approximation of this - // ICCProfile. The resulting ColorSpace will reference this ICCProfile only - // if the parametric approximation is almost exact. - const ColorSpace& GetParametricColorSpace() const; + ColorSpace GetColorSpace() const; const std::vector<char>& GetData() const; @@ -103,12 +98,7 @@ size_t size, uint64_t id); - static AnalyzeResult ExtractColorSpaces( - const std::vector<char>& data, - gfx::ColorSpace* parametric_color_space, - float* parametric_tr_fn_max_error, - sk_sp<SkColorSpace>* useable_sk_color_space); - + AnalyzeResult Initialize(); void ComputeColorSpaceAndCache(); // This globally identifies this ICC profile. It is used to look up this ICC @@ -120,18 +110,21 @@ // The result of attepting to extract a color space from the color profile. AnalyzeResult analyze_result_ = kICCFailedToParse; - // |color_space| always links back to this ICC profile, and its SkColorSpace - // is always equal to the SkColorSpace created from this ICCProfile. - gfx::ColorSpace color_space_; + // Results of Skia parsing the ICC profile data. + sk_sp<SkColorSpace> sk_color_space_; - // |parametric_color_space_| will only link back to this ICC profile if it - // is accurate, and its SkColorSpace will always be parametrically created. - gfx::ColorSpace parametric_color_space_; + // The best-fit parametric primaries. + gfx::ColorSpace::PrimaryID primaries_; + SkMatrix44 to_XYZD50_; + + // The best-fit parametric transfer function. + gfx::ColorSpace::TransferID transfer_; + SkColorSpaceTransferFn transfer_fn_; // The L-infinity error of the parametric color space fit. This is undefined // unless |analyze_result_| is kICCFailedToApproximateTrFnAccurately or // kICCExtractedMatrixAndApproximatedTrFn. - float parametric_tr_fn_error_ = -1; + float transfer_fn_error_ = 0; FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, BT709toSRGBICC); FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, GetColorSpace);
diff --git a/ui/gfx/icc_profile_unittest.cc b/ui/gfx/icc_profile_unittest.cc index d9a008d..186fceb 100644 --- a/ui/gfx/icc_profile_unittest.cc +++ b/ui/gfx/icc_profile_unittest.cc
@@ -32,8 +32,12 @@ EXPECT_EQ(icc_profile.GetColorSpace().ToSkColorSpace().get(), sk_color_space.get()); // The parametric generating code should recognize that this is SRGB. - EXPECT_EQ(icc_profile.GetParametricColorSpace(), ColorSpace::CreateSRGB()); - EXPECT_EQ(icc_profile.GetParametricColorSpace().ToSkColorSpace().get(), + EXPECT_EQ(icc_profile.GetColorSpace().GetParametricApproximation(), + ColorSpace::CreateSRGB()); + EXPECT_EQ(icc_profile.GetColorSpace() + .GetParametricApproximation() + .ToSkColorSpace() + .get(), sk_color_space.get()); // The generated color space should recognize that this is SRGB. EXPECT_EQ(color_space.ToSkColorSpace().get(), sk_color_space.get()); @@ -78,7 +82,8 @@ // This ICC profile has three transfer functions that differ enough that the // parametric color space is considered inaccurate. ICCProfile multi_tr_fn = ICCProfileForTestingNoAnalyticTrFn(); - EXPECT_NE(multi_tr_fn.GetColorSpace(), multi_tr_fn.GetParametricColorSpace()); + EXPECT_NE(multi_tr_fn.GetColorSpace(), + multi_tr_fn.GetColorSpace().GetParametricApproximation()); ICCProfile multi_tr_fn_color_space; EXPECT_TRUE( @@ -86,35 +91,40 @@ EXPECT_EQ(multi_tr_fn_color_space, multi_tr_fn); ICCProfile multi_tr_fn_parametric_color_space; - EXPECT_TRUE(multi_tr_fn.GetParametricColorSpace().GetICCProfile( - &multi_tr_fn_parametric_color_space)); + EXPECT_TRUE( + multi_tr_fn.GetColorSpace().GetParametricApproximation().GetICCProfile( + &multi_tr_fn_parametric_color_space)); EXPECT_NE(multi_tr_fn_parametric_color_space, multi_tr_fn); // This ICC profile has a transfer function with T(1) that is greater than 1 // in the approximation, but is still close enough to be considered accurate. ICCProfile overshoot = ICCProfileForTestingOvershoot(); - EXPECT_EQ(overshoot.GetColorSpace(), overshoot.GetParametricColorSpace()); + EXPECT_EQ(overshoot.GetColorSpace(), + overshoot.GetColorSpace().GetParametricApproximation()); ICCProfile overshoot_color_space; EXPECT_TRUE(overshoot.GetColorSpace().GetICCProfile(&overshoot_color_space)); EXPECT_EQ(overshoot_color_space, overshoot); ICCProfile overshoot_parametric_color_space; - EXPECT_TRUE(overshoot.GetParametricColorSpace().GetICCProfile( - &overshoot_parametric_color_space)); + EXPECT_TRUE( + overshoot.GetColorSpace().GetParametricApproximation().GetICCProfile( + &overshoot_parametric_color_space)); EXPECT_EQ(overshoot_parametric_color_space, overshoot); // This ICC profile is precisely represented by the parametric color space. ICCProfile accurate = ICCProfileForTestingAdobeRGB(); - EXPECT_EQ(accurate.GetColorSpace(), accurate.GetParametricColorSpace()); + EXPECT_EQ(accurate.GetColorSpace(), + accurate.GetColorSpace().GetParametricApproximation()); ICCProfile accurate_color_space; EXPECT_TRUE(accurate.GetColorSpace().GetICCProfile(&accurate_color_space)); EXPECT_EQ(accurate_color_space, accurate); ICCProfile accurate_parametric_color_space; - EXPECT_TRUE(accurate.GetParametricColorSpace().GetICCProfile( - &accurate_parametric_color_space)); + EXPECT_TRUE( + accurate.GetColorSpace().GetParametricApproximation().GetICCProfile( + &accurate_parametric_color_space)); EXPECT_EQ(accurate_parametric_color_space, accurate); // This ICC profile has only an A2B representation. We cannot create an @@ -136,12 +146,15 @@ ICCProfile::FromData(bad_data.data(), bad_data.size()); EXPECT_FALSE(garbage_profile.IsValid()); EXPECT_FALSE(garbage_profile.GetColorSpace().IsValid()); - EXPECT_FALSE(garbage_profile.GetParametricColorSpace().IsValid()); + EXPECT_FALSE( + garbage_profile.GetColorSpace().GetParametricApproximation().IsValid()); ICCProfile default_ctor_profile; EXPECT_FALSE(default_ctor_profile.IsValid()); EXPECT_FALSE(default_ctor_profile.GetColorSpace().IsValid()); - EXPECT_FALSE(default_ctor_profile.GetParametricColorSpace().IsValid()); + EXPECT_FALSE(default_ctor_profile.GetColorSpace() + .GetParametricApproximation() + .IsValid()); } TEST(ICCProfile, GenericRGB) {
diff --git a/ui/gfx/native_pixmap.h b/ui/gfx/native_pixmap.h index c168001..1677dc0 100644 --- a/ui/gfx/native_pixmap.h +++ b/ui/gfx/native_pixmap.h
@@ -34,14 +34,6 @@ virtual gfx::BufferFormat GetBufferFormat() const = 0; virtual gfx::Size GetBufferSize() const = 0; - // Return an id that is guaranteed to be unique and equal for all instances - // of this NativePixmap backed by the same buffer, for the duration of its - // lifetime. If such id cannot be generated, 0 (an invalid id) is returned. - // - // TODO(posciak): crbug.com/771863, remove this once a different mechanism - // for protected shared memory buffers is implemented. - virtual uint32_t GetUniqueId() const = 0; - // Sets the overlay plane to switch to at the next page flip. // |widget| specifies the screen to display this overlay plane on. // |plane_z_order| specifies the stacking order of the plane relative to the
diff --git a/ui/gl/extension_set.cc b/ui/gl/extension_set.cc index f1b0154..3b28e75 100644 --- a/ui/gl/extension_set.cc +++ b/ui/gl/extension_set.cc
@@ -4,6 +4,7 @@ #include "ui/gl/extension_set.h" #include "base/strings/string_split.h" +#include "base/strings/string_util.h" namespace gl { @@ -17,4 +18,10 @@ return extension_set.find(extension) != extension_set.end(); } +std::string MakeExtensionString(const ExtensionSet& extension_set) { + std::vector<base::StringPiece> extension_list(extension_set.begin(), + extension_set.end()); + return base::JoinString(extension_list, " "); +} + } // namespace gl
diff --git a/ui/gl/extension_set.h b/ui/gl/extension_set.h index e8d3622..2380536 100644 --- a/ui/gl/extension_set.h +++ b/ui/gl/extension_set.h
@@ -25,6 +25,8 @@ return HasExtension(extension_set, base::StringPiece(extension, N - 1)); } +GL_EXPORT std::string MakeExtensionString(const ExtensionSet& extension_set); + } // namespace gl #endif // UI_GL_EXTENSION_SET_H_
diff --git a/ui/gl/gl_context_glx_unittest.cc b/ui/gl/gl_context_glx_unittest.cc index 5b0a4276..3fe50e1 100644 --- a/ui/gl/gl_context_glx_unittest.cc +++ b/ui/gl/gl_context_glx_unittest.cc
@@ -47,11 +47,9 @@ ASSERT_TRUE(context->MakeCurrent(surface.get())); EXPECT_TRUE(context->GetHandle()); - // Destroy the window, and turn off sync behaviour. We should get no x11 - // errors so far. + // Destroy the window. We should get no x11 errors so far. context->ReleaseCurrent(surface.get()); XDestroyWindow(xdisplay, xwindow); - XSynchronize(xdisplay, False); ASSERT_FALSE(error_tracker.FoundNewError()); // Now that the window is gone, MakeCurrent() should fail. But the context @@ -59,6 +57,7 @@ EXPECT_FALSE(context->MakeCurrent(surface.get())); ASSERT_TRUE(context->GetHandle()); EXPECT_TRUE(error_tracker.FoundNewError()); + XSynchronize(xdisplay, False); } } // namespace gl
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc index 234c3f9..6cc5b50a 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -63,7 +63,6 @@ return gfx::BufferFormat::BGRA_8888; } gfx::Size GetBufferSize() const override { return gfx::Size(); } - uint32_t GetUniqueId() const override { return 0; } bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, int plane_z_order,
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer.cc b/ui/ozone/platform/drm/gpu/gbm_buffer.cc index 38ad6cb..e7b24aa 100644 --- a/ui/ozone/platform/drm/gpu/gbm_buffer.cc +++ b/ui/ozone/platform/drm/gpu/gbm_buffer.cc
@@ -261,11 +261,11 @@ // Try to use scanout if supported. int gbm_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; - if (!gbm_device_is_format_supported(gbm->device(), format, gbm_flags)) - gbm_flags &= ~GBM_BO_USE_SCANOUT; + bool try_scanout = + gbm_device_is_format_supported(gbm->device(), format, gbm_flags); gbm_bo* bo = nullptr; - if (gbm_device_is_format_supported(gbm->device(), format, gbm_flags)) { + if (try_scanout) { struct gbm_import_fd_planar_data fd_data; fd_data.width = size.width(); fd_data.height = size.height(); @@ -287,6 +287,8 @@ LOG(ERROR) << "nullptr returned from gbm_bo_import"; return nullptr; } + } else { + gbm_flags &= ~GBM_BO_USE_SCANOUT; } scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, format, gbm_flags, 0, @@ -363,10 +365,6 @@ return buffer_->GetSize(); } -uint32_t GbmPixmap::GetUniqueId() const { - return buffer_->GetHandle(); -} - bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, int plane_z_order, gfx::OverlayTransform plane_transform,
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer.h b/ui/ozone/platform/drm/gpu/gbm_buffer.h index 4891b8f..6715274 100644 --- a/ui/ozone/platform/drm/gpu/gbm_buffer.h +++ b/ui/ozone/platform/drm/gpu/gbm_buffer.h
@@ -119,7 +119,6 @@ uint64_t GetDmaBufModifier(size_t plane) const override; gfx::BufferFormat GetBufferFormat() const override; gfx::Size GetBufferSize() const override; - uint32_t GetUniqueId() const override; bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, int plane_z_order, gfx::OverlayTransform plane_transform,
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc index ca8a520..cbb3e077 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -160,7 +160,7 @@ } scoped_refptr<gfx::NativePixmap> -GbmSurfaceFactory::CreateNativePixmapFromHandleInternal( +GbmSurfaceFactory::CreateNativePixmapFromHandle( gfx::AcceleratedWidget widget, gfx::Size size, gfx::BufferFormat format, @@ -176,6 +176,7 @@ } std::vector<gfx::NativePixmapPlane> planes; + for (const auto& plane : handle.planes) { planes.push_back(plane); } @@ -184,44 +185,7 @@ widget, size, format, std::move(scoped_fds), planes); if (!buffer) return nullptr; - return base::MakeRefCounted<GbmPixmap>(this, buffer); } -scoped_refptr<gfx::NativePixmap> -GbmSurfaceFactory::CreateNativePixmapFromHandle( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - const gfx::NativePixmapHandle& handle) { - // Query the external service (if available), whether it recognizes this - // NativePixmapHandle, and whether it can provide a corresponding NativePixmap - // backing it. If so, the handle is consumed. Otherwise, the handle remains - // valid and can be further importer by standard means. - if (!get_protected_native_pixmap_callback_.is_null()) { - auto protected_pixmap = get_protected_native_pixmap_callback_.Run(handle); - if (protected_pixmap) - return protected_pixmap; - } - - return CreateNativePixmapFromHandleInternal(widget, size, format, handle); -} - -scoped_refptr<gfx::NativePixmap> -GbmSurfaceFactory::CreateNativePixmapForProtectedBufferHandle( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - const gfx::NativePixmapHandle& handle) { - // Create a new NativePixmap without querying the external service for any - // existing mappings. - return CreateNativePixmapFromHandleInternal(widget, size, format, handle); -} - -void GbmSurfaceFactory::SetGetProtectedNativePixmapDelegate( - const GetProtectedNativePixmapCallback& - get_protected_native_pixmap_callback) { - get_protected_native_pixmap_callback_ = get_protected_native_pixmap_callback; -} - } // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h index 3955c1c1..ce1abfdc 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
@@ -50,22 +50,8 @@ gfx::Size size, gfx::BufferFormat format, const gfx::NativePixmapHandle& handle) override; - void SetGetProtectedNativePixmapDelegate( - const GetProtectedNativePixmapCallback& - get_protected_native_pixmap_callback) override; - scoped_refptr<gfx::NativePixmap> CreateNativePixmapForProtectedBufferHandle( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - const gfx::NativePixmapHandle& handle) override; private: - scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandleInternal( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - const gfx::NativePixmapHandle& handle); - std::unique_ptr<GLOzone> egl_implementation_; std::unique_ptr<GLOzone> osmesa_implementation_; @@ -75,8 +61,6 @@ std::map<gfx::AcceleratedWidget, GbmSurfaceless*> widget_to_surface_map_; - GetProtectedNativePixmapCallback get_protected_native_pixmap_callback_; - DISALLOW_COPY_AND_ASSIGN(GbmSurfaceFactory); };
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc index 4ba3929..dcfcf54 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -83,7 +83,6 @@ uint64_t GetDmaBufModifier(size_t plane) const override { return 0; } gfx::BufferFormat GetBufferFormat() const override { return format_; } gfx::Size GetBufferSize() const override { return gfx::Size(); } - uint32_t GetUniqueId() const override { return 0; } bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, int plane_z_order, gfx::OverlayTransform plane_transform,
diff --git a/ui/ozone/public/surface_factory_ozone.cc b/ui/ozone/public/surface_factory_ozone.cc index c7c2dc3..527aa29 100644 --- a/ui/ozone/public/surface_factory_ozone.cc +++ b/ui/ozone/public/surface_factory_ozone.cc
@@ -52,17 +52,4 @@ return nullptr; } -scoped_refptr<gfx::NativePixmap> -SurfaceFactoryOzone::CreateNativePixmapForProtectedBufferHandle( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - const gfx::NativePixmapHandle& handle) { - return nullptr; -} - -void SurfaceFactoryOzone::SetGetProtectedNativePixmapDelegate( - const GetProtectedNativePixmapCallback& - get_protected_native_pixmap_callback) {} - } // namespace ui
diff --git a/ui/ozone/public/surface_factory_ozone.h b/ui/ozone/public/surface_factory_ozone.h index 1b7ba91..6e7726a 100644 --- a/ui/ozone/public/surface_factory_ozone.h +++ b/ui/ozone/public/surface_factory_ozone.h
@@ -99,38 +99,6 @@ gfx::BufferFormat format, const gfx::NativePixmapHandle& handle); - // A temporary solution that allows protected NativePixmap management to be - // handled outside the Ozone platform (crbug.com/771863). - // The current implementation uses dummy NativePixmaps as transparent handles - // to separate NativePixmaps with actual contents. This method takes - // a NativePixmapHandle to such a dummy pixmap, and creates a NativePixmap - // instance for it. - virtual scoped_refptr<gfx::NativePixmap> - CreateNativePixmapForProtectedBufferHandle( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - const gfx::NativePixmapHandle& handle); - - // This callback can be used by implementations of this interface to query - // for a NativePixmap for the given NativePixmapHandle, instead of importing - // it via standard means. This happens if an external service is maintaining - // a separate mapping of NativePixmapHandles to NativePixmaps. - // If this callback returns non-nullptr, the returned NativePixmap should - // be used instead of the NativePixmap that would have been produced by the - // standard, implementation-specific NativePixmapHandle import mechanism. - using GetProtectedNativePixmapCallback = - base::Callback<scoped_refptr<gfx::NativePixmap>( - const gfx::NativePixmapHandle&)>; - // Called by an external service to set the GetProtectedNativePixmapCallback, - // to be used by the implementation when importing NativePixmapHandles. - // TODO(posciak): crbug.com/778555, move this to platform-specific - // implementation(s) and make protected pixmap handling transparent to the - // clients of this interface, removing the need for this callback. - virtual void SetGetProtectedNativePixmapDelegate( - const GetProtectedNativePixmapCallback& - get_protected_native_pixmap_callback); - protected: SurfaceFactoryOzone(); virtual ~SurfaceFactoryOzone();
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index 893c33af..77eea3f 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -44,7 +44,7 @@ const gfx::Font::Weight kActiveWeight = gfx::Font::Weight::BOLD; const gfx::Font::Weight kInactiveWeight = gfx::Font::Weight::NORMAL; -const int kHarmonyTabStripTabHeight = 40; +const int kHarmonyTabStripTabHeight = 32; // The View containing the text for each tab in the tab strip. class TabLabel : public Label {
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html index 6b8a0016..783160c8 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html
@@ -151,7 +151,7 @@ <div> <button is="paper-icon-button-light" id="switchMode" tabindex="2" title="[[switchModeLabel]]" on-tap="onTapSwitchMode_" - disabled="[[!cameraOnline_]]"> + disabled="[[!cameraOnline_]]" hidden="[[!videomodeEnabled]]"> </button> </div> </div>
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js index 99b73c34..93d4ec9 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js
@@ -37,6 +37,12 @@ takePhotoLabel: String, switchModeLabel: String, + /** True if video mode is enabled. */ + videomodeEnabled: { + type: Boolean, + value: false, + }, + /** * True if currently in video mode. * @private {boolean}
diff --git a/url/url_canon_icu.cc b/url/url_canon_icu.cc index d0468cc..19c5c23 100644 --- a/url/url_canon_icu.cc +++ b/url/url_canon_icu.cc
@@ -101,7 +101,10 @@ // registrars, search engines) converge toward a consensus. value = uidna_openUTS46(UIDNA_CHECK_BIDI, &err); if (U_FAILURE(err)) { - CHECK(false) << "failed to open UTS46 data with error: " << err; + CHECK(false) << "failed to open UTS46 data with error: " << err + << ". If you see this error message in a test environment " + << "your test environment likely lacks the required data " + << "tables for libicu. See https://crbug.com/778929."; value = NULL; } }