diff --git a/DEPS b/DEPS index 5d35fd00..3b01e1f 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,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': '4ccd862d2940c47e7815c1309814e3de1c791e84', + 'skia_revision': '9fa740365215931c8208fe57a55c7ebac1303d95', # 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': '66930adb48a5aff530971c6afcddd827e55bd5e6', + 'v8_revision': 'e9a711fa15ac8a3654d8f7c794965cc1965699a0', # 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. @@ -52,7 +52,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': '20e005b2a1548cf16c627ba82144446bffd69493', + 'angle_revision': '67f5ce42461d831cce30f737fa81919508c1368e', # 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. @@ -64,7 +64,7 @@ # 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': 'f6baf6b1d101a889d2cfc7cb925e726dbffb89db', + 'pdfium_revision': '5eb58cd552c184998ed24634db4b2e6e770f39bd', # 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.
diff --git a/android_webview/native/aw_metrics_service_client_impl.cc b/android_webview/native/aw_metrics_service_client_impl.cc index d3848cb..381fb98 100644 --- a/android_webview/native/aw_metrics_service_client_impl.cc +++ b/android_webview/native/aw_metrics_service_client_impl.cc
@@ -147,8 +147,8 @@ void AwMetricsServiceClientImpl::SetMetricsEnabled(bool enabled) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // For now, UMA is only enabled on future versions. - if (base::android::BuildInfo::GetInstance()->sdk_int() <= + // For now, UMA is only enabled on Android N+. + if (base::android::BuildInfo::GetInstance()->sdk_int() < base::android::SDK_VERSION_NOUGAT) { return; }
diff --git a/ash/devtools/ash_devtools_unittest.cc b/ash/devtools/ash_devtools_unittest.cc index f840134f..5ebb719c 100644 --- a/ash/devtools/ash_devtools_unittest.cc +++ b/ash/devtools/ash_devtools_unittest.cc
@@ -5,6 +5,7 @@ #include "ash/devtools/ash_devtools_css_agent.h" #include "ash/devtools/ash_devtools_dom_agent.h" #include "ash/root_window_controller.h" +#include "ash/shell.h" #include "ash/shell_port.h" #include "ash/test/ash_test.h" #include "ash/wm/widget_finder.h" @@ -134,14 +135,13 @@ return -1; } -WmWindow* GetHighlightingWindow(int root_window_index) { - WmWindow::Windows overlay_windows = - ShellPort::Get() - ->GetAllRootWindows()[root_window_index] - ->GetChildByShellWindowId(kShellWindowId_OverlayContainer) - ->GetChildren(); - for (WmWindow* window : overlay_windows) { - if (window->aura_window()->GetName() == "HighlightingWidget") +aura::Window* GetHighlightingWindow(int root_window_index) { + const aura::Window::Windows& overlay_windows = + Shell::GetAllRootWindows()[root_window_index] + ->GetChildById(kShellWindowId_OverlayContainer) + ->children(); + for (aura::Window* window : overlay_windows) { + if (window->GetName() == "HighlightingWidget") return window; } NOTREACHED(); @@ -167,14 +167,13 @@ } void ExpectHighlighted(const gfx::Rect& bounds, int root_window_index) { - WmWindow* highlighting_window = GetHighlightingWindow(root_window_index); + aura::Window* highlighting_window = GetHighlightingWindow(root_window_index); EXPECT_TRUE(highlighting_window->IsVisible()); EXPECT_EQ(bounds, highlighting_window->GetBoundsInScreen()); - EXPECT_EQ(kBackgroundColor, - GetInternalWidgetForWindow(highlighting_window->aura_window()) - ->GetRootView() - ->background() - ->get_color()); + EXPECT_EQ(kBackgroundColor, GetInternalWidgetForWindow(highlighting_window) + ->GetRootView() + ->background() + ->get_color()); } } // namespace
diff --git a/ash/laser/laser_pointer_view.cc b/ash/laser/laser_pointer_view.cc index 956fbd9..5f5b757a 100644 --- a/ash/laser/laser_pointer_view.cc +++ b/ash/laser/laser_pointer_view.cc
@@ -438,7 +438,8 @@ void LaserPointerView::DidReceiveCompositorFrameAck( const cc::ReturnedResourceArray& resources) { - ReclaimResources(resources); + if (!resources.empty()) + ReclaimResources(resources); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&LaserPointerView::OnDidDrawSurface,
diff --git a/ash/mus/app_launch_unittest.cc b/ash/mus/app_launch_unittest.cc index 1ee880a4..e9a3e60 100644 --- a/ash/mus/app_launch_unittest.cc +++ b/ash/mus/app_launch_unittest.cc
@@ -34,8 +34,8 @@ }; TEST_F(AppLaunchTest, TestQuickLaunch) { - connector()->Connect(mojom::kServiceName); - connector()->Connect(mash::quick_launch::mojom::kServiceName); + connector()->StartService(mojom::kServiceName); + connector()->StartService(mash::quick_launch::mojom::kServiceName); ui::mojom::WindowServerTestPtr test_interface; connector()->BindInterface(ui::mojom::kServiceName, &test_interface);
diff --git a/ash/mus/test/ash_test_impl_mus.cc b/ash/mus/test/ash_test_impl_mus.cc index 32a33bd..92e5bb5 100644 --- a/ash/mus/test/ash_test_impl_mus.cc +++ b/ash/mus/test/ash_test_impl_mus.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" +#include "ui/aura/window.h" #include "ui/wm/core/window_util.h" namespace ash { @@ -54,10 +55,10 @@ const gfx::Rect& bounds_in_screen, ui::wm::WindowType type, int shell_window_id) { - WmWindow* window = - WmWindow::Get(wm_test_base_->CreateTestWindow(bounds_in_screen, type)); - window->SetShellWindowId(shell_window_id); - return base::MakeUnique<WindowOwner>(window); + aura::Window* window = + wm_test_base_->CreateTestWindow(bounds_in_screen, type); + window->set_id(shell_window_id); + return base::MakeUnique<WindowOwner>(WmWindow::Get(window)); } std::unique_ptr<WindowOwner> AshTestImplMus::CreateToplevelTestWindow(
diff --git a/ash/mus/top_level_window_factory.cc b/ash/mus/top_level_window_factory.cc index 1c810c12..0a92119 100644 --- a/ash/mus/top_level_window_factory.cc +++ b/ash/mus/top_level_window_factory.cc
@@ -131,9 +131,8 @@ aura::Window* context = nullptr; aura::Window* container_window = nullptr; if (GetInitialContainerId(*properties, &container_id)) { - container_window = root_window_controller->GetWindow() - ->GetChildByShellWindowId(container_id) - ->aura_window(); + container_window = + root_window_controller->GetRootWindow()->GetChildById(container_id); } else { context = root_window_controller->GetRootWindow(); } @@ -160,9 +159,8 @@ // Pick a parent so display information is obtained. Will pick the real one // once transient parent found. aura::Window* unparented_control_container = - root_window_controller->GetWindow() - ->GetChildByShellWindowId(kShellWindowId_UnparentedControlContainer) - ->aura_window(); + root_window_controller->GetRootWindow()->GetChildById( + kShellWindowId_UnparentedControlContainer); // DetachedTitleAreaRendererForClient is owned by the client. DetachedTitleAreaRendererForClient* renderer = new DetachedTitleAreaRendererForClient(unparented_control_container,
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index e8ca3eb..a8e3e2d5 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -245,11 +245,10 @@ root_window_controller->Init(root_window_type); // TODO: To avoid lots of IPC AddActivationParent() should take an array. // http://crbug.com/682048. - WmWindow* root_window = root_window_controller->GetWindow(); + aura::Window* root_window = root_window_controller->GetRootWindow(); for (size_t i = 0; i < kNumActivatableShellWindowIds; ++i) { window_manager_client_->AddActivationParent( - root_window->GetChildByShellWindowId(kActivatableShellWindowIds[i]) - ->aura_window()); + root_window->GetChildById(kActivatableShellWindowIds[i])); } root_window_controllers_.insert(std::move(root_window_controller)); }
diff --git a/ash/mus/window_manager_application.cc b/ash/mus/window_manager_application.cc index d530f49d..abd098e 100644 --- a/ash/mus/window_manager_application.cc +++ b/ash/mus/window_manager_application.cc
@@ -22,7 +22,6 @@ #include "chromeos/system/fake_statistics_provider.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/dbus/bluez_dbus_manager.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/tracing/public/cpp/provider.h"
diff --git a/ash/mus/window_manager_unittest.cc b/ash/mus/window_manager_unittest.cc index 84f23a4..3604021 100644 --- a/ash/mus/window_manager_unittest.cc +++ b/ash/mus/window_manager_unittest.cc
@@ -87,7 +87,7 @@ WindowTreeClientDelegate window_tree_delegate; - connector()->Connect(mojom::kServiceName); + connector()->StartService(mojom::kServiceName); // Connect to mus and create a new top level window. The request goes to // |ash|, but is async.
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 38906af6..fa9d48b 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -20,6 +20,7 @@ #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_settings.h" +#include "ash/screen_util.h" #include "ash/session/session_controller.h" #include "ash/shelf/shelf_delegate.h" #include "ash/shelf/shelf_layout_manager.h" @@ -164,18 +165,17 @@ } // Reparents |window| to |new_parent|. -// TODO(sky): This should take an aura::Window. http://crbug.com/671246. -void ReparentWindow(WmWindow* window, WmWindow* new_parent) { - const gfx::Size src_size = window->GetParent()->GetBounds().size(); - const gfx::Size dst_size = new_parent->GetBounds().size(); +void ReparentWindow(aura::Window* window, aura::Window* new_parent) { + const gfx::Size src_size = window->parent()->bounds().size(); + const gfx::Size dst_size = new_parent->bounds().size(); // Update the restore bounds to make it relative to the display. - wm::WindowState* state = window->GetWindowState(); + wm::WindowState* state = wm::GetWindowState(window); gfx::Rect restore_bounds; const bool has_restore_bounds = state->HasRestoreBounds(); const bool update_bounds = state->IsNormalOrSnapped() || state->IsMinimized(); gfx::Rect work_area_in_new_parent = - wm::GetDisplayWorkAreaBoundsInParent(new_parent); + ScreenUtil::GetDisplayWorkAreaBoundsInParent(new_parent); gfx::Rect local_bounds; if (update_bounds) { @@ -201,8 +201,7 @@ } // Reparents the appropriate set of windows from |src| to |dst|. -// TODO(sky): This should take an aura::Window. http://crbug.com/671246. -void ReparentAllWindows(WmWindow* src, WmWindow* dst) { +void ReparentAllWindows(aura::Window* src, aura::Window* dst) { // Set of windows to move. const int kContainerIdsToMove[] = { kShellWindowId_DefaultContainer, @@ -228,15 +227,17 @@ } for (int id : container_ids) { - WmWindow* src_container = src->GetChildByShellWindowId(id); - WmWindow* dst_container = dst->GetChildByShellWindowId(id); - while (!src_container->GetChildren().empty()) { + aura::Window* src_container = src->GetChildById(id); + aura::Window* dst_container = dst->GetChildById(id); + while (!src_container->children().empty()) { // Restart iteration from the source container windows each time as they // may change as a result of moving other windows. - WmWindow::Windows src_container_children = src_container->GetChildren(); - WmWindow::Windows::const_iterator iter = src_container_children.begin(); + const aura::Window::Windows& src_container_children = + src_container->children(); + auto iter = src_container_children.begin(); while (iter != src_container_children.end() && - SystemModalContainerLayoutManager::IsModalBackground(*iter)) { + SystemModalContainerLayoutManager::IsModalBackground( + WmWindow::Get(*iter))) { ++iter; } // If the entire window list is modal background windows then stop. @@ -389,9 +390,8 @@ WmWindow* modal_container = nullptr; if (window) { WmWindow* window_container = wm::GetContainerForWindow(window); - if (window_container && - window_container->GetShellWindowId() >= - kShellWindowId_LockScreenContainer) { + if (window_container && window_container->aura_window()->id() >= + kShellWindowId_LockScreenContainer) { modal_container = GetWmContainer(kShellWindowId_LockSystemModalContainer); } else { modal_container = GetWmContainer(kShellWindowId_SystemModalContainer); @@ -618,7 +618,7 @@ void RootWindowController::MoveWindowsTo(aura::Window* dst) { // Clear the workspace controller, so it doesn't incorrectly update the shelf. workspace_controller_.reset(); - ReparentAllWindows(GetWindow(), WmWindow::Get(dst)); + ReparentAllWindows(GetRootWindow(), dst); } void RootWindowController::UpdateShelfVisibility() {
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 22bc7b2..ad89d6d7 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -77,9 +77,8 @@ // Returns true if the window is in the app list window container. bool IsAppListWindow(WmWindow* window) { - return window->GetParent() && - window->GetParent()->GetShellWindowId() == - kShellWindowId_AppListContainer; + return window->GetParent() && window->GetParent()->aura_window()->id() == + kShellWindowId_AppListContainer; } } // namespace
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 2b3fdfa..abaf370 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -148,7 +148,7 @@ params.delegate = delegate_view_; shelf_container->GetRootWindowController() ->ConfigureWidgetInitParamsForContainer( - this, shelf_container->GetShellWindowId(), ¶ms); + this, shelf_container->aura_window()->id(), ¶ms); Init(params); // The shelf should not take focus when initially shown.
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc index ed36c787..af2627c 100644 --- a/ash/system/status_area_widget.cc +++ b/ash/system/status_area_widget.cc
@@ -45,7 +45,7 @@ params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; status_container->GetRootWindowController() ->ConfigureWidgetInitParamsForContainer( - this, status_container->GetShellWindowId(), ¶ms); + this, status_container->aura_window()->id(), ¶ms); Init(params); set_focus_on_creation(false); SetContentsView(status_area_widget_delegate_);
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index d3b3f10a..6f6892a 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc
@@ -180,7 +180,7 @@ WmWindow* wm_gained_active = WmWindow::Get(gained_active); int container_id = - wm::GetContainerForWindow(wm_gained_active)->GetShellWindowId(); + wm::GetContainerForWindow(wm_gained_active)->aura_window()->id(); // Don't close the bubble if a popup notification is activated. if (container_id == kShellWindowId_StatusContainer)
diff --git a/ash/system/tray/tray_event_filter.cc b/ash/system/tray/tray_event_filter.cc index f6d98c2..df42c1b 100644 --- a/ash/system/tray/tray_event_filter.cc +++ b/ash/system/tray/tray_event_filter.cc
@@ -10,6 +10,7 @@ #include "ash/system/tray/tray_bubble_wrapper.h" #include "ash/wm/container_finder.h" #include "ash/wm_window.h" +#include "ui/aura/window.h" #include "ui/views/widget/widget.h" namespace ash { @@ -47,7 +48,7 @@ views::Widget* target) { if (target) { WmWindow* window = WmWindow::Get(target->GetNativeWindow()); - int container_id = wm::GetContainerForWindow(window)->GetShellWindowId(); + int container_id = wm::GetContainerForWindow(window)->aura_window()->id(); // Don't process events that occurred inside an embedded menu, for example // the right-click menu in a popup notification. if (container_id == kShellWindowId_MenuContainer)
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 90e7a6da..29591f6 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -13,7 +13,6 @@ #include "ash/root_window_controller.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/test/ash_test_base.h" #include "ash/test/test_session_controller_client.h" #include "ash/test/test_wallpaper_delegate.h" @@ -27,6 +26,7 @@ #include "base/threading/sequenced_worker_pool.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/aura/window.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/test/layer_animator_test_controller.h" #include "ui/gfx/canvas.h" @@ -49,9 +49,9 @@ // Returns number of child windows in a shell window container. int ChildCountForContainer(int container_id) { - WmWindow* root = ShellPort::Get()->GetPrimaryRootWindow(); - WmWindow* container = root->GetChildByShellWindowId(container_id); - return static_cast<int>(container->GetChildren().size()); + aura::Window* root = Shell::Get()->GetPrimaryRootWindow(); + aura::Window* container = root->GetChildById(container_id); + return static_cast<int>(container->children().size()); } // Steps a widget's layer animation until it is completed. Animations must be @@ -120,7 +120,7 @@ // Ash shell initialization creates wallpaper. Reset it so we can manually // control wallpaper creation and animation in our tests. RootWindowController* root_window_controller = - ShellPort::Get()->GetPrimaryRootWindow()->GetRootWindowController(); + Shell::Get()->GetPrimaryRootWindowController(); root_window_controller->SetWallpaperWidgetController(nullptr); root_window_controller->SetAnimatingWallpaperWidgetController(nullptr); controller_ = Shell::Get()->wallpaper_controller(); @@ -131,9 +131,8 @@ WallpaperView* wallpaper_view() { WallpaperWidgetController* controller = - ShellPort::Get() - ->GetPrimaryRootWindow() - ->GetRootWindowController() + Shell::Get() + ->GetPrimaryRootWindowController() ->animating_wallpaper_widget_controller() ->GetController(false); EXPECT_TRUE(controller); @@ -187,9 +186,8 @@ // TODO(bshe): Don't require tests to run animations; it's slow. void RunDesktopControllerAnimation() { WallpaperWidgetController* controller = - ShellPort::Get() - ->GetPrimaryRootWindow() - ->GetRootWindowController() + Shell::Get() + ->GetPrimaryRootWindowController() ->animating_wallpaper_widget_controller() ->GetController(false); EXPECT_TRUE(controller); @@ -266,7 +264,7 @@ // The new wallpaper is ready to animate. RootWindowController* root_window_controller = - ShellPort::Get()->GetPrimaryRootWindow()->GetRootWindowController(); + Shell::Get()->GetPrimaryRootWindowController(); EXPECT_TRUE(root_window_controller->animating_wallpaper_widget_controller() ->GetController(false)); EXPECT_FALSE(root_window_controller->wallpaper_widget_controller()); @@ -302,7 +300,7 @@ // In this state we have two wallpaper views stored in different properties. // Both are in the lock screen wallpaper container. RootWindowController* root_window_controller = - ShellPort::Get()->GetPrimaryRootWindow()->GetRootWindowController(); + Shell::Get()->GetPrimaryRootWindowController(); EXPECT_TRUE(root_window_controller->animating_wallpaper_widget_controller() ->GetController(false)); EXPECT_TRUE(root_window_controller->wallpaper_widget_controller()); @@ -343,7 +341,7 @@ controller->CreateEmptyWallpaper(); RootWindowController* root_window_controller = - ShellPort::Get()->GetPrimaryRootWindow()->GetRootWindowController(); + Shell::Get()->GetPrimaryRootWindowController(); WallpaperWidgetController* animating_controller = root_window_controller->animating_wallpaper_widget_controller() ->GetController(false);
diff --git a/ash/wm/always_on_top_controller.cc b/ash/wm/always_on_top_controller.cc index de8b48c..c5eabb3 100644 --- a/ash/wm/always_on_top_controller.cc +++ b/ash/wm/always_on_top_controller.cc
@@ -15,7 +15,7 @@ AlwaysOnTopController::AlwaysOnTopController(WmWindow* viewport) : always_on_top_container_(viewport) { - DCHECK_NE(kShellWindowId_DefaultContainer, viewport->GetShellWindowId()); + DCHECK_NE(kShellWindowId_DefaultContainer, viewport->aura_window()->id()); always_on_top_container_->SetLayoutManager( base::MakeUnique<WorkspaceLayoutManager>(viewport)); // Container should be empty.
diff --git a/ash/wm/container_finder.cc b/ash/wm/container_finder.cc index 03f553db..1371655 100644 --- a/ash/wm/container_finder.cc +++ b/ash/wm/container_finder.cc
@@ -46,7 +46,7 @@ // Otherwise those that originate from LockScreen container and above are // placed in the screen lock modal container. int window_container_id = - window->GetTransientParent()->GetParent()->GetShellWindowId(); + window->GetTransientParent()->GetParent()->aura_window()->id(); if (window_container_id < kShellWindowId_LockScreenContainer) return root->GetChildByShellWindowId(kShellWindowId_SystemModalContainer); return root->GetChildByShellWindowId(kShellWindowId_LockSystemModalContainer); @@ -64,7 +64,7 @@ WmWindow* GetContainerForWindow(WmWindow* window) { WmWindow* parent = window->GetParent(); // The first parent with an explicit shell window ID is the container. - while (parent && parent->GetShellWindowId() == kShellWindowId_Invalid) + while (parent && parent->aura_window()->id() == kShellWindowId_Invalid) parent = parent->GetParent(); return parent; } @@ -101,7 +101,7 @@ return target_root->GetChildByShellWindowId( kShellWindowId_DragImageAndTooltipContainer); default: - NOTREACHED() << "Window " << window->GetShellWindowId() + NOTREACHED() << "Window " << window->aura_window()->id() << " has unhandled type " << window->GetType(); break; }
diff --git a/ash/wm/container_finder_unittest.cc b/ash/wm/container_finder_unittest.cc index 459ac7d..44b8261 100644 --- a/ash/wm/container_finder_unittest.cc +++ b/ash/wm/container_finder_unittest.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/test/ash_test.h" #include "ash/wm_window.h" +#include "ui/aura/window.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/widget/widget.h" @@ -20,15 +21,15 @@ // Create a normal widget in the default container. std::unique_ptr<views::Widget> widget = CreateTestWidget(gfx::Rect(1, 2, 3, 4)); - WmWindow* window = WmWindow::Get(widget->GetNativeWindow()); + aura::Window* window = widget->GetNativeWindow(); // The window itself is not a container. - EXPECT_EQ(kShellWindowId_Invalid, window->GetShellWindowId()); + EXPECT_EQ(kShellWindowId_Invalid, window->id()); // Container lookup finds the default container. - WmWindow* container = wm::GetContainerForWindow(window); + WmWindow* container = wm::GetContainerForWindow(WmWindow::Get(window)); ASSERT_TRUE(container); - EXPECT_EQ(kShellWindowId_DefaultContainer, container->GetShellWindowId()); + EXPECT_EQ(kShellWindowId_DefaultContainer, container->aura_window()->id()); } } // namespace ash
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc index b8b835c..f7899c2 100644 --- a/ash/wm/default_state.cc +++ b/ash/wm/default_state.cc
@@ -18,6 +18,7 @@ #include "ash/wm/wm_event.h" #include "ash/wm/wm_screen_util.h" #include "ash/wm_window.h" +#include "ui/aura/window.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -55,12 +56,14 @@ if (!display_area.Intersects(restore_bounds)) { const display::Display& display = display::Screen::GetScreen()->GetDisplayMatching(restore_bounds); - WmWindow* new_root = - ShellPort::Get()->GetRootWindowForDisplayId(display.id()); - if (new_root != window_state->window()->GetRootWindow()) { - WmWindow* new_container = new_root->GetChildByShellWindowId( - window_state->window()->GetParent()->GetShellWindowId()); - new_container->AddChild(window_state->window()); + RootWindowController* new_root_controller = + Shell::Get()->GetRootWindowControllerWithDisplayId(display.id()); + if (new_root_controller->GetRootWindow() != + window_state->window()->GetRootWindow()->aura_window()) { + aura::Window* new_container = + new_root_controller->GetRootWindow()->GetChildById( + window_state->window()->GetParent()->aura_window()->id()); + new_container->AddChild(window_state->window()->aura_window()); } } }
diff --git a/ash/wm/focus_rules.cc b/ash/wm/focus_rules.cc index 4477e9d..6bb9484 100644 --- a/ash/wm/focus_rules.cc +++ b/ash/wm/focus_rules.cc
@@ -20,7 +20,7 @@ // The window must exist within a container that supports activation. // The window cannot be blocked by a modal transient. - return IsActivatableShellWindowId(window->GetParent()->GetShellWindowId()); + return IsActivatableShellWindowId(window->GetParent()->aura_window()->id()); } bool IsWindowConsideredActivatable(WmWindow* window) { @@ -51,7 +51,7 @@ if (!window->GetTargetVisibility()) return false; - const int parent_shell_window_id = window->GetParent()->GetShellWindowId(); + const int parent_shell_window_id = window->GetParent()->aura_window()->id(); return parent_shell_window_id == kShellWindowId_DefaultContainer || parent_shell_window_id == kShellWindowId_LockScreenContainer; }
diff --git a/ash/wm/maximize_mode/workspace_backdrop_delegate.cc b/ash/wm/maximize_mode/workspace_backdrop_delegate.cc index fc812136..496cc7f1 100644 --- a/ash/wm/maximize_mode/workspace_backdrop_delegate.cc +++ b/ash/wm/maximize_mode/workspace_backdrop_delegate.cc
@@ -35,9 +35,9 @@ // To disallow the MRU list from picking this window up it should not be // activateable. params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; - DCHECK_NE(kShellWindowId_Invalid, container_->GetShellWindowId()); + DCHECK_NE(kShellWindowId_Invalid, container_->aura_window()->id()); container_->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( - background_, container_->GetShellWindowId(), ¶ms); + background_, container_->aura_window()->id(), ¶ms); background_->Init(params); background_window_ = WmWindow::Get(background_->GetNativeWindow()); // Do not use the animation system. We don't want the bounds animation and
diff --git a/ash/wm/overview/scoped_transform_overview_window.cc b/ash/wm/overview/scoped_transform_overview_window.cc index 1f70ded9..71ac284e 100644 --- a/ash/wm/overview/scoped_transform_overview_window.cc +++ b/ash/wm/overview/scoped_transform_overview_window.cc
@@ -483,7 +483,7 @@ window_->GetRootWindow() ->GetRootWindowController() ->ConfigureWidgetInitParamsForContainer( - minimized_widget_.get(), window_->GetParent()->GetShellWindowId(), + minimized_widget_.get(), window_->GetParent()->aura_window()->id(), ¶ms); minimized_widget_->set_focus_on_creation(false); minimized_widget_->Init(params);
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc index 12aa74d..cba7519 100644 --- a/ash/wm/overview/window_selector.cc +++ b/ash/wm/overview/window_selector.cc
@@ -529,7 +529,7 @@ return; for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { - if (new_window->GetParent()->GetShellWindowId() == + if (new_window->GetParent()->aura_window()->id() == wm::kSwitchableWindowContainerIds[i] && !new_window->GetTransientParent()) { // The new window is in one of the switchable containers, abort overview.
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc index dd2acf6..eb53ce63 100644 --- a/ash/wm/overview/window_selector_item.cc +++ b/ash/wm/overview/window_selector_item.cc
@@ -619,7 +619,7 @@ root_window_->GetRootWindowController() ->ConfigureWidgetInitParamsForContainer( item_widget_.get(), - transform_window_.window()->GetParent()->GetShellWindowId(), + transform_window_.window()->GetParent()->aura_window()->id(), ¶ms_label); item_widget_->set_focus_on_creation(false); item_widget_->Init(params_label);
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 6cdd5e83..3548346f 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -516,9 +516,9 @@ ToggleOverview(); const std::vector<std::unique_ptr<WindowSelectorItem>>& overview1 = GetWindowItemsForRoot(0); - EXPECT_EQ(1, overview1[0]->GetWindow()->GetShellWindowId()); - EXPECT_EQ(3, overview1[1]->GetWindow()->GetShellWindowId()); - EXPECT_EQ(2, overview1[2]->GetWindow()->GetShellWindowId()); + EXPECT_EQ(1, overview1[0]->GetWindow()->aura_window()->id()); + EXPECT_EQ(3, overview1[1]->GetWindow()->aura_window()->id()); + EXPECT_EQ(2, overview1[2]->GetWindow()->aura_window()->id()); ToggleOverview(); // Activate the second window. @@ -528,9 +528,9 @@ GetWindowItemsForRoot(0); // The order should be MRU. - EXPECT_EQ(2, overview2[0]->GetWindow()->GetShellWindowId()); - EXPECT_EQ(1, overview2[1]->GetWindow()->GetShellWindowId()); - EXPECT_EQ(3, overview2[2]->GetWindow()->GetShellWindowId()); + EXPECT_EQ(2, overview2[0]->GetWindow()->aura_window()->id()); + EXPECT_EQ(1, overview2[1]->GetWindow()->aura_window()->id()); + EXPECT_EQ(3, overview2[2]->GetWindow()->aura_window()->id()); ToggleOverview(); } @@ -1403,7 +1403,7 @@ // string from the window IDs. const int index = index_path_for_direction[key_index][i]; EXPECT_EQ(GetSelectedWindow()->id(), - overview_windows[index - 1]->GetWindow()->GetShellWindowId()); + overview_windows[index - 1]->GetWindow()->aura_window()->id()); } ToggleOverview(); }
diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc index c3d9cd13..6478520 100644 --- a/ash/wm/panels/panel_layout_manager.cc +++ b/ash/wm/panels/panel_layout_manager.cc
@@ -222,7 +222,7 @@ params.bounds.set_height(kArrowHeight); params.accept_events = false; parent->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( - this, parent->GetShellWindowId(), ¶ms); + this, parent->aura_window()->id(), ¶ms); set_focus_on_creation(false); Init(params); WmWindow* widget_window = WmWindow::Get(this->GetNativeWindow()); @@ -274,8 +274,8 @@ return static_cast<PanelLayoutManager*>( window->GetRootWindow() - ->GetChildByShellWindowId(kShellWindowId_PanelContainer) ->aura_window() + ->GetChildById(kShellWindowId_PanelContainer) ->layout_manager()); }
diff --git a/ash/wm/switchable_windows.cc b/ash/wm/switchable_windows.cc index 6e0920d..a82e3dd6 100644 --- a/ash/wm/switchable_windows.cc +++ b/ash/wm/switchable_windows.cc
@@ -6,6 +6,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/wm_window.h" +#include "ui/aura/window.h" namespace ash { namespace wm { @@ -20,7 +21,7 @@ bool IsSwitchableContainer(const WmWindow* window) { if (!window) return false; - const int shell_window_id = window->GetShellWindowId(); + const int shell_window_id = window->aura_window()->id(); for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { if (shell_window_id == kSwitchableWindowContainerIds[i]) return true;
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc index d76a045b..1a2d659 100644 --- a/ash/wm/system_modal_container_layout_manager.cc +++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -81,7 +81,7 @@ // TODO(mash): IsUserSessionBlocked() depends on knowing the login state. We // need a non-stub version of SessionStateDelegate. crbug.com/648964 if (Shell::GetAshConfig() != Config::MASH) { - DCHECK(container_->GetShellWindowId() != + DCHECK(container_->aura_window()->id() != kShellWindowId_LockSystemModalContainer || Shell::Get()->session_controller()->IsUserSessionBlocked()); } @@ -184,7 +184,7 @@ // static bool SystemModalContainerLayoutManager::IsModalBackground(WmWindow* window) { - int id = window->GetParent()->GetShellWindowId(); + int id = window->GetParent()->aura_window()->id(); if (id != kShellWindowId_SystemModalContainer && id != kShellWindowId_LockSystemModalContainer) return false;
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc index 7140703a..f5e981ad 100644 --- a/ash/wm/window_positioning_utils.cc +++ b/ash/wm/window_positioning_utils.cc
@@ -50,7 +50,7 @@ WmWindow* dst_root = Shell::GetRootWindowControllerWithDisplayId(display.id())->GetWindow(); for (WmWindow* transient_child : window->GetTransientChildren()) { - const int container_id = transient_child->GetParent()->GetShellWindowId(); + const int container_id = transient_child->GetParent()->aura_window()->id(); DCHECK_GE(container_id, 0); WmWindow* container = dst_root->GetChildByShellWindowId(container_id); const gfx::Rect transient_child_bounds_in_screen = @@ -144,7 +144,7 @@ DCHECK(dst_root); WmWindow* dst_container = nullptr; if (dst_root != window->GetRootWindow()) { - int container_id = window->GetParent()->GetShellWindowId(); + int container_id = window->GetParent()->aura_window()->id(); // All containers that uses screen coordinates must have valid window ids. DCHECK_GE(container_id, 0); // Don't move modal background.
diff --git a/ash/wm/wm_snap_to_pixel_layout_manager.cc b/ash/wm/wm_snap_to_pixel_layout_manager.cc index e27d77e..a645cc8 100644 --- a/ash/wm/wm_snap_to_pixel_layout_manager.cc +++ b/ash/wm/wm_snap_to_pixel_layout_manager.cc
@@ -20,8 +20,8 @@ // static void WmSnapToPixelLayoutManager::InstallOnContainers(WmWindow* window) { for (WmWindow* child : window->GetChildren()) { - if (child->GetShellWindowId() < kShellWindowId_Min || - child->GetShellWindowId() > kShellWindowId_Max) // not a container + if (child->aura_window()->id() < kShellWindowId_Min || + child->aura_window()->id() > kShellWindowId_Max) // not a container continue; if (child->aura_window()->GetProperty(kSnapChildrenToPixelBoundary)) { if (!child->GetLayoutManager() && !child->aura_window()->layout_manager())
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc index 143d922..d334e9c 100644 --- a/ash/wm/workspace/phantom_window_controller.cc +++ b/ash/wm/workspace/phantom_window_controller.cc
@@ -120,7 +120,7 @@ phantom_widget->SetVisibilityChangedAnimationsEnabled(false); WmWindow* phantom_widget_window = WmWindow::Get(phantom_widget->GetNativeWindow()); - phantom_widget_window->SetShellWindowId(kShellWindowId_PhantomWindow); + phantom_widget_window->aura_window()->set_id(kShellWindowId_PhantomWindow); phantom_widget->SetBounds(bounds_in_screen); // TODO(sky): I suspect this is never true, verify that. if (phantom_widget_window->GetParent() == window_->GetParent()) {
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index 9eb5c6c..2017cdd 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -374,7 +374,7 @@ // only windows in the default workspace container will go fullscreen but // this should really be tracked by the RootWindowController since // technically any container could get a fullscreen window. - if (window_->GetShellWindowId() != kShellWindowId_DefaultContainer) + if (window_->aura_window()->id() != kShellWindowId_DefaultContainer) return; bool is_fullscreen = wm::GetWindowForFullscreenMode(window_) != nullptr; if (is_fullscreen != is_fullscreen_) {
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 8b227d4..8243788b 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -72,7 +72,7 @@ window_state->CreateDragDetails(point_in_parent, window_component, source); const int parent_shell_window_id = - window->GetParent() ? window->GetParent()->GetShellWindowId() : -1; + window->GetParent() ? window->GetParent()->aura_window()->id() : -1; if (window->GetParent() && (parent_shell_window_id == kShellWindowId_DefaultContainer || parent_shell_window_id == kShellWindowId_PanelContainer)) {
diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc index af1162e8..14ca8c9 100644 --- a/ash/wm/workspace_controller.cc +++ b/ash/wm/workspace_controller.cc
@@ -12,12 +12,14 @@ #include "ash/shell_port.h" #include "ash/wm/fullscreen_window_finder.h" #include "ash/wm/window_state.h" +#include "ash/wm/window_state_aura.h" #include "ash/wm/wm_window_animations.h" #include "ash/wm/workspace/workspace_event_handler.h" #include "ash/wm/workspace/workspace_layout_manager.h" #include "ash/wm/workspace/workspace_layout_manager_backdrop_delegate.h" #include "ash/wm_window.h" #include "base/memory/ptr_util.h" +#include "ui/aura/window.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" @@ -62,17 +64,18 @@ bool window_overlaps_launcher = false; // The default container may contain windows that may overlap the launcher // shelf and affect its transparency. - WmWindow* container = viewport_->GetRootWindow()->GetChildByShellWindowId( - kShellWindowId_DefaultContainer); - for (WmWindow* window : container->GetChildren()) { - wm::WindowState* window_state = window->GetWindowState(); + aura::Window* container = + viewport_->GetRootWindow()->aura_window()->GetChildById( + kShellWindowId_DefaultContainer); + for (aura::Window* window : container->children()) { + wm::WindowState* window_state = wm::GetWindowState(window); if (window_state->ignored_by_shelf() || - (window->GetLayer() && !window->GetLayer()->GetTargetVisibility())) { + (window->layer() && !window->layer()->GetTargetVisibility())) { continue; } if (window_state->IsMaximized()) return wm::WORKSPACE_WINDOW_STATE_MAXIMIZED; - window_overlaps_launcher |= window->GetBounds().Intersects(shelf_bounds); + window_overlaps_launcher |= window->bounds().Intersects(shelf_bounds); } return window_overlaps_launcher
diff --git a/ash/wm_window.cc b/ash/wm_window.cc index aa950b0..186d14e 100644 --- a/ash/wm_window.cc +++ b/ash/wm_window.cc
@@ -155,14 +155,6 @@ return root ? RootWindowController::ForWindow(root) : nullptr; } -void WmWindow::SetShellWindowId(int id) { - window_->set_id(id); -} - -int WmWindow::GetShellWindowId() const { - return window_->id(); -} - ui::wm::WindowType WmWindow::GetType() const { return window_->type(); }
diff --git a/ash/wm_window.h b/ash/wm_window.h index 7ce8e27..de47237a 100644 --- a/ash/wm_window.h +++ b/ash/wm_window.h
@@ -109,8 +109,6 @@ RootWindowController* GetRootWindowController(); // See shell_window_ids.h for list of known ids. - void SetShellWindowId(int id); - int GetShellWindowId() const; WmWindow* GetChildByShellWindowId(int id); ui::wm::WindowType GetType() const;
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 48686b8..f7918544 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -523,6 +523,8 @@ "test/fake_compositor_frame_sink.h", "test/fake_compositor_frame_sink_client.cc", "test/fake_compositor_frame_sink_client.h", + "test/fake_compositor_frame_sink_support_client.cc", + "test/fake_compositor_frame_sink_support_client.h", "test/fake_content_layer_client.cc", "test/fake_content_layer_client.h", "test/fake_external_begin_frame_source.cc",
diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc index d1227031..84b0a41 100644 --- a/cc/surfaces/compositor_frame_sink_support.cc +++ b/cc/surfaces/compositor_frame_sink_support.cc
@@ -74,7 +74,6 @@ const ReturnedResourceArray& resources) { if (resources.empty()) return; - if (!ack_pending_count_ && client_) { client_->ReclaimResources(resources); return;
diff --git a/cc/surfaces/display_unittest.cc b/cc/surfaces/display_unittest.cc index d9559eea..603d068 100644 --- a/cc/surfaces/display_unittest.cc +++ b/cc/surfaces/display_unittest.cc
@@ -14,13 +14,12 @@ #include "cc/quads/render_pass.h" #include "cc/resources/shared_bitmap_manager.h" #include "cc/scheduler/begin_frame_source.h" +#include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/display_client.h" #include "cc/surfaces/display_scheduler.h" #include "cc/surfaces/frame_sink_id.h" #include "cc/surfaces/local_surface_id_allocator.h" #include "cc/surfaces/surface.h" -#include "cc/surfaces/surface_factory.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" #include "cc/test/fake_output_surface.h" #include "cc/test/scheduler_test_common.h" @@ -36,22 +35,6 @@ static constexpr FrameSinkId kArbitraryFrameSinkId(3, 3); -class FakeSurfaceFactoryClient : public SurfaceFactoryClient { - public: - FakeSurfaceFactoryClient() : begin_frame_source_(nullptr) {} - - void ReturnResources(const ReturnedResourceArray& resources) override {} - - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override { - begin_frame_source_ = begin_frame_source; - } - - BeginFrameSource* begin_frame_source() { return begin_frame_source_; } - - private: - BeginFrameSource* begin_frame_source_; -}; - class TestSoftwareOutputDevice : public SoftwareOutputDevice { public: TestSoftwareOutputDevice() {} @@ -99,15 +82,16 @@ class DisplayTest : public testing::Test { public: DisplayTest() - : factory_(kArbitraryFrameSinkId, &manager_, &surface_factory_client_), - task_runner_(new base::NullTaskRunner) { - manager_.RegisterFrameSinkId(kArbitraryFrameSinkId); - } + : support_(CompositorFrameSinkSupport::Create( + nullptr, + &manager_, + kArbitraryFrameSinkId, + true /* is_root */, + true /* handles_frame_sink_id_invalidation */, + true /* needs_sync_points */)), + task_runner_(new base::NullTaskRunner) {} - ~DisplayTest() override { - manager_.InvalidateFrameSinkId(kArbitraryFrameSinkId); - factory_.EvictSurface(); - } + ~DisplayTest() override { support_->EvictFrame(); } void SetUpDisplay(const RendererSettings& settings, std::unique_ptr<TestWebGraphicsContext3D> context) { @@ -144,13 +128,11 @@ CompositorFrame frame; pass_list->swap(frame.render_pass_list); - factory_.SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); } SurfaceManager manager_; - FakeSurfaceFactoryClient surface_factory_client_; - SurfaceFactory factory_; + std::unique_ptr<CompositorFrameSinkSupport> support_; LocalSurfaceIdAllocator id_allocator_; scoped_refptr<base::NullTaskRunner> task_runner_; TestSharedBitmapManager shared_bitmap_manager_; @@ -352,8 +334,7 @@ pass_list.swap(frame.render_pass_list); frame.metadata.latency_info.push_back(ui::LatencyInfo()); - factory_.SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); EXPECT_TRUE(scheduler_->damaged); EXPECT_FALSE(scheduler_->display_resized_); EXPECT_FALSE(scheduler_->has_new_root_surface); @@ -382,8 +363,7 @@ CompositorFrame frame; pass_list.swap(frame.render_pass_list); - factory_.SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); EXPECT_TRUE(scheduler_->damaged); EXPECT_FALSE(scheduler_->display_resized_); EXPECT_FALSE(scheduler_->has_new_root_surface);
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc index 0e4e133a..04cca79 100644 --- a/cc/surfaces/surface_aggregator_unittest.cc +++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -18,11 +18,11 @@ #include "cc/quads/surface_draw_quad.h" #include "cc/quads/texture_draw_quad.h" #include "cc/resources/shared_bitmap_manager.h" +#include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/local_surface_id_allocator.h" #include "cc/surfaces/surface.h" -#include "cc/surfaces/surface_factory.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" +#include "cc/test/fake_compositor_frame_sink_support_client.h" #include "cc/test/fake_resource_provider.h" #include "cc/test/render_pass_test_utils.h" #include "cc/test/surface_aggregator_test_helpers.h" @@ -35,10 +35,16 @@ namespace { constexpr FrameSinkId kArbitraryRootFrameSinkId(1, 1); -constexpr FrameSinkId kArbitraryChildFrameSinkId1(2, 2); -constexpr FrameSinkId kArbitraryChildFrameSinkId2(3, 3); +constexpr FrameSinkId kArbitraryFrameSinkId1(2, 2); +constexpr FrameSinkId kArbitraryFrameSinkId2(3, 3); constexpr FrameSinkId kArbitraryMiddleFrameSinkId(4, 4); +constexpr FrameSinkId kArbitraryReservedFrameSinkId(5, 5); +constexpr FrameSinkId kArbitraryFrameSinkId3(6, 6); const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create(); +constexpr bool kRootIsRoot = true; +constexpr bool kChildIsRoot = false; +constexpr bool kHandlesFrameSinkIdInvalidation = true; +constexpr bool kNeedsSyncPoints = false; SurfaceId InvalidSurfaceId() { static SurfaceId invalid(FrameSinkId(), @@ -51,47 +57,36 @@ return size; } -class EmptySurfaceFactoryClient : public SurfaceFactoryClient { - public: - void ReturnResources(const ReturnedResourceArray& resources) override {} - - void WillDrawSurface(const LocalSurfaceId& id, - const gfx::Rect& damage_rect) override { - last_local_surface_id_ = id; - last_damage_rect_ = damage_rect; - } - - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {} - - gfx::Rect last_damage_rect_; - LocalSurfaceId last_local_surface_id_; -}; - class SurfaceAggregatorTest : public testing::Test { public: explicit SurfaceAggregatorTest(bool use_damage_rect) - : factory_(kArbitraryRootFrameSinkId, &manager_, &empty_client_), + : support_( + CompositorFrameSinkSupport::Create(&fake_client_, + &manager_, + kArbitraryRootFrameSinkId, + kRootIsRoot, + kHandlesFrameSinkIdInvalidation, + kNeedsSyncPoints)), aggregator_(&manager_, NULL, use_damage_rect) {} SurfaceAggregatorTest() : SurfaceAggregatorTest(false) {} void TearDown() override { - factory_.EvictSurface(); + support_->EvictFrame(); testing::Test::TearDown(); } protected: SurfaceManager manager_; - EmptySurfaceFactoryClient empty_client_; - SurfaceFactory factory_; + FakeCompositorFrameSinkSupportClient fake_client_; + std::unique_ptr<CompositorFrameSinkSupport> support_; SurfaceAggregator aggregator_; }; TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { LocalSurfaceId local_surface_id(7, base::UnguessableToken::Create()); SurfaceId one_id(kArbitraryRootFrameSinkId, local_surface_id); - factory_.SubmitCompositorFrame(local_surface_id, CompositorFrame(), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(local_surface_id, CompositorFrame()); CompositorFrame frame = aggregator_.Aggregate(one_id); EXPECT_TRUE(frame.render_pass_list.empty()); @@ -101,9 +96,13 @@ public: explicit SurfaceAggregatorValidSurfaceTest(bool use_damage_rect) : SurfaceAggregatorTest(use_damage_rect), - child_factory_(kArbitraryChildFrameSinkId1, - &manager_, - &empty_child_client_) {} + child_support_( + CompositorFrameSinkSupport::Create(nullptr, + &manager_, + kArbitraryReservedFrameSinkId, + kChildIsRoot, + kHandlesFrameSinkIdInvalidation, + kNeedsSyncPoints)) {} SurfaceAggregatorValidSurfaceTest() : SurfaceAggregatorValidSurfaceTest(false) {} @@ -111,11 +110,11 @@ SurfaceAggregatorTest::SetUp(); root_local_surface_id_ = allocator_.GenerateId(); root_surface_ = manager_.GetSurfaceForId( - SurfaceId(factory_.frame_sink_id(), root_local_surface_id_)); + SurfaceId(support_->frame_sink_id(), root_local_surface_id_)); } void TearDown() override { - child_factory_.EvictSurface(); + child_support_->EvictFrame(); SurfaceAggregatorTest::TearDown(); } @@ -124,7 +123,7 @@ SurfaceId* surface_ids, size_t expected_surface_count) { CompositorFrame aggregated_frame = aggregator_.Aggregate( - SurfaceId(factory_.frame_sink_id(), root_local_surface_id_)); + SurfaceId(support_->frame_sink_id(), root_local_surface_id_)); TestPassesMatchExpectations(expected_passes, expected_pass_count, &aggregated_frame.render_pass_list); @@ -144,41 +143,38 @@ } } - void SubmitPassListAsFrame(SurfaceFactory* factory, + void SubmitPassListAsFrame(CompositorFrameSinkSupport* support, const LocalSurfaceId& local_surface_id, RenderPassList* pass_list) { CompositorFrame frame; pass_list->swap(frame.render_pass_list); - factory->SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(local_surface_id, std::move(frame)); } - void SubmitCompositorFrame(SurfaceFactory* factory, + void SubmitCompositorFrame(CompositorFrameSinkSupport* support, test::Pass* passes, size_t pass_count, const LocalSurfaceId& local_surface_id) { RenderPassList pass_list; AddPasses(&pass_list, gfx::Rect(SurfaceSize()), passes, pass_count); - SubmitPassListAsFrame(factory, local_surface_id, &pass_list); + SubmitPassListAsFrame(support, local_surface_id, &pass_list); } void QueuePassAsFrame(std::unique_ptr<RenderPass> pass, const LocalSurfaceId& local_surface_id, - SurfaceFactory* factory) { + CompositorFrameSinkSupport* support) { CompositorFrame child_frame; child_frame.render_pass_list.push_back(std::move(pass)); - factory->SubmitCompositorFrame(local_surface_id, std::move(child_frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(local_surface_id, std::move(child_frame)); } protected: LocalSurfaceId root_local_surface_id_; Surface* root_surface_; LocalSurfaceIdAllocator allocator_; - EmptySurfaceFactoryClient empty_child_client_; - SurfaceFactory child_factory_; + std::unique_ptr<CompositorFrameSinkSupport> child_support_; LocalSurfaceIdAllocator child_allocator_; }; @@ -189,24 +185,26 @@ test::Quad::SolidColorQuad(SK_ColorBLUE)}; test::Pass passes[] = {test::Pass(quads, arraysize(quads))}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id}; AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids)); // Check that WillDrawSurface was called. - EXPECT_EQ(gfx::Rect(SurfaceSize()), empty_client_.last_damage_rect_); - EXPECT_EQ(root_local_surface_id_, empty_client_.last_local_surface_id_); + EXPECT_EQ(gfx::Rect(SurfaceSize()), fake_client_.last_damage_rect()); + EXPECT_EQ(root_local_surface_id_, fake_client_.last_local_surface_id()); } TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) { - SurfaceFactory embedded_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> embedded_support( + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId(); - SurfaceId embedded_surface_id(embedded_factory.frame_sink_id(), + SurfaceId embedded_surface_id(embedded_support->frame_sink_id(), embedded_local_surface_id); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN), @@ -214,17 +212,17 @@ test::Pass embedded_passes[] = { test::Pass(embedded_quads, arraysize(embedded_quads))}; - SubmitCompositorFrame(&embedded_factory, embedded_passes, + SubmitCompositorFrame(embedded_support.get(), embedded_passes, arraysize(embedded_passes), embedded_local_surface_id); test::Quad quads[] = { test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), .5f)}; test::Pass passes[] = {test::Pass(quads, arraysize(quads))}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); RenderPassList& render_pass_list(aggregated_frame.render_pass_list); @@ -240,7 +238,7 @@ ASSERT_EQ(1u, shared_quad_state_list2.size()); EXPECT_EQ(.5f, shared_quad_state_list2.ElementAt(0)->opacity); - embedded_factory.EvictSurface(); + embedded_support->EvictFrame(); } TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) { @@ -251,10 +249,10 @@ test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0]), 1), test::Pass(quads[1], arraysize(quads[1]), 2)}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id}; AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids)); @@ -269,10 +267,10 @@ test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0]), 2), test::Pass(quads[1], arraysize(quads[1]), 1)}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); - SurfaceId surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame; aggregated_frame = aggregator_.Aggregate(surface_id); @@ -288,7 +286,7 @@ test::Pass passes2[] = {test::Pass(quads[0], arraysize(quads[0]), 3), test::Pass(quads[1], arraysize(quads[1]), 1)}; - SubmitCompositorFrame(&factory_, passes2, arraysize(passes2), + SubmitCompositorFrame(support_.get(), passes2, arraysize(passes2), root_local_surface_id_); // The RenderPass that still exists should keep the same ID. @@ -298,7 +296,7 @@ EXPECT_NE(id2, id0); EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id); - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); // |id1| didn't exist in the previous frame, so it should be @@ -316,17 +314,19 @@ // embedded_surface has a frame containing only a solid color quad. The solid // color quad should be aggregated into the final frame. TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) { - SurfaceFactory embedded_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> embedded_support( + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId(); - SurfaceId embedded_surface_id(embedded_factory.frame_sink_id(), + SurfaceId embedded_surface_id(embedded_support->frame_sink_id(), embedded_local_surface_id); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { test::Pass(embedded_quads, arraysize(embedded_quads))}; - SubmitCompositorFrame(&embedded_factory, embedded_passes, + SubmitCompositorFrame(embedded_support.get(), embedded_passes, arraysize(embedded_passes), embedded_local_surface_id); test::Quad root_quads[] = { @@ -335,7 +335,7 @@ test::Quad::SolidColorQuad(SK_ColorBLACK)}; test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; - SubmitCompositorFrame(&factory_, root_passes, arraysize(root_passes), + SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes), root_local_surface_id_); test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE), @@ -343,28 +343,32 @@ test::Quad::SolidColorQuad(SK_ColorBLACK)}; test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id, embedded_surface_id}; AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); - embedded_factory.EvictSurface(); + embedded_support->EvictFrame(); } // This test verifies that in the absence of a primary Surface, // SurfaceAggregator will embed a fallback Surface, if available. If the primary // Surface is available, though, the fallback will not be used. TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) { - SurfaceFactory primary_child_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> primary_child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId(); - SurfaceId primary_child_surface_id(primary_child_factory.frame_sink_id(), + SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(), primary_child_local_surface_id); - SurfaceFactory fallback_child_factory(kArbitraryChildFrameSinkId2, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> fallback_child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId(); - SurfaceId fallback_child_surface_id(fallback_child_factory.frame_sink_id(), + SurfaceId fallback_child_surface_id(fallback_child_support->frame_sink_id(), fallback_child_local_surface_id); test::Quad fallback_child_quads[] = {test::Quad::SolidColorQuad(SK_ColorRED)}; @@ -373,7 +377,7 @@ // Submit a CompositorFrame to the fallback Surface containing a red // SolidColorDrawQuad. - SubmitCompositorFrame(&fallback_child_factory, fallback_child_passes, + SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes, arraysize(fallback_child_passes), fallback_child_local_surface_id); @@ -383,7 +387,7 @@ primary_child_surface_id, fallback_child_surface_id, 1.f)}; test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; - SubmitCompositorFrame(&factory_, root_passes, arraysize(root_passes), + SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes), root_local_surface_id_); // There is no CompositorFrame submitted to |primary_child_surface_id| and so @@ -393,7 +397,7 @@ test::Pass expected_passes1[] = { test::Pass(expected_quads1, arraysize(expected_quads1))}; - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id, primary_child_surface_id, fallback_child_surface_id}; AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids, @@ -406,7 +410,7 @@ // Submit a CompositorFrame to the primary Surface containing a green // SolidColorDrawQuad. - SubmitCompositorFrame(&primary_child_factory, primary_child_passes, + SubmitCompositorFrame(primary_child_support.get(), primary_child_passes, arraysize(primary_child_passes), primary_child_local_surface_id); @@ -419,17 +423,19 @@ AggregateAndVerify(expected_passes2, arraysize(expected_passes2), ids, arraysize(ids)); - primary_child_factory.EvictSurface(); - fallback_child_factory.EvictSurface(); + primary_child_support->EvictFrame(); + fallback_child_support->EvictFrame(); } // This test verifies that in the presence of both primary Surface and fallback // Surface, the fallback will not be used. TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) { - SurfaceFactory primary_child_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> primary_child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId(); - SurfaceId primary_child_surface_id(primary_child_factory.frame_sink_id(), + SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(), primary_child_local_surface_id); test::Quad primary_child_quads[] = { test::Quad::SolidColorQuad(SK_ColorGREEN)}; @@ -438,14 +444,16 @@ // Submit a CompositorFrame to the primary Surface containing a green // SolidColorDrawQuad. - SubmitCompositorFrame(&primary_child_factory, primary_child_passes, + SubmitCompositorFrame(primary_child_support.get(), primary_child_passes, arraysize(primary_child_passes), primary_child_local_surface_id); - SurfaceFactory fallback_child_factory(kArbitraryChildFrameSinkId2, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> fallback_child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId(); - SurfaceId fallback_child_surface_id(fallback_child_factory.frame_sink_id(), + SurfaceId fallback_child_surface_id(fallback_child_support->frame_sink_id(), fallback_child_local_surface_id); test::Quad fallback_child_quads[] = {test::Quad::SolidColorQuad(SK_ColorRED)}; @@ -454,7 +462,7 @@ // Submit a CompositorFrame to the fallback Surface containing a red // SolidColorDrawQuad. - SubmitCompositorFrame(&fallback_child_factory, fallback_child_passes, + SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes, arraysize(fallback_child_passes), fallback_child_local_surface_id); @@ -464,7 +472,7 @@ primary_child_surface_id, fallback_child_surface_id, 1.f)}; test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; - SubmitCompositorFrame(&factory_, root_passes, arraysize(root_passes), + SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes), root_local_surface_id_); // The CompositorFrame is submitted to |primary_child_surface_id|, so @@ -474,33 +482,35 @@ test::Pass expected_passes1[] = { test::Pass(expected_quads1, arraysize(expected_quads1))}; - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id, primary_child_surface_id, fallback_child_surface_id}; AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids, arraysize(ids)); - primary_child_factory.EvictSurface(); - fallback_child_factory.EvictSurface(); + primary_child_support->EvictFrame(); + fallback_child_support->EvictFrame(); } TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) { - SurfaceFactory embedded_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> embedded_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId(); - SurfaceId embedded_surface_id(embedded_factory.frame_sink_id(), + SurfaceId embedded_surface_id(embedded_support->frame_sink_id(), embedded_local_surface_id); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { test::Pass(embedded_quads, arraysize(embedded_quads))}; - SubmitCompositorFrame(&embedded_factory, embedded_passes, + SubmitCompositorFrame(embedded_support.get(), embedded_passes, arraysize(embedded_passes), embedded_local_surface_id); std::unique_ptr<CopyOutputRequest> copy_request( CopyOutputRequest::CreateEmptyRequest()); CopyOutputRequest* copy_request_ptr = copy_request.get(); - embedded_factory.RequestCopyOfSurface(std::move(copy_request)); + embedded_support->RequestCopyOfSurface(std::move(copy_request)); test::Quad root_quads[] = { test::Quad::SolidColorQuad(SK_ColorWHITE), @@ -508,10 +518,10 @@ test::Quad::SolidColorQuad(SK_ColorBLACK)}; test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; - SubmitCompositorFrame(&factory_, root_passes, arraysize(root_passes), + SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); test::Quad expected_quads[] = { @@ -537,22 +547,24 @@ aggregator_.previous_contained_surfaces().end()); } - embedded_factory.EvictSurface(); + embedded_support->EvictFrame(); } // Root surface may contain copy requests. TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) { - SurfaceFactory embedded_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> embedded_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId(); - SurfaceId embedded_surface_id(embedded_factory.frame_sink_id(), + SurfaceId embedded_surface_id(embedded_support->frame_sink_id(), embedded_local_surface_id); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { test::Pass(embedded_quads, arraysize(embedded_quads))}; - SubmitCompositorFrame(&embedded_factory, embedded_passes, + SubmitCompositorFrame(embedded_support.get(), embedded_passes, arraysize(embedded_passes), embedded_local_surface_id); std::unique_ptr<CopyOutputRequest> copy_request( CopyOutputRequest::CreateEmptyRequest()); @@ -577,11 +589,10 @@ frame.render_pass_list[1]->copy_requests.push_back( std::move(copy_request2)); - factory_.SubmitCompositorFrame(root_local_surface_id_, std::move(frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame)); } - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE), @@ -617,33 +628,37 @@ DCHECK(original_pass_list[0]->copy_requests.empty()); DCHECK(original_pass_list[1]->copy_requests.empty()); - embedded_factory.EvictSurface(); + embedded_support->EvictFrame(); } TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) { - SurfaceFactory embedded_factory(kArbitraryChildFrameSinkId1, &manager_, - &empty_client_); - SurfaceFactory parent_factory(kArbitraryRootFrameSinkId, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> embedded_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> parent_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId2, kRootIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId(); - SurfaceId embedded_surface_id(embedded_factory.frame_sink_id(), + SurfaceId embedded_surface_id(embedded_support->frame_sink_id(), embedded_local_surface_id); - SurfaceId nonexistent_surface_id(factory_.frame_sink_id(), + SurfaceId nonexistent_surface_id(support_->frame_sink_id(), allocator_.GenerateId()); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { test::Pass(embedded_quads, arraysize(embedded_quads))}; - SubmitCompositorFrame(&embedded_factory, embedded_passes, + SubmitCompositorFrame(embedded_support.get(), embedded_passes, arraysize(embedded_passes), embedded_local_surface_id); std::unique_ptr<CopyOutputRequest> copy_request( CopyOutputRequest::CreateEmptyRequest()); CopyOutputRequest* copy_request_ptr = copy_request.get(); - embedded_factory.RequestCopyOfSurface(std::move(copy_request)); + embedded_support->RequestCopyOfSurface(std::move(copy_request)); LocalSurfaceId parent_local_surface_id = allocator_.GenerateId(); - SurfaceId parent_surface_id(parent_factory.frame_sink_id(), + SurfaceId parent_surface_id(parent_support->frame_sink_id(), parent_local_surface_id); test::Quad parent_quads[] = { @@ -661,9 +676,8 @@ frame.metadata.referenced_surfaces.push_back(embedded_surface_id); - parent_factory.SubmitCompositorFrame(parent_local_surface_id, - std::move(frame), - SurfaceFactory::DrawCallback()); + parent_support->SubmitCompositorFrame(parent_local_surface_id, + std::move(frame)); } test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE), @@ -680,11 +694,10 @@ // included in previous_contained_surfaces, but otherwise ignored. frame.metadata.referenced_surfaces.push_back(nonexistent_surface_id); - factory_.SubmitCompositorFrame(root_local_surface_id_, std::move(frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame)); } - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); // First pass should come from surface that had a copy request but was not @@ -702,7 +715,7 @@ aggregated_frame.render_pass_list[0]->copy_requests[0].get()); SurfaceId surface_ids[] = { - SurfaceId(factory_.frame_sink_id(), root_local_surface_id_), + SurfaceId(support_->frame_sink_id(), root_local_surface_id_), parent_surface_id, embedded_surface_id, nonexistent_surface_id}; EXPECT_EQ(arraysize(surface_ids), aggregator_.previous_contained_surfaces().size()); @@ -712,14 +725,14 @@ aggregator_.previous_contained_surfaces().end()); } - embedded_factory.EvictSurface(); - parent_factory.EvictSurface(); + embedded_support->EvictFrame(); + parent_support->EvictFrame(); } // This tests referencing a surface that has multiple render passes. TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) { LocalSurfaceId embedded_local_surface_id = child_allocator_.GenerateId(); - SurfaceId embedded_surface_id(child_factory_.frame_sink_id(), + SurfaceId embedded_surface_id(child_support_->frame_sink_id(), embedded_local_surface_id); int pass_ids[] = {1, 2, 3}; @@ -733,7 +746,7 @@ test::Pass(embedded_quads[1], arraysize(embedded_quads[1]), pass_ids[1]), test::Pass(embedded_quads[2], arraysize(embedded_quads[2]), pass_ids[2])}; - SubmitCompositorFrame(&child_factory_, embedded_passes, + SubmitCompositorFrame(child_support_.get(), embedded_passes, arraysize(embedded_passes), embedded_local_surface_id); test::Quad root_quads[][2] = { @@ -746,10 +759,10 @@ test::Pass(root_quads[1], arraysize(root_quads[1]), pass_ids[1]), test::Pass(root_quads[2], arraysize(root_quads[2]), pass_ids[2])}; - SubmitCompositorFrame(&factory_, root_passes, arraysize(root_passes), + SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -861,14 +874,14 @@ test::Quad::SolidColorQuad(SK_ColorBLUE)}; test::Pass passes[] = {test::Pass(quads, arraysize(quads))}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN), test::Quad::SolidColorQuad(SK_ColorBLUE)}; test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id, InvalidSurfaceId()}; AggregateAndVerify( @@ -879,7 +892,7 @@ // should also just be dropped. TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) { LocalSurfaceId empty_local_surface_id = allocator_.GenerateId(); - SurfaceId surface_with_no_frame_id(factory_.frame_sink_id(), + SurfaceId surface_with_no_frame_id(support_->frame_sink_id(), empty_local_surface_id); test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN), @@ -888,14 +901,14 @@ test::Quad::SolidColorQuad(SK_ColorBLUE)}; test::Pass passes[] = {test::Pass(quads, arraysize(quads))}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN), test::Quad::SolidColorQuad(SK_ColorBLUE)}; test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); SurfaceId ids[] = {root_surface_id, surface_with_no_frame_id}; AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); @@ -904,13 +917,13 @@ // Tests a surface quad referencing itself, generating a trivial cycle. // The quad creating the cycle should be dropped from the final frame. TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) { - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); test::Quad quads[] = { test::Quad::SurfaceQuad(root_surface_id, InvalidSurfaceId(), 1.f), test::Quad::SolidColorQuad(SK_ColorYELLOW)}; test::Pass passes[] = {test::Pass(quads, arraysize(quads))}; - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorYELLOW)}; @@ -924,7 +937,7 @@ // Tests a more complex cycle with one intermediate surface. TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) { LocalSurfaceId child_local_surface_id = allocator_.GenerateId(); - SurfaceId child_surface_id(child_factory_.frame_sink_id(), + SurfaceId child_surface_id(child_support_->frame_sink_id(), child_local_surface_id); test::Quad parent_quads[] = { @@ -934,18 +947,18 @@ test::Pass parent_passes[] = { test::Pass(parent_quads, arraysize(parent_quads))}; - SubmitCompositorFrame(&factory_, parent_passes, arraysize(parent_passes), + SubmitCompositorFrame(support_.get(), parent_passes, arraysize(parent_passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); test::Quad child_quads[] = { test::Quad::SolidColorQuad(SK_ColorGREEN), test::Quad::SurfaceQuad(root_surface_id, InvalidSurfaceId(), 1.f), test::Quad::SolidColorQuad(SK_ColorMAGENTA)}; test::Pass child_passes[] = {test::Pass(child_quads, arraysize(child_quads))}; - SubmitCompositorFrame(&child_factory_, child_passes, arraysize(child_passes), - child_local_surface_id); + SubmitCompositorFrame(child_support_.get(), child_passes, + arraysize(child_passes), child_local_surface_id); // The child surface's reference to the root_surface_ will be dropped, so // we'll end up with: @@ -968,7 +981,7 @@ // namespace and update RenderPassDrawQuad's id references to match. TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) { LocalSurfaceId child_local_surface_id = allocator_.GenerateId(); - SurfaceId child_surface_id(child_factory_.frame_sink_id(), + SurfaceId child_surface_id(child_support_->frame_sink_id(), child_local_surface_id); int child_pass_id[] = {1, 2}; @@ -978,7 +991,7 @@ test::Pass(child_quad[0], arraysize(child_quad[0]), child_pass_id[0]), test::Pass(child_quad[1], arraysize(child_quad[1]), child_pass_id[1])}; - SubmitCompositorFrame(&child_factory_, surface_passes, + SubmitCompositorFrame(child_support_.get(), surface_passes, arraysize(surface_passes), child_local_surface_id); // Pass IDs from the parent surface may collide with ones from the child. @@ -990,10 +1003,10 @@ test::Pass(parent_quad[0], arraysize(parent_quad[0]), parent_pass_id[0]), test::Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])}; - SubmitCompositorFrame(&factory_, parent_passes, arraysize(parent_passes), + SubmitCompositorFrame(support_.get(), parent_passes, arraysize(parent_passes), root_local_surface_id_); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1085,20 +1098,24 @@ SkBlendMode::kSrcIn, // 5 SkBlendMode::kDstIn, // 6 }; - - SurfaceFactory grandchild_factory(FrameSinkId(2, 2), &manager_, - &empty_client_); - SurfaceFactory child_one_factory(FrameSinkId(3, 3), &manager_, - &empty_client_); - SurfaceFactory child_two_factory(FrameSinkId(4, 4), &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> grandchild_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> child_one_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> child_two_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId3, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); int pass_id = 1; LocalSurfaceId grandchild_local_surface_id = allocator_.GenerateId(); - SurfaceId grandchild_surface_id(grandchild_factory.frame_sink_id(), + SurfaceId grandchild_surface_id(grandchild_support->frame_sink_id(), grandchild_local_surface_id); - grandchild_factory.SubmitCompositorFrame(grandchild_local_surface_id, - CompositorFrame(), - SurfaceFactory::DrawCallback()); + grandchild_support->SubmitCompositorFrame(grandchild_local_surface_id, + CompositorFrame()); std::unique_ptr<RenderPass> grandchild_pass = RenderPass::Create(); gfx::Rect output_rect(SurfaceSize()); gfx::Rect damage_rect(SurfaceSize()); @@ -1108,14 +1125,13 @@ AddSolidColorQuadWithBlendMode( SurfaceSize(), grandchild_pass.get(), blend_modes[2]); QueuePassAsFrame(std::move(grandchild_pass), grandchild_local_surface_id, - &grandchild_factory); + grandchild_support.get()); LocalSurfaceId child_one_local_surface_id = allocator_.GenerateId(); - SurfaceId child_one_surface_id(child_one_factory.frame_sink_id(), + SurfaceId child_one_surface_id(child_one_support->frame_sink_id(), child_one_local_surface_id); - child_one_factory.SubmitCompositorFrame(child_one_local_surface_id, - CompositorFrame(), - SurfaceFactory::DrawCallback()); + child_one_support->SubmitCompositorFrame(child_one_local_surface_id, + CompositorFrame()); std::unique_ptr<RenderPass> child_one_pass = RenderPass::Create(); child_one_pass->SetNew(pass_id, output_rect, damage_rect, @@ -1131,14 +1147,13 @@ AddSolidColorQuadWithBlendMode( SurfaceSize(), child_one_pass.get(), blend_modes[3]); QueuePassAsFrame(std::move(child_one_pass), child_one_local_surface_id, - &child_one_factory); + child_one_support.get()); LocalSurfaceId child_two_local_surface_id = allocator_.GenerateId(); - SurfaceId child_two_surface_id(child_two_factory.frame_sink_id(), + SurfaceId child_two_surface_id(child_two_support->frame_sink_id(), child_two_local_surface_id); - child_two_factory.SubmitCompositorFrame(child_two_local_surface_id, - CompositorFrame(), - SurfaceFactory::DrawCallback()); + child_two_support->SubmitCompositorFrame(child_two_local_surface_id, + CompositorFrame()); std::unique_ptr<RenderPass> child_two_pass = RenderPass::Create(); child_two_pass->SetNew(pass_id, output_rect, damage_rect, @@ -1146,7 +1161,7 @@ AddSolidColorQuadWithBlendMode( SurfaceSize(), child_two_pass.get(), blend_modes[5]); QueuePassAsFrame(std::move(child_two_pass), child_two_local_surface_id, - &child_two_factory); + child_two_support.get()); std::unique_ptr<RenderPass> root_pass = RenderPass::Create(); root_pass->SetNew(pass_id, output_rect, damage_rect, @@ -1171,9 +1186,10 @@ AddSolidColorQuadWithBlendMode( SurfaceSize(), root_pass.get(), blend_modes[6]); - QueuePassAsFrame(std::move(root_pass), root_local_surface_id_, &factory_); + QueuePassAsFrame(std::move(root_pass), root_local_surface_id_, + support_.get()); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1192,9 +1208,9 @@ << iter.index(); } - grandchild_factory.EvictSurface(); - child_one_factory.EvictSurface(); - child_two_factory.EvictSurface(); + grandchild_support->EvictFrame(); + child_one_support->EvictFrame(); + child_two_support->EvictFrame(); } // This tests that when aggregating a frame with multiple render passes that we @@ -1216,11 +1232,13 @@ // contributing render pass' transform in the aggregate frame should not be // affected. TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { - SurfaceFactory middle_factory(kArbitraryMiddleFrameSinkId, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> middle_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Innermost child surface. LocalSurfaceId child_local_surface_id = allocator_.GenerateId(); - SurfaceId child_surface_id(child_factory_.frame_sink_id(), + SurfaceId child_surface_id(child_support_->frame_sink_id(), child_local_surface_id); { int child_pass_id[] = {1, 2}; @@ -1250,14 +1268,13 @@ child_root_pass_sqs->is_clipped = true; child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5); - child_factory_.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support_->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); } // Middle child surface. LocalSurfaceId middle_local_surface_id = allocator_.GenerateId(); - SurfaceId middle_surface_id(middle_factory.frame_sink_id(), + SurfaceId middle_surface_id(middle_support->frame_sink_id(), middle_local_surface_id); { test::Quad middle_quads[] = { @@ -1277,9 +1294,8 @@ middle_root_pass->shared_quad_state_list.front(); middle_root_pass_sqs->quad_to_target_transform.Scale(2, 3); - middle_factory.SubmitCompositorFrame(middle_local_surface_id, - std::move(middle_frame), - SurfaceFactory::DrawCallback()); + middle_support->SubmitCompositorFrame(middle_local_surface_id, + std::move(middle_frame)); } // Root surface. @@ -1306,10 +1322,10 @@ root_frame.render_pass_list[0]->transform_to_root_target.Translate(10, 5); - factory_.SubmitCompositorFrame(root_local_surface_id_, std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, + std::move(root_frame)); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1382,13 +1398,15 @@ ->shared_quad_state_list.ElementAt(1) ->clip_rect.ToString()); - middle_factory.EvictSurface(); + middle_support->EvictFrame(); } // Tests that damage rects are aggregated correctly when surfaces change. TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { - SurfaceFactory parent_factory(kArbitraryMiddleFrameSinkId, &manager_, - &empty_client_); + std::unique_ptr<CompositorFrameSinkSupport> parent_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); test::Quad child_quads[] = {test::Quad::RenderPassQuad(1)}; test::Pass child_passes[] = { test::Pass(child_quads, arraysize(child_quads), 1)}; @@ -1403,11 +1421,10 @@ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0); LocalSurfaceId child_local_surface_id = allocator_.GenerateId(); - SurfaceId child_surface_id(child_factory_.frame_sink_id(), + SurfaceId child_surface_id(child_support_->frame_sink_id(), child_local_surface_id); - child_factory_.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support_->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); test::Quad parent_surface_quads[] = { test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)}; @@ -1421,11 +1438,10 @@ parent_surface_passes, arraysize(parent_surface_passes)); LocalSurfaceId parent_local_surface_id = allocator_.GenerateId(); - SurfaceId parent_surface_id(parent_factory.frame_sink_id(), + SurfaceId parent_surface_id(parent_support->frame_sink_id(), parent_local_surface_id); - parent_factory.SubmitCompositorFrame(parent_local_surface_id, - std::move(parent_surface_frame), - SurfaceFactory::DrawCallback()); + parent_support->SubmitCompositorFrame(parent_local_surface_id, + std::move(parent_surface_frame)); test::Quad root_surface_quads[] = { test::Quad::SurfaceQuad(parent_surface_id, InvalidSurfaceId(), 1.f)}; @@ -1445,10 +1461,10 @@ root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 10, 10); root_frame.render_pass_list[1]->damage_rect = gfx::Rect(5, 5, 100, 100); - factory_.SubmitCompositorFrame(root_local_surface_id_, std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, + std::move(root_frame)); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1471,11 +1487,11 @@ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0); child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10); - child_factory_.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support_->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), + root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1499,9 +1515,8 @@ ->quad_to_target_transform.Translate(0, 10); root_frame.render_pass_list[0]->damage_rect = gfx::Rect(0, 0, 1, 1); - factory_.SubmitCompositorFrame(root_local_surface_id_, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, + std::move(root_frame)); } { @@ -1514,11 +1529,11 @@ ->quad_to_target_transform.Translate(0, 10); root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 1, 1, 1); - factory_.SubmitCompositorFrame(root_local_surface_id_, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, + std::move(root_frame)); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), + root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1534,7 +1549,8 @@ // No Surface changed, so no damage should be given. { - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), + root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1560,7 +1576,7 @@ gfx::Rect(SurfaceSize()))); } - parent_factory.EvictSurface(); + parent_support->EvictFrame(); } // Check that damage is correctly calculated for surfaces. @@ -1576,11 +1592,12 @@ root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 100, 100); - factory_.SubmitCompositorFrame(root_local_surface_id_, std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id_, + std::move(root_frame)); { - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), + root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1594,7 +1611,7 @@ } LocalSurfaceId second_root_local_surface_id = allocator_.GenerateId(); - SurfaceId second_root_surface_id(factory_.frame_sink_id(), + SurfaceId second_root_surface_id(support_->frame_sink_id(), second_root_local_surface_id); { test::Quad root_render_pass_quads[] = {test::Quad::SolidColorQuad(1)}; @@ -1608,9 +1625,8 @@ root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 2, 3, 4); - factory_.SubmitCompositorFrame(second_root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(second_root_local_surface_id, + std::move(root_frame)); } { CompositorFrame aggregated_frame = @@ -1647,7 +1663,7 @@ // Tests that quads outside the damage rect are ignored. TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { LocalSurfaceId child_local_surface_id = allocator_.GenerateId(); - SurfaceId child_surface_id(child_factory_.frame_sink_id(), + SurfaceId child_surface_id(child_support_->frame_sink_id(), child_local_surface_id); // The child surface has three quads, one with a visible rect of 13,13 4x4 and // the other other with a visible rect of 10,10 2x2 (relative to root target @@ -1685,7 +1701,7 @@ child_pass_list[2]->quad_list.ElementAt(0)->visible_rect = gfx::Rect(0, 0, 2, 2); - SubmitPassListAsFrame(&child_factory_, child_local_surface_id, + SubmitPassListAsFrame(child_support_.get(), child_local_surface_id, &child_pass_list); } @@ -1704,10 +1720,11 @@ ->quad_to_target_transform.Translate(10, 10); root_pass->damage_rect = gfx::Rect(0, 0, 1, 1); - SubmitPassListAsFrame(&factory_, root_local_surface_id_, &root_pass_list); + SubmitPassListAsFrame(support_.get(), root_local_surface_id_, + &root_pass_list); } - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id); const RenderPassList& aggregated_pass_list = @@ -1736,7 +1753,8 @@ root_pass->shared_quad_state_list.front() ->quad_to_target_transform.Translate(10, 10); root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); - SubmitPassListAsFrame(&factory_, root_local_surface_id_, &root_pass_list); + SubmitPassListAsFrame(support_.get(), root_local_surface_id_, + &root_pass_list); } { @@ -1786,7 +1804,7 @@ child_root_pass->copy_requests.push_back( CopyOutputRequest::CreateEmptyRequest()); child_root_pass->damage_rect = gfx::Rect(); - SubmitPassListAsFrame(&child_factory_, child_local_surface_id, + SubmitPassListAsFrame(child_support_.get(), child_local_surface_id, &child_pass_list); } @@ -1846,7 +1864,8 @@ RenderPass* root_pass = root_pass_list[2].get(); filter_pass->filters.Append(FilterOperation::CreateBlurFilter(2)); root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); - SubmitPassListAsFrame(&factory_, root_local_surface_id_, &root_pass_list); + SubmitPassListAsFrame(support_.get(), root_local_surface_id_, + &root_pass_list); } { @@ -1894,7 +1913,8 @@ ->quad_to_target_transform.Translate(10, 10); pass->background_filters.Append(FilterOperation::CreateBlurFilter(2)); root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); - SubmitPassListAsFrame(&factory_, root_local_surface_id_, &root_pass_list); + SubmitPassListAsFrame(support_.get(), root_local_surface_id_, + &root_pass_list); } { @@ -1938,32 +1958,11 @@ std::unique_ptr<SurfaceAggregator> aggregator_; }; -class ResourceTrackingSurfaceFactoryClient : public SurfaceFactoryClient { - public: - ResourceTrackingSurfaceFactoryClient() {} - ~ResourceTrackingSurfaceFactoryClient() override {} - - void ReturnResources(const ReturnedResourceArray& resources) override { - returned_resources_ = resources; - } - - ReturnedResourceArray returned_resources() const { - return returned_resources_; - } - - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {} - - private: - ReturnedResourceArray returned_resources_; - - DISALLOW_COPY_AND_ASSIGN(ResourceTrackingSurfaceFactoryClient); -}; - void SubmitCompositorFrameWithResources(ResourceId* resource_ids, size_t num_resource_ids, bool valid, SurfaceId child_id, - SurfaceFactory* factory, + CompositorFrameSinkSupport* support, SurfaceId surface_id) { CompositorFrame frame; std::unique_ptr<RenderPass> pass = RenderPass::Create(); @@ -2002,27 +2001,29 @@ nearest_neighbor, secure_output_only); } frame.render_pass_list.push_back(std::move(pass)); - factory->SubmitCompositorFrame(surface_id.local_surface_id(), - std::move(frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(surface_id.local_surface_id(), + std::move(frame)); } TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { - ResourceTrackingSurfaceFactoryClient client; - SurfaceFactory factory(kArbitraryRootFrameSinkId, &manager_, &client); + FakeCompositorFrameSinkSupportClient client; + std::unique_ptr<CompositorFrameSinkSupport> support = + CompositorFrameSinkSupport::Create( + &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId local_surface_id(7u, base::UnguessableToken::Create()); - SurfaceId surface_id(factory.frame_sink_id(), local_surface_id); + SurfaceId surface_id(support->frame_sink_id(), local_surface_id); ResourceId ids[] = {11, 12, 13}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), - &factory, surface_id); + support.get(), surface_id); CompositorFrame frame = aggregator_->Aggregate(surface_id); // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); - SubmitCompositorFrameWithResources(NULL, 0u, true, SurfaceId(), &factory, + SubmitCompositorFrameWithResources(NULL, 0u, true, SurfaceId(), support.get(), surface_id); frame = aggregator_->Aggregate(surface_id); @@ -2035,14 +2036,17 @@ EXPECT_THAT(returned_ids, testing::WhenSorted(testing::ElementsAreArray(ids))); - factory.EvictSurface(); + support->EvictFrame(); } TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { - ResourceTrackingSurfaceFactoryClient client; - SurfaceFactory factory(kArbitraryRootFrameSinkId, &manager_, &client); + FakeCompositorFrameSinkSupportClient client; + std::unique_ptr<CompositorFrameSinkSupport> support = + CompositorFrameSinkSupport::Create( + &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId local_surface_id(7u, base::UnguessableToken::Create()); - SurfaceId surface_id(factory.frame_sink_id(), local_surface_id); + SurfaceId surface_id(support->frame_sink_id(), local_surface_id); CompositorFrame frame; std::unique_ptr<RenderPass> pass = RenderPass::Create(); @@ -2054,42 +2058,47 @@ resource.is_software = false; frame.resource_list.push_back(resource); frame.render_pass_list.push_back(std::move(pass)); - factory.SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(local_surface_id, std::move(frame)); CompositorFrame returned_frame = aggregator_->Aggregate(surface_id); // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); - SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), &factory, + SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), support.get(), surface_id); ASSERT_EQ(1u, client.returned_resources().size()); EXPECT_EQ(11u, client.returned_resources()[0].id); - factory.EvictSurface(); + support->EvictFrame(); } TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) { - ResourceTrackingSurfaceFactoryClient client; - SurfaceFactory factory1(FrameSinkId(1, 1), &manager_, &client); - SurfaceFactory factory2(FrameSinkId(2, 2), &manager_, &client); + FakeCompositorFrameSinkSupportClient client; + std::unique_ptr<CompositorFrameSinkSupport> support1 = + CompositorFrameSinkSupport::Create( + &client, &manager_, FrameSinkId(1, 1), kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> support2 = + CompositorFrameSinkSupport::Create( + &client, &manager_, FrameSinkId(2, 2), kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create()); - SurfaceId surface1_id(factory1.frame_sink_id(), local_frame1_id); + SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id); LocalSurfaceId local_frame2_id(8u, base::UnguessableToken::Create()); - SurfaceId surface2_id(factory2.frame_sink_id(), local_frame2_id); + SurfaceId surface2_id(support2->frame_sink_id(), local_frame2_id); ResourceId ids[] = {11, 12, 13}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), - &factory1, surface1_id); + support1.get(), surface1_id); ResourceId ids2[] = {14, 15, 16}; SubmitCompositorFrameWithResources(ids2, arraysize(ids2), true, SurfaceId(), - &factory2, surface2_id); + support2.get(), surface2_id); CompositorFrame frame = aggregator_->Aggregate(surface1_id); - SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), &factory1, + SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), support1.get(), surface1_id); // Nothing should be available to be returned yet. @@ -2107,40 +2116,47 @@ testing::WhenSorted(testing::ElementsAreArray(ids))); EXPECT_EQ(3u, resource_provider_->num_resources()); - factory1.EvictSurface(); - factory2.EvictSurface(); + support1->EvictFrame(); + support2->EvictFrame(); } // Ensure that aggregator completely ignores Surfaces that reference invalid // resources. TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { - ResourceTrackingSurfaceFactoryClient client; - SurfaceFactory root_factory(kArbitraryRootFrameSinkId, &manager_, &client); - SurfaceFactory middle_factory(kArbitraryMiddleFrameSinkId, &manager_, - &client); - SurfaceFactory child_factory(kArbitraryChildFrameSinkId1, &manager_, &client); + std::unique_ptr<CompositorFrameSinkSupport> root_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> middle_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId root_local_surface_id(7u, kArbitraryToken); - SurfaceId root_surface_id(root_factory.frame_sink_id(), + SurfaceId root_surface_id(root_support->frame_sink_id(), root_local_surface_id); LocalSurfaceId middle_local_surface_id(8u, kArbitraryToken); - SurfaceId middle_surface_id(middle_factory.frame_sink_id(), + SurfaceId middle_surface_id(middle_support->frame_sink_id(), middle_local_surface_id); LocalSurfaceId child_local_surface_id(9u, kArbitraryToken); - SurfaceId child_surface_id(child_factory.frame_sink_id(), + SurfaceId child_surface_id(child_support->frame_sink_id(), child_local_surface_id); ResourceId ids[] = {14, 15, 16}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), - &child_factory, child_surface_id); + child_support.get(), child_surface_id); ResourceId ids2[] = {17, 18, 19}; SubmitCompositorFrameWithResources(ids2, arraysize(ids2), false, - child_surface_id, &middle_factory, + child_surface_id, middle_support.get(), middle_surface_id); ResourceId ids3[] = {20, 21, 22}; SubmitCompositorFrameWithResources(ids3, arraysize(ids3), true, - middle_surface_id, &root_factory, + middle_surface_id, root_support.get(), root_surface_id); CompositorFrame frame; @@ -2151,7 +2167,7 @@ EXPECT_EQ(1u, pass_list->back()->shared_quad_state_list.size()); EXPECT_EQ(3u, pass_list->back()->quad_list.size()); SubmitCompositorFrameWithResources(ids2, arraysize(ids), true, - child_surface_id, &middle_factory, + child_surface_id, middle_support.get(), middle_surface_id); frame = aggregator_->Aggregate(root_surface_id); @@ -2161,24 +2177,29 @@ EXPECT_EQ(3u, pass_list->back()->shared_quad_state_list.size()); EXPECT_EQ(9u, pass_list->back()->quad_list.size()); - root_factory.EvictSurface(); - middle_factory.EvictSurface(); - child_factory.EvictSurface(); + root_support->EvictFrame(); + middle_support->EvictFrame(); + child_support->EvictFrame(); } TEST_F(SurfaceAggregatorWithResourcesTest, SecureOutputTexture) { - ResourceTrackingSurfaceFactoryClient client; - SurfaceFactory factory1(FrameSinkId(1, 1), &manager_, &client); - SurfaceFactory factory2(FrameSinkId(2, 2), &manager_, &client); + std::unique_ptr<CompositorFrameSinkSupport> support1 = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, FrameSinkId(1, 1), kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> support2 = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, FrameSinkId(2, 2), kChildIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create()); - SurfaceId surface1_id(factory1.frame_sink_id(), local_frame1_id); + SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id); LocalSurfaceId local_frame2_id(8u, base::UnguessableToken::Create()); - SurfaceId surface2_id(factory2.frame_sink_id(), local_frame2_id); + SurfaceId surface2_id(support2->frame_sink_id(), local_frame2_id); ResourceId ids[] = {11, 12, 13}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), - &factory1, surface1_id); + support1.get(), surface1_id); CompositorFrame frame = aggregator_->Aggregate(surface1_id); @@ -2201,8 +2222,7 @@ CompositorFrame frame; frame.render_pass_list.push_back(std::move(pass)); - factory2.SubmitCompositorFrame(local_frame2_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support2->SubmitCompositorFrame(local_frame2_id, std::move(frame)); } frame = aggregator_->Aggregate(surface2_id); @@ -2228,8 +2248,8 @@ // Output is insecure, so texture should be drawn. EXPECT_EQ(DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material); - factory1.EvictSurface(); - factory2.EvictSurface(); + support1->EvictFrame(); + support2->EvictFrame(); } // Ensure that the render passes have correct color spaces. @@ -2244,10 +2264,10 @@ gfx::ColorSpace color_space2 = gfx::ColorSpace::CreateSRGB(); gfx::ColorSpace color_space3 = gfx::ColorSpace::CreateSCRGBLinear(); - SubmitCompositorFrame(&factory_, passes, arraysize(passes), + SubmitCompositorFrame(support_.get(), passes, arraysize(passes), root_local_surface_id_); - SurfaceId surface_id(factory_.frame_sink_id(), root_local_surface_id_); + SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_); CompositorFrame aggregated_frame; aggregator_.SetOutputColorSpace(color_space1, color_space1);
diff --git a/cc/surfaces/surface_hittest_unittest.cc b/cc/surfaces/surface_hittest_unittest.cc index fc27635c..312a7ae 100644 --- a/cc/surfaces/surface_hittest_unittest.cc +++ b/cc/surfaces/surface_hittest_unittest.cc
@@ -5,10 +5,9 @@ #include <stddef.h> #include "cc/output/compositor_frame.h" +#include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/local_surface_id_allocator.h" #include "cc/surfaces/surface.h" -#include "cc/surfaces/surface_factory.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_hittest.h" #include "cc/surfaces/surface_manager.h" #include "cc/test/surface_hittest_test_helpers.h" @@ -20,7 +19,11 @@ namespace { -static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); +constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); +constexpr bool kIsRoot = true; +constexpr bool kIsChildRoot = false; +constexpr bool kHandlesFrameSinkIdInvalidation = true; +constexpr bool kNeedsSyncPoints = true; struct TestCase { SurfaceId input_surface_id; @@ -62,9 +65,11 @@ // not crash. TEST(SurfaceHittestTest, Hittest_BadCompositorFrameDoesNotCrash) { SurfaceManager manager; - EmptySurfaceFactoryClient client; FrameSinkId root_frame_sink_id(kArbitraryFrameSinkId); - SurfaceFactory root_factory(root_frame_sink_id, &manager, &client); + std::unique_ptr<CompositorFrameSinkSupport> root_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, kArbitraryFrameSinkId, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Creates a root surface. gfx::Rect root_rect(300, 300); @@ -86,9 +91,8 @@ LocalSurfaceIdAllocator root_allocator; LocalSurfaceId root_local_surface_id = root_allocator.GenerateId(); SurfaceId root_surface_id(root_frame_sink_id, root_local_surface_id); - root_factory.SubmitCompositorFrame(root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + root_support->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); { SurfaceHittest hittest(nullptr, &manager); @@ -99,16 +103,18 @@ root_surface_id, gfx::Point(100, 100), &transform)); } - root_factory.EvictSurface(); + root_support->EvictFrame(); } TEST(SurfaceHittestTest, Hittest_SingleSurface) { SurfaceManager manager; // Set up root FrameSink. - EmptySurfaceFactoryClient root_client; FrameSinkId root_frame_sink_id(1, 1); - SurfaceFactory root_factory(root_frame_sink_id, &manager, &root_client); + std::unique_ptr<CompositorFrameSinkSupport> root_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, root_frame_sink_id, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Creates a root surface. gfx::Rect root_rect(300, 300); @@ -119,9 +125,8 @@ LocalSurfaceIdAllocator root_allocator; LocalSurfaceId root_local_surface_id = root_allocator.GenerateId(); SurfaceId root_surface_id(root_frame_sink_id, root_local_surface_id); - root_factory.SubmitCompositorFrame(root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + root_support->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); TestCase tests[] = { { root_surface_id, @@ -133,21 +138,25 @@ RunTests(nullptr, &manager, tests, arraysize(tests)); - root_factory.EvictSurface(); + root_support->EvictFrame(); } TEST(SurfaceHittestTest, Hittest_ChildSurface) { SurfaceManager manager; // Set up root FrameSink. - EmptySurfaceFactoryClient root_client; FrameSinkId root_frame_sink_id(1, 1); - SurfaceFactory root_factory(root_frame_sink_id, &manager, &root_client); + std::unique_ptr<CompositorFrameSinkSupport> root_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, root_frame_sink_id, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Set up child FrameSink. - EmptySurfaceFactoryClient child_client; FrameSinkId child_frame_sink_id(2, 2); - SurfaceFactory child_factory(child_frame_sink_id, &manager, &child_client); + std::unique_ptr<CompositorFrameSinkSupport> child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, child_frame_sink_id, kIsChildRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Creates a root surface. gfx::Rect root_rect(300, 300); @@ -172,9 +181,8 @@ LocalSurfaceIdAllocator root_allocator; LocalSurfaceId root_local_surface_id = root_allocator.GenerateId(); SurfaceId root_surface_id(root_frame_sink_id, root_local_surface_id); - root_factory.SubmitCompositorFrame(root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + root_support->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); // Creates a child surface. RenderPass* child_pass = nullptr; @@ -191,9 +199,8 @@ root_rect, child_solid_quad_rect); // Submit the frame. - child_factory.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); TestCase tests[] = { { @@ -246,9 +253,8 @@ root_rect, child_rect, child_surface_id); - root_factory.SubmitCompositorFrame(root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + root_support->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); // Verify that point (100, 100) no longer falls on the child surface. // Verify that the transform to the child surface's space has also shifted. @@ -272,8 +278,8 @@ EXPECT_EQ(gfx::Point(25, 25), point_in_target_space); } - root_factory.EvictSurface(); - child_factory.EvictSurface(); + root_support->EvictFrame(); + child_support->EvictFrame(); } // This test verifies that hit testing will progress to the next quad if it @@ -282,14 +288,18 @@ SurfaceManager manager; // Set up root FrameSink. - EmptySurfaceFactoryClient root_client; FrameSinkId root_frame_sink_id(1, 1); - SurfaceFactory root_factory(root_frame_sink_id, &manager, &root_client); + std::unique_ptr<CompositorFrameSinkSupport> root_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, root_frame_sink_id, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Set up child FrameSink. - EmptySurfaceFactoryClient child_client; FrameSinkId child_frame_sink_id(2, 2); - SurfaceFactory child_factory(child_frame_sink_id, &manager, &child_client); + std::unique_ptr<CompositorFrameSinkSupport> child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, child_frame_sink_id, kIsChildRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Creates a root surface. gfx::Rect root_rect(300, 300); @@ -319,9 +329,8 @@ LocalSurfaceIdAllocator root_allocator; LocalSurfaceId root_local_surface_id = root_allocator.GenerateId(); SurfaceId root_surface_id(root_frame_sink_id, root_local_surface_id); - root_factory.SubmitCompositorFrame(root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + root_support->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); // Creates a child surface. RenderPass* child_pass = nullptr; @@ -338,9 +347,8 @@ child_solid_quad_rect); // Submit the frame. - child_factory.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); TestCase tests[] = { { @@ -383,15 +391,17 @@ RunTests(nullptr, &manager, tests, arraysize(tests)); - root_factory.EvictSurface(); - child_factory.EvictSurface(); + root_support->EvictFrame(); + child_support->EvictFrame(); } TEST(SurfaceHittestTest, Hittest_RenderPassDrawQuad) { SurfaceManager manager; - EmptySurfaceFactoryClient client; FrameSinkId root_frame_sink_id(kArbitraryFrameSinkId); - SurfaceFactory factory(root_frame_sink_id, &manager, &client); + std::unique_ptr<CompositorFrameSinkSupport> support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, root_frame_sink_id, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Create a CompostiorFrame with two RenderPasses. gfx::Rect root_rect(300, 300); @@ -437,8 +447,7 @@ LocalSurfaceIdAllocator root_allocator; LocalSurfaceId root_local_surface_id = root_allocator.GenerateId(); SurfaceId root_surface_id(root_frame_sink_id, root_local_surface_id); - factory.SubmitCompositorFrame(root_local_surface_id, std::move(root_frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(root_local_surface_id, std::move(root_frame)); TestCase tests[] = { // These tests just miss the RenderPassDrawQuad. @@ -486,21 +495,25 @@ RunTests(nullptr, &manager, tests, arraysize(tests)); - factory.EvictSurface(); + support->EvictFrame(); } TEST(SurfaceHittestTest, Hittest_SingleSurface_WithInsetsDelegate) { SurfaceManager manager; // Set up root FrameSink. - EmptySurfaceFactoryClient root_client; FrameSinkId root_frame_sink_id(1, 1); - SurfaceFactory root_factory(root_frame_sink_id, &manager, &root_client); + std::unique_ptr<CompositorFrameSinkSupport> root_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, root_frame_sink_id, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Set up child FrameSink. - EmptySurfaceFactoryClient child_client; FrameSinkId child_frame_sink_id(2, 2); - SurfaceFactory child_factory(child_frame_sink_id, &manager, &child_client); + std::unique_ptr<CompositorFrameSinkSupport> child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, child_frame_sink_id, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); // Creates a root surface. gfx::Rect root_rect(300, 300); @@ -524,9 +537,8 @@ LocalSurfaceIdAllocator root_allocator; LocalSurfaceId root_local_surface_id = root_allocator.GenerateId(); SurfaceId root_surface_id(root_frame_sink_id, root_local_surface_id); - root_factory.SubmitCompositorFrame(root_local_surface_id, - std::move(root_frame), - SurfaceFactory::DrawCallback()); + root_support->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); // Creates a child surface. RenderPass* child_pass = nullptr; @@ -541,9 +553,8 @@ root_rect, child_solid_quad_rect); // Submit the frame. - child_factory.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); TestCase test_expectations_without_insets[] = { {root_surface_id, gfx::Point(55, 55), child_surface_id, gfx::Point(5, 5)}, @@ -622,8 +633,8 @@ EXPECT_EQ(0, accept_delegate.reject_target_overrides()); EXPECT_EQ(2, accept_delegate.accept_target_overrides()); - root_factory.EvictSurface(); - child_factory.EvictSurface(); + root_support->EvictFrame(); + child_support->EvictFrame(); } } // namespace cc
diff --git a/cc/surfaces/surface_manager_ref_unittest.cc b/cc/surfaces/surface_manager_ref_unittest.cc index fb21ce3..eb678f8 100644 --- a/cc/surfaces/surface_manager_ref_unittest.cc +++ b/cc/surfaces/surface_manager_ref_unittest.cc
@@ -8,9 +8,8 @@ #include <vector> #include "base/memory/ptr_util.h" +#include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/surface.h" -#include "cc/surfaces/surface_factory.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_id.h" #include "cc/surfaces/surface_manager.h" #include "testing/gmock/include/gmock/gmock.h" @@ -29,12 +28,6 @@ constexpr FrameSinkId kFrameSink2(2, 0); constexpr FrameSinkId kFrameSink3(3, 0); -class StubSurfaceFactoryClient : public SurfaceFactoryClient { - public: - void ReturnResources(const ReturnedResourceArray& resources) override {} - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {} -}; - } // namespace // Tests for reference tracking in SurfaceManager. @@ -43,27 +36,38 @@ SurfaceManager& manager() { return *manager_; } // Creates a new Surface with the provided |frame_sink_id| and |local_id|. - // Will first create a SurfaceFactory for |frame_sink_id| if necessary. + // Will first create a Surfacesupport for |frame_sink_id| if necessary. SurfaceId CreateSurface(const FrameSinkId& frame_sink_id, uint32_t local_id) { LocalSurfaceId local_surface_id(local_id, base::UnguessableToken::Deserialize(0, 1u)); - GetFactory(frame_sink_id) - .SubmitCompositorFrame(local_surface_id, CompositorFrame(), - SurfaceFactory::DrawCallback()); + GetCompositorFrameSinkSupport(frame_sink_id) + .SubmitCompositorFrame(local_surface_id, CompositorFrame()); return SurfaceId(frame_sink_id, local_surface_id); } // Destroy Surface with |surface_id|. void DestroySurface(const SurfaceId& surface_id) { - GetFactory(surface_id.frame_sink_id()).EvictSurface(); + GetCompositorFrameSinkSupport(surface_id.frame_sink_id()).EvictFrame(); } - SurfaceFactory& GetFactory(const FrameSinkId& frame_sink_id) { - auto& factory_ptr = factories_[frame_sink_id]; - if (!factory_ptr) - factory_ptr = base::MakeUnique<SurfaceFactory>(frame_sink_id, - manager_.get(), &client_); - return *factory_ptr; + CompositorFrameSinkSupport& GetCompositorFrameSinkSupport( + const FrameSinkId& frame_sink_id) { + auto& support_ptr = supports_[frame_sink_id]; + if (!support_ptr) { + constexpr bool is_root = false; + constexpr bool handles_frame_sink_id_invalidation = true; + constexpr bool needs_sync_points = true; + support_ptr = CompositorFrameSinkSupport::Create( + nullptr, manager_.get(), frame_sink_id, is_root, + handles_frame_sink_id_invalidation, needs_sync_points); + } + return *support_ptr; + } + + void DestroyCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id) { + auto support_ptr = supports_.find(frame_sink_id); + ASSERT_NE(support_ptr, supports_.end()); + supports_.erase(support_ptr); } void RemoveSurfaceReference(const SurfaceId& parent_id, @@ -105,18 +109,17 @@ SurfaceManager::LifetimeType::REFERENCES); } void TearDown() override { - for (auto& factory : factories_) - factory.second->EvictSurface(); - factories_.clear(); + for (auto& support : supports_) + support.second->EvictFrame(); + supports_.clear(); manager_.reset(); } std::unordered_map<FrameSinkId, - std::unique_ptr<SurfaceFactory>, + std::unique_ptr<CompositorFrameSinkSupport>, FrameSinkIdHash> - factories_; + supports_; std::unique_ptr<SurfaceManager> manager_; - StubSurfaceFactoryClient client_; }; TEST_F(SurfaceManagerRefTest, AddReference) { @@ -464,7 +467,7 @@ // When |kFrameSink1| is invalidated it shouldn't change the surface // references. - manager().InvalidateFrameSinkId(kFrameSink1); + DestroyCompositorFrameSinkSupport(kFrameSink1); ASSERT_THAT(GetReferencesFor(id1), UnorderedElementsAre(parent_id)); } @@ -499,7 +502,7 @@ // If the parent client crashes then the CompositorFrameSink connection will // be closed and the FrameSinkId invalidated. The temporary reference // |kFrameSink1| owns to |id2a| will be removed. - manager().InvalidateFrameSinkId(kFrameSink1); + DestroyCompositorFrameSinkSupport(kFrameSink1); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1b)); // If the parent has crashed then the window server will have already removed
diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc index c20f313d..e40cc05 100644 --- a/cc/surfaces/surface_unittest.cc +++ b/cc/surfaces/surface_unittest.cc
@@ -5,10 +5,9 @@ #include "cc/surfaces/surface.h" #include "base/memory/ptr_util.h" #include "cc/output/copy_output_result.h" +#include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/local_surface_id_allocator.h" #include "cc/surfaces/surface_dependency_tracker.h" -#include "cc/surfaces/surface_factory.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" #include "cc/test/begin_frame_args_test.h" #include "cc/test/fake_external_begin_frame_source.h" @@ -19,36 +18,23 @@ namespace cc { namespace { -static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); - -class FakeSurfaceFactoryClient : public SurfaceFactoryClient { - public: - FakeSurfaceFactoryClient() : begin_frame_source_(nullptr) {} - - void ReturnResources(const ReturnedResourceArray& resources) override {} - - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override { - begin_frame_source_ = begin_frame_source; - } - - BeginFrameSource* begin_frame_source() { return begin_frame_source_; } - - private: - BeginFrameSource* begin_frame_source_; -}; +constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); +constexpr bool kIsRoot = true; +constexpr bool kHandlesFrameSinkIdInvalidation = true; +constexpr bool kNeedsSyncPoints = true; TEST(SurfaceTest, SurfaceLifetime) { SurfaceManager manager; - FakeSurfaceFactoryClient surface_factory_client; - SurfaceFactory factory(kArbitraryFrameSinkId, &manager, - &surface_factory_client); + std::unique_ptr<CompositorFrameSinkSupport> support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, kArbitraryFrameSinkId, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId local_surface_id(6, base::UnguessableToken::Create()); SurfaceId surface_id(kArbitraryFrameSinkId, local_surface_id); - factory.SubmitCompositorFrame(local_surface_id, CompositorFrame(), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(local_surface_id, CompositorFrame()); EXPECT_TRUE(manager.GetSurfaceForId(surface_id)); - factory.EvictSurface(); + support->EvictFrame(); EXPECT_EQ(NULL, manager.GetSurfaceForId(surface_id)); } @@ -71,21 +57,21 @@ // aggregated on the next frame. TEST(SurfaceTest, CopyRequestLifetime) { SurfaceManager manager; - FakeSurfaceFactoryClient surface_factory_client; - SurfaceFactory factory(kArbitraryFrameSinkId, &manager, - &surface_factory_client); + std::unique_ptr<CompositorFrameSinkSupport> support = + CompositorFrameSinkSupport::Create( + nullptr, &manager, kArbitraryFrameSinkId, kIsRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId local_surface_id(6, base::UnguessableToken::Create()); SurfaceId surface_id(kArbitraryFrameSinkId, local_surface_id); CompositorFrame frame; frame.render_pass_list.push_back(RenderPass::Create()); - factory.SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(local_surface_id, std::move(frame)); Surface* surface = manager.GetSurfaceForId(surface_id); ASSERT_TRUE(!!surface); bool copy_called = false; - factory.RequestCopyOfSurface(CopyOutputRequest::CreateRequest( + support->RequestCopyOfSurface(CopyOutputRequest::CreateRequest( base::Bind(&TestCopyResultCallback, ©_called))); EXPECT_TRUE(manager.GetSurfaceForId(surface_id)); EXPECT_FALSE(copy_called); @@ -99,8 +85,7 @@ frame.render_pass_list.back()->id = i * 3 + start_id + 1; frame.render_pass_list.push_back(RenderPass::Create()); frame.render_pass_list.back()->id = i * 3 + start_id + 2; - factory.SubmitCompositorFrame(local_surface_id, std::move(frame), - SurfaceFactory::DrawCallback()); + support->SubmitCompositorFrame(local_surface_id, std::move(frame)); } int last_pass_id = (max_frame - 1) * 3 + start_id + 2; @@ -120,7 +105,7 @@ copy_requests.find(last_pass_id)->second->SendEmptyResult(); EXPECT_TRUE(copy_called); - factory.EvictSurface(); + support->EvictFrame(); } } // namespace
diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc index b980980..0b81474c 100644 --- a/cc/surfaces/surfaces_pixeltest.cc +++ b/cc/surfaces/surfaces_pixeltest.cc
@@ -6,11 +6,10 @@ #include "cc/quads/render_pass.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/surface_draw_quad.h" +#include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/local_surface_id_allocator.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_aggregator.h" -#include "cc/surfaces/surface_factory.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" #include "cc/test/pixel_comparator.h" #include "cc/test/pixel_test.h" @@ -21,28 +20,31 @@ namespace cc { namespace { -static constexpr FrameSinkId kArbitraryRootFrameSinkId(1, 1); -static constexpr FrameSinkId kArbitraryChildFrameSinkId(2, 2); -static constexpr FrameSinkId kArbitraryLeftFrameSinkId(3, 3); -static constexpr FrameSinkId kArbitraryRightFrameSinkId(4, 4); - -class EmptySurfaceFactoryClient : public SurfaceFactoryClient { - public: - void ReturnResources(const ReturnedResourceArray& resources) override {} - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {} -}; +constexpr FrameSinkId kArbitraryRootFrameSinkId(1, 1); +constexpr FrameSinkId kArbitraryChildFrameSinkId(2, 2); +constexpr FrameSinkId kArbitraryLeftFrameSinkId(3, 3); +constexpr FrameSinkId kArbitraryRightFrameSinkId(4, 4); +constexpr bool kIsRoot = true; +constexpr bool kIsChildRoot = false; +constexpr bool kHandlesFrameSinkIdInvalidation = true; +constexpr bool kNeedsSyncPoints = true; class SurfacesPixelTest : public RendererPixelTest<GLRenderer> { public: SurfacesPixelTest() - : factory_(kArbitraryRootFrameSinkId, &manager_, &client_) {} - ~SurfacesPixelTest() override { factory_.EvictSurface(); } + : support_( + CompositorFrameSinkSupport::Create(nullptr, + &manager_, + kArbitraryRootFrameSinkId, + kIsRoot, + kHandlesFrameSinkIdInvalidation, + kNeedsSyncPoints)) {} + ~SurfacesPixelTest() override { support_->EvictFrame(); } protected: SurfaceManager manager_; LocalSurfaceIdAllocator allocator_; - EmptySurfaceFactoryClient client_; - SurfaceFactory factory_; + std::unique_ptr<CompositorFrameSinkSupport> support_; }; SharedQuadState* CreateAndAppendTestSharedQuadState( @@ -85,9 +87,8 @@ root_frame.render_pass_list.push_back(std::move(pass)); LocalSurfaceId root_local_surface_id = allocator_.GenerateId(); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id); - factory_.SubmitCompositorFrame(root_local_surface_id, std::move(root_frame), - SurfaceFactory::DrawCallback()); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id); + support_->SubmitCompositorFrame(root_local_surface_id, std::move(root_frame)); SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id); @@ -103,12 +104,16 @@ // Draws a frame with simple surface embedding. TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { gfx::Size child_size(200, 100); - SurfaceFactory child_factory(kArbitraryChildFrameSinkId, &manager_, &client_); + std::unique_ptr<CompositorFrameSinkSupport> child_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryChildFrameSinkId, kIsChildRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + LocalSurfaceId child_local_surface_id = allocator_.GenerateId(); - SurfaceId child_surface_id(child_factory.frame_sink_id(), + SurfaceId child_surface_id(child_support->frame_sink_id(), child_local_surface_id); LocalSurfaceId root_local_surface_id = allocator_.GenerateId(); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id); { gfx::Rect rect(device_viewport_size_); @@ -138,8 +143,8 @@ CompositorFrame root_frame; root_frame.render_pass_list.push_back(std::move(pass)); - factory_.SubmitCompositorFrame(root_local_surface_id, std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); } { @@ -163,9 +168,8 @@ CompositorFrame child_frame; child_frame.render_pass_list.push_back(std::move(pass)); - child_factory.SubmitCompositorFrame(child_local_surface_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + child_support->SubmitCompositorFrame(child_local_surface_id, + std::move(child_frame)); } SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); @@ -178,7 +182,7 @@ base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), pixel_comparator)); - child_factory.EvictSurface(); + child_support->EvictFrame(); } // Tests a surface quad that has a non-identity transform into its pass. @@ -192,14 +196,21 @@ // bottom_blue_quad (100x100 @ 0x100) // right_child -> top_blue_quad (100x100 @ 0x0), // bottom_green_quad (100x100 @ 0x100) - SurfaceFactory left_factory(kArbitraryLeftFrameSinkId, &manager_, &client_); - SurfaceFactory right_factory(kArbitraryRightFrameSinkId, &manager_, &client_); + std::unique_ptr<CompositorFrameSinkSupport> left_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryLeftFrameSinkId, kIsChildRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); + std::unique_ptr<CompositorFrameSinkSupport> right_support = + CompositorFrameSinkSupport::Create( + nullptr, &manager_, kArbitraryRightFrameSinkId, kIsChildRoot, + kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); LocalSurfaceId left_child_local_id = allocator_.GenerateId(); - SurfaceId left_child_id(left_factory.frame_sink_id(), left_child_local_id); + SurfaceId left_child_id(left_support->frame_sink_id(), left_child_local_id); LocalSurfaceId right_child_local_id = allocator_.GenerateId(); - SurfaceId right_child_id(right_factory.frame_sink_id(), right_child_local_id); + SurfaceId right_child_id(right_support->frame_sink_id(), + right_child_local_id); LocalSurfaceId root_local_surface_id = allocator_.GenerateId(); - SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id); + SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id); { gfx::Rect rect(device_viewport_size_); @@ -232,8 +243,8 @@ CompositorFrame root_frame; root_frame.render_pass_list.push_back(std::move(pass)); - factory_.SubmitCompositorFrame(root_local_surface_id, std::move(root_frame), - SurfaceFactory::DrawCallback()); + support_->SubmitCompositorFrame(root_local_surface_id, + std::move(root_frame)); } { @@ -265,9 +276,8 @@ CompositorFrame child_frame; child_frame.render_pass_list.push_back(std::move(pass)); - left_factory.SubmitCompositorFrame(left_child_local_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + left_support->SubmitCompositorFrame(left_child_local_id, + std::move(child_frame)); } { @@ -299,9 +309,8 @@ CompositorFrame child_frame; child_frame.render_pass_list.push_back(std::move(pass)); - right_factory.SubmitCompositorFrame(right_child_local_id, - std::move(child_frame), - SurfaceFactory::DrawCallback()); + right_support->SubmitCompositorFrame(right_child_local_id, + std::move(child_frame)); } SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); @@ -315,8 +324,8 @@ base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), pixel_comparator)); - left_factory.EvictSurface(); - right_factory.EvictSurface(); + left_support->EvictFrame(); + right_support->EvictFrame(); } } // namespace
diff --git a/cc/test/fake_compositor_frame_sink_support_client.cc b/cc/test/fake_compositor_frame_sink_support_client.cc new file mode 100644 index 0000000..ab502e8 --- /dev/null +++ b/cc/test/fake_compositor_frame_sink_support_client.cc
@@ -0,0 +1,36 @@ +// 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 "cc/test/fake_compositor_frame_sink_support_client.h" + +#include "cc/surfaces/surface_manager.h" + +namespace cc { + +FakeCompositorFrameSinkSupportClient::FakeCompositorFrameSinkSupportClient() = + default; +FakeCompositorFrameSinkSupportClient::~FakeCompositorFrameSinkSupportClient() = + default; + +void FakeCompositorFrameSinkSupportClient::DidReceiveCompositorFrameAck( + const ReturnedResourceArray& resources) { + returned_resources_ = resources; +} + +void FakeCompositorFrameSinkSupportClient::OnBeginFrame( + const BeginFrameArgs& args) {} + +void FakeCompositorFrameSinkSupportClient::ReclaimResources( + const ReturnedResourceArray& resources) { + returned_resources_ = resources; +} + +void FakeCompositorFrameSinkSupportClient::WillDrawSurface( + const LocalSurfaceId& local_surface_id, + const gfx::Rect& damage_rect) { + last_local_surface_id_ = local_surface_id; + last_damage_rect_ = damage_rect; +} + +}; // namespace cc
diff --git a/cc/test/fake_compositor_frame_sink_support_client.h b/cc/test/fake_compositor_frame_sink_support_client.h new file mode 100644 index 0000000..444315f --- /dev/null +++ b/cc/test/fake_compositor_frame_sink_support_client.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 CC_TEST_FAKE_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_ +#define CC_TEST_FAKE_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_ + +#include "cc/surfaces/compositor_frame_sink_support_client.h" +#include "cc/surfaces/local_surface_id.h" +#include "ui/gfx/geometry/rect.h" + +namespace cc { + +class FakeCompositorFrameSinkSupportClient + : public CompositorFrameSinkSupportClient { + public: + FakeCompositorFrameSinkSupportClient(); + ~FakeCompositorFrameSinkSupportClient() override; + + // CompositorFrameSinkSupportClient implementation. + void DidReceiveCompositorFrameAck( + const ReturnedResourceArray& resources) override; + void OnBeginFrame(const BeginFrameArgs& args) override; + void ReclaimResources(const ReturnedResourceArray& resources) override; + void WillDrawSurface(const LocalSurfaceId& local_surface_id, + const gfx::Rect& damage_rect) override; + + const gfx::Rect& last_damage_rect() const { return last_damage_rect_; } + const LocalSurfaceId& last_local_surface_id() const { + return last_local_surface_id_; + } + const ReturnedResourceArray& returned_resources() const { + return returned_resources_; + } + + private: + gfx::Rect last_damage_rect_; + LocalSurfaceId last_local_surface_id_; + ReturnedResourceArray returned_resources_; + + DISALLOW_COPY_AND_ASSIGN(FakeCompositorFrameSinkSupportClient); +}; + +} // namespace cc + +#endif // CC_TEST_FAKE_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
diff --git a/cc/test/surface_hittest_test_helpers.h b/cc/test/surface_hittest_test_helpers.h index 2a5b754..6ec3c36c3 100644 --- a/cc/test/surface_hittest_test_helpers.h +++ b/cc/test/surface_hittest_test_helpers.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "cc/quads/render_pass.h" -#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_hittest_delegate.h" #include "cc/surfaces/surface_id.h" #include "ui/gfx/geometry/insets.h" @@ -25,12 +24,6 @@ namespace test { -class EmptySurfaceFactoryClient : public SurfaceFactoryClient { - public: - void ReturnResources(const ReturnedResourceArray& resources) override {} - void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {} -}; - void CreateSharedQuadState(RenderPass* pass, const gfx::Transform& transform, const gfx::Rect& root_rect);
diff --git a/chrome/android/java/res/layout/data_reduction_old_stats_layout.xml b/chrome/android/java/res/layout/data_reduction_old_stats_layout.xml index 592602e..4a6ad76d 100644 --- a/chrome/android/java/res/layout/data_reduction_old_stats_layout.xml +++ b/chrome/android/java/res/layout/data_reduction_old_stats_layout.xml
@@ -21,15 +21,14 @@ <include layout="@layout/data_usage_chart" /> - <LinearLayout + <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/data_reduction_start_date" - android:layout_width="0dp" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1" android:textAppearance="@style/PreferenceSummary" android:textSize="14sp" /> @@ -40,7 +39,7 @@ android:textAppearance="@style/PreferenceSummary" android:textSize="14sp" /> - </LinearLayout> + </FrameLayout> <LinearLayout android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/data_reduction_stats_layout.xml b/chrome/android/java/res/layout/data_reduction_stats_layout.xml index 2b9eedd..58d2097 100644 --- a/chrome/android/java/res/layout/data_reduction_stats_layout.xml +++ b/chrome/android/java/res/layout/data_reduction_stats_layout.xml
@@ -82,15 +82,14 @@ <include layout="@layout/data_usage_chart" /> - <LinearLayout + <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/data_reduction_start_date" - android:layout_width="0dp" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1" android:textAppearance="@style/PreferenceSummary" android:textSize="14sp" /> @@ -101,7 +100,7 @@ android:textAppearance="@style/PreferenceSummary" android:textSize="14sp" /> - </LinearLayout> + </FrameLayout> <TextView android:id="@+id/data_reduction_proxy_unreachable"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java index 96b6acee..7c562fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java
@@ -83,6 +83,8 @@ } mPosterBitmap = posterBitmap; if (mNotificationBuilder == null || mMediaRouteController == null) return; + + updateNotificationBuilderIfPosterIsGoodEnough(); mNotificationBuilder.setNotificationLargeIcon(mMediaRouteController.getPoster()); updateNotification(); } @@ -108,10 +110,11 @@ .setPrivate(false) .setNotificationSmallIcon(R.drawable.ic_notification_media_route) .setContentIntent(contentIntent) - .setNotificationLargeIcon(mMediaRouteController.getPoster()) .setDefaultNotificationLargeIcon(R.drawable.cast_playing_square) .setId(R.id.remote_notification) .setListener(this); + + updateNotificationBuilderIfPosterIsGoodEnough(); mState = initialState; updateNotification(); mIsShowing = true; @@ -145,7 +148,7 @@ // poster changes. public void onPosterBitmapChanged() { if (mNotificationBuilder == null || mMediaRouteController == null) return; - mNotificationBuilder.setNotificationLargeIcon(mMediaRouteController.getPoster()); + updateNotificationBuilderIfPosterIsGoodEnough(); updateNotification(); } @@ -235,4 +238,12 @@ boolean isShowingForTests() { return mIsShowing; } + + private void updateNotificationBuilderIfPosterIsGoodEnough() { + Bitmap poster = mMediaRouteController.getPoster(); + if (MediaNotificationManager.isBitmapSuitableAsMediaImage(poster)) { + mNotificationBuilder.setNotificationLargeIcon(poster); + mNotificationBuilder.setMediaSessionImage(poster); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java index 17ba5e0..8aaa7bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -60,6 +60,8 @@ public class MediaNotificationManager { private static final String TAG = "MediaNotification"; + static final int MINIMAL_MEDIA_IMAGE_SIZE_PX = 114; + @VisibleForTesting static final int CUSTOM_MEDIA_SESSION_ACTION_STOP = MediaSessionAction.LAST + 1; @@ -540,6 +542,15 @@ return HIGH_IMAGE_SIZE_PX; } + /** + * @returns Whether |icon| is suitable as the media image, i.e. bigger than the minimal size. + * @param icon The icon to be checked. + */ + public static boolean isBitmapSuitableAsMediaImage(Bitmap icon) { + return icon != null && icon.getWidth() >= MINIMAL_MEDIA_IMAGE_SIZE_PX + && icon.getHeight() >= MINIMAL_MEDIA_IMAGE_SIZE_PX; + } + private static MediaNotificationManager getManager(int notificationId) { return sManagers.get(notificationId); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java index e7667418..f1b70d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -41,7 +41,6 @@ private static final String TAG = "MediaSession"; private static final String UNICODE_PLAY_CHARACTER = "\u25B6"; - private static final int MINIMAL_FAVICON_SIZE = 114; private static final int HIDE_NOTIFICATION_DELAY_MILLIS = 1000; private Tab mTab; @@ -352,8 +351,9 @@ private MediaSessionTabHelper(Tab tab) { mTab = tab; mTab.addObserver(mTabObserver); - mMediaImageManager = new MediaImageManager( - MINIMAL_FAVICON_SIZE, MediaNotificationManager.getIdealMediaImageSize()); + mMediaImageManager = + new MediaImageManager(MediaNotificationManager.MINIMAL_MEDIA_IMAGE_SIZE_PX, + MediaNotificationManager.getIdealMediaImageSize()); if (mTab.getWebContents() != null) setWebContents(tab.getWebContents()); Activity activity = getActivityFromTab(mTab); @@ -417,9 +417,7 @@ private boolean updateFavicon(Bitmap icon) { if (icon == null) return false; - if (icon.getWidth() < MINIMAL_FAVICON_SIZE || icon.getHeight() < MINIMAL_FAVICON_SIZE) { - return false; - } + if (!MediaNotificationManager.isBitmapSuitableAsMediaImage(icon)) return false; if (mFavicon != null && (icon.getWidth() < mFavicon.getWidth() || icon.getHeight() < mFavicon.getHeight())) { return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java index 4c3f177..77cfb84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java
@@ -15,9 +15,11 @@ import android.text.format.DateUtils; import android.text.format.Formatter; import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; +import android.widget.FrameLayout; import android.widget.TextView; import org.chromium.base.Callback; @@ -127,6 +129,15 @@ } /** + * Keep the graph labels LTR oriented. In RTL languages, numbers and plots remain LTR. + */ + @SuppressLint("RtlHardcoded") + private void forceLayoutGravityOfGraphLabels() { + ((FrameLayout.LayoutParams) mStartDateTextView.getLayoutParams()).gravity = Gravity.LEFT; + ((FrameLayout.LayoutParams) mEndDateTextView.getLayoutParams()).gravity = Gravity.RIGHT; + } + + /** * Sets up a data usage chart and text views containing data reduction statistics. * @param view The current view. */ @@ -142,6 +153,7 @@ mEndDateTextView = (TextView) view.findViewById(R.id.data_reduction_end_date); mDataReductionBreakdownView = (DataReductionSiteBreakdownView) view.findViewById(R.id.breakdown); + forceLayoutGravityOfGraphLabels(); updateReductionStatistics(); setDetailText();
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index cde0de6..deb2dbe 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -483,7 +483,7 @@ Search and site suggestions </message> <message name="IDS_SEARCH_SITE_SUGGESTIONS_SUMMARY" desc="Summary for search and site suggestions."> - Use a prediction service to show related queries and websites as you browse + Use prediction services to suggest searches and websites </message> <message name="IDS_SAFE_BROWSING_EXTENDED_REPORTING_TITLE" desc="Title for checkbox that controls whether details of possible security incidents will be sent to Google."> Security incidents
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2ee6b3d..eabe276 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10406,19 +10406,6 @@ </message> </if> - <!-- Media throttle infobar --> - <if expr="is_android"> - <message name="IDS_MEDIA_THROTTLE_INFOBAR_TEXT" desc="Text to display on the info bar whenever user wants to playback a video after being throttled."> - Android is having trouble playing media. - </message> - <message name="IDS_MEDIA_THROTTLE_INFOBAR_BLOCK_BUTTON" desc="Label for choosing 'Block' on media throttle infobar.[CHAR-LIMIT=32]"> - Wait - </message> - <message name="IDS_MEDIA_THROTTLE_INFOBAR_ALLOW_BUTTON" desc="Label for choosing 'Allow' on media throttle infobar. [CHAR-LIMIT=32]"> - Try again - </message> - </if> - <message name="IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TITLE" desc="The title text that is used in the manage passwords bubble when the user has generated a password."> Password saved </message>
diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc index e857c970..a50a807 100644 --- a/chrome/app/mash/mash_runner.cc +++ b/chrome/app/mash/mash_runner.cc
@@ -243,11 +243,13 @@ // Ping services that we know we want to launch on startup (UI service, // window manager, quick launch app). - context.connector()->Connect(ui::mojom::kServiceName); - context.connector()->Connect(content::mojom::kPackagedServicesServiceName); + context.connector()->StartService(ui::mojom::kServiceName); + context.connector()->StartService( + content::mojom::kPackagedServicesServiceName); if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMash)) { - context.connector()->Connect(mash::common::GetWindowManagerServiceName()); - context.connector()->Connect(mash::quick_launch::mojom::kServiceName); + context.connector()->StartService( + mash::common::GetWindowManagerServiceName()); + context.connector()->StartService(mash::quick_launch::mojom::kServiceName); } run_loop.Run();
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 164d131..97f28975 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2830,8 +2830,6 @@ "android/logo_bridge.h", "android/logo_service.cc", "android/logo_service.h", - "android/media/media_throttle_infobar_delegate.cc", - "android/media/media_throttle_infobar_delegate.h", "android/metrics/launch_metrics.cc", "android/metrics/launch_metrics.h", "android/metrics/uma_session_stats.cc",
diff --git a/chrome/browser/android/media/media_throttle_infobar_delegate.cc b/chrome/browser/android/media/media_throttle_infobar_delegate.cc deleted file mode 100644 index 10e46cf..0000000 --- a/chrome/browser/android/media/media_throttle_infobar_delegate.cc +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2015 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/android/media/media_throttle_infobar_delegate.h" - -#include <stddef.h> -#include <utility> - -#include "base/metrics/histogram_macros.h" -#include "chrome/browser/android/android_theme_resources.h" -#include "chrome/browser/infobars/infobar_service.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" -#include "components/infobars/core/infobar.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/web_contents.h" -#include "ui/base/l10n/l10n_util.h" -#include "url/gurl.h" - -// static -void MediaThrottleInfoBarDelegate::Create( - content::WebContents* web_contents, - const DecodeRequestGrantedCallback& callback) { - InfoBarService* infobar_service = - InfoBarService::FromWebContents(web_contents); - std::unique_ptr<infobars::InfoBar> new_infobar( - infobar_service->CreateConfirmInfoBar( - std::unique_ptr<ConfirmInfoBarDelegate>( - new MediaThrottleInfoBarDelegate(callback)))); - - for (size_t i = 0; i < infobar_service->infobar_count(); ++i) { - infobars::InfoBar* old_infobar = infobar_service->infobar_at(i); - MediaThrottleInfoBarDelegate* delegate = - old_infobar->delegate()->AsMediaThrottleInfoBarDelegate(); - if (delegate != nullptr) { - infobar_service->ReplaceInfoBar(old_infobar, std::move(new_infobar)); - return; - } - } - - infobar_service->AddInfoBar(std::move(new_infobar)); -} - -MediaThrottleInfoBarDelegate::MediaThrottleInfoBarDelegate( - const DecodeRequestGrantedCallback& callback) - : infobar_response_(UMA_THROTTLE_INFOBAR_NO_RESPONSE), - decode_granted_callback_(callback) { -} - -MediaThrottleInfoBarDelegate::~MediaThrottleInfoBarDelegate() { - UMA_HISTOGRAM_ENUMERATION("Media.Android.ThrottleInfobarResponse", - infobar_response_, - UMA_THROTTLE_INFOBAR_RESPONSE_COUNT); -} - -infobars::InfoBarDelegate::InfoBarIdentifier -MediaThrottleInfoBarDelegate::GetIdentifier() const { - return MEDIA_THROTTLE_INFOBAR_DELEGATE; -} - -MediaThrottleInfoBarDelegate* - MediaThrottleInfoBarDelegate::AsMediaThrottleInfoBarDelegate() { - return this; -} - -base::string16 MediaThrottleInfoBarDelegate::GetMessageText() const { - return l10n_util::GetStringUTF16(IDS_MEDIA_THROTTLE_INFOBAR_TEXT); -} - -int MediaThrottleInfoBarDelegate::GetIconId() const { - return IDR_ANDROID_INFOBAR_WARNING; -} - -base::string16 MediaThrottleInfoBarDelegate::GetButtonLabel( - InfoBarButton button) const { - return l10n_util::GetStringUTF16((button == BUTTON_OK) ? - IDS_MEDIA_THROTTLE_INFOBAR_BLOCK_BUTTON : - IDS_MEDIA_THROTTLE_INFOBAR_ALLOW_BUTTON); -} - -bool MediaThrottleInfoBarDelegate::Accept() { - infobar_response_ = UMA_THROTTLE_INFOBAR_WAIT; - decode_granted_callback_.Run(false); - return true; -} - -bool MediaThrottleInfoBarDelegate::Cancel() { - infobar_response_ = UMA_THROTTLE_INFOBAR_TRY_AGAIN; - decode_granted_callback_.Run(true); - return true; -} - -void MediaThrottleInfoBarDelegate::InfoBarDismissed() { - infobar_response_ = UMA_THROTTLE_INFOBAR_DISMISSED; - decode_granted_callback_.Run(false); -}
diff --git a/chrome/browser/android/media/media_throttle_infobar_delegate.h b/chrome/browser/android/media/media_throttle_infobar_delegate.h deleted file mode 100644 index 621f16a..0000000 --- a/chrome/browser/android/media/media_throttle_infobar_delegate.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2015 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_ANDROID_MEDIA_MEDIA_THROTTLE_INFOBAR_DELEGATE_H_ -#define CHROME_BROWSER_ANDROID_MEDIA_MEDIA_THROTTLE_INFOBAR_DELEGATE_H_ - -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "components/infobars/core/confirm_infobar_delegate.h" - -namespace content { -class WebContents; -} - -enum UMAThrottleInfobarResponse { - UMA_THROTTLE_INFOBAR_NO_RESPONSE, - UMA_THROTTLE_INFOBAR_TRY_AGAIN, - UMA_THROTTLE_INFOBAR_WAIT, - UMA_THROTTLE_INFOBAR_DISMISSED, - // NOTE: Add responses only immediately above this line. Make sure to - // update the enum list in tools/metrics/histograms/histograms.xml - // accordingly. - UMA_THROTTLE_INFOBAR_RESPONSE_COUNT -}; - -class MediaThrottleInfoBarDelegate : public ConfirmInfoBarDelegate { - public: - typedef base::Callback<void(bool)> DecodeRequestGrantedCallback; - ~MediaThrottleInfoBarDelegate() override; - - // Static method to create the object - static void Create( - content::WebContents* web_contents, - const DecodeRequestGrantedCallback& callback); - - private: - explicit MediaThrottleInfoBarDelegate( - const DecodeRequestGrantedCallback& callback); - - // ConfirmInfoBarDelegate: - infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; - MediaThrottleInfoBarDelegate* AsMediaThrottleInfoBarDelegate() override; - base::string16 GetMessageText() const override; - int GetIconId() const override; - base::string16 GetButtonLabel(InfoBarButton button) const override; - bool Accept() override; - bool Cancel() override; - void InfoBarDismissed() override; - - UMAThrottleInfobarResponse infobar_response_; - - DecodeRequestGrantedCallback decode_granted_callback_; - - DISALLOW_COPY_AND_ASSIGN(MediaThrottleInfoBarDelegate); -}; - -#endif // CHROME_BROWSER_ANDROID_MEDIA_MEDIA_THROTTLE_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc index deccbc6..fa26ef6c 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.cc +++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/android/banners/app_banner_manager_android.h" #include "chrome/browser/android/feature_utilities.h" #include "chrome/browser/android/hung_renderer_infobar_delegate.h" -#include "chrome/browser/android/media/media_throttle_infobar_delegate.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/file_select_helper.h" #include "chrome/browser/infobars/infobar_service.h" @@ -275,12 +274,6 @@ ->CheckMediaAccessPermission(web_contents, security_origin, type); } -void TabWebContentsDelegateAndroid::RequestMediaDecodePermission( - content::WebContents* web_contents, - const base::Callback<void(bool)>& callback) { - MediaThrottleInfoBarDelegate::Create(web_contents, callback); -} - bool TabWebContentsDelegateAndroid::RequestPpapiBrokerPermission( WebContents* web_contents, const GURL& url,
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.h b/chrome/browser/android/tab_web_contents_delegate_android.h index 3f557591..1d85597 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.h +++ b/chrome/browser/android/tab_web_contents_delegate_android.h
@@ -67,9 +67,6 @@ bool CheckMediaAccessPermission(content::WebContents* web_contents, const GURL& security_origin, content::MediaStreamType type) override; - void RequestMediaDecodePermission( - content::WebContents* web_contents, - const base::Callback<void(bool)>& callback) override; bool RequestPpapiBrokerPermission( content::WebContents* web_contents, const GURL& url,
diff --git a/chrome/browser/browsing_data/browsing_data_remover.h b/chrome/browser/browsing_data/browsing_data_remover.h index 4edae603..757d8a8 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.h +++ b/chrome/browser/browsing_data/browsing_data_remover.h
@@ -7,6 +7,7 @@ #include <memory> #include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/browsing_data/browsing_data_remover_delegate.h" @@ -179,6 +180,14 @@ virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; + // A |callback| that will be called just before a deletion task is completed + // and observers are notified. The receiver must respond by calling + // |continue_to_completion| to finish the task. Used in tests to artificially + // prolong execution. + virtual void SetWouldCompleteCallbackForTesting( + const base::Callback<void(const base::Closure& continue_to_completion)>& + callback) = 0; + // Parameters of the last call are exposed to be used by tests. Removal and // origin type masks equal to -1 mean that no removal has ever been executed. // TODO(msramek): If other consumers than tests are interested in this,
diff --git a/chrome/browser/browsing_data/browsing_data_remover_impl.cc b/chrome/browser/browsing_data/browsing_data_remover_impl.cc index dee3c1a..d9df6f1 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_impl.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_impl.cc
@@ -139,9 +139,6 @@ } // namespace -BrowsingDataRemoverImpl::CompletionInhibitor* - BrowsingDataRemoverImpl::completion_inhibitor_ = nullptr; - BrowsingDataRemoverImpl::SubTask::SubTask(const base::Closure& forward_callback) : is_pending_(false), forward_callback_(forward_callback), @@ -184,6 +181,7 @@ clear_channel_ids_(sub_task_forward_callback_), clear_http_auth_cache_(sub_task_forward_callback_), clear_storage_partition_data_(sub_task_forward_callback_), + storage_partition_for_testing_(nullptr), weak_ptr_factory_(this) { DCHECK(browser_context_); } @@ -565,6 +563,12 @@ observer_list_.RemoveObserver(observer); } +void BrowsingDataRemoverImpl::SetWouldCompleteCallbackForTesting( + const base::Callback<void(const base::Closure& continue_to_completion)>& + callback) { + would_complete_callback_ = callback; +} + void BrowsingDataRemoverImpl::OverrideStoragePartitionForTesting( content::StoragePartition* storage_partition) { storage_partition_for_testing_ = storage_partition; @@ -655,9 +659,9 @@ if (!AllDone()) return; - if (completion_inhibitor_) { - completion_inhibitor_->OnBrowsingDataRemoverWouldComplete( - this, base::Bind(&BrowsingDataRemoverImpl::Notify, GetWeakPtr())); + if (!would_complete_callback_.is_null()) { + would_complete_callback_.Run( + base::Bind(&BrowsingDataRemoverImpl::Notify, GetWeakPtr())); return; }
diff --git a/chrome/browser/browsing_data/browsing_data_remover_impl.h b/chrome/browser/browsing_data/browsing_data_remover_impl.h index 41281c14..3e87fa4 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_impl.h +++ b/chrome/browser/browsing_data/browsing_data_remover_impl.h
@@ -12,7 +12,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/synchronization/waitable_event_watcher.h" #include "base/time/time.h" @@ -33,22 +32,6 @@ class BrowsingDataRemoverImpl : public BrowsingDataRemover { public: - // The completion inhibitor can artificially delay completion of the browsing - // data removal process. It is used during testing to simulate scenarios in - // which the deletion stalls or takes a very long time. - class CompletionInhibitor { - public: - // Invoked when a |remover| is just about to complete clearing browser data, - // and will be prevented from completing until after the callback - // |continue_to_completion| is run. - virtual void OnBrowsingDataRemoverWouldComplete( - BrowsingDataRemoverImpl* remover, - const base::Closure& continue_to_completion) = 0; - - protected: - virtual ~CompletionInhibitor() {} - }; - // Used to track the deletion of a single data storage backend. class SubTask { public: @@ -78,15 +61,6 @@ // Is the BrowsingDataRemoverImpl currently in the process of removing data? bool is_removing() { return is_removing_; } - // Sets a CompletionInhibitor, which will be notified each time an instance is - // about to complete a browsing data removal process, and will be able to - // artificially delay the completion. - // TODO(crbug.com/483528): Make this non-static. - static void set_completion_inhibitor_for_testing( - CompletionInhibitor* inhibitor) { - completion_inhibitor_ = inhibitor; - } - // BrowsingDataRemover implementation: void SetEmbedderDelegate( std::unique_ptr<BrowsingDataRemoverDelegate> embedder_delegate) override; @@ -122,6 +96,10 @@ void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; + void SetWouldCompleteCallbackForTesting( + const base::Callback<void(const base::Closure& continue_to_completion)>& + callback) override; + const base::Time& GetLastUsedBeginTime() override; const base::Time& GetLastUsedEndTime() override; int GetLastUsedRemovalMask() override; @@ -205,7 +183,8 @@ // Returns true if we're all done. bool AllDone(); - // Retrieve a UI thread-bound weak pointer to this BrowsingDataRemoverImpl. + // Like GetWeakPtr(), but returns a weak pointer to BrowsingDataRemoverImpl + // for internal purposes. base::WeakPtr<BrowsingDataRemoverImpl> GetWeakPtr(); // The browser context we're to remove from. @@ -232,10 +211,11 @@ // Removal tasks to be processed. std::queue<RemovalTask> task_queue_; - // If non-NULL, the |completion_inhibitor_| is notified each time an instance + // If non-null, the |would_complete_callback_| is called each time an instance // is about to complete a browsing data removal process, and has the ability // to artificially delay completion. Used for testing. - static CompletionInhibitor* completion_inhibitor_; + base::Callback<void(const base::Closure& continue_to_completion)> + would_complete_callback_; // A callback to NotifyIfDone() used by SubTasks instances. const base::Closure sub_task_forward_callback_; @@ -253,7 +233,7 @@ base::ObserverList<Observer, true> observer_list_; // We do not own this. - content::StoragePartition* storage_partition_for_testing_ = nullptr; + content::StoragePartition* storage_partition_for_testing_; base::WeakPtrFactory<BrowsingDataRemoverImpl> weak_ptr_factory_;
diff --git a/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.cc index 53518b5..0c34444 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -1438,12 +1438,12 @@ }; TEST_F(BrowsingDataRemoverImplTest, CompletionInhibition) { - // The |completion_inhibitor| on the stack should prevent removal sessions - // from completing until after ContinueToCompletion() is called. - BrowsingDataRemoverCompletionInhibitor completion_inhibitor; - BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>( BrowsingDataRemoverFactory::GetForBrowserContext(GetBrowserContext())); + + // The |completion_inhibitor| on the stack should prevent removal sessions + // from completing until after ContinueToCompletion() is called. + BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover); InspectableCompletionObserver completion_observer(remover); remover->RemoveAndReply( base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES, @@ -1473,12 +1473,13 @@ BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>( BrowsingDataRemoverFactory::GetForBrowserContext(GetBrowserContext())); InspectableCompletionObserver completion_observer(remover); - BrowsingDataRemoverCompletionInhibitor completion_inhibitor; + BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover); remover->RemoveAndReply( base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES, BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, &completion_observer); completion_inhibitor.BlockUntilNearCompletion(); + completion_inhibitor.Reset(); // Verify that the deletion has not yet been completed and the observer has // not been called. @@ -1590,7 +1591,7 @@ filter_builder_2->AddRegisterableDomain("example.com"); MultipleTasksObserver observer(remover); - BrowsingDataRemoverCompletionInhibitor completion_inhibitor; + BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover); // Test several tasks with various configuration of masks, filters, and target // observers.
diff --git a/chrome/browser/browsing_data/browsing_data_remover_test_util.cc b/chrome/browser/browsing_data/browsing_data_remover_test_util.cc index 9bdc5a3..6677ff7d 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_test_util.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_test_util.cc
@@ -22,14 +22,27 @@ message_loop_runner_->Quit(); } -BrowsingDataRemoverCompletionInhibitor::BrowsingDataRemoverCompletionInhibitor() - : message_loop_runner_(new content::MessageLoopRunner) { - BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(this); +BrowsingDataRemoverCompletionInhibitor::BrowsingDataRemoverCompletionInhibitor( + BrowsingDataRemover* remover) + : remover_(remover), message_loop_runner_(new content::MessageLoopRunner) { + DCHECK(remover); + remover_->SetWouldCompleteCallbackForTesting( + base::Bind(&BrowsingDataRemoverCompletionInhibitor:: + OnBrowsingDataRemoverWouldComplete, + base::Unretained(this))); } BrowsingDataRemoverCompletionInhibitor:: ~BrowsingDataRemoverCompletionInhibitor() { - BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(nullptr); + Reset(); +} + +void BrowsingDataRemoverCompletionInhibitor::Reset() { + if (!remover_) + return; + remover_->SetWouldCompleteCallbackForTesting( + base::Callback<void(const base::Closure&)>()); + remover_ = nullptr; } void BrowsingDataRemoverCompletionInhibitor::BlockUntilNearCompletion() { @@ -44,7 +57,6 @@ } void BrowsingDataRemoverCompletionInhibitor::OnBrowsingDataRemoverWouldComplete( - BrowsingDataRemoverImpl* remover, const base::Closure& continue_to_completion) { DCHECK(continue_to_completion_callback_.is_null()); continue_to_completion_callback_ = continue_to_completion;
diff --git a/chrome/browser/browsing_data/browsing_data_remover_test_util.h b/chrome/browser/browsing_data/browsing_data_remover_test_util.h index c0c7dd4d..bb0847c 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_test_util.h +++ b/chrome/browser/browsing_data/browsing_data_remover_test_util.h
@@ -9,7 +9,6 @@ #include "base/memory/ref_counted.h" #include "base/scoped_observer.h" #include "chrome/browser/browsing_data/browsing_data_remover.h" -#include "chrome/browser/browsing_data/browsing_data_remover_impl.h" #include "content/public/test/test_utils.h" // This class can be used to wait for a BrowsingDataRemover to complete @@ -33,22 +32,32 @@ DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverCompletionObserver); }; -class BrowsingDataRemoverCompletionInhibitor - : public BrowsingDataRemoverImpl::CompletionInhibitor { +// The completion inhibitor can artificially delay completion of the browsing +// data removal process. It is used during testing to simulate scenarios in +// which the deletion stalls or takes a very long time. +// +// This class will detach itself from |remover| upon its destruction. +// If |remover| is destroyed during a test (e.g. in profile shutdown tests), +// users must call Reset() to detach it in advance. +class BrowsingDataRemoverCompletionInhibitor { public: - BrowsingDataRemoverCompletionInhibitor(); - ~BrowsingDataRemoverCompletionInhibitor() override; + explicit BrowsingDataRemoverCompletionInhibitor(BrowsingDataRemover* remover); + virtual ~BrowsingDataRemoverCompletionInhibitor(); + + void Reset(); void BlockUntilNearCompletion(); void ContinueToCompletion(); protected: - // BrowsingDataRemoverImpl::CompletionInhibitor: - void OnBrowsingDataRemoverWouldComplete( - BrowsingDataRemoverImpl* remover, - const base::Closure& continue_to_completion) override; + virtual void OnBrowsingDataRemoverWouldComplete( + const base::Closure& continue_to_completion); private: + // Not owned by this class. If the pointer becomes invalid, the owner of + // this class is responsible for calling Reset(). + BrowsingDataRemover* remover_; + scoped_refptr<content::MessageLoopRunner> message_loop_runner_; base::Closure continue_to_completion_callback_;
diff --git a/chrome/browser/chromeos/login/login_screen_policy_browsertest.cc b/chrome/browser/chromeos/login/login_screen_policy_browsertest.cc index 5d0d29c0..5da1aaf 100644 --- a/chrome/browser/chromeos/login/login_screen_policy_browsertest.cc +++ b/chrome/browser/chromeos/login/login_screen_policy_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/memory/ref_counted.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" @@ -16,6 +17,7 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/settings/cros_settings_names.h" #include "components/user_manager/user_manager.h" +#include "content/public/browser/notification_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/input_method_manager.h" @@ -75,6 +77,11 @@ } IN_PROC_BROWSER_TEST_F(LoginScreenPolicyTest, RestrictInputMethods) { + content::WindowedNotificationObserver( + chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, + content::NotificationService::AllSources()) + .Wait(); + input_method::InputMethodManager* imm = input_method::InputMethodManager::Get(); ASSERT_TRUE(imm);
diff --git a/chrome/browser/component_updater/cros_component_installer.cc b/chrome/browser/component_updater/cros_component_installer.cc index 0881d90..22fc25f 100644 --- a/chrome/browser/component_updater/cros_component_installer.cc +++ b/chrome/browser/component_updater/cros_component_installer.cc
@@ -21,28 +21,6 @@ namespace component_updater { #if defined(OS_CHROMEOS) -void LogLoadResult(chromeos::DBusMethodCallStatus call_status, - const std::string& result) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { - DVLOG(1) << "Call to imageloader service failed."; - return; - } - if (result.empty()) { - DVLOG(1) << "Component load failed"; - return; - } -} -void ImageLoaderLoad(const std::string& name) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - chromeos::ImageLoaderClient* loader = - chromeos::DBusThreadManager::Get()->GetImageLoaderClient(); - if (loader) { - loader->LoadComponent(name, base::Bind(&LogLoadResult)); - } else { - DVLOG(1) << "Failed to get ImageLoaderClient object."; - } -} void LogRegistrationResult(const std::string& name, chromeos::DBusMethodCallStatus call_status, bool result) { @@ -55,8 +33,8 @@ DVLOG(1) << "Component registration failed"; return; } - ImageLoaderLoad(name); } + void ImageLoaderRegistration(const std::string& version, const base::FilePath& install_dir, const std::string& name) { @@ -71,6 +49,7 @@ DVLOG(1) << "Failed to get ImageLoaderClient object."; } } + ComponentConfig::ComponentConfig(const std::string& name, const std::string& dir, const std::string& sha2hashstr) @@ -201,6 +180,34 @@ install_callback)); return true; } + +void MountResult(const base::Callback<void(const std::string&)>& mount_callback, + chromeos::DBusMethodCallStatus call_status, + const std::string& result) { + if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { + DVLOG(1) << "Call to imageloader service failed."; + base::PostTask(FROM_HERE, base::Bind(mount_callback, "")); + return; + } + if (result.empty()) { + DVLOG(1) << "Component load failed"; + base::PostTask(FROM_HERE, base::Bind(mount_callback, "")); + return; + } + base::PostTask(FROM_HERE, base::Bind(mount_callback, result)); +} + +void CrOSComponent::LoadCrOSComponent( + const std::string& name, + const base::Callback<void(const std::string&)>& mount_callback) { + chromeos::ImageLoaderClient* loader = + chromeos::DBusThreadManager::Get()->GetImageLoaderClient(); + if (loader) { + loader->LoadComponent(name, base::Bind(&MountResult, mount_callback)); + } else { + DVLOG(1) << "Failed to get ImageLoaderClient object."; + } +} #endif // defined(OS_CHROMEOS } // namespace component_updater
diff --git a/chrome/browser/component_updater/cros_component_installer.h b/chrome/browser/component_updater/cros_component_installer.h index fa9b9859..2a55c84 100644 --- a/chrome/browser/component_updater/cros_component_installer.h +++ b/chrome/browser/component_updater/cros_component_installer.h
@@ -66,19 +66,12 @@ // // example: // ... - // void PerformOperations(chromeos::DBusMethodCallStatus call_status, - // const std::string& version){ - // if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { - // DVLOG(1) << "Call to imageloader service failed."; + // void load_callback(const std::string& result){ + // if (result.empty) { + // // component is not mounted. // return; // } - // if (version.empty()) { - // DVLOG(1) << "[PerformOperations] Component is not installed"; - // return; - // } - // // [mounted compnent path: /run/imageloader/[component name]/[version]] - // // - // // [component is ready to do your work] + // // [component mount point: result] // } // void install_callback(update_client::Error error){ // // switch(error){ @@ -86,7 +79,7 @@ // // // component is installed // // break; // // case update_client::Error::INVALID_ARGUMENT: - // // // your install failed due of your wrong parameters. + // // // your install failed due to your wrong parameters. // // break; // // default: // // // your install failed due to system failure. @@ -95,13 +88,7 @@ // // Even when error code other than NONE returned (your install failed), // // component might has already being installed previously. // // Plus, if you want to know current version of component. - // chromeos::ImageLoaderClient* loader = - // chromeos::DBusThreadManager::Get()->GetImageLoaderClient(); - // if (loader) { - // loader->GetComponentVersion("escpr", base::Bind(&PerformOperations)); - // } else { - // VLOG(0) << "Failed to get ImageLoaderClient object."; - // } + // component_updater:CrOSComponent::LoadCrOSComponent(name, load_callback); // } // ... // component_updater::CrOSComponent::InstallCrOSComponent( @@ -112,6 +99,10 @@ const std::string& name, const update_client::Callback& install_callback); + static void LoadCrOSComponent( + const std::string& name, + const base::Callback<void(const std::string&)>& mount_callback); + private: CrOSComponent() {} // Register a component.
diff --git a/chrome/browser/extensions/external_loader.h b/chrome/browser/extensions/external_loader.h index ecc11d68..83948db 100644 --- a/chrome/browser/extensions/external_loader.h +++ b/chrome/browser/extensions/external_loader.h
@@ -69,6 +69,8 @@ // this task should invoke |LoadFinished| with a PostTask. This scheme of // posting tasks will avoid concurrent access and imply the necessary memory // barriers. + // TODO(lazyboy): To avoid |prefs_| getting unexpectedly overwritten before it + // is consumed, consider passing the prefs directly in LoadFinished(). std::unique_ptr<base::DictionaryValue> prefs_; private:
diff --git a/chrome/browser/extensions/external_registry_loader_win.cc b/chrome/browser/extensions/external_registry_loader_win.cc index 0c10884..6f331080 100644 --- a/chrome/browser/extensions/external_registry_loader_win.cc +++ b/chrome/browser/extensions/external_registry_loader_win.cc
@@ -190,17 +190,20 @@ void ExternalRegistryLoader::LoadOnFileThread() { base::TimeTicks start_time = base::TimeTicks::Now(); - prefs_ = LoadPrefsOnFileThread(); + std::unique_ptr<base::DictionaryValue> prefs = LoadPrefsOnFileThread(); LOCAL_HISTOGRAM_TIMES("Extensions.ExternalRegistryLoaderWin", base::TimeTicks::Now() - start_time); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&ExternalRegistryLoader::CompleteLoadAndStartWatchingRegistry, - this)); + this, base::Passed(&prefs))); } -void ExternalRegistryLoader::CompleteLoadAndStartWatchingRegistry() { +void ExternalRegistryLoader::CompleteLoadAndStartWatchingRegistry( + std::unique_ptr<base::DictionaryValue> prefs) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(prefs); + prefs_ = std::move(prefs); LoadFinished(); // Attempt to watch registry if we haven't already.
diff --git a/chrome/browser/extensions/external_registry_loader_win.h b/chrome/browser/extensions/external_registry_loader_win.h index 9b93cec..f596d2d 100644 --- a/chrome/browser/extensions/external_registry_loader_win.h +++ b/chrome/browser/extensions/external_registry_loader_win.h
@@ -21,12 +21,15 @@ void StartLoading() override; + // Overridden to mock registry reading in unit tests. + virtual std::unique_ptr<base::DictionaryValue> LoadPrefsOnFileThread(); + private: friend class base::RefCountedThreadSafe<ExternalLoader>; - std::unique_ptr<base::DictionaryValue> LoadPrefsOnFileThread(); void LoadOnFileThread(); - void CompleteLoadAndStartWatchingRegistry(); + void CompleteLoadAndStartWatchingRegistry( + std::unique_ptr<base::DictionaryValue> prefs); void UpdatePrefsOnFileThread(); void OnRegistryKeyChanged(base::win::RegKey* key);
diff --git a/chrome/browser/extensions/external_registry_loader_win_unittest.cc b/chrome/browser/extensions/external_registry_loader_win_unittest.cc index cc83b7c..059b4d2 100644 --- a/chrome/browser/extensions/external_registry_loader_win_unittest.cc +++ b/chrome/browser/extensions/external_registry_loader_win_unittest.cc
@@ -8,13 +8,17 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" +#include "base/values.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" namespace extensions { namespace { +const char kDummyRegistryKey[] = "dummyId"; + class TestExternalRegistryLoader : public ExternalRegistryLoader { public: TestExternalRegistryLoader() {} @@ -26,19 +30,32 @@ run_loop_.Run(); } + std::vector<int> GetPrefsTestIds() { return prefs_test_ids_; } + private: ~TestExternalRegistryLoader() override {} + std::unique_ptr<base::DictionaryValue> LoadPrefsOnFileThread() override { + return DictionaryBuilder().Set(kDummyRegistryKey, id_++).Build(); + } void LoadFinished() override { ExternalRegistryLoader::LoadFinished(); ++load_finished_count_; ASSERT_LE(load_finished_count_, 2); + + ASSERT_TRUE(prefs_); + int prefs_test_id = -1; + EXPECT_TRUE(prefs_->GetInteger(kDummyRegistryKey, &prefs_test_id)); + prefs_test_ids_.push_back(prefs_test_id); + if (load_finished_count_ == 2) run_loop_.Quit(); } base::RunLoop run_loop_; int load_finished_count_ = 0; + int id_ = 0; + std::vector<int> prefs_test_ids_; DISALLOW_COPY_AND_ASSIGN(TestExternalRegistryLoader); }; @@ -71,4 +88,26 @@ base::RunLoop().RunUntilIdle(); } +// Tests that calling StartLoading() twice does not overwrite previous prefs +// before LoadFinished consumes it. +// Regression test for https://crbug.com/709304: if two StartLoading() schedules +// two LoadPrefsOnFileThread, then the second LoadPrefsOnFileThread could +// overwrite the first one's prefs. +TEST_F(ExternalRegistryLoaderUnittest, TwoStartLoadingDoesNotOverwritePrefs) { + scoped_refptr<TestExternalRegistryLoader> test_loader = + make_scoped_refptr(new TestExternalRegistryLoader()); + + test_loader->StartLoading(); + test_loader->StartLoading(); + + test_loader->WaitForTwoLoadsToFinished(); + // Let registry watcher code complete. + base::RunLoop().RunUntilIdle(); + + std::vector<int> prefs_test_ids = test_loader->GetPrefsTestIds(); + ASSERT_EQ(2u, prefs_test_ids.size()); + EXPECT_EQ(0, prefs_test_ids[0]); + EXPECT_EQ(1, prefs_test_ids[1]); +} + } // namespace extensions
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc index 2d2fea24..b9eb5d539 100644 --- a/chrome/browser/profiles/profile_manager_browsertest.cc +++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -5,13 +5,15 @@ #include <stddef.h> #include "base/bind.h" +#include "base/callback.h" #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "chrome/browser/browsing_data/browsing_data_remover_impl.h" +#include "chrome/browser/browsing_data/browsing_data_remover.h" +#include "chrome/browser/browsing_data/browsing_data_remover_factory.h" #include "chrome/browser/lifetime/keep_alive_types.h" #include "chrome/browser/lifetime/scoped_keep_alive.h" #include "chrome/browser/password_manager/password_store_factory.h" @@ -68,23 +70,31 @@ // deleted. It also create ScopedKeepAlive object to prevent browser shutdown // started in case browser has become windowless. class MultipleProfileDeletionObserver - : public BrowsingDataRemoverImpl::CompletionInhibitor, - public ProfileAttributesStorage::Observer { + : public ProfileAttributesStorage::Observer { public: explicit MultipleProfileDeletionObserver(size_t expected_count) : expected_count_(expected_count), profiles_created_count_(0), profiles_data_removed_count_(0) { EXPECT_GT(expected_count_, 0u); - g_browser_process->profile_manager()->GetProfileAttributesStorage(). - AddObserver(this); - BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(this); + ProfileManager* profile_manager = g_browser_process->profile_manager(); + profile_manager->GetProfileAttributesStorage().AddObserver(this); + + base::Callback<void(const base::Closure&)> would_complete_callback = + base::Bind(&MultipleProfileDeletionObserver:: + OnBrowsingDataRemoverWouldComplete, + base::Unretained(this)); + for (Profile* profile : profile_manager->GetLoadedProfiles()) { + BrowsingDataRemoverFactory::GetForBrowserContext(profile) + ->SetWouldCompleteCallbackForTesting(would_complete_callback); + } } + ~MultipleProfileDeletionObserver() override { g_browser_process->profile_manager()->GetProfileAttributesStorage(). RemoveObserver(this); - BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(nullptr); } + void Wait() { keep_alive_ = base::MakeUnique<ScopedKeepAlive>( KeepAliveOrigin::PROFILE_HELPER, KeepAliveRestartOption::DISABLED); @@ -99,8 +109,7 @@ // TODO(https://crbug.com/704601): remove this code when bug is fixed. void OnBrowsingDataRemoverWouldComplete( - BrowsingDataRemoverImpl* remover, - const base::Closure& continue_to_completion) override { + const base::Closure& continue_to_completion) { continue_to_completion.Run(); profiles_data_removed_count_++; MaybeQuit();
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js b/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js index c1d472b..31ad8476 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js +++ b/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js
@@ -192,7 +192,7 @@ this.tables_ = tables; // Initial refresh; set options from user preferences. - this.refresh(localStorage['brailleTable'], localStorage['brailleTable8']); + this.refresh(localStorage['brailleTable']); }.bind(this)); },
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json b/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json index ed218b0..c08ebdc 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
@@ -726,6 +726,15 @@ } }, { + "command": "toggleBrailleTable", + "sequence": { + "cvoxModifier": true, + "keys": { + "keyCode": [65, 71] + } + } + }, + { "command": "viewGraphicAsBraille", "sequence": { "cvoxModifier": true,
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js index de8b7ef..9073bcd 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js
@@ -64,6 +64,9 @@ 'autoRead': false, 'brailleCaptions': false, 'brailleSideBySide': true, + 'brailleTableType': 'brailleTable8', + 'brailleTable6': 'en-UEB-g2', + 'brailleTable8': 'en-US-comp8', // TODO(dtseng): Leaking state about multiple key maps here until we have a // class to manage multiple key maps. Also, this doesn't belong as a pref; // should just store in local storage.
diff --git a/chrome/browser/resources/chromeos/chromevox/common/command_store.js b/chrome/browser/resources/chromeos/chromevox/common/command_store.js index 18da1ead..6a54a38 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/command_store.js +++ b/chrome/browser/resources/chromeos/chromevox/common/command_store.js
@@ -352,7 +352,12 @@ 'darkenScreen': { msgId: 'darken_screen', category: 'help_commands' -}, + }, + + 'toggleBrailleTable': { + msgId: 'toggle_braille_table', + category: 'help_commands' + }, 'toggleKeyboardHelp': {announce: false, disallowContinuation: true,
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js index 2208f0bb..717e78e 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
@@ -313,7 +313,8 @@ Role.WINDOW, Role.EMBEDDED_OBJECT, Role.IFRAME, - Role.IFRAME_PRESENTATIONAL]); + Role.IFRAME_PRESENTATIONAL, + Role.UNKNOWN]); /** * Returns whether the given node should not be crossed when performing
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/braille_command_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/braille_command_handler.js index 1abce1a..9469ee7 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/braille_command_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/braille_command_handler.js
@@ -141,6 +141,9 @@ // s. map([2, 3, 4], 'toggleSpeechOnOrOff'); + + // g. + map([1, 2, 4, 5], 'toggleBrailleTable'); }; BrailleCommandHandler.init_();
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js index fd27489..ad04393 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
@@ -178,6 +178,27 @@ cvox.BrailleCaptionsBackground.setActive( !cvox.BrailleCaptionsBackground.isEnabled()); return false; + case 'toggleBrailleTable': + var brailleTableType = localStorage['brailleTableType']; + var output = ''; + if (brailleTableType == 'brailleTable6') { + brailleTableType = 'brailleTable8'; + + // This label reads "switch to 8 dot braille". + output = '@OPTIONS_BRAILLE_TABLE_TYPE_6'; + } else { + brailleTableType = 'brailleTable6'; + + // This label reads "switch to 6 dot braille". + output = '@OPTIONS_BRAILLE_TABLE_TYPE_8'; + } + + localStorage['brailleTable'] = localStorage[brailleTableType]; + localStorage['brailleTableType'] = brailleTableType; + cvox.BrailleBackground.getInstance().getTranslatorManager().refresh( + localStorage[brailleTableType]); + new Output().format(output).go(); + return false; case 'toggleChromeVoxVersion': if (!ChromeVoxState.instance.toggleNext()) return false;
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd index 57b49979..2761bda 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -2727,6 +2727,9 @@ <message desc="Description of a command that toggles text to speech feedback on or off." name="IDS_CHROMEVOX_SPEECH_ON_OFF_DESCRIPTION"> Toggle speech on or off </message> + <message desc="Description of a command that toggles between 6 and 8 dot braille." name="IDS_CHROMEVOX_TOGGLE_BRAILLE_TABLE"> + Toggle between 6 and 8 dot braille + </message> </messages> </release> </grit>
diff --git a/chrome/browser/resources/chromeos/switch_access/switch_access.js b/chrome/browser/resources/chromeos/switch_access/switch_access.js index 0adc858..58bcb3a 100644 --- a/chrome/browser/resources/chromeos/switch_access/switch_access.js +++ b/chrome/browser/resources/chromeos/switch_access/switch_access.js
@@ -107,14 +107,6 @@ if (!this.node_) return; - let state = this.node_.state; - if (state && state.focusable) - console.log('Node was focusable, doing default on it') - else if (state) - console.log('Node was not focusable, but still doing default'); - else - console.log('Node has no state, still doing default'); - console.log('\n'); this.node_.doDefault(); }, @@ -170,6 +162,7 @@ if (node) { console.log('Name = ' + node.name); console.log('Role = ' + node.role); + console.log('Root role = ' + node.root.role); if (!node.parent) console.log('At index ' + node.indexInParent + ', has no parent'); else {
diff --git a/chrome/browser/resources/chromeos/switch_access/tree_walker.js b/chrome/browser/resources/chromeos/switch_access/tree_walker.js index ce8237d7..5fc9f1f1 100644 --- a/chrome/browser/resources/chromeos/switch_access/tree_walker.js +++ b/chrome/browser/resources/chromeos/switch_access/tree_walker.js
@@ -116,11 +116,32 @@ * Returns true if |node| is interesting. * * @param {!chrome.automation.AutomationNode} node - * @return {boolean|undefined} + * @return {boolean} * @private */ isInteresting_: function(node) { - return node.state && node.state.focusable; + let loc = node.location; + let parent = node.parent; + let root = node.root; + let role = node.role; + let state = node.state; + + // Skip things that are offscreen + if (state[chrome.automation.StateType.OFFSCREEN] + || loc.top < 0 || loc.left < 0) + return false; + + if (parent) { + // crbug.com/710559 + // Work around for browser tabs + if (role === chrome.automation.RoleType.TAB + && parent.role === chrome.automation.RoleType.TAB_LIST + && root.role === chrome.automation.RoleType.DESKTOP) + return true; + } + + // The general rule that applies to everything. + return state[chrome.automation.StateType.FOCUSABLE] === true; }, /**
diff --git a/chrome/browser/resources/chromeos/switch_access/tree_walker_unittest.gtestjs b/chrome/browser/resources/chromeos/switch_access/tree_walker_unittest.gtestjs index 52782ee..380f2d5 100644 --- a/chrome/browser/resources/chromeos/switch_access/tree_walker_unittest.gtestjs +++ b/chrome/browser/resources/chromeos/switch_access/tree_walker_unittest.gtestjs
@@ -23,6 +23,7 @@ browsePreload: DUMMY_URL, getSampleTree: function() { + let loc = {left: 0, top: 0, width: 0, height: 0}; // root // middle1 // leaf1 @@ -31,14 +32,14 @@ // middle2 // leaf4 // leaf5 - let root = {}; - let middle1 = {}; - let middle2 = {}; - let leaf1 = {}; - let leaf2 = {}; - let leaf3 = {}; - let leaf4 = {}; - let leaf5 = {}; + let root = {location: loc, state: {}}; + let middle1 = {location: loc, state: {}}; + let middle2 = {location: loc, state: {}}; + let leaf1 = {location: loc, state: {}}; + let leaf2 = {location: loc, state: {}}; + let leaf3 = {location: loc, state: {}}; + let leaf4 = {location: loc, state: {}}; + let leaf5 = {location: loc, state: {}}; root.firstChild = middle1; root.lastChild = middle2; @@ -79,6 +80,11 @@ }; TEST_F('AutomationTreeWalkerUnitTest', 'MoveToNode', function() { + chrome.automation = { + RoleType: {DESKTOP: 'desktop', TAB: 'tab', TAB_LIST: 'tabList'}, + StateType: {FOCUSABLE: 'focusable', OFFSCREEN: 'offscreen'} + }; + let t = this.getSampleTree(); let treeWalker = new AutomationTreeWalker(); @@ -154,14 +160,36 @@ }); TEST_F('AutomationTreeWalkerUnitTest', 'IsInteresting', function() { - let node1 = {}; - let node2 = {state: {}}; - let node3 = {state: {focusable: false}}; - let node4 = {state: {focusable: true}}; + chrome.automation = { + RoleType: {DESKTOP: 'desktop', TAB: 'tab', TAB_LIST: 'tabList'}, + StateType: {FOCUSABLE: 'focusable', OFFSCREEN: 'offscreen'} + }; + let treeWalker = new AutomationTreeWalker(); - assertTrue(treeWalker.isInteresting_(node1) === undefined); - assertTrue(treeWalker.isInteresting_(node2) === undefined); - assertFalse(treeWalker.isInteresting_(node3)); - assertTrue(treeWalker.isInteresting_(node4)); + // Testing focusable. + let loc1 = {left: 0, top: 0, width: 0, height: 0}; + let node1 = {location: loc1, state: {}}; + let node2 = {location: loc1, state: {focusable: false}}; + let node3 = {location: loc1, state: {focusable: true}}; + assertFalse(treeWalker.isInteresting_(node1)); + assertFalse(treeWalker.isInteresting_(node2)); + assertTrue(treeWalker.isInteresting_(node3)); + + // Testing onscreen. + let loc2 = {left: -1, top: 0, width: 0, height: 0}; + let loc3 = {left: 0, top: -1, width: 0, height: 0}; + let node4 = {location: loc2, state: {focusable: true}}; + let node5 = {location: loc3, state: {focusable: true}}; + assertFalse(treeWalker.isInteresting_(node4)); + assertFalse(treeWalker.isInteresting_(node5)); + + // Testing if tab. + let node6 = {location: loc1, role: 'desktop', state: {}}; + let node7 = {location: loc1, role: 'tabList', state: {}}; + let node8 = + {location: loc1, parent: node7, root: node6, role: 'tab', state: {}}; + assertFalse(treeWalker.isInteresting_(node6)); + assertFalse(treeWalker.isInteresting_(node7)); + assertTrue(treeWalker.isInteresting_(node8)); });
diff --git a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js index 6e46140..7a5f37e 100644 --- a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js +++ b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js
@@ -74,9 +74,11 @@ var screenLockDiv = lockScreen.root.querySelector('#screenLockDiv'); screenLockDiv.hidden = true; - // The fingerprint settings on options is always hidden. + // The fingerprint settings and easy unlock on options is always hidden. var fingerprintDiv = lockScreen.root.querySelector('#fingerprintDiv'); fingerprintDiv.hidden = true; + var easyUnlockDiv = lockScreen.root.querySelector('#easyUnlock'); + easyUnlockDiv.hidden = true; var passwordPrompt = lockScreen.root. querySelector('settings-password-prompt-dialog');
diff --git a/chrome/browser/resources/options/compiled_resources.gyp b/chrome/browser/resources/options/compiled_resources.gyp index 4ec0fcd..269ab04 100644 --- a/chrome/browser/resources/options/compiled_resources.gyp +++ b/chrome/browser/resources/options/compiled_resources.gyp
@@ -44,7 +44,9 @@ '../../../../ui/webui/resources/js/util.js', '../../../../chrome/browser/resources/chromeos/keyboard/keyboard_utils.js', '../../../../ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '../../../../ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', '../settings/compiled_resources2.gyp:route', + '../settings/people_page/compiled_resources2.gyp:easy_unlock_browser_proxy', '../settings/people_page/compiled_resources2.gyp:fingerprint_browser_proxy', '../settings/people_page/compiled_resources2.gyp:lock_screen_constants', '../settings/people_page/compiled_resources2.gyp:lock_state_behavior',
diff --git a/chrome/browser/resources/options_resources.grd b/chrome/browser/resources/options_resources.grd index 40f031ce..4ddc0f1 100644 --- a/chrome/browser/resources/options_resources.grd +++ b/chrome/browser/resources/options_resources.grd
@@ -54,6 +54,18 @@ <structure name="IDR_OPTIONS_SETUP_PIN_DIALOG_HTML" file="settings/people_page/setup_pin_dialog.html" type="chrome_html" /> + <structure name="IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_JS" + file="settings/people_page/easy_unlock_browser_proxy.js" + type="chrome_html" /> + <structure name="IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_HTML" + file="settings/people_page/easy_unlock_browser_proxy.html" + type="chrome_html" /> + <structure name="IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_JS" + file="settings/people_page/easy_unlock_turn_off_dialog.js" + type="chrome_html" /> + <structure name="IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_HTML" + file="settings/people_page/easy_unlock_turn_off_dialog.html" + type="chrome_html" /> <structure name="IDR_OPTIONS_FINGERPRINT_LIST_JS" file="settings/people_page/fingerprint_list.js" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp index 41543e0..3eb9053 100644 --- a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp
@@ -86,6 +86,38 @@ 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'lock_screen', + 'dependencies': [ + '../compiled_resources2.gyp:route', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', + 'easy_unlock_browser_proxy', + 'easy_unlock_turn_off_dialog', + 'fingerprint_browser_proxy', + 'lock_screen_constants', + 'lock_state_behavior', + 'password_prompt_dialog', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'lock_screen_constants', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/cr_profile_avatar_selector/compiled_resources2.gyp:cr_profile_avatar_selector', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'lock_state_behavior', + 'dependencies': [ + '../compiled_resources2.gyp:route', + '<(EXTERNS_GYP):quick_unlock_private', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'manage_profile', 'dependencies': [ '../compiled_resources2.gyp:route', @@ -122,10 +154,8 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:icon', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', - 'easy_unlock_browser_proxy', - 'easy_unlock_turn_off_dialog', + 'lock_screen', 'lock_screen_constants', 'lock_state_behavior', 'profile_info_browser_proxy', @@ -141,33 +171,6 @@ 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { - 'target_name': 'lock_state_behavior', - 'dependencies': [ - '../compiled_resources2.gyp:route', - '<(EXTERNS_GYP):quick_unlock_private', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'lock_screen_constants', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'lock_screen', - 'dependencies': [ - '../compiled_resources2.gyp:route', - 'fingerprint_browser_proxy', - 'lock_screen_constants', - 'lock_state_behavior', - 'password_prompt_dialog', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { 'target_name': 'setup_fingerprint_dialog', 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -181,9 +184,9 @@ 'target_name': 'setup_pin_dialog', 'dependencies': [ '../compiled_resources2.gyp:route', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', 'lock_screen_constants', 'password_prompt_dialog', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], },
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html index 6064de3..4fcf66d0 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.html +++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -2,9 +2,12 @@ <link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/action_link_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.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-radio-group/paper-radio-group.html"> <link rel="import" href="../controls/settings_toggle_button.html"> +<link rel="import" href="easy_unlock_browser_proxy.html"> +<link rel="import" href="easy_unlock_turn_off_dialog.html"> <link rel="import" href="fingerprint_browser_proxy.html"> <link rel="import" href="lock_screen_constants.html"> <link rel="import" href="lock_state_behavior.html"> @@ -19,6 +22,13 @@ <dom-module id="settings-lock-screen"> <template> <style include="settings-shared action-link"> + #easyUnlock .start { + /* When the easy unlock toggle is shown, the easy unlock section's + * content becomes squashed to the top and bottom edges. Use padding to + * ensure the easy unlock content looks correct. */ + padding: 11px 0; + } + .radio-indent { -webkit-margin-start: 36px; } @@ -75,12 +85,56 @@ </div> </template> + <template is="dom-if" if="[[easyUnlockAllowed_]]"> + <div id="easyUnlock" class="settings-box two-line"> + <div class="start"> + <div>$i18n{easyUnlockSectionTitle}</div> + <div class="secondary"> + [[getEasyUnlockDescription_(easyUnlockEnabled_, + '$i18nPolymer{easyUnlockDescription}', + '$i18nPolymer{easyUnlockSetupIntro}')]] + <a target="_blank" href="$i18n{easyUnlockLearnMoreURL}"> + $i18n{learnMore} + </a> + <template is="dom-if" if="[[getShowEasyUnlockToggle_( + easyUnlockEnabled_, easyUnlockProximityDetectionAllowed_)]]"> + <settings-toggle-button + pref="{{prefs.easy_unlock.proximity_required}}" + label="$i18n{easyUnlockRequireProximityLabel}"> + </settings-toggle-button> + </template> + </div> + </div> + <div class="secondary-action"> + <template is="dom-if" if="[[!easyUnlockEnabled_]]"> + <paper-button id="easyUnlockSetup" class="secondary-button" + on-tap="onEasyUnlockSetupTap_"> + $i18n{easyUnlockSetupButton} + </paper-button> + </template> + <template is="dom-if" if="[[easyUnlockEnabled_]]"> + <paper-button id="easyUnlockTurnOff" class="secondary-button" + on-tap="onEasyUnlockTurnOffTap_"> + $i18n{easyUnlockTurnOffButton} + </paper-button> + </template> + </div> + </div> + </template> + <settings-password-prompt-dialog id="passwordPrompt" on-close="onPasswordClosed_" set-modes="{{setModes_}}"> </settings-password-prompt-dialog> + <settings-setup-pin-dialog id="setupPin" on-done="onPinSetupDone_" set-modes="[[setModes_]]"> </settings-setup-pin-dialog> + + <template is="dom-if" if="[[showEasyUnlockTurnOffDialog_]]"> + <easy-unlock-turn-off-dialog id="easyUnlockTurnOffDialog" + on-close="onEasyUnlockTurnOffDialogClose_"> + </easy-unlock-turn-off-dialog> + </template> </div> </template>
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.js b/chrome/browser/resources/settings/people_page/lock_screen.js index 419671a..0699ef1 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.js +++ b/chrome/browser/resources/settings/people_page/lock_screen.js
@@ -17,13 +17,16 @@ Polymer({ is: 'settings-lock-screen', - behaviors: [I18nBehavior, LockStateBehavior, settings.RouteObserverBehavior], + behaviors: [ + I18nBehavior, + LockStateBehavior, + WebUIListenerBehavior, + settings.RouteObserverBehavior, + ], properties: { /** Preferences state. */ - prefs: { - type: Object - }, + prefs: {type: Object}, /** * setModes_ is a partially applied function that stores the previously @@ -35,7 +38,7 @@ */ setModes_: { type: Object, - observer: 'onSetModesChanged_' + observer: 'onSetModesChanged_', }, /** @@ -47,7 +50,9 @@ */ writeUma_: { type: Object, - value: function() { return settings.recordLockScreenProgress; } + value: function() { + return settings.recordLockScreenProgress; + }, }, /** @@ -79,10 +84,52 @@ type: Number, value: 0, }, + + /** + * True if Easy Unlock is allowed on this machine. + */ + easyUnlockAllowed_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('easyUnlockAllowed'); + }, + readOnly: true, + }, + + /** + * True if Easy Unlock is enabled. + */ + easyUnlockEnabled_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('easyUnlockEnabled'); + }, + }, + + /** + * True if Easy Unlock's proximity detection feature is allowed. + */ + easyUnlockProximityDetectionAllowed_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('easyUnlockAllowed') && + loadTimeData.getBoolean('easyUnlockProximityDetectionAllowed'); + }, + readOnly: true, + }, + + /** @private */ + showEasyUnlockTurnOffDialog_: { + type: Boolean, + value: false, + }, }, + /** @private {?settings.EasyUnlockBrowserProxy} */ + easyUnlockBrowserProxy_: null, + /** @private {?settings.FingerprintBrowserProxy} */ - browserProxy_: null, + fingerprintBrowserProxy_: null, /** selectedUnlockType is defined in LockStateBehavior. */ observers: ['selectedUnlockTypeChanged_(selectedUnlockType)'], @@ -91,7 +138,19 @@ attached: function() { if (this.shouldAskForPassword_(settings.getCurrentRoute())) this.$.passwordPrompt.open(); - this.browserProxy_ = settings.FingerprintBrowserProxyImpl.getInstance(); + + this.easyUnlockBrowserProxy_ = + settings.EasyUnlockBrowserProxyImpl.getInstance(); + this.fingerprintBrowserProxy_ = + settings.FingerprintBrowserProxyImpl.getInstance(); + + if (this.easyUnlockAllowed_) { + this.addWebUIListener( + 'easy-unlock-enabled-status', + this.handleEasyUnlockEnabledStatusChanged_.bind(this)); + this.easyUnlockBrowserProxy_.getEnabledStatus().then( + this.handleEasyUnlockEnabledStatusChanged_.bind(this)); + } }, /** @@ -102,9 +161,8 @@ */ currentRouteChanged: function(newRoute, oldRoute) { if (newRoute == settings.Route.LOCK_SCREEN && - this.fingerprintUnlockEnabled_ && - this.browserProxy_) { - this.browserProxy_.getNumFingerprints().then( + this.fingerprintUnlockEnabled_ && this.fingerprintBrowserProxy_) { + this.fingerprintBrowserProxy_.getNumFingerprints().then( function(numFingerprints) { this.numFingerprints_ = numFingerprints; }.bind(this)); @@ -206,4 +264,59 @@ shouldAskForPassword_: function(route) { return route == settings.Route.LOCK_SCREEN && !this.setModes_; }, + + /** + * Handler for when the Easy Unlock enabled status has changed. + * @private + */ + handleEasyUnlockEnabledStatusChanged_: function(easyUnlockEnabled) { + this.easyUnlockEnabled_ = easyUnlockEnabled; + this.showEasyUnlockTurnOffDialog_ = + easyUnlockEnabled && this.showEasyUnlockTurnOffDialog_; + }, + + /** @private */ + onEasyUnlockSetupTap_: function() { + this.easyUnlockBrowserProxy_.startTurnOnFlow(); + }, + + /** + * @param {!Event} e + * @private + */ + onEasyUnlockTurnOffTap_: function(e) { + // Prevent the end of the tap event from focusing what is underneath the + // button. + e.preventDefault(); + this.showEasyUnlockTurnOffDialog_ = true; + }, + + /** @private */ + onEasyUnlockTurnOffDialogClose_: function() { + this.showEasyUnlockTurnOffDialog_ = false; + + // Restores focus on close to either the turn-off or set-up button, + // whichever is being displayed. + this.$$('.secondary-button').focus(); + }, + + /** + * @param {boolean} enabled + * @param {!string} enabledStr + * @param {!string} disabledStr + * @private + */ + getEasyUnlockDescription_: function(enabled, enabledStr, disabledStr) { + return enabled ? enabledStr : disabledStr; + }, + + /** + * @param {boolean} easyUnlockEnabled + * @param {boolean} proximityDetectionAllowed + * @private + */ + getShowEasyUnlockToggle_: function( + easyUnlockEnabled, proximityDetectionAllowed) { + return easyUnlockEnabled && proximityDetectionAllowed; + }, });
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html index 4d8794c5..9e488b3 100644 --- a/chrome/browser/resources/settings/people_page/people_page.html +++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -22,8 +22,6 @@ <if expr="chromeos"> <link rel="import" href="change_picture.html"> -<link rel="import" href="easy_unlock_browser_proxy.html"> -<link rel="import" href="easy_unlock_turn_off_dialog.html"> <link rel="import" href="fingerprint_list.html"> <link rel="import" href="lock_screen.html"> <link rel="import" href="lock_state_behavior.html"> @@ -72,11 +70,6 @@ color: var(--settings-error-color); } - #easy-unlock .start { - /* Use padding to ensure taller content looks correct. */ - padding: 11px 0; - } - .icon-container { display: flex; flex-shrink: 0; @@ -219,50 +212,6 @@ aria-describedby="lockScrenSecondary"></button> </div> </template> - - <template is="dom-if" if="[[easyUnlockAllowed_]]"> - <div id="easy-unlock" class="settings-box two-line"> - <div class="start"> - <div>$i18n{easyUnlockSectionTitle}</div> - <div class="secondary"> - <template is="dom-if" if="[[!easyUnlockEnabled_]]"> - $i18n{easyUnlockSetupIntro} - </template> - <template is="dom-if" if="[[easyUnlockEnabled_]]"> - $i18n{easyUnlockDescription} - </template> - <a target="_blank" href="$i18n{easyUnlockLearnMoreURL}"> - $i18n{learnMore} - </a> - <!-- TODO(dbeam): this should be 1 dom-if with a method instead - of 2 nested dom-ifs. --> - <template is="dom-if" if="[[easyUnlockEnabled_]]"> - <template is="dom-if" - if="[[easyUnlockProximityDetectionAllowed_]]"> - <settings-toggle-button - pref="{{prefs.easy_unlock.proximity_required}}" - label="$i18n{easyUnlockRequireProximityLabel}"> - </settings-toggle-button> - </template> - </template> - </div> - </div> - <div class="secondary-action"> - <template is="dom-if" if="[[!easyUnlockEnabled_]]"> - <paper-button id="easyUnlockSetup" class="secondary-button" - on-tap="onEasyUnlockSetupTap_"> - $i18n{easyUnlockSetupButton} - </paper-button> - </template> - <template is="dom-if" if="[[easyUnlockEnabled_]]"> - <paper-button id="easyUnlockTurnOff" class="secondary-button" - on-tap="onEasyUnlockTurnOffTap_"> - $i18n{easyUnlockTurnOffButton} - </paper-button> - </template> - </div> - </div> - </template> </if> <div id="manage-other-people-subpage-trigger" @@ -286,8 +235,7 @@ on-tap="onManageSupervisedUsers_" actionable> <div class="start">$i18n{manageSupervisedUsers}</div> <button class="icon-external" is="paper-icon-button-light" - aria-label="$i18n{manageSupervisedUsers}" - aria-describedby="manageSupervisedUsersSecondary"></button> + aria-label="$i18n{manageSupervisedUsers}"></button> </div> </template> </neon-animatable> @@ -396,13 +344,6 @@ </settings-import-data-dialog> </template> -<if expr="chromeos"> - <template is="dom-if" if="[[showEasyUnlockTurnOffDialog_]]"> - <easy-unlock-turn-off-dialog id="easyUnlockTurnOffDialog" - on-close="onEasyUnlockTurnOffDialogClose_"> - </easy-unlock-turn-off-dialog> - </template> -</if> </template> <script src="people_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index e222cc4..b90834a 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -97,53 +97,6 @@ }, readOnly: true, }, - - /** @private {!settings.EasyUnlockBrowserProxy} */ - easyUnlockBrowserProxy_: { - type: Object, - value: function() { - return settings.EasyUnlockBrowserProxyImpl.getInstance(); - }, - }, - - /** - * True if Easy Unlock is allowed on this machine. - */ - easyUnlockAllowed_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('easyUnlockAllowed'); - }, - readOnly: true, - }, - - /** - * True if Easy Unlock is enabled. - */ - easyUnlockEnabled_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('easyUnlockEnabled'); - }, - }, - - /** - * True if Easy Unlock's proximity detection feature is allowed. - */ - easyUnlockProximityDetectionAllowed_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('easyUnlockAllowed') && - loadTimeData.getBoolean('easyUnlockProximityDetectionAllowed'); - }, - readOnly: true, - }, - - /** @private */ - showEasyUnlockTurnOffDialog_: { - type: Boolean, - value: false, - }, // </if> /** @private {!Map<string, string>} */ @@ -192,16 +145,6 @@ this.handleSyncStatus_.bind(this)); this.addWebUIListener('sync-status-changed', this.handleSyncStatus_.bind(this)); - -// <if expr="chromeos"> - if (this.easyUnlockAllowed_) { - this.addWebUIListener( - 'easy-unlock-enabled-status', - this.handleEasyUnlockEnabledStatusChanged_.bind(this)); - this.easyUnlockBrowserProxy_.getEnabledStatus().then( - this.handleEasyUnlockEnabledStatusChanged_.bind(this)); - } -// </if> }, /** @protected */ @@ -292,18 +235,6 @@ this.syncStatus = syncStatus; }, -// <if expr="chromeos"> - /** - * Handler for when the Easy Unlock enabled status has changed. - * @private - */ - handleEasyUnlockEnabledStatusChanged_: function(easyUnlockEnabled) { - this.easyUnlockEnabled_ = easyUnlockEnabled; - this.showEasyUnlockTurnOffDialog_ = - easyUnlockEnabled && this.showEasyUnlockTurnOffDialog_; - }, -// </if> - /** @private */ onPictureTap_: function() { // <if expr="chromeos"> @@ -404,25 +335,6 @@ onConfigureLockTap_: function() { settings.navigateTo(settings.Route.LOCK_SCREEN); }, - - /** @private */ - onEasyUnlockSetupTap_: function() { - this.easyUnlockBrowserProxy_.startTurnOnFlow(); - }, - - /** - * @param {!Event} e - * @private - */ - onEasyUnlockTurnOffTap_: function(e) { - e.preventDefault(); - this.showEasyUnlockTurnOffDialog_ = true; - }, - - /** @private */ - onEasyUnlockTurnOffDialogClose_: function() { - this.showEasyUnlockTurnOffDialog_ = false; - }, // </if> /** @private */
diff --git a/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc b/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc index c74e1da..9631966 100644 --- a/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc +++ b/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc
@@ -14,6 +14,7 @@ #include "base/run_loop.h" #include "chrome/test/base/in_process_browser_test.h" #include "ui/app_list/presenter/app_list.h" +#include "ui/aura/window.h" #include "ui/events/test/event_generator.h" using AppListTest = InProcessBrowserTest; @@ -25,29 +26,28 @@ ash::ShelfWidget* shelf_widget = shelf->shelf_widget(); ash::AppListButton* app_list_button = shelf_widget->GetAppListButton(); - ash::WmWindow* root_window = - ash::WmWindow::Get(ash::wm::GetActiveWindow())->GetRootWindow(); - ash::WmWindow* app_list_container = root_window->GetChildByShellWindowId( - ash::kShellWindowId_AppListContainer); + aura::Window* root_window = ash::wm::GetActiveWindow()->GetRootWindow(); + aura::Window* app_list_container = + root_window->GetChildById(ash::kShellWindowId_AppListContainer); ui::test::EventGenerator generator(shelf_widget->GetNativeWindow()); // Click the app list button to show the app list. ash::Shell* shell = ash::Shell::Get(); EXPECT_FALSE(shell->app_list()->GetTargetVisibility()); - EXPECT_EQ(0u, app_list_container->GetChildren().size()); + EXPECT_EQ(0u, app_list_container->children().size()); EXPECT_FALSE(app_list_button->is_showing_app_list()); generator.set_current_location( app_list_button->GetBoundsInScreen().CenterPoint()); generator.ClickLeftButton(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(shell->app_list()->GetTargetVisibility()); - EXPECT_EQ(1u, app_list_container->GetChildren().size()); + EXPECT_EQ(1u, app_list_container->children().size()); EXPECT_TRUE(app_list_button->is_showing_app_list()); // Click the button again to dismiss the app list; the window animates closed. generator.ClickLeftButton(); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(shell->app_list()->GetTargetVisibility()); - EXPECT_EQ(1u, app_list_container->GetChildren().size()); + EXPECT_EQ(1u, app_list_container->children().size()); EXPECT_FALSE(app_list_button->is_showing_app_list()); }
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc index 577fed7..74adde50 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
@@ -62,7 +62,8 @@ ChromeBrowserMainExtraPartsViewsLinux:: ~ChromeBrowserMainExtraPartsViewsLinux() { - views::X11DesktopHandler::get()->RemoveObserver(this); + if (views::X11DesktopHandler::get_dont_create()) + views::X11DesktopHandler::get_dont_create()->RemoveObserver(this); } void ChromeBrowserMainExtraPartsViewsLinux::PreEarlyInitialization() {
diff --git a/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc index e45d1b2a..f6d22b31 100644 --- a/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc
@@ -152,7 +152,7 @@ ExpectBodyContains(std::vector<base::string16>{ base::UTF8ToUTF16("\"payerName\": \"John H. Doe\""), base::UTF8ToUTF16("\"payerEmail\": \"johndoe@hades.com\""), - base::UTF8ToUTF16("\"payerPhone\": \"16502111111\"")}); + base::UTF8ToUTF16("\"payerPhone\": \"+16502111111\"")}); } class PaymentRequestPaymentResponseOneContactDetailTest
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index f7a7ddd..db8dec1d 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -877,8 +877,13 @@ SigninScreenHandler::SetUserInputMethod(populated_email_, gaia_ime_state.get()); } else { - std::vector<std::string> input_methods = - imm->GetInputMethodUtil()->GetHardwareLoginInputMethodIds(); + std::vector<std::string> input_methods; + if (gaia_ime_state->GetAllowedInputMethods().empty()) { + input_methods = + imm->GetInputMethodUtil()->GetHardwareLoginInputMethodIds(); + } else { + input_methods = gaia_ime_state->GetAllowedInputMethods(); + } const std::string owner_im = SigninScreenHandler::GetUserLastInputMethod( user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail()); const std::string system_im = g_browser_process->local_state()->GetString(
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index bcb26d6..c67657c9 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -329,7 +329,6 @@ chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); if (keyboard) keyboard->AddObserver(this); - OnAllowedInputMethodsChanged(); allowed_input_methods_subscription_ = chromeos::CrosSettings::Get()->AddSettingsObserver( chromeos::kDeviceLoginScreenInputMethods, @@ -1377,6 +1376,7 @@ webui_visible_ = true; if (preferences_changed_delayed_) OnPreferencesChanged(); + OnAllowedInputMethodsChanged(); } void SigninScreenHandler::HandleCancelPasswordChangedFlow( @@ -1603,6 +1603,7 @@ void SigninScreenHandler::OnShowAddUser() { is_account_picker_showing_first_time_ = false; + EnforcePolicyInputMethods(std::string()); gaia_screen_handler_->ShowGaiaAsync(); } @@ -1624,6 +1625,9 @@ } void SigninScreenHandler::OnAllowedInputMethodsChanged() { + if (!webui_visible_) + return; + if (focused_pod_account_id_) { std::string user_input_method = GetUserLastInputMethod(focused_pod_account_id_->GetUserEmail());
diff --git a/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc b/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc index 700d0b4..6d49702 100644 --- a/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc +++ b/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc
@@ -6,6 +6,8 @@ #include "base/macros.h" #include "build/build_config.h" +#include "chrome/browser/browsing_data/browsing_data_remover.h" +#include "chrome/browser/browsing_data/browsing_data_remover_factory.h" #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -57,7 +59,8 @@ IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest, MAYBE_CommitButtonDisabledWhileDeletionInProgress) { const char kCommitButtonId[] = "#clear-browser-data-commit"; - BrowsingDataRemoverCompletionInhibitor completion_inhibitor; + BrowsingDataRemoverCompletionInhibitor completion_inhibitor( + BrowsingDataRemoverFactory::GetForBrowserContext(browser()->profile())); // Navigate to the Clear Browsing Data dialog to ensure that the commit button // is initially enabled, usable, and gets disabled after having been pressed.
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc index f82ca20..4fea4576 100644 --- a/chrome/browser/ui/webui/options/options_ui.cc +++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -139,6 +139,14 @@ constexpr char kLockScreenJSPath[] = "people_page/lock_screen.js"; constexpr char kSetupPinHTMLPath[] = "people_page/setup_pin_dialog.html"; constexpr char kSetupPinJSPath[] = "people_page/setup_pin_dialog.js"; +constexpr char kEasyUnlockBrowserProxyHTMLPath[] = + "people_page/easy_unlock_browser_proxy.html"; +constexpr char kEasyUnlockBrowserProxyJSPath[] = + "people_page/easy_unlock_browser_proxy.js"; +constexpr char kEasyUnlockTurnOffDialogHTMLPath[] = + "people_page/easy_unlock_turn_off_dialog.html"; +constexpr char kEasyUnlockTurnOffDialogJSPath[] = + "people_page/easy_unlock_turn_off_dialog.js"; constexpr char kFingerprintListHTMLPath[] = "people_page/fingerprint_list.html"; constexpr char kFingerprintListJSPath[] = "people_page/fingerprint_list.js"; constexpr char kSetupFingerprintHTMLPath[] = @@ -311,6 +319,14 @@ IDR_OPTIONS_LOCK_STATE_BEHAVIOR_JS; path_to_idr_map_[kLockScreenHTMLPath] = IDR_OPTIONS_LOCK_SCREEN_HTML; path_to_idr_map_[kLockScreenJSPath] = IDR_OPTIONS_LOCK_SCREEN_JS; + path_to_idr_map_[kEasyUnlockBrowserProxyHTMLPath] = + IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_HTML; + path_to_idr_map_[kEasyUnlockBrowserProxyJSPath] = + IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_JS; + path_to_idr_map_[kEasyUnlockTurnOffDialogHTMLPath] = + IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_HTML; + path_to_idr_map_[kEasyUnlockTurnOffDialogJSPath] = + IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_JS; path_to_idr_map_[kSetupPinHTMLPath] = IDR_OPTIONS_SETUP_PIN_DIALOG_HTML; path_to_idr_map_[kSetupPinJSPath] = IDR_OPTIONS_SETUP_PIN_DIALOG_JS; path_to_idr_map_[kFingerprintListHTMLPath] =
diff --git a/chrome/browser/ui/webui/profile_helper_browsertest.cc b/chrome/browser/ui/webui/profile_helper_browsertest.cc index 5b09006..ae889fc 100644 --- a/chrome/browser/ui/webui/profile_helper_browsertest.cc +++ b/chrome/browser/ui/webui/profile_helper_browsertest.cc
@@ -6,7 +6,9 @@ #include "base/run_loop.h" #include "base/scoped_observer.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browsing_data/browsing_data_remover_impl.h" +#include "chrome/browser/browsing_data/browsing_data_remover.h" +#include "chrome/browser/browsing_data/browsing_data_remover_factory.h" +#include "chrome/browser/browsing_data/browsing_data_remover_test_util.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_manager.h" @@ -66,29 +68,6 @@ ScopedObserver<BrowserList, chrome::BrowserListObserver> scoped_observer_; }; -// TODO(bug 704601): remove it when bug is fixed. -class BrowsingDataRemoverObserver - : public BrowsingDataRemoverImpl::CompletionInhibitor { - public: - explicit BrowsingDataRemoverObserver(const base::Closure& callback) - : callback_(callback) { - BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(this); - } - ~BrowsingDataRemoverObserver() override { - BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(nullptr); - } - - private: - void OnBrowsingDataRemoverWouldComplete( - BrowsingDataRemoverImpl* remover, - const base::Closure& continue_to_completion) override { - continue_to_completion.Run(); - callback_.Run(); - } - - const base::Closure callback_; -}; - } // namespace using ProfileHelperTest = InProcessBrowserTest; @@ -205,11 +184,12 @@ Profile* additional_profile = CreateProfile(); EXPECT_EQ(2u, storage.GetNumberOfProfiles()); - base::RunLoop loop; - BrowsingDataRemoverObserver observer(loop.QuitClosure()); + BrowsingDataRemoverCompletionInhibitor inhibitor( + BrowsingDataRemoverFactory::GetForBrowserContext(additional_profile)); webui::DeleteProfileAtPath(additional_profile->GetPath(), &web_ui, ProfileMetrics::DELETE_PROFILE_SETTINGS); - loop.Run(); + inhibitor.BlockUntilNearCompletion(); + inhibitor.ContinueToCompletion(); EXPECT_EQ(1u, browser_list->size()); EXPECT_TRUE(base::ContainsValue(*browser_list, original_browser));
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index 40e20be..0ee7196 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -596,7 +596,14 @@ ContentSettingsPattern pattern = ContentSettingsPattern::FromString(pattern_string); - ResolveJavascriptCallback(*callback_id, base::Value(pattern.IsValid())); + bool valid = pattern.IsValid(); + + // If the input is just '*' don't allow it, even though it's a valid pattern. + // This changes the default setting. + if (pattern == ContentSettingsPattern::Wildcard()) + valid = false; + + ResolveJavascriptCallback(*callback_id, base::Value(valid)); } void SiteSettingsHandler::HandleUpdateIncognitoStatus(
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 070d4ca..a156676 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -353,6 +353,16 @@ invalid.AppendString(bad_pattern); handler()->HandleIsPatternValid(&invalid); ValidatePattern(false, 2U); + + // The wildcard pattern ('*') is a valid pattern, but not allowed to be + // entered in site settings as it changes the default setting. + // (crbug.com/709539). + base::ListValue invalid_wildcard; + std::string bad_pattern_wildcard("*"); + invalid_wildcard.AppendString(kCallbackId); + invalid_wildcard.AppendString(bad_pattern_wildcard); + handler()->HandleIsPatternValid(&invalid_wildcard); + ValidatePattern(false, 3U); } TEST_F(SiteSettingsHandlerTest, Incognito) {
diff --git a/chrome/test/base/mash_browser_tests_main.cc b/chrome/test/base/mash_browser_tests_main.cc index bc097e1..d5ea89c 100644 --- a/chrome/test/base/mash_browser_tests_main.cc +++ b/chrome/test/base/mash_browser_tests_main.cc
@@ -44,7 +44,7 @@ FILE_PATH_LITERAL("mash_browser_tests_catalog.json"); void ConnectToDefaultApps(service_manager::Connector* connector) { - connector->Connect(mash::session::mojom::kServiceName); + connector->StartService(mash::session::mojom::kServiceName); } class MashTestSuite : public ChromeTestSuite {
diff --git a/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js b/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js index 2659015..b9b1a1ae 100644 --- a/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js +++ b/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js
@@ -37,7 +37,7 @@ GEN('#define MAYBE_EasyUnlock EasyUnlock'); GEN('#endif'); -// Runs change picture tests. +// Runs easy unlock tests. TEST_F('SettingsEasyUnlockBrowserTest', 'MAYBE_EasyUnlock', function() { /** * A test version of EasyUnlockBrowserProxy. Provides helper methods @@ -99,20 +99,14 @@ }, }; - /** @type {?SettingsPeoplePageElement} */ - var page = null; + /** @type {?SettingsLockScreenElement} */ + var lockScreen = null; /** @type {?TestEasyUnlockBrowserProxy} */ var browserProxy = null; - /** @type {?CrSettingsPrefs} */ - var prefs = null; - - var self = this; - suite('SettingsEasyUnlock', function() { suiteSetup(function() { - self.basicPage.set('pageVisibility.people', true); Polymer.dom.flush(); // These overrides are necessary for this test to function on ChromeOS @@ -131,10 +125,6 @@ easyUnlockTurnOffDescription: '', easyUnlockTurnOffButton: '', }); - - // Before clearing the body, save a copy of the real prefs so we can - // cleanly re-create the People page element. - prefs = document.querySelector('settings-ui').$$('settings-prefs').prefs; }); setup(function() { @@ -142,25 +132,19 @@ settings.EasyUnlockBrowserProxyImpl.instance_ = browserProxy; PolymerTest.clearBody(); - page = document.createElement('settings-people-page'); - page.currentRoute = { - page: 'basic', - section: '', - subpage: [], - }; - page.prefs = prefs; + lockScreen = document.createElement('settings-lock-screen'); }); test('setup button', function() { - document.body.appendChild(page); + document.body.appendChild(lockScreen); return browserProxy.whenCalled('getEnabledStatus').then(function() { - assertTrue(page.easyUnlockAllowed_); - expectFalse(page.easyUnlockEnabled_); + assertTrue(lockScreen.easyUnlockAllowed_); + expectFalse(lockScreen.easyUnlockEnabled_); Polymer.dom.flush(); - var setupButton = page.$$('#easyUnlockSetup'); + var setupButton = lockScreen.$$('#easyUnlockSetup'); assertTrue(!!setupButton); expectFalse(setupButton.hidden); @@ -171,70 +155,77 @@ test('turn off dialog', function() { browserProxy.setEnabledStatus(true); - document.body.appendChild(page); + document.body.appendChild(lockScreen); var turnOffDialog = null; - return browserProxy.whenCalled('getEnabledStatus').then(function() { - assertTrue(page.easyUnlockAllowed_); - expectTrue(page.easyUnlockEnabled_); + return browserProxy.whenCalled('getEnabledStatus') + .then(function() { + assertTrue(lockScreen.easyUnlockAllowed_); + expectTrue(lockScreen.easyUnlockEnabled_); - Polymer.dom.flush(); + Polymer.dom.flush(); - var turnOffButton = page.$$('#easyUnlockTurnOff'); - assertTrue(!!turnOffButton); - expectFalse(turnOffButton.hidden) + var turnOffButton = lockScreen.$$('#easyUnlockTurnOff'); + assertTrue(!!turnOffButton); + expectFalse(turnOffButton.hidden) - MockInteractions.tap(turnOffButton); - return browserProxy.whenCalled('getTurnOffFlowStatus'); - }).then(function() { - Polymer.dom.flush(); + MockInteractions.tap(turnOffButton); + return browserProxy.whenCalled('getTurnOffFlowStatus'); + }) + .then(function() { + Polymer.dom.flush(); - turnOffDialog = page.$$('#easyUnlockTurnOffDialog'); - assertTrue(!!turnOffDialog); + turnOffDialog = lockScreen.$$('#easyUnlockTurnOffDialog'); + assertTrue(!!turnOffDialog); - // Verify that elements on the turn off dialog are hidden or active - // according to the easy unlock turn off status. - var turnOffDialogButtonContainer = - turnOffDialog.$$('.button-container'); - var turnOffDialogButtonSpinner = turnOffDialog.$$('paper-spinner'); - var turnOffDialogConfirmButton = turnOffDialog.$$('#turnOff'); - var turnOffDialogCancelButton = turnOffDialog.$$('.cancel-button'); - assertTrue(!!turnOffDialogButtonContainer); - assertTrue(!!turnOffDialogButtonSpinner); - assertTrue(!!turnOffDialogConfirmButton); - assertTrue(!!turnOffDialogCancelButton); + // Verify that elements on the turn off dialog are hidden or active + // according to the easy unlock turn off status. + var turnOffDialogButtonContainer = + turnOffDialog.$$('.button-container'); + var turnOffDialogButtonSpinner = turnOffDialog.$$('paper-spinner'); + var turnOffDialogConfirmButton = turnOffDialog.$$('#turnOff'); + var turnOffDialogCancelButton = turnOffDialog.$$('.cancel-button'); + assertTrue(!!turnOffDialogButtonContainer); + assertTrue(!!turnOffDialogButtonSpinner); + assertTrue(!!turnOffDialogConfirmButton); + assertTrue(!!turnOffDialogCancelButton); - cr.webUIListenerCallback('easy-unlock-turn-off-flow-status', 'offline'); - expectTrue(turnOffDialogButtonContainer.hidden); - expectFalse(turnOffDialogButtonSpinner.active); + cr.webUIListenerCallback( + 'easy-unlock-turn-off-flow-status', 'offline'); + expectTrue(turnOffDialogButtonContainer.hidden); + expectFalse(turnOffDialogButtonSpinner.active); - cr.webUIListenerCallback('easy-unlock-turn-off-flow-status', 'pending'); - expectFalse(turnOffDialogButtonContainer.hidden); - expectTrue(turnOffDialogButtonSpinner.active); + cr.webUIListenerCallback( + 'easy-unlock-turn-off-flow-status', 'pending'); + expectFalse(turnOffDialogButtonContainer.hidden); + expectTrue(turnOffDialogButtonSpinner.active); - cr.webUIListenerCallback('easy-unlock-turn-off-flow-status', - 'server-error'); - expectFalse(turnOffDialogButtonContainer.hidden); - expectTrue(turnOffDialogCancelButton.hidden); + cr.webUIListenerCallback( + 'easy-unlock-turn-off-flow-status', 'server-error'); + expectFalse(turnOffDialogButtonContainer.hidden); + expectTrue(turnOffDialogCancelButton.hidden); - cr.webUIListenerCallback('easy-unlock-turn-off-flow-status', 'idle'); - expectFalse(turnOffDialogConfirmButton.hidden); + cr.webUIListenerCallback( + 'easy-unlock-turn-off-flow-status', 'idle'); + expectFalse(turnOffDialogConfirmButton.hidden); - MockInteractions.tap(turnOffDialogConfirmButton); + MockInteractions.tap(turnOffDialogConfirmButton); - return browserProxy.whenCalled('startTurnOffFlow'); - }).then(function() { - // To signal successful turnoff, the enabled status is broadcast - // as false. At that point, the dialog should close and cancel - // any in-progress turnoff flow. The cancellation should be - // a no-op assuming the turnoff originated from this tab. - cr.webUIListenerCallback('easy-unlock-enabled-status', false); - return browserProxy.whenCalled('cancelTurnOffFlow'); - }).then(function() { - Polymer.dom.flush(); - expectFalse(turnOffDialog.$.dialog.open); - }); + return browserProxy.whenCalled('startTurnOffFlow'); + }) + .then(function() { + // To signal successful turnoff, the enabled status is broadcast + // as false. At that point, the dialog should close and cancel + // any in-progress turnoff flow. The cancellation should be + // a no-op assuming the turnoff originated from this tab. + cr.webUIListenerCallback('easy-unlock-enabled-status', false); + return browserProxy.whenCalled('cancelTurnOffFlow'); + }) + .then(function() { + Polymer.dom.flush(); + expectFalse(turnOffDialog.$.dialog.open); + }); }); });
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc index 9047cdc..32cb9e9 100644 --- a/components/error_page/common/localized_error.cc +++ b/components/error_page/common/localized_error.cc
@@ -248,6 +248,12 @@ SUGGEST_CONTACT_ADMINISTRATOR, SHOW_NO_BUTTONS, }, + {net::ERR_SSL_VERSION_INTERFERENCE, + IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, + IDS_ERRORPAGES_SUMMARY_CONNECTION_FAILED, + SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG, + SHOW_BUTTON_RELOAD, + }, {net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_SSL_SECURITY_ERROR,
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 7b05e9a..7fe5345 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -845,6 +845,21 @@ return title_; } +void ShellSurface::SaveWindowPlacement(const gfx::Rect& bounds, + ui::WindowShowState show_state) { + if (bounds_mode_ != BoundsMode::CLIENT) + WidgetDelegate::SaveWindowPlacement(bounds, show_state); +} + +bool ShellSurface::GetSavedWindowPlacement( + const views::Widget* widget, + gfx::Rect* bounds, + ui::WindowShowState* show_state) const { + if (bounds_mode_ != BoundsMode::CLIENT) + return WidgetDelegate::GetSavedWindowPlacement(widget, bounds, show_state); + return false; +} + void ShellSurface::WindowClosing() { if (resizer_) EndDrag(true /* revert */);
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index 80c93ea..1356c9a 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -225,6 +225,11 @@ bool CanMaximize() const override; bool CanMinimize() const override; base::string16 GetWindowTitle() const override; + void SaveWindowPlacement(const gfx::Rect& bounds, + ui::WindowShowState show_state) override; + bool GetSavedWindowPlacement(const views::Widget* widget, + gfx::Rect* bounds, + ui::WindowShowState* show_state) const override; void WindowClosing() override; views::Widget* GetWidget() override; const views::Widget* GetWidget() const override;
diff --git a/components/feature_engagement_tracker/internal/BUILD.gn b/components/feature_engagement_tracker/internal/BUILD.gn index fcdd0828..00badef3 100644 --- a/components/feature_engagement_tracker/internal/BUILD.gn +++ b/components/feature_engagement_tracker/internal/BUILD.gn
@@ -38,6 +38,10 @@ "store.h", ] + public_deps = [ + "//components/feature_engagement_tracker/internal/proto", + ] + deps = [ "//base", "//components/feature_engagement_tracker/public",
diff --git a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc index 4917161..daa58c3 100644 --- a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc +++ b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
@@ -8,7 +8,9 @@ #include "base/feature_list.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" +#include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "components/feature_engagement_tracker/internal/editable_configuration.h" #include "components/feature_engagement_tracker/internal/in_memory_store.h" @@ -36,7 +38,7 @@ class FeatureEngagementTrackerImplTest : public ::testing::Test { public: - void SetUp() override { + FeatureEngagementTrackerImplTest() { std::unique_ptr<Store> store = base::MakeUnique<InMemoryStore>(); std::unique_ptr<EditableConfiguration> configuration = base::MakeUnique<EditableConfiguration>(); @@ -52,9 +54,12 @@ tracker_.reset(new FeatureEngagementTrackerImpl( std::move(store), std::move(configuration), std::move(validator))); + // Ensure all initialization is finished. + base::RunLoop().RunUntilIdle(); } protected: + base::MessageLoop message_loop_; std::unique_ptr<FeatureEngagementTrackerImpl> tracker_; base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/components/feature_engagement_tracker/internal/in_memory_store.cc b/components/feature_engagement_tracker/internal/in_memory_store.cc index 113fa037..0c9fa6e4 100644 --- a/components/feature_engagement_tracker/internal/in_memory_store.cc +++ b/components/feature_engagement_tracker/internal/in_memory_store.cc
@@ -4,22 +4,43 @@ #include "components/feature_engagement_tracker/internal/in_memory_store.h" +#include <vector> + +#include "base/bind.h" #include "base/feature_list.h" +#include "base/memory/ptr_util.h" +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "components/feature_engagement_tracker/internal/store.h" namespace feature_engagement_tracker { -InMemoryStore::InMemoryStore() : Store(), ready_(false) {} +InMemoryStore::InMemoryStore(std::unique_ptr<std::vector<Event>> events) + : Store(), events_(std::move(events)), ready_(false) {} + +InMemoryStore::InMemoryStore() + : InMemoryStore(base::MakeUnique<std::vector<Event>>()) {} InMemoryStore::~InMemoryStore() = default; void InMemoryStore::Load(const OnLoadedCallback& callback) { - // TODO(nyquist): Post result back to callback. - ready_ = true; + HandleLoadResult(callback, true); } bool InMemoryStore::IsReady() const { return ready_; } +void InMemoryStore::WriteEvent(const Event& event) { + // Intentionally ignore all writes. +} + +void InMemoryStore::HandleLoadResult(const OnLoadedCallback& callback, + bool success) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, success, base::Passed(&events_))); + ready_ = success; +} + } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/in_memory_store.h b/components/feature_engagement_tracker/internal/in_memory_store.h index 536c353..939037c 100644 --- a/components/feature_engagement_tracker/internal/in_memory_store.h +++ b/components/feature_engagement_tracker/internal/in_memory_store.h
@@ -5,22 +5,36 @@ #ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_IN_MEMORY_STORE_H_ #define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_IN_MEMORY_STORE_H_ +#include <vector> + #include "base/macros.h" #include "components/feature_engagement_tracker/internal/store.h" namespace feature_engagement_tracker { - // An InMemoryStore provides a DB layer that stores all data in-memory. +// All data is made available to this class during construction, and can be +// loaded once by a caller. All calls to WriteEvent(...) are ignored. class InMemoryStore : public Store { public: + explicit InMemoryStore(std::unique_ptr<std::vector<Event>> events); InMemoryStore(); ~InMemoryStore() override; // Store implementation. void Load(const OnLoadedCallback& callback) override; bool IsReady() const override; + void WriteEvent(const Event& event) override; + + protected: + // Posts the result of loading and sets up the ready state. + // Protected and virtual for testing. + virtual void HandleLoadResult(const OnLoadedCallback& callback, bool success); private: + // All events that this in-memory store was constructed with. This will be + // reset when Load(...) is called. + std::unique_ptr<std::vector<Event>> events_; + // Whether the store is ready or not. It is true after Load(...) has been // invoked. bool ready_;
diff --git a/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc b/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc index 0b1d880..be3f0ad 100644 --- a/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc +++ b/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc
@@ -4,22 +4,66 @@ #include "components/feature_engagement_tracker/internal/in_memory_store.h" +#include <memory> +#include <vector> + #include "base/bind.h" +#include "base/callback.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" namespace feature_engagement_tracker { namespace { -void NoOpCallback(bool success) {} -class InMemoryStoreTest : public ::testing::Test {}; +class InMemoryStoreTest : public ::testing::Test { + public: + InMemoryStoreTest() + : load_callback_has_been_invoked_(false), last_result_(false) {} + + void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) { + load_callback_has_been_invoked_ = true; + last_result_ = success; + loaded_events_.reset(events.release()); + } + + protected: + bool load_callback_has_been_invoked_; + bool last_result_; + std::unique_ptr<std::vector<Event>> loaded_events_; + base::MessageLoop message_loop_; +}; } // namespace -TEST_F(InMemoryStoreTest, LoadShouldMakeReady) { - InMemoryStore store; +TEST_F(InMemoryStoreTest, LoadShouldProvideEventsAsCallback) { + std::unique_ptr<std::vector<Event>> events = + base::MakeUnique<std::vector<Event>>(); + Event foo; + Event bar; + events->push_back(foo); + events->push_back(bar); + + // Create a new store and verify it's not ready yet. + InMemoryStore store(std::move(events)); EXPECT_FALSE(store.IsReady()); - store.Load(base::Bind(&NoOpCallback)); + + // Load the data and ensure the callback is not immediately invoked, since the + // result should be posted. + store.Load( + base::Bind(&InMemoryStoreTest::LoadCallback, base::Unretained(this))); + EXPECT_FALSE(load_callback_has_been_invoked_); + + // Run the message loop until it's idle to finish to ensure the result is + // available. + base::RunLoop().RunUntilIdle(); + + // The two events should have been loaded, and the store should be ready. + EXPECT_TRUE(load_callback_has_been_invoked_); EXPECT_TRUE(store.IsReady()); + EXPECT_EQ(2u, loaded_events_->size()); + EXPECT_TRUE(last_result_); } } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/model.h b/components/feature_engagement_tracker/internal/model.h index 966fa2d..30110663 100644 --- a/components/feature_engagement_tracker/internal/model.h +++ b/components/feature_engagement_tracker/internal/model.h
@@ -6,6 +6,7 @@ #define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_MODEL_H_ #include <map> +#include <string> #include "base/callback.h" #include "base/macros.h" @@ -16,6 +17,7 @@ } // namespace base namespace feature_engagement_tracker { +class Event; // A Model provides all necessary runtime state. class Model { @@ -44,6 +46,15 @@ // Returns whether any in-product help is currently showing. virtual bool IsCurrentlyShowing() const = 0; + // Retrieves the Event object for the event with the given name. If the event + // is not found, an empty event will be returned. Calling this before the + // Model has finished initializing will result in undefined behavior. + virtual const Event& GetEvent(const std::string& event_name) = 0; + + // Increments the counter for today for how many times the event has happened. + // If the event has never happened before, the Event object will be created. + virtual void IncrementEvent(const std::string& event_name) = 0; + protected: Model() = default;
diff --git a/components/feature_engagement_tracker/internal/model_impl.cc b/components/feature_engagement_tracker/internal/model_impl.cc index f0d4196e..26d6e21f 100644 --- a/components/feature_engagement_tracker/internal/model_impl.cc +++ b/components/feature_engagement_tracker/internal/model_impl.cc
@@ -6,7 +6,14 @@ #include <map> #include <memory> +#include <string> +#include <vector> +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "components/feature_engagement_tracker/internal/configuration.h" #include "components/feature_engagement_tracker/internal/model.h" #include "components/feature_engagement_tracker/internal/store.h" @@ -19,14 +26,14 @@ store_(std::move(store)), configuration_(std::move(configuration)), ready_(false), - currently_showing_(false) {} + currently_showing_(false), + weak_factory_(this) {} ModelImpl::~ModelImpl() = default; void ModelImpl::Initialize(const OnModelInitializationFinished& callback) { - // TODO(nyquist): Initialize Store and post result back to callback. - // Only set ready when Store has fully loaded. - ready_ = true; + store_->Load(base::Bind(&ModelImpl::OnStoreLoaded, weak_factory_.GetWeakPtr(), + callback)); } bool ModelImpl::IsReady() const { @@ -46,4 +53,68 @@ return currently_showing_; } +const Event& ModelImpl::GetEvent(const std::string& event_name) { + return GetNonConstEvent(event_name); +} + +void ModelImpl::IncrementEvent(const std::string& event_name) { + // TODO(nyquist): Add support for pending events, and also add UMA. + DCHECK(ready_); + + Event& event = GetNonConstEvent(event_name); + uint32_t current_day = GetCurrentDay(); + for (int i = 0; i < event.events_size(); ++i) { + Event_Count* event_count = event.mutable_events(i); + DCHECK(event_count->has_day()); + DCHECK(event_count->has_count()); + if (event_count->day() == current_day) { + event_count->set_count(event_count->count() + 1); + store_->WriteEvent(event); + return; + } + } + + // Day not found for event, adding new day with a count of 1. + Event_Count* event_count = event.add_events(); + event_count->set_day(current_day); + event_count->set_count(1u); + store_->WriteEvent(event); +} + +uint32_t ModelImpl::GetCurrentDay() { + // TODO(nyquist): Implement this according to specification. + return 1u; +} + +void ModelImpl::OnStoreLoaded(const OnModelInitializationFinished& callback, + bool success, + std::unique_ptr<std::vector<Event>> events) { + if (!success) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback, false)); + return; + } + + for (auto& event : *events) { + DCHECK_NE("", event.name()); + events_[event.name()] = event; + } + + // TODO(nyquist): Clear expired data. + + ready_ = true; + + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback, true)); +} + +Event& ModelImpl::GetNonConstEvent(const std::string& event_name) { + if (events_.find(event_name) == events_.end()) { + // Event does not exist yet, so create it. + events_[event_name].set_name(event_name); + store_->WriteEvent(events_[event_name]); + } + return events_[event_name]; +} + } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/model_impl.h b/components/feature_engagement_tracker/internal/model_impl.h index dcbefa29..ff456e13 100644 --- a/components/feature_engagement_tracker/internal/model_impl.h +++ b/components/feature_engagement_tracker/internal/model_impl.h
@@ -5,11 +5,16 @@ #ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_MODEL_IMPL_H_ #define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_MODEL_IMPL_H_ +#include <map> #include <memory> +#include <string> +#include <vector> #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "components/feature_engagement_tracker/internal/configuration.h" #include "components/feature_engagement_tracker/internal/model.h" +#include "components/feature_engagement_tracker/internal/proto/event.pb.h" namespace base { struct Feature; @@ -32,20 +37,41 @@ const base::Feature& feature) const override; void SetIsCurrentlyShowing(bool is_showing) override; bool IsCurrentlyShowing() const override; + const Event& GetEvent(const std::string& event_name) override; + void IncrementEvent(const std::string& event_name) override; + + protected: + // Returns the number of days since epoch (1970-01-01) in the local timezone. + // Protected and virtual for testing. + virtual uint32_t GetCurrentDay(); private: + // Callback for loading the underlying store. + void OnStoreLoaded(const OnModelInitializationFinished& callback, + bool success, + std::unique_ptr<std::vector<Event>> events); + + // Internal version for getting the non-const version of a stored Event. + // Creates the event if it is not already stored. + Event& GetNonConstEvent(const std::string& event_name); + // The underlying store for all events. std::unique_ptr<Store> store_; // The current configuration for all features. std::unique_ptr<Configuration> configuration_; + // An in-memory representation of all events. + std::map<std::string, Event> events_; + // Whether the model has been fully initialized. bool ready_; // Whether the model is currently showing an in-product help. bool currently_showing_; + base::WeakPtrFactory<ModelImpl> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(ModelImpl); };
diff --git a/components/feature_engagement_tracker/internal/model_impl_unittest.cc b/components/feature_engagement_tracker/internal/model_impl_unittest.cc index 3651b58..ef57d2a 100644 --- a/components/feature_engagement_tracker/internal/model_impl_unittest.cc +++ b/components/feature_engagement_tracker/internal/model_impl_unittest.cc
@@ -7,12 +7,16 @@ #include <memory> #include "base/bind.h" +#include "base/callback.h" #include "base/feature_list.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" +#include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "components/feature_engagement_tracker/internal/editable_configuration.h" #include "components/feature_engagement_tracker/internal/in_memory_store.h" +#include "components/feature_engagement_tracker/internal/proto/event.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace feature_engagement_tracker { @@ -23,8 +27,6 @@ const base::Feature kTestFeatureBar{"test_bar", base::FEATURE_DISABLED_BY_DEFAULT}; -void NoOpCallback(bool success) {} - void RegisterFeatureConfig(EditableConfiguration* configuration, const base::Feature& feature, bool valid) { @@ -34,10 +36,113 @@ configuration->SetConfiguration(&feature, config); } +void SetEventCountForDay(Event* event, uint32_t day, uint32_t count) { + Event_Count* event_count = event->add_events(); + event_count->set_day(day); + event_count->set_count(count); +} + +// Verifies that the given |event| contains a |day| with the correct |count|, +// and that the day only exists a single time. +void VerifyEventCount(const Event& event, uint32_t day, uint32_t count) { + bool found_day = false; + for (int i = 0; i < event.events_size(); ++i) { + Event_Count event_count = event.events(i); + if (event_count.day() == day) { + EXPECT_FALSE(found_day); + found_day = true; + EXPECT_EQ(count, event_count.count()); + } + } + EXPECT_TRUE(found_day); +} + +// Verifies that the event |a| and |b| contain the exact same data. +void VerifyEqual(const Event& a, const Event& b) { + EXPECT_EQ(a.name(), b.name()); + EXPECT_EQ(a.events_size(), b.events_size()); + for (int i = 0; i < a.events_size(); ++i) { + VerifyEventCount(b, a.events(i).day(), a.events(i).count()); + } +} + +// A test-only implementation of InMemoryStore that tracks calls to +// WriteEvent(...). +class TestInMemoryStore : public InMemoryStore { + public: + explicit TestInMemoryStore(std::unique_ptr<std::vector<Event>> events, + bool load_should_succeed) + : InMemoryStore(std::move(events)), + load_should_succeed_(load_should_succeed) {} + + void Load(const OnLoadedCallback& callback) override { + HandleLoadResult(callback, load_should_succeed_); + } + + void WriteEvent(const Event& event) override { last_written_event_ = event; } + + Event GetLastWrittenEvent() { return last_written_event_; } + + private: + // Temporary store the last written event. + Event last_written_event_; + + // Denotes whether the call to Load(...) should succeed or not. This impacts + // both the ready-state and the result for the OnLoadedCallback. + bool load_should_succeed_; +}; + +// Creates a TestInMemoryStore containing three hard coded events. +std::unique_ptr<TestInMemoryStore> CreatePrefilledStore() { + std::unique_ptr<std::vector<Event>> events = + base::MakeUnique<std::vector<Event>>(); + + Event foo; + foo.set_name("foo"); + SetEventCountForDay(&foo, 1, 1); + events->push_back(foo); + + Event bar; + bar.set_name("bar"); + SetEventCountForDay(&bar, 1, 3); + SetEventCountForDay(&bar, 2, 3); + SetEventCountForDay(&bar, 5, 5); + events->push_back(bar); + + Event qux; + qux.set_name("qux"); + SetEventCountForDay(&qux, 1, 5); + SetEventCountForDay(&qux, 2, 1); + SetEventCountForDay(&qux, 3, 2); + events->push_back(qux); + + return base::MakeUnique<TestInMemoryStore>(std::move(events), true); +} + +// A test-only implementation of ModelImpl to be able to change the current +// day while a test is running. +class TestModelImpl : public ModelImpl { + public: + TestModelImpl(std::unique_ptr<Store> store, + std::unique_ptr<Configuration> configuration) + : ModelImpl(std::move(store), std::move(configuration)), + current_day_(0) {} + ~TestModelImpl() override {} + + uint32_t GetCurrentDay() override { return current_day_; } + + void SetCurrentDay(uint32_t current_day) { current_day_ = current_day; } + + private: + uint32_t current_day_; +}; + class ModelImplTest : public ::testing::Test { public: + ModelImplTest() + : got_initialize_callback_(false), initialize_callback_result_(false) {} + void SetUp() override { - std::unique_ptr<Store> store = base::MakeUnique<InMemoryStore>(); std::unique_ptr<EditableConfiguration> configuration = base::MakeUnique<EditableConfiguration>(); @@ -47,23 +152,213 @@ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {}); - model_.reset(new ModelImpl(std::move(store), std::move(configuration))); + std::unique_ptr<TestInMemoryStore> store = CreateStore(); + store_ = store.get(); + + model_.reset(new TestModelImpl(std::move(store), std::move(configuration))); + } + + virtual std::unique_ptr<TestInMemoryStore> CreateStore() { + return CreatePrefilledStore(); + } + + void OnModelInitializationFinished(bool success) { + got_initialize_callback_ = true; + initialize_callback_result_ = success; } protected: - std::unique_ptr<ModelImpl> model_; + std::unique_ptr<TestModelImpl> model_; + TestInMemoryStore* store_; + bool got_initialize_callback_; + bool initialize_callback_result_; + + private: + base::MessageLoop message_loop_; base::test::ScopedFeatureList scoped_feature_list_; }; + +class LoadFailingModelImplTest : public ModelImplTest { + public: + LoadFailingModelImplTest() : ModelImplTest() {} + + std::unique_ptr<TestInMemoryStore> CreateStore() override { + return base::MakeUnique<TestInMemoryStore>( + base::MakeUnique<std::vector<Event>>(), false); + } +}; + } // namespace -TEST_F(ModelImplTest, InitializationShouldMakeReady) { - EXPECT_FALSE(model_->IsReady()); - model_->Initialize(base::Bind(&NoOpCallback)); +TEST_F(ModelImplTest, InitializeShouldLoadEntries) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(model_->IsReady()); + EXPECT_TRUE(got_initialize_callback_); + EXPECT_TRUE(initialize_callback_result_); + + // Verify that all the data matches what was put into the store in + // CreateStore(). + Event foo_event = model_->GetEvent("foo"); + EXPECT_EQ("foo", foo_event.name()); + EXPECT_EQ(1, foo_event.events_size()); + VerifyEventCount(foo_event, 1u, 1u); + + Event bar_event = model_->GetEvent("bar"); + EXPECT_EQ("bar", bar_event.name()); + EXPECT_EQ(3, bar_event.events_size()); + VerifyEventCount(bar_event, 1u, 3u); + VerifyEventCount(bar_event, 2u, 3u); + VerifyEventCount(bar_event, 5u, 5u); + + Event qux_event = model_->GetEvent("qux"); + EXPECT_EQ("qux", qux_event.name()); + EXPECT_EQ(3, qux_event.events_size()); + VerifyEventCount(qux_event, 1u, 5u); + VerifyEventCount(qux_event, 2u, 1u); + VerifyEventCount(qux_event, 3u, 2u); } -TEST_F(ModelImplTest, ShowingState) { - model_->Initialize(base::Bind(&NoOpCallback)); +TEST_F(ModelImplTest, RetrievingNewEventsShouldYieldEmpty) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + Event no_event = model_->GetEvent("no"); + EXPECT_EQ("no", no_event.name()); + EXPECT_EQ(0, no_event.events_size()); + VerifyEqual(no_event, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, IncrementingNonExistingEvent) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + model_->SetCurrentDay(1u); + + // Incrementing the event should work even if it does not exist. + model_->IncrementEvent("nonexisting"); + Event event1 = model_->GetEvent("nonexisting"); + EXPECT_EQ("nonexisting", event1.name()); + EXPECT_EQ(1, event1.events_size()); + VerifyEventCount(event1, 1u, 1u); + VerifyEqual(event1, store_->GetLastWrittenEvent()); + + // Incrementing the event after it has been initialized to 1, it should now + // have a count of 2 for the given day. + model_->IncrementEvent("nonexisting"); + Event event2 = model_->GetEvent("nonexisting"); + Event_Count event2_count = event2.events(0); + EXPECT_EQ(1, event2.events_size()); + VerifyEventCount(event2, 1u, 2u); + VerifyEqual(event2, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, IncrementingNonExistingEventMultipleDays) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + model_->SetCurrentDay(1u); + model_->IncrementEvent("nonexisting"); + model_->SetCurrentDay(2u); + model_->IncrementEvent("nonexisting"); + model_->IncrementEvent("nonexisting"); + model_->SetCurrentDay(3u); + model_->IncrementEvent("nonexisting"); + Event event = model_->GetEvent("nonexisting"); + EXPECT_EQ(3, event.events_size()); + VerifyEventCount(event, 1u, 1u); + VerifyEventCount(event, 2u, 2u); + VerifyEventCount(event, 3u, 1u); + VerifyEqual(event, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, IncrementingSingleDayExistingEvent) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + model_->SetCurrentDay(1u); + + // |foo| is inserted into the store with a count of 1 at day 1. + Event foo_event = model_->GetEvent("foo"); + EXPECT_EQ("foo", foo_event.name()); + EXPECT_EQ(1, foo_event.events_size()); + VerifyEventCount(foo_event, 1u, 1u); + + // Incrementing |foo| should change count to 2. + model_->IncrementEvent("foo"); + Event foo_event2 = model_->GetEvent("foo"); + EXPECT_EQ(1, foo_event2.events_size()); + VerifyEventCount(foo_event2, 1u, 2u); + VerifyEqual(foo_event2, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, IncrementingSingleDayExistingEventTwice) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + model_->SetCurrentDay(1u); + + // |foo| is inserted into the store with a count of 1 at day 1, so + // incrementing twice should lead to 3. + model_->IncrementEvent("foo"); + model_->IncrementEvent("foo"); + Event foo_event = model_->GetEvent("foo"); + EXPECT_EQ(1, foo_event.events_size()); + VerifyEventCount(foo_event, 1u, 3u); + VerifyEqual(foo_event, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, IncrementingExistingMultiDayEvent) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + // |bar| is inserted into the store with a count of 3 at day 2. Incrementing + // that day should lead to a count of 4. + model_->SetCurrentDay(2u); + Event bar_event = model_->GetEvent("bar"); + VerifyEventCount(bar_event, 2u, 3u); + model_->IncrementEvent("bar"); + Event bar_event2 = model_->GetEvent("bar"); + VerifyEventCount(bar_event2, 2u, 4u); + VerifyEqual(bar_event2, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, IncrementingExistingMultiDayEventNewDay) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(model_->IsReady()); + + // |bar| does not contain entries for day 10, so incrementing should create + // the day. + model_->SetCurrentDay(10u); + model_->IncrementEvent("bar"); + Event bar_event = model_->GetEvent("bar"); + VerifyEventCount(bar_event, 10u, 1u); + VerifyEqual(bar_event, store_->GetLastWrittenEvent()); + model_->IncrementEvent("bar"); + Event bar_event2 = model_->GetEvent("bar"); + VerifyEventCount(bar_event2, 10u, 2u); + VerifyEqual(bar_event2, store_->GetLastWrittenEvent()); +} + +TEST_F(ModelImplTest, ShowState) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(model_->IsReady()); EXPECT_FALSE(model_->IsCurrentlyShowing()); @@ -78,4 +373,13 @@ EXPECT_FALSE(model_->IsCurrentlyShowing()); } +TEST_F(LoadFailingModelImplTest, FailedInitializeInformsCaller) { + model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished, + base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(model_->IsReady()); + EXPECT_TRUE(got_initialize_callback_); + EXPECT_FALSE(initialize_callback_result_); +} + } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc b/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc index 4bcd08e..d39f122 100644 --- a/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc +++ b/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
@@ -8,6 +8,7 @@ #include "base/metrics/field_trial.h" #include "base/test/scoped_feature_list.h" #include "components/feature_engagement_tracker/internal/model.h" +#include "components/feature_engagement_tracker/internal/proto/event.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace feature_engagement_tracker { @@ -40,8 +41,15 @@ bool IsCurrentlyShowing() const override { return false; } + const Event& GetEvent(const std::string& event_name) override { + return empty_event_; + } + + void IncrementEvent(const std::string& event_name) override {} + private: FeatureConfig feature_config_; + Event empty_event_; DISALLOW_COPY_AND_ASSIGN(TestModel); };
diff --git a/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc b/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc index c7c7598..c8ee8c7 100644 --- a/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc +++ b/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc
@@ -4,11 +4,14 @@ #include "components/feature_engagement_tracker/internal/once_condition_validator.h" +#include <string> + #include "base/feature_list.h" #include "base/metrics/field_trial.h" #include "base/test/scoped_feature_list.h" #include "components/feature_engagement_tracker/internal/editable_configuration.h" #include "components/feature_engagement_tracker/internal/model.h" +#include "components/feature_engagement_tracker/internal/proto/event.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace feature_engagement_tracker { @@ -44,17 +47,22 @@ EditableConfiguration& GetConfiguration() { return configuration_; } + const Event& GetEvent(const std::string& event_name) override { + return empty_event_; + } + + void IncrementEvent(const std::string& event_name) override {} + private: EditableConfiguration configuration_; + Event empty_event_; bool ready_; bool is_showing_; }; class OnceConditionValidatorTest : public ::testing::Test { public: - OnceConditionValidatorTest() = default; - - void SetUp() override { + OnceConditionValidatorTest() { // By default, model should be ready. model_.SetIsReady(true); }
diff --git a/components/feature_engagement_tracker/internal/proto/BUILD.gn b/components/feature_engagement_tracker/internal/proto/BUILD.gn new file mode 100644 index 0000000..686f184 --- /dev/null +++ b/components/feature_engagement_tracker/internal/proto/BUILD.gn
@@ -0,0 +1,11 @@ +# 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") + +proto_library("proto") { + sources = [ + "event.proto", + ] +}
diff --git a/components/feature_engagement_tracker/internal/proto/event.proto b/components/feature_engagement_tracker/internal/proto/event.proto new file mode 100644 index 0000000..9b619a2 --- /dev/null +++ b/components/feature_engagement_tracker/internal/proto/event.proto
@@ -0,0 +1,27 @@ +// 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. +// +// FeatureEngagementTracker content. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package feature_engagement_tracker; + +// Event stores state for a specific event a count per day it has happened. +message Event { + // Count stores a pair of a day and how many times something happened that + // day. + message Count { + optional uint32 day = 1; + optional uint32 count = 2; + } + + // The descriptive name of the event. + optional string name = 1; + + // The number of this event that happened per day. + repeated Count events = 2; +}
diff --git a/components/feature_engagement_tracker/internal/store.h b/components/feature_engagement_tracker/internal/store.h index 9a1e2c9..cef9b460 100644 --- a/components/feature_engagement_tracker/internal/store.h +++ b/components/feature_engagement_tracker/internal/store.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "components/feature_engagement_tracker/internal/proto/event.pb.h" namespace feature_engagement_tracker { @@ -14,17 +15,23 @@ class Store { public: // TODO(nyquist): Add vector of all events to result callback. - using OnLoadedCallback = base::Callback<void(bool success)>; + using OnLoadedCallback = + base::Callback<void(bool success, std::unique_ptr<std::vector<Event>>)>; virtual ~Store() = default; - // Loads the database from storage and asynchronously posts the result back. + // Loads the database from storage and asynchronously posts the result back + // on the caller's thread. + // Ownership of the loaded data is given to the caller. virtual void Load(const OnLoadedCallback& callback) = 0; // Returns whether the database is ready, i.e. whether it has been fully // loaded. virtual bool IsReady() const = 0; + // Stores the given event to persistent storage. + virtual void WriteEvent(const Event& event) = 0; + protected: Store() = default;
diff --git a/components/filesystem/file_system_app.cc b/components/filesystem/file_system_app.cc index e12cba1..c54639c 100644 --- a/components/filesystem/file_system_app.cc +++ b/components/filesystem/file_system_app.cc
@@ -11,7 +11,6 @@ #include "base/files/file_util.h" #include "base/memory/ptr_util.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_context.h"
diff --git a/components/font_service/font_service_app.cc b/components/font_service/font_service_app.cc index 57700b2..5dfe5f9 100644 --- a/components/font_service/font_service_app.cc +++ b/components/font_service/font_service_app.cc
@@ -9,7 +9,6 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "mojo/public/cpp/system/platform_handle.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/service_context.h" static_assert(
diff --git a/components/history/core/browser/thumbnail_database.cc b/components/history/core/browser/thumbnail_database.cc index f476c6e..d9bc22de 100644 --- a/components/history/core/browser/thumbnail_database.cc +++ b/components/history/core/browser/thumbnail_database.cc
@@ -82,9 +82,9 @@ // fatal (in fact, very old data may be expired immediately at startup // anyhow). -// Version 8: ???????? by rogerm@chromium.org on 2015-??-?? +// Version 8: 982ef2c1/r323176 by rogerm@chromium.org on 2015-03-31 // Version 7: 911a634d/r209424 by qsr@chromium.org on 2013-07-01 -// Version 6: 610f923b/r152367 by pkotwicz@chromium.org on 2012-08-20 +// Version 6: 610f923b/r152367 by pkotwicz@chromium.org on 2012-08-20 (depr.) // Version 5: e2ee8ae9/r105004 by groby@chromium.org on 2011-10-12 (deprecated) // Version 4: 5f104d76/r77288 by sky@chromium.org on 2011-03-08 (deprecated) // Version 3: 09911bf3/r15 by initial.commit on 2008-07-26 (deprecated) @@ -94,7 +94,7 @@ // the new version and a test to verify that Init() works with it. const int kCurrentVersionNumber = 8; const int kCompatibleVersionNumber = 8; -const int kDeprecatedVersionNumber = 5; // and earlier. +const int kDeprecatedVersionNumber = 6; // and earlier. void FillIconMapping(const sql::Statement& statement, const GURL& page_url, @@ -146,8 +146,7 @@ } // NOTE(shess): Schema modifications must consider initial creation in -// |InitImpl()|, recovery in |RecoverDatabaseOrRaze()|, and history pruning in -// |RetainDataForPageUrls()|. +// |InitImpl()| and history pruning in |RetainDataForPageUrls()|. bool InitTables(sql::Connection* db) { const char kIconMappingSql[] = "CREATE TABLE IF NOT EXISTS icon_mapping" @@ -190,8 +189,7 @@ } // NOTE(shess): Schema modifications must consider initial creation in -// |InitImpl()|, recovery in |RecoverDatabaseOrRaze()|, and history pruning in -// |RetainDataForPageUrls()|. +// |InitImpl()| and history pruning in |RetainDataForPageUrls()|. bool InitIndices(sql::Connection* db) { const char kIconMappingUrlIndexSql[] = "CREATE INDEX IF NOT EXISTS icon_mapping_page_url_idx" @@ -218,199 +216,6 @@ return true; } -enum RecoveryEventType { - RECOVERY_EVENT_RECOVERED = 0, - RECOVERY_EVENT_FAILED_SCOPER, - RECOVERY_EVENT_FAILED_META_VERSION_ERROR, // obsolete - RECOVERY_EVENT_FAILED_META_VERSION_NONE, // obsolete - RECOVERY_EVENT_FAILED_META_WRONG_VERSION6, // obsolete - RECOVERY_EVENT_FAILED_META_WRONG_VERSION5, // obsolete - RECOVERY_EVENT_FAILED_META_WRONG_VERSION, - RECOVERY_EVENT_FAILED_RECOVER_META, // obsolete - RECOVERY_EVENT_FAILED_META_INSERT, // obsolete - RECOVERY_EVENT_FAILED_INIT, - RECOVERY_EVENT_FAILED_RECOVER_FAVICONS, // obsolete - RECOVERY_EVENT_FAILED_FAVICONS_INSERT, // obsolete - RECOVERY_EVENT_FAILED_RECOVER_FAVICON_BITMAPS, // obsolete - RECOVERY_EVENT_FAILED_FAVICON_BITMAPS_INSERT, // obsolete - RECOVERY_EVENT_FAILED_RECOVER_ICON_MAPPING, // obsolete - RECOVERY_EVENT_FAILED_ICON_MAPPING_INSERT, // obsolete - RECOVERY_EVENT_RECOVERED_VERSION6, // obsolete - RECOVERY_EVENT_FAILED_META_INIT, - RECOVERY_EVENT_FAILED_META_VERSION, - RECOVERY_EVENT_DEPRECATED, - RECOVERY_EVENT_FAILED_V5_INITSCHEMA, // obsolete - RECOVERY_EVENT_FAILED_V5_AUTORECOVER_FAVICONS, // obsolete - RECOVERY_EVENT_FAILED_V5_AUTORECOVER_ICON_MAPPING, // obsolete - RECOVERY_EVENT_RECOVERED_VERSION5, // obsolete - RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICONS, - RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICON_BITMAPS, - RECOVERY_EVENT_FAILED_AUTORECOVER_ICON_MAPPING, - RECOVERY_EVENT_FAILED_COMMIT, - - // Always keep this at the end. - RECOVERY_EVENT_MAX, -}; - -void RecordRecoveryEvent(RecoveryEventType recovery_event) { - UMA_HISTOGRAM_ENUMERATION("History.FaviconsRecovery", - recovery_event, RECOVERY_EVENT_MAX); -} - -// Recover the database to the extent possible, razing it if recovery -// is not possible. -// TODO(shess): This is mostly just a safe proof of concept. In the -// real world, this database is probably not worthwhile recovering, as -// opposed to just razing it and starting over whenever corruption is -// detected. So this database is a good test subject. -void RecoverDatabaseOrRaze(sql::Connection* db, const base::FilePath& db_path) { - // NOTE(shess): This code is currently specific to the version - // number. I am working on simplifying things to loosen the - // dependency, meanwhile contact me if you need to bump the version. - DCHECK_EQ(8, kCurrentVersionNumber); - - // TODO(shess): Reset back after? - db->reset_error_callback(); - - // For histogram purposes. - size_t favicons_rows_recovered = 0; - size_t favicon_bitmaps_rows_recovered = 0; - size_t icon_mapping_rows_recovered = 0; - int64_t original_size = 0; - base::GetFileSize(db_path, &original_size); - - std::unique_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path); - if (!recovery) { - // TODO(shess): Unable to create recovery connection. This - // implies something substantial is wrong. At this point |db| has - // been poisoned so there is nothing really to do. - // - // Possible responses are unclear. If the failure relates to a - // problem somehow specific to the temporary file used to back the - // database, then an in-memory database could possibly be used. - // This could potentially allow recovering the main database, and - // might be simple to implement w/in Begin(). - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_SCOPER); - return; - } - - // Setup the meta recovery table and fetch the version number from - // the corrupt database. - int version = 0; - if (!recovery->SetupMeta() || !recovery->GetMetaVersionNumber(&version)) { - // TODO(shess): Prior histograms indicate all failures are in - // creating the recover virtual table for corrupt.meta. The table - // may not exist, or the database may be too far gone. Either - // way, unclear how to resolve. - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_VERSION); - return; - } - - // This code may be able to fetch version information that the regular - // deprecation path cannot. - // NOTE(shess,rogerm): v6 is not currently deprecated in the normal Init() - // path, but is deprecated in the recovery path in the interest of keeping - // the code simple. http://crbug.com/327485 for numbers. - DCHECK_LE(kDeprecatedVersionNumber, 6); - if (version <= 6) { - sql::Recovery::Unrecoverable(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_DEPRECATED); - return; - } - - // Earlier versions have been handled or deprecated. - if (version < 7) { - sql::Recovery::Unrecoverable(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_WRONG_VERSION); - return; - } - - // Recover to current schema version. - sql::MetaTable recover_meta_table; - if (!recover_meta_table.Init(recovery->db(), kCurrentVersionNumber, - kCompatibleVersionNumber)) { - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_INIT); - return; - } - - // Create a fresh version of the database. The recovery code uses - // conflict-resolution to handle duplicates, so the indices are - // necessary. - if (!InitTables(recovery->db()) || !InitIndices(recovery->db())) { - // TODO(shess): Unable to create the new schema in the new - // database. The new database should be a temporary file, so - // being unable to work with it is pretty unclear. - // - // What are the potential responses, even? The recovery database - // could be opened as in-memory. If the temp database had a - // filesystem problem and the temp filesystem differs from the - // main database, then that could fix it. - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_INIT); - return; - } - - if (!recovery->AutoRecoverTable("favicons", &favicons_rows_recovered)) { - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICONS); - return; - } - if (!recovery->AutoRecoverTable("favicon_bitmaps", - &favicon_bitmaps_rows_recovered)) { - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICON_BITMAPS); - return; - } - if (!recovery->AutoRecoverTable("icon_mapping", - &icon_mapping_rows_recovered)) { - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_ICON_MAPPING); - return; - } - - // TODO(shess): Is it possible/likely to have broken foreign-key - // issues with the tables? - // - icon_mapping.icon_id maps to no favicons.id - // - favicon_bitmaps.icon_id maps to no favicons.id - // - favicons.id is referenced by no icon_mapping.icon_id - // - favicons.id is referenced by no favicon_bitmaps.icon_id - // This step is possibly not worth the effort necessary to develop - // and sequence the statements, as it is basically a form of garbage - // collection. - - if (!sql::Recovery::Recovered(std::move(recovery))) { - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_COMMIT); - return; - } - - // Track the size of the recovered database relative to the size of - // the input database. The size should almost always be smaller, - // unless the input database was empty to start with. If the - // percentage results are very low, something is awry. - int64_t final_size = 0; - if (original_size > 0 && - base::GetFileSize(db_path, &final_size) && - final_size > 0) { - int percentage = static_cast<int>(original_size * 100 / final_size); - UMA_HISTOGRAM_PERCENTAGE("History.FaviconsRecoveredPercentage", - std::max(100, percentage)); - } - - // Using 10,000 because these cases mostly care about "none - // recovered" and "lots recovered". More than 10,000 rows recovered - // probably means there's something wrong with the profile. - UMA_HISTOGRAM_COUNTS_10000("History.FaviconsRecoveredRowsFavicons", - static_cast<int>(favicons_rows_recovered)); - UMA_HISTOGRAM_COUNTS_10000("History.FaviconsRecoveredRowsFaviconBitmaps", - static_cast<int>(favicon_bitmaps_rows_recovered)); - UMA_HISTOGRAM_COUNTS_10000("History.FaviconsRecoveredRowsIconMapping", - static_cast<int>(icon_mapping_rows_recovered)); - - RecordRecoveryEvent(RECOVERY_EVENT_RECOVERED); -} - void DatabaseErrorCallback(sql::Connection* db, const base::FilePath& db_path, HistoryBackendClient* backend_client, @@ -425,11 +230,36 @@ } // Attempt to recover corrupt databases. - int error = (extended_error & 0xFF); - if (error == SQLITE_CORRUPT || - error == SQLITE_CANTOPEN || - error == SQLITE_NOTADB) { - RecoverDatabaseOrRaze(db, db_path); + if (sql::Recovery::ShouldRecover(extended_error)) { + // NOTE(shess): This approach is valid as of version 8. When bumping the + // version, it will PROBABLY remain valid, but consider whether any schema + // changes might break automated recovery. + DCHECK_EQ(8, kCurrentVersionNumber); + + // Prevent reentrant calls. + db->reset_error_callback(); + + // TODO(shess): Is it possible/likely to have broken foreign-key + // issues with the tables? + // - icon_mapping.icon_id maps to no favicons.id + // - favicon_bitmaps.icon_id maps to no favicons.id + // - favicons.id is referenced by no icon_mapping.icon_id + // - favicons.id is referenced by no favicon_bitmaps.icon_id + // This step is possibly not worth the effort necessary to develop + // and sequence the statements, as it is basically a form of garbage + // collection. + + // After this call, the |db| handle is poisoned so that future calls will + // return errors until the handle is re-opened. + sql::Recovery::RecoverDatabaseWithMetaVersion(db, db_path); + + // The DLOG(FATAL) below is intended to draw immediate attention to errors + // in newly-written code. Database corruption is generally a result of OS + // or hardware issues, not coding errors at the client level, so displaying + // the error would probably lead to confusion. The ignored call signals the + // test-expectation framework that the error was handled. + ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); + return; } // The default handling is to assert on debug and to ignore on release.
diff --git a/components/history/core/browser/thumbnail_database_unittest.cc b/components/history/core/browser/thumbnail_database_unittest.cc index 61873b3..b20bbaf 100644 --- a/components/history/core/browser/thumbnail_database_unittest.cc +++ b/components/history/core/browser/thumbnail_database_unittest.cc
@@ -636,34 +636,8 @@ ASSERT_TRUE(db.get() != NULL); VerifyTablesAndColumns(&db->db_); - EXPECT_TRUE(CheckPageHasIcon(db.get(), - kPageUrl1, - favicon_base::FAVICON, - kIconUrl1, - kLargeSize, - sizeof(kBlob1), - kBlob1)); - EXPECT_TRUE(CheckPageHasIcon(db.get(), - kPageUrl2, - favicon_base::FAVICON, - kIconUrl2, - kLargeSize, - sizeof(kBlob2), - kBlob2)); - EXPECT_TRUE(CheckPageHasIcon(db.get(), - kPageUrl3, - favicon_base::FAVICON, - kIconUrl1, - kLargeSize, - sizeof(kBlob1), - kBlob1)); - EXPECT_TRUE(CheckPageHasIcon(db.get(), - kPageUrl3, - favicon_base::TOUCH_ICON, - kIconUrl3, - kLargeSize, - sizeof(kBlob2), - kBlob2)); + // Version 6 is deprecated, the data should all be gone. + VerifyDatabaseEmpty(&db->db_); } // Test loading version 7 database.
diff --git a/components/history/core/browser/top_sites_database.cc b/components/history/core/browser/top_sites_database.cc index 3ae0a108..4359300 100644 --- a/components/history/core/browser/top_sites_database.cc +++ b/components/history/core/browser/top_sites_database.cc
@@ -58,16 +58,13 @@ // anyhow). // Version 3: b6d6a783/r231648 by beaudoin@chromium.org on 2013-10-29 -// Version 2: eb0b24e6/r87284 by satorux@chromium.org on 2011-05-31 +// Version 2: eb0b24e6/r87284 by satorux@chromium.org on 2011-05-31 (deprecated) // Version 1: 809cc4d8/r64072 by sky@chromium.org on 2010-10-27 (deprecated) // NOTE(shess): When changing the version, add a new golden file for // the new version and a test to verify that Init() works with it. -// NOTE(shess): RecoverDatabaseOrRaze() depends on the specific -// version number. The code is subtle and in development, contact me -// if the necessary changes are not obvious. static const int kVersionNumber = 3; -static const int kDeprecatedVersionNumber = 1; // and earlier. +static const int kDeprecatedVersionNumber = 2; // and earlier. bool InitTables(sql::Connection* db) { const char kThumbnailsSql[] = @@ -108,9 +105,8 @@ // Track various failure (and success) cases in recovery code. // // TODO(shess): The recovery code is complete, but by nature runs in challenging -// circumstances, so initially the default error response is to leave the -// existing database in place. This histogram is intended to expose the -// failures seen in the fleet. Frequent failure cases can be explored more +// circumstances, so errors will happen. This histogram is intended to expose +// the failures seen in the fleet. Frequent failure cases can be explored more // deeply to see if the complexity to fix them is warranted. Infrequent failure // cases can be resolved by marking the database unrecoverable (which will // delete the data). @@ -126,12 +122,12 @@ // Sqlite.RecoveryEvent can usually be used to get more detail about the // specific failure (see sql/recovery.cc). - RECOVERY_EVENT_FAILED_SCOPER, + OBSOLETE_RECOVERY_EVENT_FAILED_SCOPER, RECOVERY_EVENT_FAILED_META_VERSION, RECOVERY_EVENT_FAILED_META_WRONG_VERSION, - RECOVERY_EVENT_FAILED_META_INIT, - RECOVERY_EVENT_FAILED_SCHEMA_INIT, - RECOVERY_EVENT_FAILED_AUTORECOVER_THUMBNAILS, + OBSOLETE_RECOVERY_EVENT_FAILED_META_INIT, + OBSOLETE_RECOVERY_EVENT_FAILED_SCHEMA_INIT, + OBSOLETE_RECOVERY_EVENT_FAILED_AUTORECOVER_THUMBNAILS, RECOVERY_EVENT_FAILED_COMMIT, // Track invariants resolved by FixThumbnailsTable(). @@ -139,6 +135,9 @@ RECOVERY_EVENT_INVARIANT_REDIRECT, RECOVERY_EVENT_INVARIANT_CONTIGUOUS, + // Track automated full-database recovery. + RECOVERY_EVENT_FAILED_AUTORECOVER, + // Always keep this at the end. RECOVERY_EVENT_MAX, }; @@ -203,89 +202,48 @@ RecordRecoveryEvent(RECOVERY_EVENT_INVARIANT_CONTIGUOUS); } -// Recover the database to the extent possible, razing it if recovery is not -// possible. -void RecoverDatabaseOrRaze(sql::Connection* db, const base::FilePath& db_path) { +// Recover the database to the extent possible, then fixup any broken +// constraints. +void RecoverAndFixup(sql::Connection* db, const base::FilePath& db_path) { // NOTE(shess): If the version changes, review this code. DCHECK_EQ(3, kVersionNumber); - // It is almost certain that some operation against |db| will fail, prevent - // reentry. - db->reset_error_callback(); - - // For generating histogram stats. - size_t thumbnails_recovered = 0; - int64_t original_size = 0; - base::GetFileSize(db_path, &original_size); - - std::unique_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path); + std::unique_ptr<sql::Recovery> recovery = + sql::Recovery::BeginRecoverDatabase(db, db_path); if (!recovery) { - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_SCOPER); + RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER); return; } - // Setup the meta recovery table and fetch the version number from the corrupt - // database. + // If the [meta] table does not exist, or the [version] key cannot be found, + // then the schema is indeterminate. The only plausible approach would be to + // validate that the schema contains all of the tables and indices and columns + // expected, but that complexity may not be warranted, this case has only been + // seen for a few thousand database files. int version = 0; if (!recovery->SetupMeta() || !recovery->GetMetaVersionNumber(&version)) { - // TODO(shess): Prior histograms indicate all failures are in creating the - // recover virtual table for corrupt.meta. The table may not exist, or the - // database may be too far gone. Either way, unclear how to resolve. - sql::Recovery::Rollback(std::move(recovery)); + sql::Recovery::Unrecoverable(std::move(recovery)); RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_VERSION); return; } - // This code runs in a context which may be able to read version information - // that the regular deprecation path cannot. The effect of this code will be - // to raze the database. + // In this case the next open will clear the database anyhow. if (version <= kDeprecatedVersionNumber) { sql::Recovery::Unrecoverable(std::move(recovery)); RecordRecoveryEvent(RECOVERY_EVENT_DEPRECATED); return; } - // TODO(shess): Earlier versions have been deprecated, later versions should - // be impossible. Unrecoverable() seems like a feasible response if this is - // infrequent enough. - if (version != 2 && version != 3) { + // TODO(shess): Consider marking corrupt databases from the future + // Unrecoverable(), since this histogram value has never been seen. OTOH, + // this may be too risky, because if future code was correlated with + // corruption then rollback would be a sensible response. + if (version > kVersionNumber) { RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_WRONG_VERSION); sql::Recovery::Rollback(std::move(recovery)); return; } - // Both v2 and v3 recover to current schema version. - sql::MetaTable recover_meta_table; - if (!recover_meta_table.Init(recovery->db(), kVersionNumber, - kVersionNumber)) { - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_INIT); - return; - } - - // Create a fresh version of the schema. The recovery code uses - // conflict-resolution to handle duplicates, so any indices are necessary. - if (!InitTables(recovery->db())) { - // TODO(shess): Unable to create the new schema in the new database. The - // new database should be a temporary file, so being unable to work with it - // is pretty unclear. - // - // What are the potential responses, even? The recovery database could be - // opened as in-memory. If the temp database had a filesystem problem and - // the temp filesystem differs from the main database, then that could fix - // it. - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_SCHEMA_INIT); - return; - } - - // In the v2 case the missing column will get default values. - if (!recovery->AutoRecoverTable("thumbnails", &thumbnails_recovered)) { - sql::Recovery::Rollback(std::move(recovery)); - RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_THUMBNAILS); - return; - } - // TODO(shess): Inline this? FixThumbnailsTable(recovery->db()); @@ -297,23 +255,6 @@ return; } - // Track the size of the recovered database relative to the size of the input - // database. The size should almost always be smaller, unless the input - // database was empty to start with. If the percentage results are very low, - // something is awry. - int64_t final_size = 0; - if (original_size > 0 && base::GetFileSize(db_path, &final_size) && - final_size > 0) { - UMA_HISTOGRAM_PERCENTAGE("History.TopSitesRecoveredPercentage", - final_size * 100 / original_size); - } - - // Using 10,000 because these cases mostly care about "none recovered" and - // "lots recovered". More than 10,000 rows recovered probably means there's - // something wrong with the profile. - UMA_HISTOGRAM_COUNTS_10000("History.TopSitesRecoveredRowsThumbnails", - static_cast<int>(thumbnails_recovered)); - RecordRecoveryEvent(RECOVERY_EVENT_RECOVERED); } @@ -325,11 +266,21 @@ // be the history thread, but at this level I can't see how to reach that. // Attempt to recover corrupt databases. - int error = (extended_error & 0xFF); - if (error == SQLITE_CORRUPT || - error == SQLITE_CANTOPEN || - error == SQLITE_NOTADB) { - RecoverDatabaseOrRaze(db, db_path); + if (sql::Recovery::ShouldRecover(extended_error)) { + // Prevent reentrant calls. + db->reset_error_callback(); + + // After this call, the |db| handle is poisoned so that future calls will + // return errors until the handle is re-opened. + RecoverAndFixup(db, db_path); + + // The DLOG(FATAL) below is intended to draw immediate attention to errors + // in newly-written code. Database corruption is generally a result of OS + // or hardware issues, not coding errors at the client level, so displaying + // the error would probably lead to confusion. The ignored call signals the + // test-expectation framework that the error was handled. + ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); + return; } // TODO(shess): This database's error histograms look like:
diff --git a/components/history/core/browser/top_sites_database_unittest.cc b/components/history/core/browser/top_sites_database_unittest.cc index 289b983..2968355 100644 --- a/components/history/core/browser/top_sites_database_unittest.cc +++ b/components/history/core/browser/top_sites_database_unittest.cc
@@ -86,31 +86,15 @@ VerifyDatabaseEmpty(db.db_.get()); } +// Version 2 is deprecated, the resulting schema should be current, +// with no data. TEST_F(TopSitesDatabaseTest, Version2) { ASSERT_TRUE(CreateDatabaseFromSQL(file_name_, "TopSites.v2.sql")); TopSitesDatabase db; ASSERT_TRUE(db.Init(file_name_)); - VerifyTablesAndColumns(db.db_.get()); - - // Basic operational check. - MostVisitedURLList urls; - std::map<GURL, Images> thumbnails; - db.GetPageThumbnails(&urls, &thumbnails); - ASSERT_EQ(3u, urls.size()); - ASSERT_EQ(3u, thumbnails.size()); - EXPECT_EQ(kUrl0, urls[0].url); // [0] because of url_rank. - // kGoogleThumbnail includes nul terminator. - ASSERT_EQ(sizeof(kGoogleThumbnail) - 1, - thumbnails[urls[0].url].thumbnail->size()); - EXPECT_TRUE(!memcmp(thumbnails[urls[0].url].thumbnail->front(), - kGoogleThumbnail, sizeof(kGoogleThumbnail) - 1)); - - ASSERT_TRUE(db.RemoveURL(urls[1])); - db.GetPageThumbnails(&urls, &thumbnails); - ASSERT_EQ(2u, urls.size()); - ASSERT_EQ(2u, thumbnails.size()); + VerifyDatabaseEmpty(db.db_.get()); } TEST_F(TopSitesDatabaseTest, Version3) { @@ -198,29 +182,15 @@ ASSERT_TRUE(expecter.SawExpectedErrors()); } - // Corruption should be detected and recovered during Init(). After recovery, - // the Version2 checks should work. + // Corruption should be detected and recovered during Init(). { sql::test::ScopedErrorExpecter expecter; expecter.ExpectError(SQLITE_CORRUPT); TopSitesDatabase db; ASSERT_TRUE(db.Init(file_name_)); - VerifyTablesAndColumns(db.db_.get()); - - // Basic operational check. - MostVisitedURLList urls; - std::map<GURL, Images> thumbnails; - db.GetPageThumbnails(&urls, &thumbnails); - ASSERT_EQ(3u, urls.size()); - ASSERT_EQ(3u, thumbnails.size()); - EXPECT_EQ(kUrl0, urls[0].url); // [0] because of url_rank. - // kGoogleThumbnail includes nul terminator. - ASSERT_EQ(sizeof(kGoogleThumbnail) - 1, - thumbnails[urls[0].url].thumbnail->size()); - EXPECT_TRUE(!memcmp(thumbnails[urls[0].url].thumbnail->front(), - kGoogleThumbnail, sizeof(kGoogleThumbnail) - 1)); + VerifyDatabaseEmpty(db.db_.get()); ASSERT_TRUE(expecter.SawExpectedErrors()); }
diff --git a/components/infobars/core/infobar_delegate.cc b/components/infobars/core/infobar_delegate.cc index 9f597fa..c3c0c97 100644 --- a/components/infobars/core/infobar_delegate.cc +++ b/components/infobars/core/infobar_delegate.cc
@@ -131,11 +131,6 @@ return nullptr; } -MediaThrottleInfoBarDelegate* - InfoBarDelegate::AsMediaThrottleInfoBarDelegate() { - return nullptr; -} - offline_pages::OfflinePageInfoBarDelegate* InfoBarDelegate::AsOfflinePageInfoBarDelegate() { return nullptr;
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index d7297aa..c041844 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -23,7 +23,6 @@ #if defined(OS_ANDROID) class MediaStreamInfoBarDelegateAndroid; -class MediaThrottleInfoBarDelegate; namespace offline_pages { class OfflinePageInfoBarDelegate; @@ -229,7 +228,6 @@ #if defined(OS_ANDROID) virtual MediaStreamInfoBarDelegateAndroid* AsMediaStreamInfoBarDelegateAndroid(); - virtual MediaThrottleInfoBarDelegate* AsMediaThrottleInfoBarDelegate(); virtual offline_pages::OfflinePageInfoBarDelegate* AsOfflinePageInfoBarDelegate(); #endif
diff --git a/components/password_manager/content/browser/credential_manager_impl_unittest.cc b/components/password_manager/content/browser/credential_manager_impl_unittest.cc index 4032c52..9563fc2 100644 --- a/components/password_manager/content/browser/credential_manager_impl_unittest.cc +++ b/components/password_manager/content/browser/credential_manager_impl_unittest.cc
@@ -1468,6 +1468,14 @@ CredentialType::CREDENTIAL_TYPE_PASSWORD); } +TEST_F(CredentialManagerImplTest, MigrateWithEmptyStore) { + // HTTP scheme is valid for localhost. Nothing should crash. + NavigateAndCommit(GURL("http://127.0.0.1:8000/")); + + std::vector<GURL> federations; + ExpectZeroClickSignInFailure(false, true, federations); +} + TEST_F(CredentialManagerImplTest, GetSynthesizedFormForOrigin) { PasswordStore::FormDigest synthesized = cm_service_impl_->GetSynthesizedFormForOrigin();
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc index ae1279a..cd89fb0 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -131,7 +131,8 @@ void CredentialManagerPendingRequestTask::OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) { - if (results.empty()) { + // localhost is a secure origin but not https. + if (results.empty() && origin_.SchemeIs(url::kHttpsScheme)) { // Try to migrate the HTTP passwords and process them later. http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( origin_, delegate_->client(), this);
diff --git a/components/payments/content/BUILD.gn b/components/payments/content/BUILD.gn index c586afe..a200799 100644 --- a/components/payments/content/BUILD.gn +++ b/components/payments/content/BUILD.gn
@@ -26,6 +26,7 @@ "//components/payments/core", "//content/public/browser", "//mojo/public/cpp/bindings", + "//third_party/libphonenumber", ] }
diff --git a/components/payments/content/DEPS b/components/payments/content/DEPS index c72416a..548a164 100644 --- a/components/payments/content/DEPS +++ b/components/payments/content/DEPS
@@ -8,6 +8,7 @@ "+content/public", "+mojo/public/cpp", "+net", + "+third_party/libphonenumber", "+third_party/re2", "+ui/base", ]
diff --git a/components/payments/content/payment_response_helper.cc b/components/payments/content/payment_response_helper.cc index 997731f6..0d1177a 100644 --- a/components/payments/content/payment_response_helper.cc +++ b/components/payments/content/payment_response_helper.cc
@@ -9,9 +9,16 @@ #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/payments/content/payment_request_spec.h" +#include "third_party/libphonenumber/phonenumber_api.h" namespace payments { +namespace { + +using ::i18n::phonenumbers::PhoneNumberUtil; + +} // namespace + PaymentResponseHelper::PaymentResponseHelper( const std::string& app_locale, PaymentRequestSpec* spec, @@ -112,10 +119,28 @@ } if (spec_->request_payer_phone()) { DCHECK(selected_contact_profile_); - // TODO(crbug.com/705945): Format phone number according to spec. - payment_response->payer_phone = - base::UTF16ToUTF8(selected_contact_profile_->GetRawInfo( - autofill::PHONE_HOME_WHOLE_NUMBER)); + + // Try to format the phone number to the E.164 format to send in the Payment + // Response, as defined in the Payment Request spec. If it's not possible, + // send the original. More info at: + // https://w3c.github.io/browser-payment-api/#paymentrequest-updated-algorithm + // TODO(sebsg): Move this code to a reusable location. + const std::string original_number = + base::UTF16ToUTF8(selected_contact_profile_->GetInfo( + autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), + app_locale_)); + i18n::phonenumbers::PhoneNumber parsed_number; + PhoneNumberUtil* phone_number_util = PhoneNumberUtil::GetInstance(); + if (phone_number_util->Parse(original_number, "US", &parsed_number) == + ::i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) { + std::string formatted_number; + phone_number_util->Format(parsed_number, + PhoneNumberUtil::PhoneNumberFormat::E164, + &formatted_number); + payment_response->payer_phone = formatted_number; + } else { + payment_response->payer_phone = original_number; + } } delegate_->OnPaymentResponseReady(std::move(payment_response));
diff --git a/components/payments/content/payment_response_helper_unittest.cc b/components/payments/content/payment_response_helper_unittest.cc index d072121..3b56de99 100644 --- a/components/payments/content/payment_response_helper_unittest.cc +++ b/components/payments/content/payment_response_helper_unittest.cc
@@ -245,7 +245,7 @@ // Check that all the expected values were set. EXPECT_EQ("John H. Doe", response()->payer_name.value()); - EXPECT_EQ("16502111111", response()->payer_phone.value()); + EXPECT_EQ("+16502111111", response()->payer_phone.value()); EXPECT_EQ("johndoe@hades.com", response()->payer_email.value()); } @@ -266,4 +266,22 @@ EXPECT_FALSE(response()->payer_email.has_value()); } +// Tests the the generated PaymentResponse has the correct values for the +// contact details when all values are requested. +TEST_F(PaymentResponseHelperTest, + GeneratePaymentResponse_ContactPhoneIsFormatted) { + // Request one contact detail value. + mojom::PaymentOptionsPtr options = mojom::PaymentOptions::New(); + options->request_payer_phone = true; + test_address()->SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER, + base::UTF8ToUTF16("(515) 123-1234")); + RecreateSpecWithOptions(std::move(options)); + + PaymentResponseHelper helper("en-US", spec(), test_instrument(), + test_address(), test_address(), this); + + // Check that the phone was formatted. + EXPECT_EQ("+15151231234", response()->payer_phone.value()); +} + } // namespace payments
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 36ca4ab..4f0877a9 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -49,6 +49,7 @@ #include "content/public/common/content_client.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_descriptor_keys.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" @@ -707,6 +708,16 @@ std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType); + // --enable-network-service requires both --enable-browser-side-navigation + // (PlzNavigate) and the LoadingWithMojo feature. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNetworkService)) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableBrowserSideNavigation); + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kEnableFeatures, features::kLoadingWithMojo.name); + } + // Run this logic on all child processes. Zygotes will run this at a later // point in time when the command line has been updated. std::unique_ptr<base::FieldTrialList> field_trial_list;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index ef9f563..731f573 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -910,8 +910,6 @@ "media/android/media_player_renderer.h", "media/android/media_resource_getter_impl.cc", "media/android/media_resource_getter_impl.h", - "media/android/media_throttler.cc", - "media/android/media_throttler.h", "media/android/media_web_contents_observer_android.cc", "media/android/media_web_contents_observer_android.h", "media/audible_metrics.cc",
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 638e0ecc2..b7a99d5 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -42,7 +42,6 @@ #include "services/file/file_service.h" #include "services/file/public/interfaces/constants.mojom.h" #include "services/file/user_id_map.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/interfaces/service.mojom.h" #include "storage/browser/database/database_tracker.h" @@ -150,11 +149,9 @@ class BrowserContextServiceManagerConnectionHolder : public base::SupportsUserData::Data { public: - BrowserContextServiceManagerConnectionHolder( - std::unique_ptr<service_manager::Connection> connection, + explicit BrowserContextServiceManagerConnectionHolder( service_manager::mojom::ServiceRequest request) - : root_connection_(std::move(connection)), - service_manager_connection_(ServiceManagerConnection::Create( + : service_manager_connection_(ServiceManagerConnection::Create( std::move(request), BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))) {} ~BrowserContextServiceManagerConnectionHolder() override {} @@ -164,7 +161,6 @@ } private: - std::unique_ptr<service_manager::Connection> root_connection_; std::unique_ptr<ServiceManagerConnection> service_manager_connection_; DISALLOW_COPY_AND_ASSIGN(BrowserContextServiceManagerConnectionHolder); @@ -442,9 +438,9 @@ identity, std::move(service), mojo::MakeRequest(&pid_receiver)); pid_receiver->SetPID(base::GetCurrentProcId()); + service_manager_connection->GetConnector()->StartService(identity); BrowserContextServiceManagerConnectionHolder* connection_holder = new BrowserContextServiceManagerConnectionHolder( - service_manager_connection->GetConnector()->Connect(identity), std::move(service_request)); browser_context->SetUserData(kServiceManagerConnection, connection_holder);
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index ab3135b..4036937d 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -508,6 +508,7 @@ void NavigationRequest::OnResponseStarted( const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body, + mojo::ScopedDataPipeConsumerHandle consumer_handle, const SSLStatus& ssl_status, std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, @@ -580,6 +581,7 @@ // Store the response and the StreamHandle until checks have been processed. response_ = response; body_ = std::move(body); + handle_ = std::move(consumer_handle); // Check if the navigation should be allowed to proceed. navigation_handle_->WillProcessResponse( @@ -840,8 +842,8 @@ DCHECK_EQ(request_params_.has_user_gesture, begin_params_.has_user_gesture); render_frame_host->CommitNavigation(response_.get(), std::move(body_), - common_params_, request_params_, - is_view_source_); + std::move(handle_), common_params_, + request_params_, is_view_source_); frame_tree_node_->ResetNavigationRequest(true, true); }
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 24980b9..095b77f5 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -17,6 +17,7 @@ #include "content/common/navigation_params.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/common/previews_state.h" +#include "mojo/public/cpp/system/data_pipe.h" namespace content { @@ -182,6 +183,7 @@ const scoped_refptr<ResourceResponse>& response) override; void OnResponseStarted(const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body, + mojo::ScopedDataPipeConsumerHandle consumer_handle, const SSLStatus& ssl_status, std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, @@ -248,10 +250,12 @@ std::unique_ptr<NavigationHandleImpl> navigation_handle_; - // Holds the ResourceResponse and the StreamHandle for the navigation while - // the WillProcessResponse checks are performed by the NavigationHandle. + // Holds the ResourceResponse and the StreamHandle (or + // DataPipeConsumerHandle) for the navigation while the WillProcessResponse + // checks are performed by the NavigationHandle. scoped_refptr<ResourceResponse> response_; std::unique_ptr<StreamHandle> body_; + mojo::ScopedDataPipeConsumerHandle handle_; base::Closure on_start_checks_complete_closure_;
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index d84e291..6dd1df2 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -1160,11 +1160,11 @@ RenderFrameHostImpl* render_frame_host = frame_tree_node->render_manager()->GetFrameHostForNavigation( *scoped_request.get()); - render_frame_host->CommitNavigation(nullptr, // response - nullptr, // body - scoped_request->common_params(), - scoped_request->request_params(), - scoped_request->is_view_source()); + render_frame_host->CommitNavigation( + nullptr, // response + nullptr, // body + mojo::ScopedDataPipeConsumerHandle(), scoped_request->common_params(), + scoped_request->request_params(), scoped_request->is_view_source()); return; }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 55d6a08e..22394e1 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -105,6 +105,7 @@ #include "media/mojo/interfaces/remoting.mojom.h" #include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/accessibility/ax_tree.h" @@ -2642,8 +2643,8 @@ base::Optional<SourceLocation>(), CSPDisposition::CHECK /* should_check_main_world_csp */); if (IsBrowserSideNavigationEnabled()) { - CommitNavigation(nullptr, nullptr, common_params, RequestNavigationParams(), - false); + CommitNavigation(nullptr, nullptr, mojo::ScopedDataPipeConsumerHandle(), + common_params, RequestNavigationParams(), false); } else { Navigate(common_params, StartNavigationParams(), RequestNavigationParams()); } @@ -2802,11 +2803,12 @@ void RenderFrameHostImpl::CommitNavigation( ResourceResponse* response, std::unique_ptr<StreamHandle> body, + mojo::ScopedDataPipeConsumerHandle handle, const CommonNavigationParams& common_params, const RequestNavigationParams& request_params, bool is_view_source) { DCHECK( - (response && body.get()) || + (response && (body.get() || handle.is_valid())) || common_params.url.SchemeIs(url::kDataScheme) || !ShouldMakeNetworkRequestForURL(common_params.url) || FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type) || @@ -2828,7 +2830,8 @@ const GURL body_url = body.get() ? body->GetURL() : GURL(); const ResourceResponseHead head = response ? response->head : ResourceResponseHead(); - Send(new FrameMsg_CommitNavigation(routing_id_, head, body_url, common_params, + Send(new FrameMsg_CommitNavigation(routing_id_, head, body_url, + handle.release(), common_params, request_params)); // If a network request was made, update the Previews state.
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 6f30641bb..10c52a3 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -43,6 +43,7 @@ #include "content/public/common/javascript_dialog_type.h" #include "content/public/common/previews_state.h" #include "media/mojo/interfaces/interface_factory.mojom.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "net/http/http_response_headers.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/service_manager/public/cpp/interface_registry.h" @@ -539,6 +540,7 @@ // handled by this RenderFrame. void CommitNavigation(ResourceResponse* response, std::unique_ptr<StreamHandle> body, + mojo::ScopedDataPipeConsumerHandle handle, const CommonNavigationParams& common_params, const RequestNavigationParams& request_params, bool is_view_source);
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 39d00af7..2eade52 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -62,7 +62,6 @@ #include "media/media_features.h" #include "mojo/edk/embedder/embedder.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/runner/common/client_util.h" #include "ui/display/display_switches.h"
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h index c67854a..8a71b22 100644 --- a/content/browser/loader/navigation_url_loader_delegate.h +++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "content/common/content_export.h" +#include "mojo/public/cpp/system/data_pipe.h" namespace net { struct RedirectInfo; @@ -35,9 +36,12 @@ // Called when the request receives its response. No further calls will be // made to the delegate. The response body is returned as a stream in // |body_stream|. |navigation_data| is passed to the NavigationHandle. + // If --enable-network-service, then |consumer_handle| will be used, + // otherwise |body_stream|. Only one of these will ever be non-null. virtual void OnResponseStarted( const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body_stream, + mojo::ScopedDataPipeConsumerHandle consumer_handle, const SSLStatus& ssl_status, std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index b1053623..4617b46 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -100,7 +100,8 @@ bool is_stream) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - delegate_->OnResponseStarted(response, std::move(body), ssl_status, + delegate_->OnResponseStarted(response, std::move(body), + mojo::ScopedDataPipeConsumerHandle(), ssl_status, std::move(navigation_data), request_id, is_download, is_stream); }
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index b29827b..c503716 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -8,7 +8,11 @@ #include "content/browser/frame_host/navigation_request_info.h" #include "content/browser/loader/navigation_url_loader_delegate.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/global_request_id.h" +#include "content/public/browser/navigation_data.h" #include "content/public/browser/navigation_ui_data.h" +#include "content/public/browser/ssl_status.h" +#include "content/public/browser/stream_handle.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/service_names.mojom.h" #include "net/url_request/url_request_context.h" @@ -62,8 +66,11 @@ void NavigationURLLoaderNetworkService::OnReceiveResponse( const ResourceResponseHead& head, mojom::DownloadedTempFilePtr downloaded_file) { - // TODO(scottmg): This should mirror code in - // NavigationResourceHandler::OnReponseStarted(). + // TODO(scottmg): This needs to do more of what + // NavigationResourceHandler::OnReponseStarted() does. Or maybe in + // OnStartLoadingResponseBody(). + response_ = base::MakeShared<ResourceResponse>(); + response_->head = head; } void NavigationURLLoaderNetworkService::OnReceiveRedirect( @@ -91,7 +98,16 @@ int32_t transfer_size_diff) {} void NavigationURLLoaderNetworkService::OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) {} + mojo::ScopedDataPipeConsumerHandle body) { + DCHECK(response_); + // Temporarily, we pass both a stream (null) and the data pipe to the + // delegate until PlzNavigate has shipped and we can be comfortable fully + // switching to the data pipe. + delegate_->OnResponseStarted(response_, nullptr, std::move(body), SSLStatus(), + std::unique_ptr<NavigationData>(), + GlobalRequestID() /* request_id? */, + false /* is_download? */, false /* is_stream */); +} void NavigationURLLoaderNetworkService::OnComplete( const ResourceRequestCompletionStatus& completion_status) {}
diff --git a/content/browser/loader/navigation_url_loader_network_service.h b/content/browser/loader/navigation_url_loader_network_service.h index b301769..25c46e7 100644 --- a/content/browser/loader/navigation_url_loader_network_service.h +++ b/content/browser/loader/navigation_url_loader_network_service.h
@@ -66,6 +66,7 @@ mojom::URLLoaderFactoryPtr url_loader_factory_; mojo::Binding<mojom::URLLoaderClient> binding_; mojom::URLLoaderAssociatedPtr url_loader_associated_ptr_; + scoped_refptr<ResourceResponse> response_; DISALLOW_COPY_AND_ASSIGN(NavigationURLLoaderNetworkService); };
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index 36ae2e5..d5128ec 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -11,7 +11,6 @@ #include "base/memory/singleton.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/media/android/media_resource_getter_impl.h" -#include "content/browser/media/android/media_throttler.h" #include "content/browser/media/android/media_web_contents_observer_android.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -69,9 +68,13 @@ // static BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( RenderFrameHost* rfh) { - if (g_factory) - return g_factory(rfh); - return new BrowserMediaPlayerManager(rfh); + // In chrome, |g_factory| should be set to create a RemoteMediaPlayerManager, + // since RegisterFactory() should be called from + // ChromeMainDelegateAndroid::BasicStartupComplete. + // + // In webview, no factory should be set, and returning a nullptr should be + // handled by the caller. + return g_factory != nullptr ? g_factory(rfh) : nullptr; } #if !defined(USE_AURA) @@ -372,13 +375,12 @@ if (!player) return; - if (RequestDecoderResources(player_id, false)) { - StartInternal(player_id); - } else if (WebContentsDelegate* delegate = web_contents_->GetDelegate()){ - delegate->RequestMediaDecodePermission( - web_contents_, - base::Bind(&BrowserMediaPlayerManager::OnPlaybackPermissionGranted, - weak_ptr_factory_.GetWeakPtr(), player_id)); + RequestDecoderResources(player_id, false); + + player->Start(); + if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) { + video_view_->OpenVideo(); + fullscreen_player_is_released_ = false; } } @@ -484,9 +486,6 @@ bool BrowserMediaPlayerManager::RequestDecoderResources( int player_id, bool temporary) { - if (!MediaThrottler::GetInstance()->RequestDecoderResources()) - return false; - ActivePlayerMap::iterator it; // The player is already active, ignore it. A long running player should not // request temporary permissions. @@ -525,7 +524,6 @@ return; active_players_.erase(player_id); - MediaThrottler::GetInstance()->OnDecodeRequestFinished(); } int BrowserMediaPlayerManager::RoutingID() { @@ -545,24 +543,4 @@ player->Release(); } -void BrowserMediaPlayerManager::OnPlaybackPermissionGranted( - int player_id, bool granted) { - if (!granted) - return; - - MediaThrottler::GetInstance()->Reset(); - StartInternal(player_id); -} - -void BrowserMediaPlayerManager::StartInternal(int player_id) { - MediaPlayerAndroid* player = GetPlayer(player_id); - if (!player) - return; - player->Start(); - if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) { - video_view_->OpenVideo(); - fullscreen_player_is_released_ = false; - } -} - } // namespace content
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index 6fb9a4f..edbe2da3 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h
@@ -48,7 +48,8 @@ static void RegisterMediaUrlInterceptor( media::MediaUrlInterceptor* media_url_interceptor); - // Returns a new instance using the registered factory if available. + // Returns a new instance using the registered factory. + // Returns nullptr if no factory was registered. static BrowserMediaPlayerManager* Create(RenderFrameHost* rfh); #if !defined(USE_AURA) @@ -160,12 +161,6 @@ // player from |players_|. void ReleasePlayer(media::MediaPlayerAndroid* player); - // Called when user approves media playback after being throttled. - void OnPlaybackPermissionGranted(int player_id, bool granted); - - // Helper method to start playback. - void StartInternal(int player_id); - RenderFrameHost* const render_frame_host_; // An array of managed players.
diff --git a/content/browser/media/android/media_throttler.cc b/content/browser/media/android/media_throttler.cc deleted file mode 100644 index 1782373..0000000 --- a/content/browser/media/android/media_throttler.cc +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2015 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 "content/browser/media/android/media_throttler.h" - -#include "base/android/context_utils.h" -#include "base/android/jni_android.h" -#include "jni/MediaThrottler_jni.h" - -namespace content { - -// static -MediaThrottler* MediaThrottler::GetInstance() { - return base::Singleton<MediaThrottler>::get(); -} - -MediaThrottler::~MediaThrottler() {} - -bool MediaThrottler::RequestDecoderResources() { - JNIEnv* env = base::android::AttachCurrentThread(); - return Java_MediaThrottler_requestDecoderResources(env, j_media_throttler_); -} - -void MediaThrottler::OnDecodeRequestFinished() { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_MediaThrottler_onDecodeRequestFinished(env, j_media_throttler_); -} - -void MediaThrottler::Reset() { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_MediaThrottler_reset(env, j_media_throttler_); -} - -MediaThrottler::MediaThrottler() { - JNIEnv* env = base::android::AttachCurrentThread(); - CHECK(env); - - j_media_throttler_.Reset(Java_MediaThrottler_create( - env, base::android::GetApplicationContext())); -} - -} // namespace content
diff --git a/content/browser/media/android/media_throttler.h b/content/browser/media/android/media_throttler.h deleted file mode 100644 index 65130ba..0000000 --- a/content/browser/media/android/media_throttler.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2015 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 CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_THROTTLER_H_ -#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_THROTTLER_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/macros.h" -#include "base/memory/singleton.h" - -namespace content { - -class MediaThrottler { - public: - // Called to get the singleton MediaThrottler instance. - static MediaThrottler* GetInstance(); - - virtual ~MediaThrottler(); - - // Called to request the permission to decode media data. Returns true if - // permitted, or false otherwise. - bool RequestDecoderResources(); - - // Called when a decode request finishes. - void OnDecodeRequestFinished(); - - // Resets the throttler to a fresh state. - void Reset(); - - private: - friend struct base::DefaultSingletonTraits<MediaThrottler>; - MediaThrottler(); - - base::android::ScopedJavaGlobalRef<jobject> j_media_throttler_; - DISALLOW_COPY_AND_ASSIGN(MediaThrottler); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_THROTTLER_H_
diff --git a/content/browser/media/android/media_web_contents_observer_android.cc b/content/browser/media/android/media_web_contents_observer_android.cc index c61a0b0a..63eaf6f8 100644 --- a/content/browser/media/android/media_web_contents_observer_android.cc +++ b/content/browser/media/android/media_web_contents_observer_android.cc
@@ -115,44 +115,50 @@ bool MediaWebContentsObserverAndroid::OnMediaPlayerMessageReceived( const IPC::Message& msg, RenderFrameHost* render_frame_host) { + // The only BMPM instance that is still currently used is the + // RemoteMediaPlayerManager, used in casting. + // + // In the webview case, casting is not supported, and GetMediaPlayerManager() + // will return a nullptr. It is safe to not handle the messages, since the + // only message we can receive is an unavoidable MediaPlayerHostMsg_Initialize + // that WMPI sends out in WebMediaPlayerImpl::DoLoad(). + BrowserMediaPlayerManager* media_player_manager = + GetMediaPlayerManager(render_frame_host); + + if (!media_player_manager) + return false; + bool handled = true; IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserverAndroid, msg) IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen, - GetMediaPlayerManager(render_frame_host), + media_player_manager, BrowserMediaPlayerManager::OnEnterFullscreen) - IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize, - GetMediaPlayerManager(render_frame_host), + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize, media_player_manager, BrowserMediaPlayerManager::OnInitialize) - IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start, - GetMediaPlayerManager(render_frame_host), + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start, media_player_manager, BrowserMediaPlayerManager::OnStart) - IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek, - GetMediaPlayerManager(render_frame_host), + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek, media_player_manager, BrowserMediaPlayerManager::OnSeek) - IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause, - GetMediaPlayerManager(render_frame_host), + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause, media_player_manager, BrowserMediaPlayerManager::OnPause) - IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume, - GetMediaPlayerManager(render_frame_host), + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume, media_player_manager, BrowserMediaPlayerManager::OnSetVolume) - IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster, - GetMediaPlayerManager(render_frame_host), + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster, media_player_manager, BrowserMediaPlayerManager::OnSetPoster) IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SuspendAndRelease, - GetMediaPlayerManager(render_frame_host), + media_player_manager, BrowserMediaPlayerManager::OnSuspendAndReleaseResources) IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer, - GetMediaPlayerManager(render_frame_host), + media_player_manager, BrowserMediaPlayerManager::OnDestroyPlayer) IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_RequestRemotePlayback, - GetMediaPlayerManager(render_frame_host), + media_player_manager, BrowserMediaPlayerManager::OnRequestRemotePlayback) IPC_MESSAGE_FORWARD( - MediaPlayerHostMsg_RequestRemotePlaybackControl, - GetMediaPlayerManager(render_frame_host), + MediaPlayerHostMsg_RequestRemotePlaybackControl, media_player_manager, BrowserMediaPlayerManager::OnRequestRemotePlaybackControl) IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_RequestRemotePlaybackStop, - GetMediaPlayerManager(render_frame_host), + media_player_manager, BrowserMediaPlayerManager::OnRequestRemotePlaybackStop) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP()
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc index 25c56ffb..9538287 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -149,17 +149,16 @@ ui::EventType event_type = WebMouseEventTypeToEventType(web_mouse_event.GetType()); int flags = WebEventModifiersToEventFlags(web_mouse_event.GetModifiers()); + ui::PointerDetails pointer_details( + WebMousePointerTypeToEventPointerType(web_mouse_event.pointer_type)); ui::MouseEvent mouse_event(event_type, gfx::Point(), gfx::Point(), - ui::EventTimeForNow(), flags, flags); + ui::EventTimeForNow(), flags, flags, + pointer_details); gfx::PointF location( web_mouse_event.PositionInWidget().x * device_scale_factor_, web_mouse_event.PositionInWidget().y * device_scale_factor_); mouse_event.set_location_f(location); mouse_event.set_root_location_f(location); - ui::PointerDetails pointer_details = mouse_event.pointer_details(); - pointer_details.pointer_type = - WebMousePointerTypeToEventPointerType(web_mouse_event.pointer_type); - mouse_event.set_pointer_details(pointer_details); aura::Window* window = GetWindow(); mouse_event.ConvertLocationToTarget(window, window->GetRootWindow());
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 0d6f9e348..da4804e 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc
@@ -80,10 +80,6 @@ #include "base/file_descriptor_posix.h" #endif -#if defined(OS_ANDROID) -#include "content/browser/media/android/media_throttler.h" -#endif - #if defined(OS_MACOSX) #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #endif
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index a691ef8..05f7cfe 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -183,7 +183,6 @@ #include "ppapi/features/features.h" #include "services/resource_coordinator/memory/coordinator/coordinator_impl.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/runner/common/client_util.h"
diff --git a/content/browser/utility_process_host_impl.cc b/content/browser/utility_process_host_impl.cc index ea61cbf..4c5b066 100644 --- a/content/browser/utility_process_host_impl.cc +++ b/content/browser/utility_process_host_impl.cc
@@ -40,7 +40,6 @@ #include "content/public/common/service_manager_connection.h" #include "content/public/common/service_names.mojom.h" #include "mojo/edk/embedder/embedder.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/base/ui_base_switches.h"
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index a5718012..7500a8f 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc
@@ -66,7 +66,6 @@ #include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/platform_handle.h" #include "services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h" -#include "services/device/public/interfaces/constants.mojom.h" #include "services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" @@ -510,13 +509,8 @@ // also for some edge cases where there is no ServiceManagerConnection, we do // not create the power monitor. if (!base::PowerMonitor::Get() && service_manager_connection_) { - std::unique_ptr<service_manager::Connection> device_connection = - service_manager_connection_->GetConnector()->Connect( - device::mojom::kServiceName); auto power_monitor_source = - base::MakeUnique<device::PowerMonitorBroadcastSource>( - device_connection->GetRemoteInterfaces()); - + base::MakeUnique<device::PowerMonitorBroadcastSource>(GetConnector()); power_monitor_.reset( new base::PowerMonitor(std::move(power_monitor_source))); }
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index 50254c1..4484df9 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -620,7 +620,8 @@ const url::Origin& frame_origin, std::unique_ptr<RequestPeer> peer, blink::WebURLRequest::LoadingIPCType ipc_type, - mojom::URLLoaderFactory* url_loader_factory) { + mojom::URLLoaderFactory* url_loader_factory, + mojo::ScopedDataPipeConsumerHandle consumer_handle) { CheckSchemeForReferrerPolicy(*request); // Compute a unique request_id for this renderer process. @@ -634,6 +635,21 @@ loading_task_runner); } + scoped_refptr<base::SingleThreadTaskRunner> task_runner = + loading_task_runner ? loading_task_runner : main_thread_task_runner_; + + if (consumer_handle.is_valid()) { + pending_requests_[request_id]->url_loader_client = + base::MakeUnique<URLLoaderClientImpl>(request_id, this, task_runner); + + task_runner->PostTask(FROM_HERE, + base::Bind(&ResourceDispatcher::ContinueForNavigation, + weak_factory_.GetWeakPtr(), request_id, + base::Passed(std::move(consumer_handle)))); + + return request_id; + } + if (ipc_type == blink::WebURLRequest::LoadingIPCType::kMojo) { scoped_refptr<base::SingleThreadTaskRunner> task_runner = loading_task_runner ? loading_task_runner : main_thread_task_runner_; @@ -735,6 +751,36 @@ return result; } +void ResourceDispatcher::ContinueForNavigation( + int request_id, + mojo::ScopedDataPipeConsumerHandle consumer_handle) { + PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); + if (!request_info) + return; + + URLLoaderClientImpl* client_ptr = request_info->url_loader_client.get(); + + // Short circuiting call to OnReceivedResponse to immediately start + // the request. ResourceResponseHead can be empty here because we + // pull the StreamOverride's one in + // WebURLLoaderImpl::Context::OnReceivedResponse. + client_ptr->OnReceiveResponse(ResourceResponseHead(), + mojom::DownloadedTempFilePtr()); + // Start streaming now. + client_ptr->OnStartLoadingResponseBody(std::move(consumer_handle)); + + // Call OnComplete now too, as it won't get called on the client. + // TODO(kinuko): Fill this properly. + ResourceRequestCompletionStatus completion_status; + completion_status.error_code = net::OK; + completion_status.was_ignored_by_handler = false; + completion_status.exists_in_cache = false; + completion_status.completion_time = base::TimeTicks::Now(); + completion_status.encoded_data_length = -1; + completion_status.encoded_body_length = -1; + client_ptr->OnComplete(completion_status); +} + // static bool ResourceDispatcher::IsResourceDispatcherMessage( const IPC::Message& message) {
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index 5554c44b..8b61daf 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h
@@ -26,6 +26,7 @@ #include "content/public/common/resource_type.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "net/base/request_priority.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" #include "url/gurl.h" @@ -98,7 +99,8 @@ const url::Origin& frame_origin, std::unique_ptr<RequestPeer> peer, blink::WebURLRequest::LoadingIPCType ipc_type, - mojom::URLLoaderFactory* url_loader_factory); + mojom::URLLoaderFactory* url_loader_factory, + mojo::ScopedDataPipeConsumerHandle consumer_handle); // Removes a request from the |pending_requests_| list, returning true if the // request was found and removed. @@ -240,6 +242,10 @@ // invocations will return current time until set_io_timestamp is called. base::TimeTicks ConsumeIOTimestamp(); + void ContinueForNavigation( + int request_id, + mojo::ScopedDataPipeConsumerHandle consumer_handle); + // Returns true if the message passed in is a resource related message. static bool IsResourceDispatcherMessage(const IPC::Message& message);
diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc index 700e30c..24ae91c1 100644 --- a/content/child/resource_dispatcher_unittest.cc +++ b/content/child/resource_dispatcher_unittest.cc
@@ -229,7 +229,8 @@ new TestRequestPeer(dispatcher(), peer_context)); int request_id = dispatcher()->StartAsync( std::move(request), 0, nullptr, url::Origin(), std::move(peer), - blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr); + blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr, + mojo::ScopedDataPipeConsumerHandle()); peer_context->request_id = request_id; return request_id; }
diff --git a/content/child/url_loader_client_impl_unittest.cc b/content/child/url_loader_client_impl_unittest.cc index f6705b46..61b62c86 100644 --- a/content/child/url_loader_client_impl_unittest.cc +++ b/content/child/url_loader_client_impl_unittest.cc
@@ -33,7 +33,7 @@ base::MakeUnique<TestRequestPeer>(dispatcher_.get(), &request_peer_context_), blink::WebURLRequest::LoadingIPCType::kMojo, - url_loader_factory_proxy_.get()); + url_loader_factory_proxy_.get(), mojo::ScopedDataPipeConsumerHandle()); request_peer_context_.request_id = request_id_; base::RunLoop().RunUntilIdle();
diff --git a/content/child/url_response_body_consumer_unittest.cc b/content/child/url_response_body_consumer_unittest.cc index 5ab0035a..af05919c 100644 --- a/content/child/url_response_body_consumer_unittest.cc +++ b/content/child/url_response_body_consumer_unittest.cc
@@ -137,7 +137,8 @@ return dispatcher_->StartAsync( std::move(request), 0, nullptr, url::Origin(), base::MakeUnique<TestRequestPeer>(context, message_loop_.task_runner()), - blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr); + blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr, + mojo::ScopedDataPipeConsumerHandle()); } void Run(TestRequestPeer::Context* context) {
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 3b31280d..716adc9 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -602,11 +602,16 @@ // PlzNavigate: during navigation, the renderer should request a stream which // contains the body of the response. The network request has already been // made by the browser. + mojo::ScopedDataPipeConsumerHandle consumer_handle; if (stream_override_.get()) { CHECK(IsBrowserSideNavigationEnabled()); DCHECK(!sync_load_response); DCHECK_NE(WebURLRequest::kFrameTypeNone, request.GetFrameType()); - resource_request->resource_body_stream_url = stream_override_->stream_url; + if (stream_override_->consumer_handle.is_valid()) { + consumer_handle = std::move(stream_override_->consumer_handle); + } else { + resource_request->resource_body_stream_url = stream_override_->stream_url; + } } // PlzNavigate: Invalid renderer main resource requests are rejected by the @@ -641,7 +646,8 @@ std::move(resource_request), request.RequestorID(), task_runner_, extra_data->frame_origin(), base::MakeUnique<WebURLLoaderImpl::RequestPeerImpl>(this), - request.GetLoadingIPCType(), url_loader_factory_); + request.GetLoadingIPCType(), url_loader_factory_, + std::move(consumer_handle)); if (defers_loading_ != NOT_DEFERRING) resource_dispatcher_->SetDefersLoading(request_id_, true); @@ -808,6 +814,13 @@ if (!client_) return; + if (stream_override_ && stream_override_->stream_url.is_empty()) { + // Since ResourceDispatcher::ContinueForNavigation called OnComplete + // immediately, it didn't have the size of the resource immediately. So as + // data is read off the data pipe, keep track of how much we're reading. + stream_override_->total_transferred += data_length; + } + TRACE_EVENT_WITH_FLOW0( "loading", "WebURLLoaderImpl::Context::OnReceivedData", this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); @@ -850,6 +863,12 @@ const base::TimeTicks& completion_time, int64_t total_transfer_size, int64_t encoded_body_size) { + if (stream_override_ && stream_override_->stream_url.is_empty()) { + // TODO(kinuko|scottmg|jam): This is wrong. https://crbug.com/705744. + total_transfer_size = stream_override_->total_transferred; + encoded_body_size = stream_override_->total_transferred; + } + if (ftp_listing_delegate_) { ftp_listing_delegate_->OnCompletedRequest(); ftp_listing_delegate_.reset(NULL);
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h index 5f8eef6..a382570 100644 --- a/content/child/web_url_loader_impl.h +++ b/content/child/web_url_loader_impl.h
@@ -10,6 +10,7 @@ #include "content/common/content_export.h" #include "content/common/url_loader_factory.mojom.h" #include "content/public/common/resource_response.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "net/url_request/redirect_info.h" #include "third_party/WebKit/public/platform/WebURLLoader.h" #include "url/gurl.h" @@ -27,6 +28,7 @@ // TODO(clamy): The browser should be made aware on destruction of this struct // that it can release its associated stream handle. GURL stream_url; + mojo::ScopedDataPipeConsumerHandle consumer_handle; ResourceResponseHead response; std::vector<GURL> redirects; std::vector<ResourceResponseInfo> redirect_responses; @@ -35,6 +37,8 @@ // The delta between the actual transfer size and the one reported by the // AsyncResourceLoader due to not having the ResourceResponse. int total_transfer_size_delta; + + int total_transferred = 0; }; class CONTENT_EXPORT WebURLLoaderImpl
diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc index 267d027..e4877d24 100644 --- a/content/child/web_url_loader_impl_unittest.cc +++ b/content/child/web_url_loader_impl_unittest.cc
@@ -82,7 +82,8 @@ const url::Origin& frame_origin, std::unique_ptr<RequestPeer> peer, blink::WebURLRequest::LoadingIPCType ipc_type, - mojom::URLLoaderFactory* url_loader_factory) override { + mojom::URLLoaderFactory* url_loader_factory, + mojo::ScopedDataPipeConsumerHandle consumer_handle) override { EXPECT_FALSE(peer_); peer_ = std::move(peer); url_ = request->url;
diff --git a/content/common/content_param_traits.h b/content/common/content_param_traits.h index 640207c..6cd7d92 100644 --- a/content/common/content_param_traits.h +++ b/content/common/content_param_traits.h
@@ -16,6 +16,7 @@ #include "content/common/content_param_traits_macros.h" #include "content/common/cursors/webcursor.h" +#include "ipc/ipc_mojo_param_traits.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" namespace content {
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 002ae95d..b8be34e0 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -907,12 +907,14 @@ // PlzNavigate // Tells the renderer that a navigation is ready to commit. The renderer should // request |stream_url| to get access to the stream containing the body of the -// response. -IPC_MESSAGE_ROUTED4(FrameMsg_CommitNavigation, - content::ResourceResponseHead, /* response */ - GURL, /* stream_url */ - content::CommonNavigationParams, /* common_params */ - content::RequestNavigationParams /* request_params */) +// response. When --enable-network-service is in effect, |stream_url| is not +// used, and instead the data is passed to the renderer in |handle|. +IPC_MESSAGE_ROUTED5(FrameMsg_CommitNavigation, + content::ResourceResponseHead, /* response */ + GURL, /* stream_url */ + mojo::DataPipeConsumerHandle, /* handle */ + content::CommonNavigationParams, /* common_params */ + content::RequestNavigationParams /* request_params */) // PlzNavigate // Tells the renderer that a navigation failed with the error code |error_code|
diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc index 2719f50..5e5638e 100644 --- a/content/common/input/synthetic_web_input_event_builders.cc +++ b/content/common/input/synthetic_web_input_event_builders.cc
@@ -38,7 +38,7 @@ result.SetPositionInWidget(window_x, window_y); result.SetModifiers(modifiers); result.pointer_type = pointer_type; - result.id = ui::PointerEvent::kMousePointerId; + result.id = ui::MouseEvent::kMousePointerId; return result; }
diff --git a/content/network/url_loader_impl.cc b/content/network/url_loader_impl.cc index 6732481..a29cec4 100644 --- a/content/network/url_loader_impl.cc +++ b/content/network/url_loader_impl.cc
@@ -167,6 +167,8 @@ GURL(request.url), net::DEFAULT_PRIORITY, this); url_request_->set_method(request.method); + url_request_->set_first_party_for_cookies(request.first_party_for_cookies); + const Referrer referrer(request.referrer, request.referrer_policy); Referrer::SetReferrerForRequest(url_request_.get(), referrer);
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 90eef04..e87b476c 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -139,7 +139,6 @@ "java/src/org/chromium/content/browser/LauncherThread.java", "java/src/org/chromium/content/browser/MediaResourceGetter.java", "java/src/org/chromium/content/browser/MediaSessionImpl.java", - "java/src/org/chromium/content/browser/MediaThrottler.java", "java/src/org/chromium/content/browser/MemoryMonitorAndroid.java", "java/src/org/chromium/content/browser/MotionEventSynthesizer.java", "java/src/org/chromium/content/browser/NfcFactory.java", @@ -344,7 +343,6 @@ "java/src/org/chromium/content/browser/LauncherThread.java", "java/src/org/chromium/content/browser/MediaResourceGetter.java", "java/src/org/chromium/content/browser/MediaSessionImpl.java", - "java/src/org/chromium/content/browser/MediaThrottler.java", "java/src/org/chromium/content/browser/MemoryMonitorAndroid.java", "java/src/org/chromium/content/browser/MotionEventSynthesizer.java", "java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/MediaThrottler.java b/content/public/android/java/src/org/chromium/content/browser/MediaThrottler.java deleted file mode 100644 index ece07e1..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/MediaThrottler.java +++ /dev/null
@@ -1,224 +0,0 @@ -// Copyright 2015 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.content.browser; - -import android.content.Context; -import android.media.MediaPlayer; -import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; -import android.os.SystemClock; - -import org.chromium.base.Log; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.content.R; - -/** - * Class for listening to Android MediaServer Crashes to throttle media decoding - * when needed. - */ -@JNINamespace("content") -class MediaThrottler implements MediaPlayer.OnErrorListener { - private static final String TAG = "cr_MediaThrottler"; - private static final long UNKNOWN_LAST_SERVER_CRASH_TIME = -1; - - // Number of active decode requests. - private int mRequestCount; - - // Application context. - private final Context mContext; - - // Watch dog player. Used to listen to all media server crashes. - private MediaPlayer mPlayer; - - // The last media server crash time since Chrome lauches. - private long mLastCrashTime = UNKNOWN_LAST_SERVER_CRASH_TIME; - - // Server crash count since last reset() call. - private int mServerCrashCount; - - // Object for synchronized access to memeber variables. - private final Object mLock = new Object(); - - // Handler for posting delayed tasks. - private Handler mHandler; - - // Intervals between media server crashes that are considered normal. It - // takes about 5 seconds to restart the media server. So this value has to - // be larger than 5 seconds. - private static final long SERVER_CRASH_INTERVAL_THRESHOLD_IN_MILLIS = 60000; - - // Delay to keep the watch dog player alive When there are no decoding - // requests. This is introduced to avoid recreating the watch dog over and - // over if a burst of small decoding requests arrive. - private static final int RELEASE_WATCH_DOG_PLAYER_DELAY_IN_MILLIS = 5000; - - // When |mServerCrashCount| reaches this threshold, throttling will start. - // This is to prevent a page from loading a malformed video over and over - // to crash the media server excessively. - private static final int SERVER_CRASH_COUNT_THRESHOLD_FOR_THROTTLING = 4; - - /** - * A background task to release the watch dog player. - */ - private class ReleaseWatchDogTask extends AsyncTask<Void, Void, Void> { - @Override - protected Void doInBackground(Void... voids) { - synchronized (mLock) { - if (mRequestCount == 0 && mPlayer != null) { - mPlayer.release(); - mPlayer = null; - } - } - return null; - } - } - - private final Runnable mDelayedReleaseRunnable = new Runnable() { - @Override - public void run() { - new ReleaseWatchDogTask().execute(); - } - }; - - @CalledByNative - private static MediaThrottler create(Context context) { - return new MediaThrottler(context); - } - - private MediaThrottler(Context context) { - mContext = context; - mHandler = new Handler(Looper.getMainLooper()); - } - - /** - * A background task to start the watch dog player. - */ - private class StartWatchDogTask extends AsyncTask<Void, Void, Void> { - @Override - protected Void doInBackground(Void... voids) { - synchronized (mLock) { - if (mPlayer != null || mRequestCount == 0) return null; - try { - mPlayer = MediaPlayer.create(mContext, R.raw.empty); - } catch (IllegalStateException e) { - Log.e(TAG, "Exception happens while creating the watch dog player.", e); - } catch (RuntimeException e) { - Log.e(TAG, "Exception happens while creating the watch dog player.", e); - } - if (mPlayer == null) { - Log.e(TAG, "Unable to create watch dog player, treat it as server crash."); - onMediaServerCrash(); - } else { - mPlayer.setOnErrorListener(MediaThrottler.this); - } - } - return null; - } - } - - /** - * Called to request the permission to decode media data. - * - * @return true if the request is permitted, or false otherwise. - */ - @CalledByNative - private boolean requestDecoderResources() { - synchronized (mLock) { - long currentTime = SystemClock.elapsedRealtime(); - if (mLastCrashTime != UNKNOWN_LAST_SERVER_CRASH_TIME - && (currentTime - mLastCrashTime < SERVER_CRASH_INTERVAL_THRESHOLD_IN_MILLIS) - && mServerCrashCount >= SERVER_CRASH_COUNT_THRESHOLD_FOR_THROTTLING) { - Log.e(TAG, "Request to decode media data denied due to throttling."); - return false; - } - mRequestCount++; - if (mRequestCount == 1 || mPlayer == null) { - mHandler.removeCallbacks(mDelayedReleaseRunnable); - mHandler.post(new Runnable() { - @Override - public void run() { - new StartWatchDogTask().execute(); - } - }); - } - } - return true; - } - - /** - * Called to signal that a decode request has been completed. - */ - @CalledByNative - private void onDecodeRequestFinished() { - synchronized (mLock) { - mRequestCount--; - if (mRequestCount == 0) { - // Don't release the watch dog immediately, there could be a - // number of small requests coming together. - prepareToStopWatchDog(); - } - } - } - - /** - * Posts a delayed task to stop the watch dog player. - */ - private void prepareToStopWatchDog() { - mHandler.postDelayed(mDelayedReleaseRunnable, RELEASE_WATCH_DOG_PLAYER_DELAY_IN_MILLIS); - } - - @Override - public boolean onError(MediaPlayer mp, int what, int extra) { - if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) { - synchronized (mLock) { - onMediaServerCrash(); - } - } - return true; - } - - /** - * Called when media server crashes. - */ - private void onMediaServerCrash() { - assert Thread.holdsLock(mLock); - long currentTime = SystemClock.elapsedRealtime(); - if (mLastCrashTime != UNKNOWN_LAST_SERVER_CRASH_TIME - && (currentTime - mLastCrashTime < SERVER_CRASH_INTERVAL_THRESHOLD_IN_MILLIS)) { - mServerCrashCount++; - } else { - recordNumMediaServerCrashes(); - mServerCrashCount = 1; - } - mLastCrashTime = currentTime; - } - - /** - * Resets the MediaThrottler to its initial state so that subsequent requests - * will not be throttled. - */ - @CalledByNative - private void reset() { - synchronized (mLock) { - recordNumMediaServerCrashes(); - mServerCrashCount = 0; - mLastCrashTime = UNKNOWN_LAST_SERVER_CRASH_TIME; - } - } - - /** - * Records the number of consecutive media server crashes in UMA. - */ - private void recordNumMediaServerCrashes() { - assert Thread.holdsLock(mLock); - if (mServerCrashCount > 0) { - RecordHistogram.recordCountHistogram( - "Media.Android.NumMediaServerCrashes", mServerCrashCount); - } - } -}
diff --git a/content/public/app/mojo/content_renderer_manifest.json b/content/public/app/mojo/content_renderer_manifest.json index 40581d3..1f85972 100644 --- a/content/public/app/mojo/content_renderer_manifest.json +++ b/content/public/app/mojo/content_renderer_manifest.json
@@ -29,6 +29,7 @@ "device:time_zone_monitor", "device:vibration" ], + "network": [ "url_loader" ], "ui": [ "discardable_memory", "gpu_client"
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc index 3d69d32..6a368e18 100644 --- a/content/public/browser/web_contents_delegate.cc +++ b/content/public/browser/web_contents_delegate.cc
@@ -208,12 +208,6 @@ } #if defined(OS_ANDROID) -void WebContentsDelegate::RequestMediaDecodePermission( - WebContents* web_contents, - const base::Callback<void(bool)>& callback) { - callback.Run(false); -} - base::android::ScopedJavaLocalRef<jobject> WebContentsDelegate::GetContentVideoViewEmbedder() { return base::android::ScopedJavaLocalRef<jobject>();
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index bb2d849e..232d3a9 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -490,12 +490,6 @@ MediaStreamType type); #if defined(OS_ANDROID) - // Asks permission to decode media stream. After permission is determined, - // |callback| will be called with the result. - virtual void RequestMediaDecodePermission( - WebContents* web_contents, - const base::Callback<void(bool)>& callback); - // Creates a view embedding the video view. virtual base::android::ScopedJavaLocalRef<jobject> GetContentVideoViewEmbedder();
diff --git a/content/public/test/test_service.cc b/content/public/test/test_service.cc index 4e45f21..1763106 100644 --- a/content/public/test/test_service.cc +++ b/content/public/test/test_service.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" namespace content {
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 334cdba..a978544e 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -5197,6 +5197,7 @@ void RenderFrameImpl::OnCommitNavigation( const ResourceResponseHead& response, const GURL& stream_url, + mojo::DataPipeConsumerHandle handle, const CommonNavigationParams& common_params, const RequestNavigationParams& request_params) { CHECK(IsBrowserSideNavigationEnabled()); @@ -5205,6 +5206,7 @@ std::unique_ptr<StreamOverrideParameters> stream_override( new StreamOverrideParameters()); stream_override->stream_url = stream_url; + stream_override->consumer_handle = mojo::ScopedDataPipeConsumerHandle(handle); stream_override->response = response; stream_override->redirects = request_params.redirects; stream_override->redirect_responses = request_params.redirect_response;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 9fbf80e..c9abba4 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -52,6 +52,7 @@ #include "media/mojo/interfaces/remoting.mojom.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "ppapi/features/features.h" #include "services/service_manager/public/cpp/service_info.h" #include "services/service_manager/public/interfaces/connector.mojom.h" @@ -892,6 +893,7 @@ void OnPostMessageEvent(const FrameMsg_PostMessage_Params& params); void OnCommitNavigation(const ResourceResponseHead& response, const GURL& stream_url, + mojo::DataPipeConsumerHandle handle, const CommonNavigationParams& common_params, const RequestNavigationParams& request_params); void OnFailedNavigation(const CommonNavigationParams& common_params,
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 27eaf39..4ba0c48 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -306,13 +306,29 @@ blink::WebURLLoader* RendererBlinkPlatformImpl::CreateURLLoader() { ChildThreadImpl* child_thread = ChildThreadImpl::current(); - if (!url_loader_factory_ && child_thread) - child_thread->channel()->GetRemoteAssociatedInterface(&url_loader_factory_); + + mojom::URLLoaderFactory* factory = + url_loader_factory_ ? url_loader_factory_.get() + : network_service_url_loader_factory_.get(); + if (!factory && child_thread) { + bool network_service_enabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNetworkService); + if (network_service_enabled) { + connector_->BindInterface(mojom::kNetworkServiceName, + &network_service_url_loader_factory_); + factory = network_service_url_loader_factory_.get(); + } else { + child_thread->channel()->GetRemoteAssociatedInterface( + &url_loader_factory_); + factory = url_loader_factory_.get(); + } + } + // There may be no child thread in RenderViewTests. These tests can still use // data URLs to bypass the ResourceDispatcher. return new content::WebURLLoaderImpl( - child_thread ? child_thread->resource_dispatcher() : nullptr, - url_loader_factory_.get()); + child_thread ? child_thread->resource_dispatcher() : nullptr, factory); } blink::WebThread* RendererBlinkPlatformImpl::CurrentThread() {
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index f6adbef..19306dfd 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -304,6 +304,9 @@ mojom::URLLoaderFactoryAssociatedPtr url_loader_factory_; + // Only used when network service is enabled. + mojom::URLLoaderFactoryPtr network_service_url_loader_factory_; + DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl); };
diff --git a/content/test/gpu/gpu_tests/gpu_process_expectations.py b/content/test/gpu/gpu_tests/gpu_process_expectations.py index b459316..e8faff5 100644 --- a/content/test/gpu/gpu_tests/gpu_process_expectations.py +++ b/content/test/gpu/gpu_tests/gpu_process_expectations.py
@@ -19,7 +19,6 @@ # Chrome on Windows and Linux create a GPU process that uses SwiftShader # when using either --disable-gpu or a blacklisted GPU. - self.Skip('GpuProcess_no_gpu_process', ['win', 'debug'], bug=630728) self.Skip('GpuProcess_skip_gpu_process', ['win', 'linux'], bug=630728) # Currently SwiftShader is integrated only on Windows and Linux. Remove
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index 681236c..798ccc2 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -52,18 +52,3 @@ # TODO(jbauman): Re-enable when references images created. self.Fail('Pixel_DirectComposition_Video_*', ['win'], bug=704389) - - # TODO(xlai): Remove this after verifying reference images. - self.Fail('Pixel_OffscreenCanvasAccelerated2D', bug=706647) - self.Fail('Pixel_OffscreenCanvasAccelerated2DWorker', bug=706647) - self.Fail('Pixel_OffscreenCanvasUnaccelerated2D', bug=706647) - self.Fail('Pixel_OffscreenCanvasUnaccelerated2DWorker', bug=706647) - self.Fail('Pixel_OffscreenCanvasUnaccelerated2DGPUCompositing', - bug=706647) - self.Fail('Pixel_OffscreenCanvasUnaccelerated2DGPUCompositingWorker', - bug=706647) - self.Fail('Pixel_OffscreenCanvasWebGLDefault', bug=706647) - self.Fail('Pixel_OffscreenCanvasWebGLDefaultWorker', bug=706647) - self.Fail('Pixel_OffscreenCanvasWebGLSoftwareCompositing', bug=706647) - self.Fail('Pixel_OffscreenCanvasWebGLSoftwareCompositingWorker', - bug=706647)
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc index 026778e..0ba5b7e 100644 --- a/content/test/test_navigation_url_loader.cc +++ b/content/test/test_navigation_url_loader.cc
@@ -56,9 +56,9 @@ const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body, std::unique_ptr<NavigationData> navigation_data) { - delegate_->OnResponseStarted(response, std::move(body), SSLStatus(), - std::move(navigation_data), GlobalRequestID(), - false, false); + delegate_->OnResponseStarted( + response, std::move(body), mojo::ScopedDataPipeConsumerHandle(), + SSLStatus(), std::move(navigation_data), GlobalRequestID(), false, false); } TestNavigationURLLoader::~TestNavigationURLLoader() {}
diff --git a/content/test/test_navigation_url_loader_delegate.cc b/content/test/test_navigation_url_loader_delegate.cc index 443749b..1d74335d 100644 --- a/content/test/test_navigation_url_loader_delegate.cc +++ b/content/test/test_navigation_url_loader_delegate.cc
@@ -44,6 +44,7 @@ void TestNavigationURLLoaderDelegate::ReleaseBody() { body_.reset(); + handle_.reset(); } void TestNavigationURLLoaderDelegate::OnRequestRedirected( @@ -58,6 +59,7 @@ void TestNavigationURLLoaderDelegate::OnResponseStarted( const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body, + mojo::ScopedDataPipeConsumerHandle consumer_handle, const SSLStatus& ssl_status, std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, @@ -65,6 +67,7 @@ bool is_stream) { response_ = response; body_ = std::move(body); + handle_ = std::move(consumer_handle); if (response_started_) response_started_->Quit(); }
diff --git a/content/test/test_navigation_url_loader_delegate.h b/content/test/test_navigation_url_loader_delegate.h index ddc1402..1916f3f3 100644 --- a/content/test/test_navigation_url_loader_delegate.h +++ b/content/test/test_navigation_url_loader_delegate.h
@@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "content/browser/loader/navigation_url_loader_delegate.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "net/url_request/redirect_info.h" namespace base { @@ -56,6 +57,7 @@ const scoped_refptr<ResourceResponse>& response) override; void OnResponseStarted(const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body, + mojo::ScopedDataPipeConsumerHandle consumer_handle, const SSLStatus& ssl_status, std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, @@ -69,6 +71,7 @@ scoped_refptr<ResourceResponse> redirect_response_; scoped_refptr<ResourceResponse> response_; std::unique_ptr<StreamHandle> body_; + mojo::ScopedDataPipeConsumerHandle handle_; int net_error_; int on_request_handled_counter_;
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index cd75e627..6c0bb013 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -30,7 +30,8 @@ const RequestNavigationParams& request_params) { // PlzNavigate if (IsBrowserSideNavigationEnabled()) { - OnCommitNavigation(ResourceResponseHead(), GURL(), common_params, + OnCommitNavigation(ResourceResponseHead(), GURL(), + mojo::DataPipeConsumerHandle(), common_params, request_params); } else { OnNavigate(common_params, start_params, request_params);
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc index a1c8336..73c2cf8 100644 --- a/content/utility/utility_service_factory.cc +++ b/content/utility/utility_service_factory.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "content/child/child_process.h" #include "content/network/network_service.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" @@ -60,6 +61,7 @@ switches::kEnableNetworkService)) { ServiceInfo network_info; network_info.factory = base::Bind(&NetworkService::CreateNetworkService); + network_info.task_runner = ChildProcess::current()->io_task_runner(); services->insert( std::make_pair(content::mojom::kNetworkServiceName, network_info)); }
diff --git a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadDevice.java b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadDevice.java index f00f558..ca6e57e 100644 --- a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadDevice.java +++ b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadDevice.java
@@ -76,7 +76,7 @@ mAxes[i++] = axis; } } - mMappings = GamepadMappings.getMappings(mDeviceName, mAxes); + mMappings = GamepadMappings.getMappings(inputDevice, mAxes); } /**
diff --git a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java index c93f8d9a0..9b2825fa 100644 --- a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java +++ b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
@@ -4,6 +4,9 @@ package org.chromium.device.gamepad; +import android.annotation.TargetApi; +import android.os.Build; +import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; @@ -26,7 +29,38 @@ @VisibleForTesting static final String AMAZON_FIRE_DEVICE_NAME = "Amazon Fire Game Controller"; - public static GamepadMappings getMappings(String deviceName, int[] axes) { + @VisibleForTesting + static final int PS_DUALSHOCK_4_VENDOR_ID = 1356; + @VisibleForTesting + static final int PS_DUALSHOCK_4_PRODUCT_ID = 1476; + @VisibleForTesting + static final int PS_DUALSHOCK_4_SLIM_PRODUCT_ID = 2508; + + public static GamepadMappings getMappings(InputDevice device, int[] axes) { + GamepadMappings mappings = null; + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + mappings = getMappings(device.getProductId(), device.getVendorId()); + } + if (mappings == null) mappings = getMappings(device.getName()); + if (mappings == null) mappings = new UnknownGamepadMappings(axes); + return mappings; + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + @VisibleForTesting + static GamepadMappings getMappings(int productId, int vendorId) { + // Device name of a PS4 gamepad is "Wireless Controller". This is not reliably unique + // so we better go by the product and vendor ids. + if (vendorId == PS_DUALSHOCK_4_VENDOR_ID + && (productId == PS_DUALSHOCK_4_PRODUCT_ID + || productId == PS_DUALSHOCK_4_SLIM_PRODUCT_ID)) { + return new PS4GamepadMappings(); + } + return null; + } + + @VisibleForTesting + static GamepadMappings getMappings(String deviceName) { if (deviceName.startsWith(NVIDIA_SHIELD_DEVICE_NAME_PREFIX) || deviceName.equals(MICROSOFT_XBOX_PAD_DEVICE_NAME)) { return new XboxCompatibleGamepadMappings(); @@ -37,7 +71,11 @@ } else if (deviceName.equals(AMAZON_FIRE_DEVICE_NAME)) { return new AmazonFireGamepadMappings(); } + return null; + } + @VisibleForTesting + static GamepadMappings getUnknownGamepadMappings(int[] axes) { return new UnknownGamepadMappings(axes); } @@ -244,6 +282,46 @@ } } + static class PS4GamepadMappings extends GamepadMappings { + // Scale input from [-1, 1] to [0, 1] uniformly. + private static float scaleRxRy(float input) { + return 1.f - ((1.f - input) / 2.f); + } + + /** + * Method for mapping PS4 gamepad axis and button values + * to standard gamepad button and axes values. + */ + @Override + public void mapToStandardGamepad( + float[] mappedAxes, float[] mappedButtons, float[] rawAxes, float[] rawButtons) { + float a = rawButtons[KeyEvent.KEYCODE_BUTTON_A]; + float b = rawButtons[KeyEvent.KEYCODE_BUTTON_B]; + float c = rawButtons[KeyEvent.KEYCODE_BUTTON_C]; + float x = rawButtons[KeyEvent.KEYCODE_BUTTON_X]; + mappedButtons[CanonicalButtonIndex.PRIMARY] = b; + mappedButtons[CanonicalButtonIndex.SECONDARY] = c; + mappedButtons[CanonicalButtonIndex.TERTIARY] = a; + mappedButtons[CanonicalButtonIndex.QUATERNARY] = x; + + float y = rawButtons[KeyEvent.KEYCODE_BUTTON_Y]; + float z = rawButtons[KeyEvent.KEYCODE_BUTTON_Z]; + mappedButtons[CanonicalButtonIndex.LEFT_SHOULDER] = y; + mappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER] = z; + + float rx = rawAxes[MotionEvent.AXIS_RX]; + float ry = rawAxes[MotionEvent.AXIS_RY]; + mappedButtons[CanonicalButtonIndex.LEFT_TRIGGER] = scaleRxRy(rx); + mappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER] = scaleRxRy(ry); + + mapHatAxisToDpadButtons(mappedButtons, rawAxes); + mapCommonStartSelectMetaButtons(mappedButtons, rawButtons); + + mapXYAxes(mappedAxes, rawAxes); + mapZAndRZAxesToRightStick(mappedAxes, rawAxes); + } + } + private static class SamsungEIGP20GamepadMappings extends GamepadMappings { /**
diff --git a/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java b/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java index 6ed2941..fbbc33a 100644 --- a/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java +++ b/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java
@@ -62,8 +62,8 @@ @Test @Feature({"Gamepad"}) public void testShieldGamepadMappings() throws Exception { - GamepadMappings mappings = GamepadMappings.getMappings( - GamepadMappings.NVIDIA_SHIELD_DEVICE_NAME_PREFIX, null); + GamepadMappings mappings = + GamepadMappings.getMappings(GamepadMappings.NVIDIA_SHIELD_DEVICE_NAME_PREFIX); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertShieldGamepadMappings(); @@ -72,8 +72,8 @@ @Test @Feature({"Gamepad"}) public void testXBox360GamepadMappings() throws Exception { - GamepadMappings mappings = GamepadMappings.getMappings( - GamepadMappings.MICROSOFT_XBOX_PAD_DEVICE_NAME, null); + GamepadMappings mappings = + GamepadMappings.getMappings(GamepadMappings.MICROSOFT_XBOX_PAD_DEVICE_NAME); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertShieldGamepadMappings(); @@ -82,8 +82,8 @@ @Test @Feature({"Gamepad"}) public void testPS3SixAxisGamepadMappings() throws Exception { - GamepadMappings mappings = GamepadMappings.getMappings( - GamepadMappings.PS3_SIXAXIS_DEVICE_NAME, null); + GamepadMappings mappings = + GamepadMappings.getMappings(GamepadMappings.PS3_SIXAXIS_DEVICE_NAME); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY], @@ -109,8 +109,8 @@ @Test @Feature({"Gamepad"}) public void testSamsungEIGP20GamepadMappings() throws Exception { - GamepadMappings mappings = GamepadMappings.getMappings( - GamepadMappings.SAMSUNG_EI_GP20_DEVICE_NAME, null); + GamepadMappings mappings = + GamepadMappings.getMappings(GamepadMappings.SAMSUNG_EI_GP20_DEVICE_NAME); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertMappedCommonXYABButtons(); @@ -128,8 +128,8 @@ @Test @Feature({"Gamepad"}) public void testAmazonFireGamepadMappings() throws Exception { - GamepadMappings mappings = GamepadMappings.getMappings( - GamepadMappings.AMAZON_FIRE_DEVICE_NAME, null); + GamepadMappings mappings = + GamepadMappings.getMappings(GamepadMappings.AMAZON_FIRE_DEVICE_NAME); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertMappedCommonXYABButtons(); @@ -158,7 +158,7 @@ MotionEvent.AXIS_HAT_Y }; - GamepadMappings mappings = GamepadMappings.getMappings("", axes); + GamepadMappings mappings = GamepadMappings.getUnknownGamepadMappings(axes); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertMappedCommonXYABButtons(); @@ -187,7 +187,7 @@ MotionEvent.AXIS_HAT_Y }; - GamepadMappings mappings = GamepadMappings.getMappings("", axes); + GamepadMappings mappings = GamepadMappings.getUnknownGamepadMappings(axes); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertMappedCommonXYABButtons(); @@ -216,7 +216,7 @@ MotionEvent.AXIS_HAT_Y }; - GamepadMappings mappings = GamepadMappings.getMappings("", axes); + GamepadMappings mappings = GamepadMappings.getUnknownGamepadMappings(axes); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertMappedCommonXYABButtons(); @@ -241,7 +241,7 @@ MotionEvent.AXIS_RZ }; - GamepadMappings mappings = GamepadMappings.getMappings("", axes); + GamepadMappings mappings = GamepadMappings.getUnknownGamepadMappings(axes); mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); assertMappedCommonXYABButtons(); @@ -256,6 +256,42 @@ assertMapping(); } + @Test + @Feature({"Gamepad"}) + public void testPS4GamepadMappings() throws Exception { + GamepadMappings mappings = + GamepadMappings.getMappings(GamepadMappings.PS_DUALSHOCK_4_PRODUCT_ID, + GamepadMappings.PS_DUALSHOCK_4_VENDOR_ID); + mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons); + + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY], + mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE); + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY], + mRawButtons[KeyEvent.KEYCODE_BUTTON_C], ERROR_TOLERANCE); + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY], + mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE); + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY], + mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE); + + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER], + mRawButtons[KeyEvent.KEYCODE_BUTTON_Z], ERROR_TOLERANCE); + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER], + mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE); + + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER], + mRawAxes[MotionEvent.AXIS_RX], ERROR_TOLERANCE); + Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER], + mRawAxes[MotionEvent.AXIS_RY], ERROR_TOLERANCE); + + assertMappedCommonStartSelectMetaButtons(); + assertMappedXYAxes(); + assertMappedHatAxisToDpadButtons(); + assertMappedZAndRZAxesToRightStick(); + + expectNoThumbstickButtons(); + assertMapping(); + } + /** * Asserts that the current gamepad mapping being tested matches the shield mappings. */ @@ -281,6 +317,11 @@ mUnmappedButtons.set(CanonicalButtonIndex.META); } + public void expectNoThumbstickButtons() { + mUnmappedButtons.set(CanonicalButtonIndex.LEFT_THUMBSTICK); + mUnmappedButtons.set(CanonicalButtonIndex.RIGHT_THUMBSTICK); + } + public void assertMapping() { for (int i = 0; i < mMappedAxes.length; i++) { if (mUnmappedAxes.get(i)) {
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 0b2a86d..833b985a 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -884,8 +884,8 @@ mailbox_manager->PullTextureUpdates(sync_token); waiting_for_sync_point_ = false; executor_->SetScheduled(true); - QueueTask(false, base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, - gpu_thread_weak_ptr_, last_put_offset_)); + service_->ScheduleTask(base::Bind( + &InProcessCommandBuffer::ProcessTasksOnGpuThread, gpu_thread_weak_ptr_)); } void InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread() {
diff --git a/ios/chrome/browser/native_app_launcher/BUILD.gn b/ios/chrome/browser/native_app_launcher/BUILD.gn index 813ad6d..76ecaa68 100644 --- a/ios/chrome/browser/native_app_launcher/BUILD.gn +++ b/ios/chrome/browser/native_app_launcher/BUILD.gn
@@ -68,6 +68,7 @@ "//ios/chrome/browser/net", "//ios/chrome/browser/store_kit", "//ios/chrome/browser/tabs", + "//ios/chrome/browser/web:web", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/native_app_launcher", "//ios/public/provider/chrome/browser/signin",
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_util.h b/ios/chrome/browser/native_app_launcher/native_app_navigation_util.h index fd44625..36c4fbf 100644 --- a/ios/chrome/browser/native_app_launcher/native_app_navigation_util.h +++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_util.h
@@ -13,7 +13,8 @@ // Returns whether the current state is arrived at via a "link navigation" in // the sense of Native App Launcher, i.e. a navigation caused by an explicit -// user action in the rectangle of the web content area. +// user action in the rectangle of the web content area. |web_state| must not +// be nullptr. bool IsLinkNavigation(web::WebState* web_state); } // namespace native_app_launcher
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm b/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm index a99d66b..1e2298e 100644 --- a/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm +++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm
@@ -4,9 +4,8 @@ #include "ios/chrome/browser/native_app_launcher/native_app_navigation_util.h" -#include "base/logging.h" -#include "ios/web/public/navigation_item.h" -#include "ios/web/public/navigation_manager.h" +#import "ios/chrome/browser/web/navigation_manager_util.h" +#import "ios/web/public/navigation_item.h" #import "ios/web/public/web_state/web_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -16,27 +15,15 @@ namespace native_app_launcher { bool IsLinkNavigation(web::WebState* web_state) { - web::NavigationManager* navigationManager = web_state->GetNavigationManager(); - DCHECK(navigationManager); - int index = navigationManager->GetLastCommittedItemIndex(); - // Walks backward on the navigation items list looking for the first item - // that is not the result of a redirect. Check if user arrived at that - // via link click or a suggestion on the UI. - while (index >= 0) { - web::NavigationItem* item = navigationManager->GetItemAtIndex(index); - DCHECK(item); - ui::PageTransition currentTransition = item->GetTransitionType(); - // Checks non-redirect entries for transitions that are either links or - // bookmarks. - if ((currentTransition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) == 0) { - return PageTransitionCoreTypeIs(currentTransition, - ui::PAGE_TRANSITION_LINK) || - PageTransitionCoreTypeIs(currentTransition, - ui::PAGE_TRANSITION_AUTO_BOOKMARK); - } - --index; - } - return false; + DCHECK(web_state); + web::NavigationItem* item = + GetLastCommittedNonRedirectedItem(web_state->GetNavigationManager()); + if (!item) + return false; + ui::PageTransition transition = item->GetTransitionType(); + return PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK) || + PageTransitionCoreTypeIs(transition, + ui::PAGE_TRANSITION_AUTO_BOOKMARK); } } // namespace native_app_launcher
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_util_unittest.mm b/ios/chrome/browser/native_app_launcher/native_app_navigation_util_unittest.mm index d329f0a..b36ae902 100644 --- a/ios/chrome/browser/native_app_launcher/native_app_navigation_util_unittest.mm +++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_util_unittest.mm
@@ -72,15 +72,15 @@ // the first non-redirect entry. TEST_F(NativeAppNavigationUtilsTest, TestHasLinkClickedWithRedirect) { AddItem("http://foo.com/page0", ui::PAGE_TRANSITION_LINK); - AddItem("http://bar.com/page1", ui::PAGE_TRANSITION_SERVER_REDIRECT); - AddItem("http://zap.com/page2", ui::PAGE_TRANSITION_SERVER_REDIRECT); + AddItem("http://bar.com/page1", ui::PAGE_TRANSITION_CLIENT_REDIRECT); + AddItem("http://zap.com/page2", ui::PAGE_TRANSITION_CLIENT_REDIRECT); EXPECT_TRUE(native_app_launcher::IsLinkNavigation(web_state())); } // The first non-redirect entry is tested. Earlier redirects do not matter. TEST_F(NativeAppNavigationUtilsTest, TestTypedUrlWithRedirectEarlier) { AddItem("http://foo.com/page0", ui::PAGE_TRANSITION_LINK); - AddItem("http://bar.com/page1", ui::PAGE_TRANSITION_SERVER_REDIRECT); + AddItem("http://bar.com/page1", ui::PAGE_TRANSITION_CLIENT_REDIRECT); AddItem("http://blah.com/page2", ui::PAGE_TRANSITION_TYPED); EXPECT_FALSE(native_app_launcher::IsLinkNavigation(web_state())); }
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 222276a..d8c0b03 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -563,8 +563,7 @@ @property(nonatomic, assign, readonly, getter=isToolbarOnScreen) BOOL toolbarOnScreen; // Whether a new tab animation is occurring. -@property(nonatomic, assign, readonly, getter=isInNewTabAnimation) - BOOL inNewTabAnimation; +@property(nonatomic, assign, getter=isInNewTabAnimation) BOOL inNewTabAnimation; // Whether BVC prefers to hide the status bar. This value is used to determine // the response from the |prefersStatusBarHidden| method. @property(nonatomic, assign) BOOL hideStatusBar; @@ -677,7 +676,7 @@ // Updates the toolbar display based on the current tab. - (void)updateToolbar; // Updates |dialogPresenter|'s |active| property to account for the BVC's -// |active| and |visible| properties. +// |active|, |visible|, and |inNewTabAnimation| properties. - (void)updateDialogPresenterActiveState; // Dismisses popups and modal dialogs that are displayed above the BVC upon size // changes (e.g. rotation, resizing,…) or when the accessibility escape gesture @@ -1156,6 +1155,13 @@ return [self headerHeight] - [self currentHeaderOffset] > 0; } +- (void)setInNewTabAnimation:(BOOL)inNewTabAnimation { + if (_inNewTabAnimation == inNewTabAnimation) + return; + _inNewTabAnimation = inNewTabAnimation; + [self updateDialogPresenterActiveState]; +} + - (BOOL)isInNewTabAnimation { return _inNewTabAnimation; } @@ -1577,7 +1583,7 @@ } }; - _inNewTabAnimation = YES; + self.inNewTabAnimation = YES; if (!inBackground) { UIView* animationParentView = _contentArea; // Create the new page image, and load with the new tab page snapshot. @@ -1601,7 +1607,7 @@ newPage.frame.size.height - newPage.image.size.height, origin, _isOffTheRecord, NULL, ^{ [newPage removeFromSuperview]; - _inNewTabAnimation = NO; + self.inNewTabAnimation = NO; // Use the model's currentTab here because it is possible that it can // be reset to a new value before the new Tab animation finished (e.g. // if another Tab shows a dialog via |dialogPresenter|). However, that @@ -1640,7 +1646,7 @@ topCard, [_contentArea frame], IsPortrait(), ^{ [background removeFromSuperview]; [topCard removeFromSuperview]; - _inNewTabAnimation = NO; + self.inNewTabAnimation = NO; // Resnapshot the top card if it has its own toolbar, as the toolbar // will be captured in the new tab animation, but isn't desired for // the stack view snapshots. @@ -1891,7 +1897,7 @@ [self ensureViewCreated]; DCHECK(_contentArea); - if (!_inNewTabAnimation) { + if (!self.inNewTabAnimation) { // Hide findbar. |updateToolbar| will restore the findbar later. [self hideFindBarWithAnimation:NO]; @@ -1964,7 +1970,8 @@ } - (void)updateDialogPresenterActiveState { - self.dialogPresenter.active = self.active && self.viewVisible; + self.dialogPresenter.active = + self.active && self.viewVisible && !self.inNewTabAnimation; } - (void)dismissPopups { @@ -2172,7 +2179,7 @@ [self displayTab:tab isNewSelection:YES]; - if (_expectingForegroundTab && !_inNewTabAnimation) { + if (_expectingForegroundTab && !self.inNewTabAnimation) { // Now that the new tab has been displayed, return to normal. Rather than // keep a reference to the previous tab, just turn off preview mode for all // tabs (since doing so is a no-op for the tabs that don't have it set). @@ -4483,7 +4490,7 @@ - (void)startVoiceSearch { // Delay Voice Search until new tab animations have finished. - if (_inNewTabAnimation) { + if (self.inNewTabAnimation) { _startVoiceSearchAfterNewTabAnimation = YES; return; }
diff --git a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm index 26f1cd2..5e81cc9 100644 --- a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm +++ b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
@@ -7,19 +7,23 @@ #import <XCTest/XCTest.h> #import "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/dialogs/dialog_presenter.h" #include "ios/chrome/browser/ui/tools_menu/tools_menu_constants.h" #include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/test/app/chrome_test_util.h" +#import "ios/chrome/test/earl_grey/chrome_actions.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/testing/earl_grey/matchers.h" #import "ios/testing/wait_util.h" #import "ios/web/public/test/http_server.h" #import "ios/web/public/test/http_server_util.h" +#include "ios/web/public/test/url_test_util.h" #include "ios/web/public/web_state/web_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -30,6 +34,7 @@ #endif using chrome_test_util::NavigationBarDoneButton; +using web::test::HttpServer; namespace { @@ -140,11 +145,31 @@ return nil; } -// Const for an http server that returns a blank document. +// HTTP server constants. + +// URL and response for a blank document. const char* kJavaScriptTestURL = "http://jsalerts"; const char* kJavaScriptTestResponse = "<!DOCTYPE html><html><body></body></html>"; +// URL and response for a page with an onload alert. +const char* kOnLoadAlertURL = "http://onloadalert"; +const char* kOnLoadAlertResponse = + "<!DOCTYPE html><html><body onload=\"alert('alert')\"></body></html>"; + +// URL and response for a page with a link to |kOnLoadAlertURL|. +const char* kPageWithLinkURL = "http://pagewithlink"; +const char* kPageWithLinkResponseFormat = + "<!DOCTYPE html><html><body><a id=\"%s\" href=\"%s\">%s</a></body></html>"; +const char* kPageWithLinkText = "LINK TO ONLOAD ALERT PAGE"; +const char* kLinkID = "link-id"; +std::string GetPageWithLinkResponse() { + return base::SysNSStringToUTF8([NSString + stringWithFormat:@(kPageWithLinkResponseFormat), kLinkID, + HttpServer::MakeUrl(kOnLoadAlertURL).spec().c_str(), + kPageWithLinkText]); +} + // Waits until |string| is displayed on the web view. void WaitForWebDisplay(const std::string& string) { id<GREYMatcher> response1Matcher = @@ -176,13 +201,13 @@ return !error; }; GREYAssert(testing::WaitUntilConditionOrTimeout( - testing::kWaitForJSCompletionTimeout, condition), + testing::kWaitForUIElementTimeout, condition), @"Alert with title was not present: %@", alert_label); } void WaitForJavaScripDialogToBeShown() { NSString* alert_label = [DialogPresenter - localizedTitleForJavaScriptAlertFromPage:web::test::HttpServer::MakeUrl( + localizedTitleForJavaScriptAlertFromPage:HttpServer::MakeUrl( kJavaScriptTestURL)]; WaitForAlertToBeShown(alert_label); } @@ -207,7 +232,7 @@ ConditionBlock condition = ^{ NSError* error = nil; NSString* alertLabel = [DialogPresenter - localizedTitleForJavaScriptAlertFromPage:web::test::HttpServer::MakeUrl( + localizedTitleForJavaScriptAlertFromPage:HttpServer::MakeUrl( kJavaScriptTestURL)]; id<GREYMatcher> titleLabel = chrome_test_util::StaticTextWithAccessibilityLabel(alertLabel); @@ -254,9 +279,13 @@ } // namespace -@interface JavaScriptDialogTestCase : ChromeTestCase { - GURL _URL; -} +@interface JavaScriptDialogTestCase : ChromeTestCase + +// Loads the blank test page at kJavaScriptTestURL. +- (void)loadBlankTestPage; + +// Loads a page with a link to kOnLoadAlertURL. +- (void)loadPageWithLink; @end @@ -264,17 +293,11 @@ - (void)setUp { [super setUp]; - _URL = web::test::HttpServer::MakeUrl(kJavaScriptTestURL); std::map<GURL, std::string> responses; - responses[web::test::HttpServer::MakeUrl(kJavaScriptTestURL)] = - kJavaScriptTestResponse; + responses[HttpServer::MakeUrl(kJavaScriptTestURL)] = kJavaScriptTestResponse; + responses[HttpServer::MakeUrl(kPageWithLinkURL)] = GetPageWithLinkResponse(); + responses[HttpServer::MakeUrl(kOnLoadAlertURL)] = kOnLoadAlertResponse; web::test::SetUpSimpleHttpServer(responses); - - [ChromeEarlGrey loadURL:_URL]; - id<GREYMatcher> response2Matcher = - chrome_test_util::WebViewContainingText(std::string()); - [[EarlGrey selectElementWithMatcher:response2Matcher] - assertWithMatcher:grey_notNil()]; } - (void)tearDown { @@ -297,6 +320,18 @@ [super tearDown]; } +#pragma mark - Utility + +- (void)loadBlankTestPage { + [ChromeEarlGrey loadURL:HttpServer::MakeUrl(kJavaScriptTestURL)]; + WaitForWebDisplay(std::string()); +} + +- (void)loadPageWithLink { + [ChromeEarlGrey loadURL:HttpServer::MakeUrl(kPageWithLinkURL)]; + WaitForWebDisplay(kPageWithLinkText); +} + #pragma mark - Tests // Tests that an alert is shown, and that the completion block is called. @@ -308,7 +343,8 @@ @"correctly."); #endif - // Show an alert. + // Load the blank test page and show an alert. + [self loadBlankTestPage]; ShowJavaScriptDialog(JavaScriptAlertType::ALERT); // Tap the OK button. @@ -328,7 +364,8 @@ @"correctly."); #endif - // Show a confirmation dialog. + // Load the blank test page and show a confirmation dialog. + [self loadBlankTestPage]; ShowJavaScriptDialog(JavaScriptAlertType::CONFIRMATION); // Tap the OK button. @@ -348,7 +385,8 @@ @"correctly."); #endif - // Show a confirmation dialog. + // Load the blank test page and show a confirmation dialog. + [self loadBlankTestPage]; ShowJavaScriptDialog(JavaScriptAlertType::CONFIRMATION); // Tap the Cancel button. @@ -368,7 +406,8 @@ @"correctly."); #endif - // Show a prompt dialog. + // Load the blank test page and show a prompt dialog. + [self loadBlankTestPage]; ShowJavaScriptDialog(JavaScriptAlertType::PROMPT); // Enter text into text field. @@ -391,7 +430,8 @@ @"correctly."); #endif - // Show a prompt dialog. + // Load the blank test page and show a prompt dialog. + [self loadBlankTestPage]; ShowJavaScriptDialog(JavaScriptAlertType::PROMPT); // Enter text into text field. @@ -406,7 +446,8 @@ // Tests that JavaScript alerts that are shown in a loop can be suppressed. - (void)testShowJavaScriptAlertLoop { - // Evaluate JavaScript to show alerts in an endless loop. + // Load the blank test page and show alerts in a loop. + [self loadBlankTestPage]; web::WebState* webState = chrome_test_util::GetCurrentWebState(); NSString* script = GetJavaScriptAlertLoopScript(); webState->ExecuteJavaScript(base::SysNSStringToUTF16(script)); @@ -442,6 +483,9 @@ @"correctly."); #endif + // Load the blank test page. + [self loadBlankTestPage]; + // Show settings. [ChromeEarlGreyUI openToolsMenu]; [[EarlGrey @@ -481,6 +525,9 @@ @"correctly."); #endif + // Load the blank test page. + [self loadBlankTestPage]; + [ChromeEarlGreyUI openShareMenu]; // Copy URL, dismissing the share menu. @@ -499,4 +546,42 @@ WaitForWebDisplay(kAlertResultBody); } +// Tests that an alert is presented after a new tab animation is finished. +- (void)testShowJavaScriptAfterNewTabAnimation { +// TODO(crbug.com/663026): Reenable the test for devices. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Disabled for devices because existing system " + @"alerts would prevent app alerts to present " + @"correctly."); +#endif + + // Load the test page with a link to kOnLoadAlertURL and long tap on the link. + [self loadPageWithLink]; + id<GREYMatcher> webViewMatcher = + chrome_test_util::WebViewContainingText(std::string(kPageWithLinkText)); + [[EarlGrey selectElementWithMatcher:webViewMatcher] + performAction:chrome_test_util::LongPressElementForContextMenu( + kLinkID, true /* menu should appear */)]; + + // Tap on the "Open In New Tab" button. + id<GREYMatcher> newTabMatcher = testing::ContextMenuItemWithText( + l10n_util::GetNSStringWithFixup(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)); + [[EarlGrey selectElementWithMatcher:newTabMatcher] performAction:grey_tap()]; + + // Wait for the alert to be shown. + NSString* alertLabel = [DialogPresenter + localizedTitleForJavaScriptAlertFromPage:HttpServer::MakeUrl( + kJavaScriptTestURL)]; + WaitForAlertToBeShown(alertLabel); + + // Verify that the omnibox shows the correct URL when the dialog is visible. + GURL onloadURL = HttpServer::MakeUrl(kOnLoadAlertURL); + std::string title = base::UTF16ToUTF8(web::GetDisplayTitleForUrl(onloadURL)); + [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(title)] + assertWithMatcher:grey_notNil()]; + + // Close the alert. + TapOK(); +} + @end
diff --git a/ipc/ipc_mojo_param_traits.cc b/ipc/ipc_mojo_param_traits.cc index 189af35..12aaace 100644 --- a/ipc/ipc_mojo_param_traits.cc +++ b/ipc/ipc_mojo_param_traits.cc
@@ -5,6 +5,7 @@ #include "ipc/ipc_mojo_param_traits.h" #include "ipc/ipc_message_utils.h" +#include "ipc/ipc_mojo_handle_attachment.h" #include "ipc/ipc_mojo_message_helper.h" namespace IPC { @@ -47,4 +48,62 @@ l->append(")"); } +void ParamTraits<mojo::DataPipeConsumerHandle>::GetSize( + base::PickleSizer* sizer, + const param_type& p) { + GetParamSize(sizer, p.is_valid()); + if (p.is_valid()) + sizer->AddAttachment(); +} + +void ParamTraits<mojo::DataPipeConsumerHandle>::Write(base::Pickle* m, + const param_type& p) { + WriteParam(m, p.is_valid()); + if (!p.is_valid()) + return; + + m->WriteAttachment(new internal::MojoHandleAttachment( + mojo::ScopedHandle::From(mojo::ScopedDataPipeConsumerHandle(p)))); +} + +bool ParamTraits<mojo::DataPipeConsumerHandle>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r) { + bool is_valid; + if (!ReadParam(m, iter, &is_valid)) + return false; + if (!is_valid) + return true; + + scoped_refptr<base::Pickle::Attachment> attachment; + if (!m->ReadAttachment(iter, &attachment)) { + DLOG(ERROR) << "Failed to read attachment for message pipe."; + return false; + } + + MessageAttachment::Type type = + static_cast<MessageAttachment*>(attachment.get())->GetType(); + if (type != MessageAttachment::Type::MOJO_HANDLE) { + DLOG(ERROR) << "Unexpected attachment type:" << type; + return false; + } + + mojo::ScopedDataPipeConsumerHandle handle; + handle.reset(mojo::DataPipeConsumerHandle( + static_cast<internal::MojoHandleAttachment*>(attachment.get()) + ->TakeHandle() + .release() + .value())); + DCHECK(handle.is_valid()); + *r = handle.release(); + return true; +} + +void ParamTraits<mojo::DataPipeConsumerHandle>::Log(const param_type& p, + std::string* l) { + l->append("mojo::DataPipeConsumerHandle("); + LogParam(p.value(), l); + l->append(")"); +} + } // namespace IPC
diff --git a/ipc/ipc_mojo_param_traits.h b/ipc/ipc_mojo_param_traits.h index 39be43e..a4d0228c 100644 --- a/ipc/ipc_mojo_param_traits.h +++ b/ipc/ipc_mojo_param_traits.h
@@ -9,6 +9,7 @@ #include "ipc/ipc_export.h" #include "ipc/ipc_param_traits.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/message_pipe.h" namespace base { @@ -29,6 +30,17 @@ static void Log(const param_type& p, std::string* l); }; +template <> +struct IPC_EXPORT ParamTraits<mojo::DataPipeConsumerHandle> { + typedef mojo::DataPipeConsumerHandle param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r); + static void Log(const param_type& p, std::string* l); +}; + } // namespace IPC #endif // IPC_IPC_MOJO_PARAM_TRAITS_H_
diff --git a/mash/catalog_viewer/catalog_viewer.cc b/mash/catalog_viewer/catalog_viewer.cc index aab46a79..2b817c59 100644 --- a/mash/catalog_viewer/catalog_viewer.cc +++ b/mash/catalog_viewer/catalog_viewer.cc
@@ -15,7 +15,6 @@ #include "mojo/public/cpp/bindings/binding.h" #include "services/catalog/public/interfaces/catalog.mojom.h" #include "services/catalog/public/interfaces/constants.mojom.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_context.h"
diff --git a/mash/example/views_examples/views_examples.cc b/mash/example/views_examples/views_examples.cc index cb6e3d3e..8e0c2fe1 100644 --- a/mash/example/views_examples/views_examples.cc +++ b/mash/example/views_examples/views_examples.cc
@@ -11,7 +11,6 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/c/main.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/service_manager/public/cpp/interface_registry.h"
diff --git a/mash/example/window_type_launcher/window_type_launcher.cc b/mash/example/window_type_launcher/window_type_launcher.cc index 46c07923..a33422e 100644 --- a/mash/example/window_type_launcher/window_type_launcher.cc +++ b/mash/example/window_type_launcher/window_type_launcher.cc
@@ -13,7 +13,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/platform_thread.h" #include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h"
diff --git a/mash/session/session.cc b/mash/session/session.cc index d00e7ec..d02dabb 100644 --- a/mash/session/session.cc +++ b/mash/session/session.cc
@@ -24,19 +24,20 @@ StartQuickLaunch(); // Launch a chrome window for dev convience; don't do this in the long term. - context()->connector()->Connect(content::mojom::kPackagedServicesServiceName); + context()->connector()->StartService( + content::mojom::kPackagedServicesServiceName); } void Session::StartWindowManager() { // TODO(beng): monitor this service for death & bring down the whole system // if necessary. - context()->connector()->Connect(common::GetWindowManagerServiceName()); + context()->connector()->StartService(common::GetWindowManagerServiceName()); } void Session::StartQuickLaunch() { // TODO(beng): monitor this service for death & bring down the whole system // if necessary. - context()->connector()->Connect(quick_launch::mojom::kServiceName); + context()->connector()->StartService(quick_launch::mojom::kServiceName); } } // namespace session
diff --git a/mash/task_viewer/task_viewer.cc b/mash/task_viewer/task_viewer.cc index c7b8cf1..98204fa 100644 --- a/mash/task_viewer/task_viewer.cc +++ b/mash/task_viewer/task_viewer.cc
@@ -17,7 +17,6 @@ #include "mojo/public/cpp/bindings/binding.h" #include "services/catalog/public/interfaces/catalog.mojom.h" #include "services/catalog/public/interfaces/constants.mojom.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_context.h"
diff --git a/media/media_options.gni b/media/media_options.gni index 00709d3..d07f093 100644 --- a/media/media_options.gni +++ b/media/media_options.gni
@@ -54,7 +54,7 @@ # which are encoded using HEVC require |enable_hevc_demuxing| to be enabled. enable_dolby_vision_demuxing = proprietary_codecs && is_chromecast - enable_webrtc = !is_ios && !is_cast_audio_only + enable_webrtc = !is_cast_audio_only # Enable HLS with SAMPLE-AES decryption. # Enabled by default on the cast desktop implementation to allow unit tests of
diff --git a/media/mojo/interfaces/hdr_metadata_struct_traits.h b/media/mojo/interfaces/hdr_metadata_struct_traits.h index 498f830..6ca3810e 100644 --- a/media/mojo/interfaces/hdr_metadata_struct_traits.h +++ b/media/mojo/interfaces/hdr_metadata_struct_traits.h
@@ -36,6 +36,14 @@ media::MasteringMetadata* output) { output->luminance_max = data.luminance_max(); output->luminance_min = data.luminance_min(); + if (!data.ReadPrimaryR(&output->primary_r)) + return false; + if (!data.ReadPrimaryG(&output->primary_g)) + return false; + if (!data.ReadPrimaryB(&output->primary_b)) + return false; + if (!data.ReadWhitePoint(&output->white_point)) + return false; return true; } }; @@ -59,6 +67,8 @@ output->max_content_light_level = data.max_content_light_level(); output->max_frame_average_light_level = data.max_frame_average_light_level(); + if (!data.ReadMasteringMetadata(&output->mastering_metadata)) + return false; return true; } };
diff --git a/media/mojo/services/media_service.cc b/media/mojo/services/media_service.cc index 242040e..e1b5145 100644 --- a/media/mojo/services/media_service.cc +++ b/media/mojo/services/media_service.cc
@@ -11,7 +11,6 @@ #include "media/mojo/services/interface_factory_impl.h" #include "media/mojo/services/mojo_media_client.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" namespace media {
diff --git a/media/mojo/services/media_service_unittest.cc b/media/mojo/services/media_service_unittest.cc index bdc2cd7..c7e611c 100644 --- a/media/mojo/services/media_service_unittest.cc +++ b/media/mojo/services/media_service_unittest.cc
@@ -77,9 +77,8 @@ void SetUp() override { ServiceTest::SetUp(); - connection_ = connector()->Connect("media"); media::mojom::MediaServicePtr media_service; - connection_->GetInterface(&media_service); + connector()->BindInterface("media", &media_service); auto registry = base::MakeUnique<service_manager::InterfaceRegistry>(std::string()); @@ -148,7 +147,6 @@ MOCK_METHOD0(ConnectionClosed, void()); protected: - std::unique_ptr<service_manager::Connection> connection_; std::unique_ptr<base::RunLoop> run_loop_; mojom::InterfaceFactoryPtr interface_factory_; @@ -202,7 +200,12 @@ #endif // defined(ENABLE_MOJO_RENDERER) TEST_F(MediaServiceTest, Lifetime) { - connection_->SetConnectionLostClosure( + // The lifetime of the media service is controlled by the number of + // live InterfaceFactory impls, not MediaService impls, so this pipe should + // be closed when the last InterfaceFactory is destroyed. + media::mojom::MediaServicePtr media_service; + connector()->BindInterface("media", &media_service); + media_service.set_connection_error_handler( base::Bind(&MediaServiceTest::ConnectionClosed, base::Unretained(this))); // Disconnecting CDM and Renderer services doesn't terminate the app.
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index 1398543..6fa8f24 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h
@@ -390,6 +390,20 @@ // visible, because the normal Read() method is used as a fallback. NET_ERROR(READ_IF_READY_NOT_IMPLEMENTED, -174) +// This error is emitted if TLS 1.3 is enabled, connecting with it failed, but +// retrying at a downgraded maximum version succeeded. This could mean: +// +// 1. This is a transient network error that will be resolved when the user +// reloads. +// +// 2. The user is behind a buggy network middlebox, firewall, or proxy which is +// interfering with TLS 1.3. +// +// 3. The server is buggy and does not implement TLS version negotiation +// correctly. TLS 1.3 was tweaked to avoid a common server bug here, so this +// is unlikely. +NET_ERROR(SSL_VERSION_INTERFERENCE, -175) + // Certificate error codes // // The values of certificate error codes must be consecutive.
diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc index 312b927..3a85a6df 100644 --- a/net/http/http_basic_stream.cc +++ b/net/http/http_basic_stream.cc
@@ -99,6 +99,11 @@ load_timing_info); } +bool HttpBasicStream::GetAlternativeService( + AlternativeService* alternative_service) const { + return false; +} + void HttpBasicStream::GetSSLInfo(SSLInfo* ssl_info) { parser()->GetSSLInfo(ssl_info); }
diff --git a/net/http/http_basic_stream.h b/net/http/http_basic_stream.h index 4f595c92f..cf0d65d2 100644 --- a/net/http/http_basic_stream.h +++ b/net/http/http_basic_stream.h
@@ -72,6 +72,9 @@ bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + bool GetAlternativeService( + AlternativeService* alternative_service) const override; + void GetSSLInfo(SSLInfo* ssl_info) override; void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 363ae401..e95ab37 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -14970,6 +14970,12 @@ return false; } + bool GetAlternativeService( + AlternativeService* alternative_service) const override { + ADD_FAILURE(); + return false; + } + void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); } void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override { @@ -15216,6 +15222,12 @@ return false; } + bool GetAlternativeService( + AlternativeService* alternative_service) const override { + ADD_FAILURE(); + return false; + } + void GetSSLInfo(SSLInfo* ssl_info) override {} void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
diff --git a/net/http/http_response_body_drainer_unittest.cc b/net/http/http_response_body_drainer_unittest.cc index 6b725da..44943e29 100644 --- a/net/http/http_response_body_drainer_unittest.cc +++ b/net/http/http_response_body_drainer_unittest.cc
@@ -108,6 +108,10 @@ bool CanReuseConnection() const override { return can_reuse_connection_; } int64_t GetTotalReceivedBytes() const override { return 0; } int64_t GetTotalSentBytes() const override { return 0; } + bool GetAlternativeService( + AlternativeService* alternative_service) const override { + return false; + } void GetSSLInfo(SSLInfo* ssl_info) override {} void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {} bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
diff --git a/net/http/http_stream.h b/net/http/http_stream.h index 3def66ee..78458e4 100644 --- a/net/http/http_stream.h +++ b/net/http/http_stream.h
@@ -30,6 +30,7 @@ namespace net { +struct AlternativeService; class HttpNetworkSession; class HttpRequestHeaders; struct HttpRequestInfo; @@ -150,6 +151,11 @@ // undefined. virtual void GetSSLInfo(SSLInfo* ssl_info) = 0; + // Returns true and populates |alternative_service| if an alternative service + // was used to for this stream. Otherwise returns false. + virtual bool GetAlternativeService( + AlternativeService* alternative_service) const = 0; + // Get the SSLCertRequestInfo associated with this stream's connection. // This should only be called for streams over SSL sockets, otherwise the // behavior is undefined.
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index cdb3109..9c38e69 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -103,7 +103,8 @@ bool for_websockets) : session_(session), job_factory_(new DefaultJobFactory()), - for_websockets_(for_websockets) {} + for_websockets_(for_websockets), + last_logged_job_controller_count_(0) {} HttpStreamFactoryImpl::~HttpStreamFactoryImpl() { DCHECK(spdy_session_request_map_.empty()); @@ -356,11 +357,15 @@ scheme_host_port); } -void HttpStreamFactoryImpl::AddJobControllerCountToHistograms() const { +void HttpStreamFactoryImpl::AddJobControllerCountToHistograms() { // Only log the count of JobControllers when the count is hitting one of the - // boundaries which is a multiple of 100: 100, 200, 300, etc. - if (job_controller_set_.size() < 100 || job_controller_set_.size() % 100 != 0) + // boundaries for the first time which is a multiple of 100: 100, 200, 300, + // etc. + if (job_controller_set_.size() % 100 != 0 || + job_controller_set_.size() <= last_logged_job_controller_count_) { return; + } + last_logged_job_controller_count_ = job_controller_set_.size(); UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfJobController", job_controller_set_.size());
diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h index 503764c4..53f4536 100644 --- a/net/http/http_stream_factory_impl.h +++ b/net/http/http_stream_factory_impl.h
@@ -174,7 +174,7 @@ // Adds the count of JobControllers that are not completed to UMA histogram if // the count is a multiple of 100: 100, 200, 400, etc. Break down // JobControllers count based on the type of JobController. - void AddJobControllerCountToHistograms() const; + void AddJobControllerCountToHistograms(); HttpNetworkSession* const session_; @@ -196,6 +196,9 @@ const bool for_websockets_; + // The count of JobControllers that was most recently logged to histograms. + size_t last_logged_job_controller_count_; + DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImpl); };
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index 2ac222b..833c429 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -127,6 +127,10 @@ bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override { return false; } + bool GetAlternativeService( + AlternativeService* alternative_service) const override { + return false; + } void GetSSLInfo(SSLInfo* ssl_info) override {} void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {} bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
diff --git a/net/http/proxy_connect_redirect_http_stream.cc b/net/http/proxy_connect_redirect_http_stream.cc index 5b8a2bc..a493f33 100644 --- a/net/http/proxy_connect_redirect_http_stream.cc +++ b/net/http/proxy_connect_redirect_http_stream.cc
@@ -79,6 +79,11 @@ return 0; } +bool ProxyConnectRedirectHttpStream::GetAlternativeService( + AlternativeService* alternative_service) const { + return false; +} + bool ProxyConnectRedirectHttpStream::GetLoadTimingInfo( LoadTimingInfo* load_timing_info) const { if (!has_load_timing_info_)
diff --git a/net/http/proxy_connect_redirect_http_stream.h b/net/http/proxy_connect_redirect_http_stream.h index 74d9136..c66aa21 100644 --- a/net/http/proxy_connect_redirect_http_stream.h +++ b/net/http/proxy_connect_redirect_http_stream.h
@@ -51,6 +51,8 @@ int64_t GetTotalReceivedBytes() const override; int64_t GetTotalSentBytes() const override; + bool GetAlternativeService( + AlternativeService* alternative_service) const override; // This function may be called. bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index bbd14afb..53c84f4 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -563,6 +563,15 @@ // } EVENT_TYPE(SSL_CIPHER_FALLBACK) +// An SSL connection needs to be retried with a lower protocol version to detect +// if the error was due to a middlebox interfering with the protocol version we +// offered. +// The following parameters are attached to the event: +// { +// "net_error": <Net integer error code which triggered the probe>, +// } +EVENT_TYPE(SSL_VERSION_INTERFERENCE_PROBE) + // We found that our prediction of the server's certificates was correct and // we merged the verification with the SSLHostInfo. (Note: now obsolete.) EVENT_TYPE(SSL_VERIFICATION_MERGED)
diff --git a/net/quic/chromium/quic_http_stream.cc b/net/quic/chromium/quic_http_stream.cc index f52e00e..78f4bac7 100644 --- a/net/quic/chromium/quic_http_stream.cc +++ b/net/quic/chromium/quic_http_stream.cc
@@ -423,6 +423,14 @@ return true; } +bool QuicHttpStream::GetAlternativeService( + AlternativeService* alternative_service) const { + alternative_service->protocol = kProtoQUIC; + alternative_service->host = server_id_.host(); + alternative_service->port = server_id_.port(); + return true; +} + void QuicHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) { details->connection_info = ConnectionInfoFromQuicVersion(quic_version_); if (was_handshake_confirmed_)
diff --git a/net/quic/chromium/quic_http_stream.h b/net/quic/chromium/quic_http_stream.h index 01d83955..262aeed0 100644 --- a/net/quic/chromium/quic_http_stream.h +++ b/net/quic/chromium/quic_http_stream.h
@@ -64,6 +64,8 @@ int64_t GetTotalReceivedBytes() const override; int64_t GetTotalSentBytes() const override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + bool GetAlternativeService( + AlternativeService* alternative_service) const override; void PopulateNetErrorDetails(NetErrorDetails* details) override; void SetPriority(RequestPriority priority) override;
diff --git a/net/quic/chromium/quic_http_stream_test.cc b/net/quic/chromium/quic_http_stream_test.cc index 1930a1b..28d88c9a 100644 --- a/net/quic/chromium/quic_http_stream_test.cc +++ b/net/quic/chromium/quic_http_stream_test.cc
@@ -73,7 +73,7 @@ const char kUploadData[] = "Really nifty data!"; const char kDefaultServerHostName[] = "www.example.org"; -const uint16_t kDefaultServerPort = 80; +const uint16_t kDefaultServerPort = 443; class TestQuicConnection : public QuicConnection { public: @@ -362,7 +362,7 @@ void SetRequest(const string& method, const string& path, RequestPriority priority) { - request_headers_ = client_maker_.GetRequestHeaders(method, "http", path); + request_headers_ = client_maker_.GetRequestHeaders(method, "https", path); } void SetResponse(const string& status, const string& body) { @@ -646,7 +646,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); // Make sure getting load timing from the stream early does not crash. LoadTimingInfo load_timing_info; @@ -716,7 +716,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); // Start first request. EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -795,7 +795,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -889,7 +889,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -939,7 +939,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -961,7 +961,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -980,6 +980,31 @@ EXPECT_TRUE(ssl_info2.is_valid()); } +TEST_P(QuicHttpStreamTest, GetAlternativeService) { + SetRequest("GET", "/", DEFAULT_PRIORITY); + Initialize(); + + request_.method = "GET"; + request_.url = GURL("https://www.example.org/"); + + EXPECT_EQ(OK, + stream_->InitializeStream(&request_, DEFAULT_PRIORITY, + net_log_.bound(), callback_.callback())); + + AlternativeService alternative_service; + EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service)); + EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443), + alternative_service); + + session_->connection()->CloseConnection( + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE); + + AlternativeService alternative_service2; + EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2)); + EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443), + alternative_service2); +} + TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) { SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; @@ -995,7 +1020,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1035,7 +1060,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1078,7 +1103,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1119,7 +1144,7 @@ kUploadData, strlen(kUploadData))); ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_THAT(request_.upload_data_stream->Init(CompletionCallback(), NetLogWithSource()), @@ -1191,7 +1216,7 @@ upload_data_stream.AppendData(kUploadData, chunk_size, false); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -1266,7 +1291,7 @@ upload_data_stream.AppendData(kUploadData, chunk_size, false); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -1335,7 +1360,7 @@ ChunkedUploadDataStream upload_data_stream(0); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -1402,7 +1427,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1447,7 +1472,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_.bound(), callback_.callback())); @@ -1500,7 +1525,7 @@ Initialize(); request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_.bound(), callback_.callback())); @@ -1543,7 +1568,7 @@ ChunkedUploadDataStream upload_data_stream(0); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -1575,7 +1600,7 @@ ChunkedUploadDataStream upload_data_stream(0); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -1605,7 +1630,7 @@ upload_data_stream.AppendData(kUploadData, chunk_size, false); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -1623,7 +1648,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1689,7 +1714,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1763,7 +1788,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1805,7 +1830,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1877,7 +1902,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1902,7 +1927,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -1997,7 +2022,7 @@ // Initialize the first stream, for receiving the promise on. request_.method = "GET"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, @@ -2112,7 +2137,7 @@ ReadErrorUploadDataStream upload_data_stream( ReadErrorUploadDataStream::FailureMode::SYNC); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource())); @@ -2149,7 +2174,7 @@ ReadErrorUploadDataStream upload_data_stream( ReadErrorUploadDataStream::FailureMode::ASYNC); request_.method = "POST"; - request_.url = GURL("http://www.example.org/"); + request_.url = GURL("https://www.example.org/"); request_.upload_data_stream = &upload_data_stream; ASSERT_EQ(OK, request_.upload_data_stream->Init( TestCompletionCallback().callback(), NetLogWithSource()));
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index 085ef63..ab4f113 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -1066,6 +1066,11 @@ if (result < 0) return result; + if (ssl_config_.version_interference_probe) { + DCHECK_LT(ssl_config_.version_max, TLS1_3_VERSION); + return ERR_SSL_VERSION_INTERFERENCE; + } + SSLContext::GetInstance()->session_cache()->ResetLookupCount( GetSessionCacheKey()); // Check that if token binding was negotiated, then extended master secret @@ -1694,17 +1699,13 @@ std::string SSLClientSocketImpl::GetSessionCacheKey() const { std::string result = host_and_port_.ToString(); - result.append("/"); + result.push_back('/'); result.append(ssl_session_cache_shard_); - result.append("/"); - if (ssl_config_.deprecated_cipher_suites_enabled) - result.append("deprecated"); - - result.append("/"); - if (ssl_config_.channel_id_enabled) - result.append("channelid"); - + result.push_back('/'); + result.push_back(ssl_config_.deprecated_cipher_suites_enabled ? '1' : '0'); + result.push_back(ssl_config_.channel_id_enabled ? '1' : '0'); + result.push_back(ssl_config_.version_interference_probe ? '1' : '0'); return result; }
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc index b335e46b..a557e5b 100644 --- a/net/socket/ssl_client_socket_pool.cc +++ b/net/socket/ssl_client_socket_pool.cc
@@ -4,6 +4,7 @@ #include "net/socket/ssl_client_socket_pool.h" +#include <cstdlib> #include <utility> #include "base/bind.h" @@ -130,7 +131,9 @@ ? "pm/" + context.ssl_session_cache_shard : context.ssl_session_cache_shard)), callback_( - base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))) {} + base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))), + version_interference_probe_(false), + version_interference_error_(OK) {} SSLConnectJob::~SSLConnectJob() { } @@ -236,7 +239,10 @@ } int SSLConnectJob::DoTransportConnectComplete(int result) { - connection_attempts_ = transport_socket_handle_->connection_attempts(); + connection_attempts_.insert( + connection_attempts_.end(), + transport_socket_handle_->connection_attempts().begin(), + transport_socket_handle_->connection_attempts().end()); if (result == OK) { next_state_ = STATE_SSL_CONNECT; transport_socket_handle_->socket()->GetPeerAddress(&server_address_); @@ -321,13 +327,22 @@ connect_timing_.ssl_start = base::TimeTicks::Now(); + SSLConfig ssl_config = params_->ssl_config(); + if (version_interference_probe_) { + DCHECK_EQ(SSL_PROTOCOL_VERSION_TLS1_3, ssl_config.version_max); + ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; + ssl_config.version_interference_probe = true; + } ssl_socket_ = client_socket_factory_->CreateSSLClientSocket( - std::move(transport_socket_handle_), params_->host_and_port(), - params_->ssl_config(), context_); + std::move(transport_socket_handle_), params_->host_and_port(), ssl_config, + context_); return ssl_socket_->Connect(callback_); } int SSLConnectJob::DoSSLConnectComplete(int result) { + // Version interference probes should not result in success. + DCHECK(!version_interference_probe_ || result != OK); + // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( @@ -346,6 +361,32 @@ return ERR_ALPN_NEGOTIATION_FAILED; } + // Perform a TLS 1.3 version interference probe on various connection + // errors. The retry will never produce a successful connection but may map + // errors to ERR_SSL_VERSION_INTERFERENCE, which signals a probable + // version-interfering middlebox. + if (params_->ssl_config().version_max == SSL_PROTOCOL_VERSION_TLS1_3 && + !params_->ssl_config().deprecated_cipher_suites_enabled && + !version_interference_probe_) { + if (result == ERR_CONNECTION_CLOSED || result == ERR_SSL_PROTOCOL_ERROR || + result == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || + result == ERR_CONNECTION_RESET || + result == ERR_SSL_BAD_RECORD_MAC_ALERT) { + // Report the error code for each time a version interference probe is + // triggered. + UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceProbeTrigger", + std::abs(result)); + net_log().AddEventWithNetErrorCode( + NetLogEventType::SSL_VERSION_INTERFERENCE_PROBE, result); + + ResetStateForRetry(); + version_interference_probe_ = true; + version_interference_error_ = result; + next_state_ = GetInitialState(params_->GetConnectionType()); + return OK; + } + } + const std::string& host = params_->host_and_port().host(); bool is_google = host == "google.com" || @@ -450,6 +491,14 @@ std::abs(result)); } + if (result == ERR_SSL_VERSION_INTERFERENCE) { + // Record the error code version interference was detected at. + DCHECK(version_interference_probe_); + DCHECK_NE(OK, version_interference_error_); + UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceError", + std::abs(version_interference_error_)); + } + if (result == OK || IsCertificateError(result)) { SetSocket(std::move(ssl_socket_)); } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { @@ -480,6 +529,13 @@ return DoLoop(OK); } +void SSLConnectJob::ResetStateForRetry() { + transport_socket_handle_.reset(); + ssl_socket_.reset(); + error_response_info_ = HttpResponseInfo(); + server_address_ = IPEndPoint(); +} + SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory( TransportClientSocketPool* transport_pool, SOCKSClientSocketPool* socks_pool,
diff --git a/net/socket/ssl_client_socket_pool.h b/net/socket/ssl_client_socket_pool.h index 5dfc041..c4913df 100644 --- a/net/socket/ssl_client_socket_pool.h +++ b/net/socket/ssl_client_socket_pool.h
@@ -151,6 +151,8 @@ // Otherwise, it returns a net error code. int ConnectInternal() override; + void ResetStateForRetry(); + scoped_refptr<SSLSocketParams> params_; TransportClientSocketPool* const transport_pool_; SOCKSClientSocketPool* const socks_pool_; @@ -172,6 +174,12 @@ // through an HTTPS CONNECT request or a SOCKS proxy). IPEndPoint server_address_; + bool version_interference_probe_; + + // The error which triggered a TLS 1.3 version interference probe, or OK if + // none was triggered. + int version_interference_error_; + DISALLOW_COPY_AND_ASSIGN(SSLConnectJob); };
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index b5fd0a9..6067721 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -2841,6 +2841,37 @@ EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type); } +// Tests that the version_interference_probe option rejects successful +// connections and passes errors through. +TEST_F(SSLClientSocketTest, VersionInterferenceProbe) { + ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); + + SSLConfig ssl_config; + ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; + ssl_config.version_interference_probe = true; + + // Successful connections map to a dedicated error. + int rv; + ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); + EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_INTERFERENCE)); + + // Failed connections pass through. + TestCompletionCallback callback; + std::unique_ptr<StreamSocket> real_transport( + new TCPClientSocket(addr(), NULL, NULL, NetLogSource())); + std::unique_ptr<SynchronousErrorStreamSocket> transport( + new SynchronousErrorStreamSocket(std::move(real_transport))); + rv = callback.GetResult(transport->Connect(callback.callback())); + EXPECT_THAT(rv, IsOk()); + SynchronousErrorStreamSocket* raw_transport = transport.get(); + std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket( + std::move(transport), spawned_test_server()->host_port_pair(), + ssl_config)); + raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); + rv = callback.GetResult(sock->Connect(callback.callback())); + EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); +} + TEST_F(SSLClientSocketTest, RequireECDHE) { // Run test server without ECDHE. SpawnedTestServer::SSLOptions ssl_options;
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc index 8bfc4b7..0e07de3 100644 --- a/net/spdy/spdy_http_stream.cc +++ b/net/spdy/spdy_http_stream.cc
@@ -191,6 +191,11 @@ return stream_->raw_sent_bytes(); } +bool SpdyHttpStream::GetAlternativeService( + AlternativeService* alternative_service) const { + return false; +} + bool SpdyHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { if (stream_closed_) { if (!closed_stream_has_load_timing_info_)
diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h index 3605f9b..8b7a82d 100644 --- a/net/spdy/spdy_http_stream.h +++ b/net/spdy/spdy_http_stream.h
@@ -74,6 +74,8 @@ // not including proxy overhead. Note that some SPDY frames such as pings are // not associated with any stream, and are not included in this value. int64_t GetTotalSentBytes() const override; + bool GetAlternativeService( + AlternativeService* alternative_service) const override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; bool GetRemoteEndpoint(IPEndPoint* endpoint) override; void PopulateNetErrorDetails(NetErrorDetails* details) override;
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc index 726ce48..528ff2a 100644 --- a/net/ssl/ssl_config.cc +++ b/net/ssl/ssl_config.cc
@@ -28,6 +28,7 @@ version_min(kDefaultSSLVersionMin), version_max(kDefaultSSLVersionMax), deprecated_cipher_suites_enabled(false), + version_interference_probe(false), channel_id_enabled(true), false_start_enabled(true), signed_cert_timestamps_enabled(true),
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h index 7e6283d..eee5622 100644 --- a/net/ssl/ssl_config.h +++ b/net/ssl/ssl_config.h
@@ -114,6 +114,12 @@ // it. https://crbug.com/684730. bool deprecated_cipher_suites_enabled; + // Enables the version interference probing mode. While TLS 1.3 has avoided + // most endpoint intolerance, middlebox interference with TLS 1.3 is + // rampant. This causes the connection to be discarded on success with + // ERR_SSL_VERSION_INTERFERENCE. + bool version_interference_probe; + bool channel_id_enabled; // True if TLS channel ID extension is enabled. // List of Token Binding key parameters supported by the client. If empty,
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h index 60a9c3b..438bf17 100644 --- a/net/test/spawned_test_server/base_test_server.h +++ b/net/test/spawned_test_server/base_test_server.h
@@ -154,9 +154,10 @@ // server. Do not change them. enum TLSIntolerantLevel { TLS_INTOLERANT_NONE = 0, - TLS_INTOLERANT_ALL = 1, // Intolerant of all TLS versions. + TLS_INTOLERANT_ALL = 1, // Intolerant of all TLS versions. TLS_INTOLERANT_TLS1_1 = 2, // Intolerant of TLS 1.1 or higher. TLS_INTOLERANT_TLS1_2 = 3, // Intolerant of TLS 1.2 or higher. + TLS_INTOLERANT_TLS1_3 = 4, // Intolerant of TLS 1.3 or higher. }; // Values which control how the server reacts in response to a ClientHello
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py index 8fd7236..c22625ea 100755 --- a/net/tools/testserver/testserver.py +++ b/net/tools/testserver/testserver.py
@@ -2193,6 +2193,7 @@ 'fallback. 1 means all TLS versions will be ' 'aborted. 2 means TLS 1.1 or higher will be ' 'aborted. 3 means TLS 1.2 or higher will be ' + 'aborted. 4 means TLS 1.3 or higher will be ' 'aborted.') self.option_parser.add_option('--tls-intolerance-type', dest='tls_intolerance_type',
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index ec26ab8..c0665d8 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc
@@ -1136,6 +1136,11 @@ return false; } + bool GetAlternativeService( + AlternativeService* alternative_service) const override { + return false; + } + void GetSSLInfo(SSLInfo* ssl_info) override {} void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 6583968..1eb9711 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -3423,8 +3423,10 @@ rev_checking_required_local_anchors_( rev_checking_required_local_anchors), token_binding_enabled_(token_binding_enabled), - min_version_(kDefaultSSLVersionMin) {} + min_version_(kDefaultSSLVersionMin), + max_version_(kDefaultSSLVersionMax) {} + void set_max_version(uint16_t version) { max_version_ = version; } void set_min_version(uint16_t version) { min_version_ = version; } // SSLConfigService: @@ -3434,9 +3436,8 @@ config->verify_ev_cert = ev_enabled_; config->rev_checking_required_local_anchors = rev_checking_required_local_anchors_; - if (min_version_) { - config->version_min = min_version_; - } + config->version_min = min_version_; + config->version_max = max_version_; if (token_binding_enabled_) { config->token_binding_params.push_back(TB_PARAM_ECDSAP256); } @@ -3451,6 +3452,7 @@ const bool rev_checking_required_local_anchors_; const bool token_binding_enabled_; uint16_t min_version_; + uint16_t max_version_; }; // TODO(svaldez): Update tests to use EmbeddedTestServer. @@ -9369,10 +9371,21 @@ class HTTPSFallbackTest : public testing::Test { public: - HTTPSFallbackTest() : context_(true) {} + HTTPSFallbackTest() + : scoped_task_scheduler_(base::MessageLoop::current()), context_(true) { + ssl_config_service_ = new TestSSLConfigService( + true /* check for EV */, false /* online revocation checking */, + false /* require rev. checking for local anchors */, + false /* token binding enabled */); + context_.set_ssl_config_service(ssl_config_service_.get()); + } ~HTTPSFallbackTest() override {} protected: + TestSSLConfigService* ssl_config_service() { + return ssl_config_service_.get(); + } + void DoFallbackTest(const SpawnedTestServer::SSLOptions& ssl_options) { DCHECK(!request_); context_.Init(); @@ -9391,15 +9404,25 @@ base::RunLoop().Run(); } + void ExpectConnection(int version) { + EXPECT_EQ(1, delegate_.response_started_count()); + EXPECT_NE(0, delegate_.bytes_received()); + EXPECT_EQ(version, SSLConnectionStatusToVersion( + request_->ssl_info().connection_status)); + } + void ExpectFailure(int error) { EXPECT_EQ(1, delegate_.response_started_count()); EXPECT_EQ(error, delegate_.request_status()); } private: + // Required by ChannelIDService. + base::test::ScopedTaskScheduler scoped_task_scheduler_; TestDelegate delegate_; TestURLRequestContext context_; std::unique_ptr<URLRequest> request_; + scoped_refptr<TestSSLConfigService> ssl_config_service_; }; // Tests the TLS 1.0 fallback doesn't happen. @@ -9424,6 +9447,30 @@ ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH); } +// Tests that TLS 1.3 interference results in a dedicated error code. +TEST_F(HTTPSFallbackTest, TLSv1_3Interference) { + SpawnedTestServer::SSLOptions ssl_options( + SpawnedTestServer::SSLOptions::CERT_OK); + ssl_options.tls_intolerant = + SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_3; + ssl_config_service()->set_max_version(SSL_PROTOCOL_VERSION_TLS1_3); + + ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); + ExpectFailure(ERR_SSL_VERSION_INTERFERENCE); +} + +// Tests that disabling TLS 1.3 leaves TLS 1.3 interference unnoticed. +TEST_F(HTTPSFallbackTest, TLSv1_3InterferenceDisableVersion) { + SpawnedTestServer::SSLOptions ssl_options( + SpawnedTestServer::SSLOptions::CERT_OK); + ssl_options.tls_intolerant = + SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_3; + ssl_config_service()->set_max_version(SSL_PROTOCOL_VERSION_TLS1_2); + + ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); + ExpectConnection(SSL_CONNECTION_VERSION_TLS1_2); +} + class HTTPSSessionTest : public testing::Test { public: HTTPSSessionTest()
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc index efe263a..c67eb4a 100644 --- a/net/websockets/websocket_basic_handshake_stream.cc +++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -420,6 +420,11 @@ return 0; } +bool WebSocketBasicHandshakeStream::GetAlternativeService( + AlternativeService* alternative_service) const { + return false; +} + bool WebSocketBasicHandshakeStream::GetLoadTimingInfo( LoadTimingInfo* load_timing_info) const { return state_.connection()->GetLoadTimingInfo(IsConnectionReused(),
diff --git a/net/websockets/websocket_basic_handshake_stream.h b/net/websockets/websocket_basic_handshake_stream.h index dffe472e..06bc333 100644 --- a/net/websockets/websocket_basic_handshake_stream.h +++ b/net/websockets/websocket_basic_handshake_stream.h
@@ -61,6 +61,8 @@ bool CanReuseConnection() const override; int64_t GetTotalReceivedBytes() const override; int64_t GetTotalSentBytes() const override; + bool GetAlternativeService( + AlternativeService* alternative_service) const override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; void GetSSLInfo(SSLInfo* ssl_info) override; void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
diff --git a/remoting/BUILD.gn b/remoting/BUILD.gn index 2fad3f0..d2b0db8c 100644 --- a/remoting/BUILD.gn +++ b/remoting/BUILD.gn
@@ -37,6 +37,10 @@ ] } + if (is_ios) { + deps += [ "//remoting/client/ios:all" ] + } + if (enable_remoting_host) { deps += [ "//remoting:remoting_perftests",
diff --git a/remoting/client/ios/facade/host_info.cc b/remoting/client/ios/facade/host_info.cc index 671473d5..c036e535 100644 --- a/remoting/client/ios/facade/host_info.cc +++ b/remoting/client/ios/facade/host_info.cc
@@ -22,7 +22,7 @@ if (!list_value->empty()) { for (const auto& item : *list_value) { std::string token_url_pattern; - if (!item->GetAsString(&token_url_pattern)) { + if (!item.GetAsString(&token_url_pattern)) { return false; } token_url_patterns.push_back(token_url_pattern);
diff --git a/remoting/client/ios/facade/host_list_fetcher.cc b/remoting/client/ios/facade/host_list_fetcher.cc index e0016eb..6c1bb00 100644 --- a/remoting/client/ios/facade/host_list_fetcher.cc +++ b/remoting/client/ios/facade/host_list_fetcher.cc
@@ -85,10 +85,10 @@ } // Any host_info with malformed data will not be added to the hostlist. - base::DictionaryValue* host_dict; + const base::DictionaryValue* host_dict; for (const auto& host_info : *hosts) { remoting::HostInfo host; - if (host_info->GetAsDictionary(&host_dict) && + if (host_info.GetAsDictionary(&host_dict) && host.ParseHostInfo(*host_dict)) { hostlist->push_back(host); }
diff --git a/remoting/remoting_enable.gni b/remoting/remoting_enable.gni index 3b9f45e0..a031976 100644 --- a/remoting/remoting_enable.gni +++ b/remoting/remoting_enable.gni
@@ -6,5 +6,5 @@ import("//media/media_options.gni") declare_args() { - enable_remoting = !is_ios && !is_chromecast && enable_webrtc + enable_remoting = !is_chromecast && enable_webrtc }
diff --git a/services/catalog/catalog.cc b/services/catalog/catalog.cc index b062eb4..3189881d8 100644 --- a/services/catalog/catalog.cc +++ b/services/catalog/catalog.cc
@@ -25,7 +25,6 @@ #include "services/catalog/entry_cache.h" #include "services/catalog/instance.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/service_context.h" namespace catalog {
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index ea0f021..5578cf5 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -23,7 +23,6 @@ #include "services/device/power_monitor/power_monitor_message_broadcaster.h" #include "services/device/public/cpp/device_features.h" #include "services/device/time_zone_monitor/time_zone_monitor.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_info.h" #include "ui/gfx/native_widget_types.h"
diff --git a/services/device/device_service_test_base.cc b/services/device/device_service_test_base.cc index e967c17..595f669 100644 --- a/services/device/device_service_test_base.cc +++ b/services/device/device_service_test_base.cc
@@ -11,8 +11,8 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/device/device_service.h" #include "services/device/public/interfaces/constants.mojom.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/interfaces/service_factory.mojom.h" @@ -31,14 +31,17 @@ explicit ServiceTestClient(service_manager::test::ServiceTest* test) : service_manager::test::ServiceTestClient(test), io_thread_("DeviceServiceTestIOThread"), - file_thread_("DeviceServiceTestFileThread") {} + file_thread_("DeviceServiceTestFileThread") { + registry_.AddInterface<service_manager::mojom::ServiceFactory>(this); + } ~ServiceTestClient() override {} protected: - bool OnConnect(const service_manager::ServiceInfo& remote_info, - service_manager::InterfaceRegistry* registry) override { - registry->AddInterface<service_manager::mojom::ServiceFactory>(this); - return true; + void OnBindInterface(const service_manager::ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } void CreateService(service_manager::mojom::ServiceRequest request, @@ -69,6 +72,7 @@ private: base::Thread io_thread_; base::Thread file_thread_; + service_manager::BinderRegistry registry_; mojo::BindingSet<service_manager::mojom::ServiceFactory> service_factory_bindings_; std::unique_ptr<service_manager::ServiceContext> device_service_context_;
diff --git a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc index 9fb1459..e325355 100644 --- a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc +++ b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc
@@ -7,15 +7,18 @@ #include "base/location.h" #include "base/macros.h" #include "mojo/public/cpp/bindings/binding.h" +#include "services/device/public/interfaces/constants.mojom.h" +#include "services/service_manager/public/cpp/connector.h" namespace device { PowerMonitorBroadcastSource::PowerMonitorBroadcastSource( - service_manager::InterfaceProvider* interface_provider) + service_manager::Connector* connector) : last_reported_battery_power_state_(false), binding_(this) { - if (interface_provider) { + if (connector) { device::mojom::PowerMonitorPtr power_monitor; - interface_provider->GetInterface(mojo::MakeRequest(&power_monitor)); + connector->BindInterface(device::mojom::kServiceName, + mojo::MakeRequest(&power_monitor)); power_monitor->AddClient(binding_.CreateInterfacePtrAndBind()); } }
diff --git a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h index 5f8f06e..1969aff1 100644 --- a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h +++ b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h
@@ -9,7 +9,10 @@ #include "base/power_monitor/power_monitor_source.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/device/public/interfaces/power_monitor.mojom.h" -#include "services/service_manager/public/cpp/interface_provider.h" + +namespace service_manager { +class Connector; +} namespace device { @@ -18,8 +21,7 @@ class PowerMonitorBroadcastSource : public base::PowerMonitorSource, public device::mojom::PowerMonitorClient { public: - explicit PowerMonitorBroadcastSource( - service_manager::InterfaceProvider* interface_provider); + explicit PowerMonitorBroadcastSource(service_manager::Connector* connector); ~PowerMonitorBroadcastSource() override; void PowerStateChange(bool on_battery_power) override;
diff --git a/services/file/file_service.cc b/services/file/file_service.cc index d10ed4dc..21946921 100644 --- a/services/file/file_service.cc +++ b/services/file/file_service.cc
@@ -12,7 +12,6 @@ #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/file/file_system.h" #include "services/file/user_id_map.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/service_context.h" namespace file {
diff --git a/services/file/file_system.cc b/services/file/file_system.cc index e022d4c..d4ff32f 100644 --- a/services/file/file_system.cc +++ b/services/file/file_system.cc
@@ -14,7 +14,6 @@ #include "components/filesystem/lock_table.h" #include "components/filesystem/public/interfaces/types.mojom.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/service_manager/public/cpp/connection.h" namespace file {
diff --git a/services/identity/identity_service.cc b/services/identity/identity_service.cc index 1cb95dc..dfdb742 100644 --- a/services/identity/identity_service.cc +++ b/services/identity/identity_service.cc
@@ -5,7 +5,6 @@ #include "services/identity/identity_service.h" #include "services/identity/identity_manager.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/service_context.h" namespace identity {
diff --git a/services/navigation/navigation_unittest.cc b/services/navigation/navigation_unittest.cc index 5dfc8adb..740cc6f 100644 --- a/services/navigation/navigation_unittest.cc +++ b/services/navigation/navigation_unittest.cc
@@ -24,7 +24,7 @@ protected: void SetUp() override { service_manager::test::ServiceTest::SetUp(); - window_manager_connection_ = connector()->Connect("test_wm"); + connector()->StartService("test_wm"); } mojom::ViewClientPtr GetViewClient() { @@ -66,7 +66,6 @@ int load_count_ = 0; mojo::Binding<mojom::ViewClient> binding_; base::RunLoop* loop_ = nullptr; - std::unique_ptr<service_manager::Connection> window_manager_connection_; DISALLOW_COPY_AND_ASSIGN(NavigationTest); };
diff --git a/services/preferences/persistent_pref_store_impl.cc b/services/preferences/persistent_pref_store_impl.cc index fe7e4b989..959303876 100644 --- a/services/preferences/persistent_pref_store_impl.cc +++ b/services/preferences/persistent_pref_store_impl.cc
@@ -34,20 +34,27 @@ ~Connection() override = default; - void OnPrefValueChanged(const std::string& key, const base::Value* value) { - if (write_in_progress_ || !base::ContainsKey(observed_keys_, key)) + void OnPrefValuesChanged(const std::vector<mojom::PrefUpdatePtr>& updates) { + if (write_in_progress_) return; - observer_->OnPrefChanged(key, value ? value->CreateDeepCopy() : nullptr); + std::vector<mojom::PrefUpdatePtr> filtered_updates; + for (const auto& update : updates) { + if (base::ContainsKey(observed_keys_, update->key)) { + filtered_updates.push_back(mojom::PrefUpdate::New( + update->key, + update->value ? update->value->CreateDeepCopy() : nullptr, 0)); + } + } + if (!filtered_updates.empty()) + observer_->OnPrefsChanged(std::move(filtered_updates)); } private: // mojom::PersistentPrefStore: - void SetValue(const std::string& key, - std::unique_ptr<base::Value> value, - uint32_t flags) override { + void SetValues(std::vector<mojom::PrefUpdatePtr> updates) override { base::AutoReset<bool> scoped_call_in_progress(&write_in_progress_, true); - pref_store_->SetValue(key, std::move(value), flags); + pref_store_->SetValues(std::move(updates)); } void CommitPendingWrite() override { pref_store_->CommitPendingWrite(); } @@ -76,17 +83,15 @@ scoped_refptr<PersistentPrefStore> backing_pref_store, base::OnceClosure on_initialized) : backing_pref_store_(backing_pref_store) { - backing_pref_store_->AddObserver(this); if (!backing_pref_store_->IsInitializationComplete()) { + backing_pref_store_->AddObserver(this); on_initialized_ = std::move(on_initialized); initializing_ = true; backing_pref_store_->ReadPrefsAsync(nullptr); } } -PersistentPrefStoreImpl::~PersistentPrefStoreImpl() { - backing_pref_store_->RemoveObserver(this); -} +PersistentPrefStoreImpl::~PersistentPrefStoreImpl() = default; mojom::PersistentPrefStoreConnectionPtr PersistentPrefStoreImpl::CreateConnection(ObservedPrefs observed_prefs) { @@ -113,32 +118,28 @@ backing_pref_store_->ReadOnly()); } -void PersistentPrefStoreImpl::OnPrefValueChanged(const std::string& key) { - // All mutations are triggered by a client. Updates are only sent to clients - // other than the instigator so if there is only one client, it will ignore - // the update. - if (connections_.size() == 1) - return; - - const base::Value* value = nullptr; - backing_pref_store_->GetValue(key, &value); - for (auto& entry : connections_) - entry.first->OnPrefValueChanged(key, value); -} +void PersistentPrefStoreImpl::OnPrefValueChanged(const std::string& key) {} void PersistentPrefStoreImpl::OnInitializationCompleted(bool succeeded) { DCHECK(initializing_); + backing_pref_store_->RemoveObserver(this); initializing_ = false; std::move(on_initialized_).Run(); } -void PersistentPrefStoreImpl::SetValue(const std::string& key, - std::unique_ptr<base::Value> value, - uint32_t flags) { - if (value) - backing_pref_store_->SetValue(key, std::move(value), flags); - else - backing_pref_store_->RemoveValue(key, flags); +void PersistentPrefStoreImpl::SetValues( + std::vector<mojom::PrefUpdatePtr> updates) { + for (auto& entry : connections_) + entry.first->OnPrefValuesChanged(updates); + + for (auto& update : updates) { + if (update->value) { + backing_pref_store_->SetValue(update->key, std::move(update->value), + update->flags); + } else { + backing_pref_store_->RemoveValue(update->key, update->flags); + } + } } void PersistentPrefStoreImpl::CommitPendingWrite() {
diff --git a/services/preferences/persistent_pref_store_impl.h b/services/preferences/persistent_pref_store_impl.h index 49d9cd9..5111ed7 100644 --- a/services/preferences/persistent_pref_store_impl.h +++ b/services/preferences/persistent_pref_store_impl.h
@@ -14,10 +14,6 @@ #include "services/preferences/public/interfaces/preferences.mojom.h" #include "services/preferences/public/interfaces/tracked_preference_validation_delegate.mojom.h" -namespace base { -class Value; -} - namespace prefs { class PersistentPrefStoreImpl : public PrefStore::Observer { @@ -40,9 +36,7 @@ private: class Connection; - void SetValue(const std::string& key, - std::unique_ptr<base::Value> value, - uint32_t flags); + void SetValues(std::vector<mojom::PrefUpdatePtr> updates); void CommitPendingWrite(); void SchedulePendingLossyWrites();
diff --git a/services/preferences/public/cpp/persistent_pref_store_client.cc b/services/preferences/public/cpp/persistent_pref_store_client.cc index 353ac4c..9bcb92f 100644 --- a/services/preferences/public/cpp/persistent_pref_store_client.cc +++ b/services/preferences/public/cpp/persistent_pref_store_client.cc
@@ -19,12 +19,14 @@ std::vector<PrefValueStore::PrefStoreType> already_connected_types) : connector_(std::move(connector)), pref_registry_(std::move(pref_registry)), - already_connected_types_(std::move(already_connected_types)) { + already_connected_types_(std::move(already_connected_types)), + weak_factory_(this) { DCHECK(connector_); } PersistentPrefStoreClient::PersistentPrefStoreClient( - mojom::PersistentPrefStoreConnectionPtr connection) { + mojom::PersistentPrefStoreConnectionPtr connection) + : weak_factory_(this) { OnConnect(std::move(connection), std::unordered_map<PrefValueStore::PrefStoreType, prefs::mojom::PrefStoreConnectionPtr>()); @@ -57,8 +59,8 @@ DCHECK(pref_store_); const base::Value* local_value = nullptr; GetMutableValues().Get(key, &local_value); - pref_store_->SetValue( - key, local_value ? local_value->CreateDeepCopy() : nullptr, flags); + + QueueWrite(key, flags); ReportPrefValueChanged(key); } @@ -67,7 +69,7 @@ std::unique_ptr<base::Value> value, uint32_t flags) { DCHECK(pref_store_); - pref_store_->SetValue(key, value->CreateDeepCopy(), flags); + QueueWrite(key, flags); GetMutableValues().Set(key, std::move(value)); } @@ -108,6 +110,8 @@ void PersistentPrefStoreClient::CommitPendingWrite() { DCHECK(pref_store_); + if (!pending_writes_.empty()) + FlushPendingWrites(); pref_store_->CommitPendingWrite(); } @@ -125,7 +129,7 @@ if (!pref_store_) return; - pref_store_->CommitPendingWrite(); + CommitPendingWrite(); } void PersistentPrefStoreClient::OnConnect( @@ -149,4 +153,32 @@ } } +void PersistentPrefStoreClient::QueueWrite(const std::string& key, + uint32_t flags) { + if (pending_writes_.empty()) { + // Use a weak pointer since a pending write should not prolong the life of + // |this|. Instead, the destruction of |this| will flush any pending writes. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&PersistentPrefStoreClient::FlushPendingWrites, + weak_factory_.GetWeakPtr())); + } + pending_writes_.insert(std::make_pair(key, flags)); +} + +void PersistentPrefStoreClient::FlushPendingWrites() { + std::vector<mojom::PrefUpdatePtr> updates; + for (const auto& pref : pending_writes_) { + const base::Value* value = nullptr; + if (GetValue(pref.first, &value)) { + updates.push_back(mojom::PrefUpdate::New( + pref.first, value->CreateDeepCopy(), pref.second)); + } else { + updates.push_back( + mojom::PrefUpdate::New(pref.first, nullptr, pref.second)); + } + } + pref_store_->SetValues(std::move(updates)); + pending_writes_.clear(); +} + } // namespace prefs
diff --git a/services/preferences/public/cpp/persistent_pref_store_client.h b/services/preferences/public/cpp/persistent_pref_store_client.h index 6ed2b11..e317ec9 100644 --- a/services/preferences/public/cpp/persistent_pref_store_client.h +++ b/services/preferences/public/cpp/persistent_pref_store_client.h
@@ -66,15 +66,21 @@ prefs::mojom::PrefStoreConnectionPtr> other_pref_stores); + void QueueWrite(const std::string& key, uint32_t flags); + void FlushPendingWrites(); + mojom::PrefStoreConnectorPtr connector_; scoped_refptr<PrefRegistry> pref_registry_; bool read_only_ = false; PrefReadError read_error_ = PersistentPrefStore::PREF_READ_ERROR_NONE; mojom::PersistentPrefStorePtr pref_store_; + std::map<std::string, uint32_t> pending_writes_; std::unique_ptr<ReadErrorDelegate> error_delegate_; std::vector<PrefValueStore::PrefStoreType> already_connected_types_; + base::WeakPtrFactory<PersistentPrefStoreClient> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(PersistentPrefStoreClient); };
diff --git a/services/preferences/public/cpp/pref_store_client_mixin.cc b/services/preferences/public/cpp/pref_store_client_mixin.cc index a82108a..0387883 100644 --- a/services/preferences/public/cpp/pref_store_client_mixin.cc +++ b/services/preferences/public/cpp/pref_store_client_mixin.cc
@@ -82,6 +82,23 @@ } template <typename BasePrefStore> +void PrefStoreClientMixin<BasePrefStore>::OnPrefsChanged( + std::vector<mojom::PrefUpdatePtr> updates) { + for (const auto& update : updates) + OnPrefChanged(update->key, std::move(update->value)); +} + +template <typename BasePrefStore> +void PrefStoreClientMixin<BasePrefStore>::OnInitializationCompleted( + bool succeeded) { + if (!initialized_) { + initialized_ = true; + for (auto& observer : observers_) + observer.OnInitializationCompleted(succeeded); + } +} + +template <typename BasePrefStore> void PrefStoreClientMixin<BasePrefStore>::OnPrefChanged( const std::string& key, std::unique_ptr<base::Value> value) { @@ -106,16 +123,6 @@ ReportPrefValueChanged(key); } -template <typename BasePrefStore> -void PrefStoreClientMixin<BasePrefStore>::OnInitializationCompleted( - bool succeeded) { - if (!initialized_) { - initialized_ = true; - for (auto& observer : observers_) - observer.OnInitializationCompleted(succeeded); - } -} - template class PrefStoreClientMixin<::PrefStore>; template class PrefStoreClientMixin<::PersistentPrefStore>;
diff --git a/services/preferences/public/cpp/pref_store_client_mixin.h b/services/preferences/public/cpp/pref_store_client_mixin.h index 9d7a508..19cf250 100644 --- a/services/preferences/public/cpp/pref_store_client_mixin.h +++ b/services/preferences/public/cpp/pref_store_client_mixin.h
@@ -54,10 +54,12 @@ private: // prefs::mojom::PreferenceObserver: - void OnPrefChanged(const std::string& key, - std::unique_ptr<base::Value> value) override; + void OnPrefsChanged(std::vector<mojom::PrefUpdatePtr> updates) override; void OnInitializationCompleted(bool succeeded) override; + void OnPrefChanged(const std::string& key, + std::unique_ptr<base::Value> value); + // Cached preferences. // If null, indicates that initialization failed. std::unique_ptr<base::DictionaryValue> cached_prefs_;
diff --git a/services/preferences/public/cpp/pref_store_impl.cc b/services/preferences/public/cpp/pref_store_impl.cc index b88e99e3..c228962 100644 --- a/services/preferences/public/cpp/pref_store_impl.cc +++ b/services/preferences/public/cpp/pref_store_impl.cc
@@ -26,14 +26,18 @@ if (!base::ContainsKey(prefs_, key)) return; - observer_->OnPrefChanged(key, value.CreateDeepCopy()); + std::vector<mojom::PrefUpdatePtr> updates; + updates.push_back(mojom::PrefUpdate::New(key, value.CreateDeepCopy(), 0)); + observer_->OnPrefsChanged(std::move(updates)); } void OnPrefRemoved(const std::string& key) const { if (!base::ContainsKey(prefs_, key)) return; - observer_->OnPrefChanged(key, nullptr); + std::vector<mojom::PrefUpdatePtr> updates; + updates.push_back(mojom::PrefUpdate::New(key, nullptr, 0)); + observer_->OnPrefsChanged(std::move(updates)); } private:
diff --git a/services/preferences/public/cpp/tests/pref_store_client_unittest.cc b/services/preferences/public/cpp/tests/pref_store_client_unittest.cc index 6a488a1..dbf86d4 100644 --- a/services/preferences/public/cpp/tests/pref_store_client_unittest.cc +++ b/services/preferences/public/cpp/tests/pref_store_client_unittest.cc
@@ -40,7 +40,9 @@ bool initialized() { return store_->IsInitializationComplete(); } void OnPrefChanged(const std::string& key, const base::Value& value) { - observer_ptr_->OnPrefChanged(key, value.CreateDeepCopy()); + std::vector<mojom::PrefUpdatePtr> updates; + updates.push_back(mojom::PrefUpdate::New(key, value.CreateDeepCopy(), 0)); + observer_ptr_->OnPrefsChanged(std::move(updates)); } void OnInitializationCompleted() { observer_ptr_->OnInitializationCompleted(true);
diff --git a/services/preferences/public/interfaces/preferences.mojom b/services/preferences/public/interfaces/preferences.mojom index 99c0d80..47a79dc 100644 --- a/services/preferences/public/interfaces/preferences.mojom +++ b/services/preferences/public/interfaces/preferences.mojom
@@ -25,9 +25,8 @@ // Allows observing changes to prefs stored in a |PrefStore|. interface PrefStoreObserver { - // The preference with the given |key| has changed. If |value| is null then - // the preference was deleted. - OnPrefChanged(string key, mojo.common.mojom.Value? value); + // Preferences have been changed. + OnPrefsChanged(array<PrefUpdate> updates); // The PrefStore has been initialized (asynchronously). OnInitializationCompleted(bool succeeded); @@ -100,11 +99,20 @@ map<PrefStoreType, PrefStoreConnection> connections); }; +// An update to a pref. +struct PrefUpdate { + // The key of the pref being updated. + string key; + // The new value; a null |value| indicates a delete. + mojo.common.mojom.Value? value; + //|flags| is a bitmask of WritablePrefStore::PrefWriteFlags. + uint32 flags; +}; + // An interface providing mutation access to a PersistentPrefStore. interface PersistentPrefStore { - // Sets the value for |key|. A null |value| indicates a delete. |flags| is a - // bitmask of WritablePrefStore::PrefWriteFlags. - SetValue(string key, mojo.common.mojom.Value? value, uint32 flags); + // Sets the values for prefs. + SetValues(array<PrefUpdate> updates); // These mirror the C++ PersistentPrefStore methods. CommitPendingWrite();
diff --git a/services/service_manager/background/tests/background_service_manager_unittest.cc b/services/service_manager/background/tests/background_service_manager_unittest.cc index e939e0e..3d9f43d 100644 --- a/services/service_manager/background/tests/background_service_manager_unittest.cc +++ b/services/service_manager/background/tests/background_service_manager_unittest.cc
@@ -27,12 +27,6 @@ ServiceImpl() {} ~ServiceImpl() override {} - // Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - return false; - } - private: DISALLOW_COPY_AND_ASSIGN(ServiceImpl); };
diff --git a/services/service_manager/background/tests/test_service.cc b/services/service_manager/background/tests/test_service.cc index 96fd1522..1a4e59a 100644 --- a/services/service_manager/background/tests/test_service.cc +++ b/services/service_manager/background/tests/test_service.cc
@@ -5,7 +5,7 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/background/tests/test.mojom.h" #include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/interface_registry.h" +#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.h" #include "services/service_manager/public/cpp/service_runner.h" @@ -18,15 +18,16 @@ public InterfaceFactory<mojom::TestService>, public mojom::TestService { public: - TestClient() {} + TestClient() { registry_.AddInterface(this); } ~TestClient() override {} private: // Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface(this); - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<mojom::TestService>: @@ -42,6 +43,7 @@ void Quit() override { context()->RequestQuit(); } + BinderRegistry registry_; mojo::BindingSet<mojom::TestService> bindings_; DISALLOW_COPY_AND_ASSIGN(TestClient);
diff --git a/services/service_manager/connect_params.cc b/services/service_manager/connect_params.cc index e8464a8b..7947a75 100644 --- a/services/service_manager/connect_params.cc +++ b/services/service_manager/connect_params.cc
@@ -7,6 +7,9 @@ namespace service_manager { ConnectParams::ConnectParams() {} -ConnectParams::~ConnectParams() {} +ConnectParams::~ConnectParams() { + if (!start_service_callback_.is_null()) + start_service_callback_.Run(result_, resolved_identity_); +} } // namespace service_manager
diff --git a/services/service_manager/connect_params.h b/services/service_manager/connect_params.h index 8c8787a..c0cbf65 100644 --- a/services/service_manager/connect_params.h +++ b/services/service_manager/connect_params.h
@@ -10,9 +10,9 @@ #include "base/callback.h" #include "base/macros.h" +#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/interfaces/connector.mojom.h" -#include "services/service_manager/public/interfaces/interface_provider.mojom.h" #include "services/service_manager/public/interfaces/service.mojom.h" namespace service_manager { @@ -29,13 +29,6 @@ void set_target(const Identity& target) { target_ = target; } const Identity& target() const { return target_; } - void set_remote_interfaces(mojom::InterfaceProviderRequest value) { - remote_interfaces_ = std::move(value); - } - mojom::InterfaceProviderRequest TakeRemoteInterfaces() { - return std::move(remote_interfaces_); - } - void set_client_process_info( mojom::ServicePtr service, mojom::PIDReceiverRequest pid_receiver_request) { @@ -68,20 +61,15 @@ return std::move(interface_pipe_); } - void set_connect_callback(const mojom::Connector::ConnectCallback& value) { - connect_callback_ = value; - } - const mojom::Connector::ConnectCallback& connect_callback() const { - return connect_callback_; + void set_start_service_callback( + const Connector::StartServiceCallback& callback) { + start_service_callback_ = callback; } - void set_bind_interface_callback( - const mojom::Connector::BindInterfaceCallback& callback) { - bind_interface_callback_ = callback; - } - const mojom::Connector::BindInterfaceCallback& - bind_interface_callback() const { - return bind_interface_callback_; + void set_response_data(mojom::ConnectResult result, + const Identity& resolved_identity) { + result_ = result; + resolved_identity_ = resolved_identity; } private: @@ -91,13 +79,16 @@ // The identity of the application being connected to. Identity target_; - mojom::InterfaceProviderRequest remote_interfaces_; mojom::ServicePtr service_; mojom::PIDReceiverRequest pid_receiver_request_; std::string interface_name_; mojo::ScopedMessagePipeHandle interface_pipe_; - mojom::Connector::ConnectCallback connect_callback_; - mojom::Connector::BindInterfaceCallback bind_interface_callback_; + mojom::Connector::StartServiceCallback start_service_callback_; + + // These values are supplied to the response callback for StartService()/ + // BindInterface() etc. when the connection is completed. + mojom::ConnectResult result_ = mojom::ConnectResult::INVALID_ARGUMENT; + Identity resolved_identity_; DISALLOW_COPY_AND_ASSIGN(ConnectParams); };
diff --git a/services/service_manager/connect_util.cc b/services/service_manager/connect_util.cc index c37b662..085fdf60 100644 --- a/services/service_manager/connect_util.cc +++ b/services/service_manager/connect_util.cc
@@ -7,11 +7,18 @@ #include <memory> #include <utility> +#include "base/bind.h" #include "services/service_manager/connect_params.h" #include "services/service_manager/service_manager.h" namespace service_manager { +namespace { + +void EmptyStartServiceCallback(mojom::ConnectResult result, + const Identity& resolved_identity) {} +} + mojo::ScopedMessagePipeHandle BindInterface( ServiceManager* service_manager, const Identity& source, @@ -22,6 +29,7 @@ params->set_target(target); mojo::MessagePipe pipe; params->set_interface_request_info(interface_name, std::move(pipe.handle1)); + params->set_start_service_callback(base::Bind(&EmptyStartServiceCallback)); service_manager->Connect(std::move(params)); return std::move(pipe.handle0); }
diff --git a/services/service_manager/public/cpp/BUILD.gn b/services/service_manager/public/cpp/BUILD.gn index 3320e94..a2452f5c 100644 --- a/services/service_manager/public/cpp/BUILD.gn +++ b/services/service_manager/public/cpp/BUILD.gn
@@ -13,7 +13,6 @@ sources = [ "binder_registry.h", "connect.h", - "connection.h", "connector.h", "identity.h", "interface_binder.h", @@ -25,8 +24,6 @@ "lib/binder_registry.cc", "lib/callback_binder.cc", "lib/callback_binder.h", - "lib/connection_impl.cc", - "lib/connection_impl.h", "lib/connector_impl.cc", "lib/connector_impl.h", "lib/identity.cc",
diff --git a/services/service_manager/public/cpp/connection.h b/services/service_manager/public/cpp/connection.h deleted file mode 100644 index 28eee4d4..0000000 --- a/services/service_manager/public/cpp/connection.h +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2014 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 SERVICES_SERVICE_MANAGER_PUBLIC_CPP_CONNECTION_H_ -#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_CONNECTION_H_ - -#include "base/memory/weak_ptr.h" -#include "services/service_manager/public/cpp/identity.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "services/service_manager/public/interfaces/connector.mojom.h" - -namespace service_manager { - -class InterfaceProvider; - -// Represents a connection to another application. An implementation of this -// interface is returned from Connector::Connect(). -class Connection { - public: - virtual ~Connection() {} - - enum class State { - // The service manager has not yet processed the connection. - PENDING, - - // The service manager processed the connection and it was established. - // GetResult() returns mojom::ConnectionResult::SUCCESS. - CONNECTED, - - // The service manager processed the connection and establishment was - // prevented by an error, call GetResult(). - DISCONNECTED - }; - - class TestApi { - public: - explicit TestApi(Connection* connection) : connection_(connection) {} - base::WeakPtr<Connection> GetWeakPtr() { - return connection_->GetWeakPtr(); - } - - private: - Connection* connection_; - }; - - // Binds |ptr| to an implementation of Interface in the remote application. - // |ptr| can immediately be used to start sending requests to the remote - // interface. - template <typename Interface> - void GetInterface(mojo::InterfacePtr<Interface>* ptr) { - GetRemoteInterfaces()->GetInterface(ptr); - } - template <typename Interface> - void GetInterface(mojo::InterfaceRequest<Interface> request) { - GetRemoteInterfaces()->GetInterface(std::move(request)); - } - - // Returns the remote identity. While the connection is in the pending state, - // the user_id() field will be the value passed via Connect(). After the - // connection is completed, it will change to the value assigned by the - // service manager. Call AddConnectionCompletedClosure() to schedule a closure - // to be run when the resolved user id is available. - virtual const Identity& GetRemoteIdentity() const = 0; - - // Register a handler to receive an error notification on the pipe to the - // remote application's InterfaceProvider. - virtual void SetConnectionLostClosure(const base::Closure& handler) = 0; - - // Returns the result of the connection. This function should only be called - // when the connection state is not pending. Call - // AddConnectionCompletedClosure() to schedule a closure to be run when the - // connection is processed by the service manager. - virtual mojom::ConnectResult GetResult() const = 0; - - // Returns true if the connection has not yet been processed by the service - // manager. - virtual bool IsPending() const = 0; - - // Register a closure to be run when the connection has been completed by the - // service manager and remote metadata is available. Useful only for - // connections created - // via Connector::Connect(). Once the connection is complete, metadata is - // available immediately. - virtual void AddConnectionCompletedClosure(const base::Closure& callback) = 0; - - // Returns an object encapsulating a remote InterfaceProvider. - virtual InterfaceProvider* GetRemoteInterfaces() = 0; - - protected: - virtual base::WeakPtr<Connection> GetWeakPtr() = 0; -}; - -} // namespace service_manager - -#endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_CONNECTION_H_
diff --git a/services/service_manager/public/cpp/connector.h b/services/service_manager/public/cpp/connector.h index 37d8338..ae15116 100644 --- a/services/service_manager/public/cpp/connector.h +++ b/services/service_manager/public/cpp/connector.h
@@ -7,7 +7,6 @@ #include <memory> -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/interfaces/connector.mojom.h" #include "services/service_manager/public/interfaces/service.mojom.h" @@ -17,27 +16,31 @@ // An interface that encapsulates the Service Manager's brokering interface, by // which -// connections between services are established. Once Connect() is called, -// this class is bound to the thread the call was made on and it cannot be -// passed to another thread without calling Clone(). +// connections between services are established. Once either StartService() or +// BindInterface() is called, this class is bound to the thread the call was +// made on and it cannot be passed to another thread without calling Clone(). // // An instance of this class is created internally by ServiceContext for use // on the thread ServiceContext is instantiated on. // // To use this interface on another thread, call Clone() and pass the new -// instance to the desired thread before calling Connect(). +// instance to the desired thread before calling StartService() or +// BindInterface(). // // While instances of this object are owned by the caller, the underlying // connection with the service manager is bound to the lifetime of the instance -// that -// created it, i.e. when the application is terminated the Connector pipe is -// closed. +// that created it, i.e. when the application is terminated the Connector pipe +// is closed. class Connector { public: + using StartServiceCallback = + base::Callback<void(mojom::ConnectResult, const Identity& identity)>; + class TestApi { public: using Binder = base::Callback<void(mojo::ScopedMessagePipeHandle)>; explicit TestApi(Connector* connector) : connector_(connector) {} + ~TestApi() { connector_->ResetStartServiceCallback(); } // Allows caller to specify a callback to bind requests for |interface_name| // from |service_name| locally, rather than passing the request through the @@ -50,6 +53,13 @@ } void ClearBinderOverrides() { connector_->ClearBinderOverrides(); } + // Register a callback to be run with the result of an attempt to start a + // service. This will be run in response to calls to StartService() or + // BindInterface(). + void SetStartServiceCallback(const StartServiceCallback& callback) { + connector_->SetStartServiceCallback(callback); + } + private: Connector* connector_; }; @@ -60,22 +70,20 @@ // for the other end the Connector's interface. static std::unique_ptr<Connector> Create(mojom::ConnectorRequest* request); + // Creates an instance of a service for |identity|. + virtual void StartService(const Identity& identity) = 0; + + // Creates an instance of the service |name| inheriting the caller's identity. + virtual void StartService(const std::string& name) = 0; + // Creates an instance of a service for |identity| in a process started by the - // client (or someone else). Must be called before Connect() may be called to - // |identity|. + // client (or someone else). Must be called before BindInterface() may be + // called to |identity|. virtual void StartService( const Identity& identity, mojom::ServicePtr service, mojom::PIDReceiverRequest pid_receiver_request) = 0; - // Requests a new connection to a service. Returns a pointer to the - // connection if the connection is permitted by that service, nullptr - // otherwise. Once this method is called, this object is bound to the thread - // on which the call took place. To pass to another thread, call Clone() and - // pass the result. - virtual std::unique_ptr<Connection> Connect(const std::string& name) = 0; - virtual std::unique_ptr<Connection> Connect(const Identity& target) = 0; - // Connect to |target| & request to bind |Interface|. template <typename Interface> void BindInterface(const Identity& target, @@ -100,8 +108,9 @@ mojo::ScopedMessagePipeHandle interface_pipe) = 0; // Creates a new instance of this class which may be passed to another thread. - // The returned object may be passed multiple times until Connect() is called, - // at which point this method must be called again to pass again. + // The returned object may be passed multiple times until StartService() or + // BindInterface() is called, at which point this method must be called again + // to pass again. virtual std::unique_ptr<Connector> Clone() = 0; // Binds a Connector request to the other end of this Connector. @@ -114,6 +123,9 @@ const std::string& interface_name, const TestApi::Binder& binder) = 0; virtual void ClearBinderOverrides() = 0; + virtual void SetStartServiceCallback( + const StartServiceCallback& callback) = 0; + virtual void ResetStartServiceCallback() = 0; }; } // namespace service_manager
diff --git a/services/service_manager/public/cpp/lib/connection_impl.cc b/services/service_manager/public/cpp/lib/connection_impl.cc deleted file mode 100644 index bd4ca44..0000000 --- a/services/service_manager/public/cpp/lib/connection_impl.cc +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2014 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 "services/service_manager/public/cpp/lib/connection_impl.h" - -#include <stdint.h> - -#include <utility> - -#include "base/bind.h" -#include "base/logging.h" -#include "services/service_manager/public/cpp/connection.h" -#include "services/service_manager/public/cpp/interface_binder.h" - -namespace service_manager { -namespace internal { - -//////////////////////////////////////////////////////////////////////////////// -// ConnectionImpl, public: - -ConnectionImpl::ConnectionImpl() - : weak_factory_(this) {} - -ConnectionImpl::ConnectionImpl(const Identity& remote, State initial_state) - : remote_(remote), - state_(initial_state), - weak_factory_(this) { -} - -ConnectionImpl::~ConnectionImpl() {} - -void ConnectionImpl::SetRemoteInterfaces( - std::unique_ptr<InterfaceProvider> remote_interfaces) { - remote_interfaces_owner_ = std::move(remote_interfaces); - set_remote_interfaces(remote_interfaces_owner_.get()); -} - -service_manager::mojom::Connector::ConnectCallback -ConnectionImpl::GetConnectCallback() { - return base::Bind(&ConnectionImpl::OnConnectionCompleted, - weak_factory_.GetWeakPtr()); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConnectionImpl, Connection implementation: - -const Identity& ConnectionImpl::GetRemoteIdentity() const { - return remote_; -} - -void ConnectionImpl::SetConnectionLostClosure(const base::Closure& handler) { - remote_interfaces_->SetConnectionLostClosure(handler); -} - -service_manager::mojom::ConnectResult ConnectionImpl::GetResult() const { - return result_; -} - -bool ConnectionImpl::IsPending() const { - return state_ == State::PENDING; -} - -void ConnectionImpl::AddConnectionCompletedClosure( - const base::Closure& callback) { - if (IsPending()) - connection_completed_callbacks_.push_back(callback); - else - callback.Run(); -} - -InterfaceProvider* ConnectionImpl::GetRemoteInterfaces() { - return remote_interfaces_; -} - -base::WeakPtr<Connection> ConnectionImpl::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConnectionImpl, private: - -void ConnectionImpl::OnConnectionCompleted( - service_manager::mojom::ConnectResult result, - const std::string& target_user_id) { - DCHECK(State::PENDING == state_); - - result_ = result; - state_ = result_ == service_manager::mojom::ConnectResult::SUCCEEDED - ? State::CONNECTED - : State::DISCONNECTED; - remote_.set_user_id(target_user_id); - std::vector<base::Closure> callbacks; - callbacks.swap(connection_completed_callbacks_); - for (auto callback : callbacks) - callback.Run(); -} - -} // namespace internal -} // namespace service_manager
diff --git a/services/service_manager/public/cpp/lib/connection_impl.h b/services/service_manager/public/cpp/lib/connection_impl.h deleted file mode 100644 index a1fabf5..0000000 --- a/services/service_manager/public/cpp/lib/connection_impl.h +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2014 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 SERVICES_SERVICE_MANAGER_PUBLIC_CPP_LIB_CONNECTION_IMPL_H_ -#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_LIB_CONNECTION_IMPL_H_ - -#include <stdint.h> - -#include <set> -#include <string> - -#include "base/callback.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/service_manager/public/cpp/connection.h" -#include "services/service_manager/public/cpp/identity.h" -#include "services/service_manager/public/cpp/interface_provider_spec.h" -#include "services/service_manager/public/interfaces/connector.mojom.h" -#include "services/service_manager/public/interfaces/interface_provider.mojom.h" - -namespace service_manager { -namespace internal { - -// A ConnectionImpl represents each half of a connection between two -// applications, allowing customization of which interfaces are published to the -// other. -class ConnectionImpl : public Connection { - public: - ConnectionImpl(); - ConnectionImpl(const Identity& remote, State initial_state); - ~ConnectionImpl() override; - - // Sets the remote provider, transferring ownership to the ConnectionImpl. - void SetRemoteInterfaces( - std::unique_ptr<InterfaceProvider> remote_interfaces); - - // Sets the remote provider, without transferring ownership. - void set_remote_interfaces(InterfaceProvider* remote_interfaces) { - remote_interfaces_ = remote_interfaces; - } - - service_manager::mojom::Connector::ConnectCallback GetConnectCallback(); - - private: - // Connection: - const Identity& GetRemoteIdentity() const override; - void SetConnectionLostClosure(const base::Closure& handler) override; - service_manager::mojom::ConnectResult GetResult() const override; - bool IsPending() const override; - void AddConnectionCompletedClosure(const base::Closure& callback) override; - InterfaceProvider* GetRemoteInterfaces() override; - base::WeakPtr<Connection> GetWeakPtr() override; - - void OnConnectionCompleted(service_manager::mojom::ConnectResult result, - const std::string& target_user_id); - - Identity remote_; - - State state_; - service_manager::mojom::ConnectResult result_ = - service_manager::mojom::ConnectResult::SUCCEEDED; - std::vector<base::Closure> connection_completed_callbacks_; - - InterfaceProvider* remote_interfaces_ = nullptr; - - std::unique_ptr<InterfaceProvider> remote_interfaces_owner_; - - base::WeakPtrFactory<ConnectionImpl> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ConnectionImpl); -}; - -} // namespace internal -} // namespace service_manager - -#endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_LIB_CONNECTION_IMPL_H_
diff --git a/services/service_manager/public/cpp/lib/connector_impl.cc b/services/service_manager/public/cpp/lib/connector_impl.cc index 3e7c8410..0040a32 100644 --- a/services/service_manager/public/cpp/lib/connector_impl.cc +++ b/services/service_manager/public/cpp/lib/connector_impl.cc
@@ -6,14 +6,9 @@ #include "base/memory/ptr_util.h" #include "services/service_manager/public/cpp/identity.h" -#include "services/service_manager/public/cpp/lib/connection_impl.h" namespace service_manager { -namespace { -void EmptyBindCallback(mojom::ConnectResult, const std::string&) {} -} - ConnectorImpl::ConnectorImpl(mojom::ConnectorPtrInfo unbound_state) : unbound_state_(std::move(unbound_state)), weak_factory_(this) { thread_checker_.DetachFromThread(); @@ -32,6 +27,17 @@ connector_.reset(); } +void ConnectorImpl::StartService(const Identity& identity) { + if (BindConnectorIfNecessary()) + connector_->StartService(identity, + base::Bind(&ConnectorImpl::StartServiceCallback, + weak_factory_.GetWeakPtr())); +} + +void ConnectorImpl::StartService(const std::string& name) { + StartService(Identity(name, mojom::kInheritUserID)); +} + void ConnectorImpl::StartService( const Identity& identity, mojom::ServicePtr service, @@ -40,33 +46,11 @@ return; DCHECK(service.is_bound() && pid_receiver_request.is_pending()); - connector_->StartService(identity, - service.PassInterface().PassHandle(), - std::move(pid_receiver_request)); -} - -std::unique_ptr<Connection> ConnectorImpl::Connect(const std::string& name) { - return Connect(Identity(name, mojom::kInheritUserID)); -} - -std::unique_ptr<Connection> ConnectorImpl::Connect(const Identity& target) { - if (!BindConnectorIfNecessary()) - return nullptr; - - DCHECK(thread_checker_.CalledOnValidThread()); - - mojom::InterfaceProviderPtr remote_interfaces; - mojom::InterfaceProviderRequest remote_request(&remote_interfaces); - std::unique_ptr<internal::ConnectionImpl> connection( - new internal::ConnectionImpl(target, Connection::State::PENDING)); - std::unique_ptr<InterfaceProvider> remote_interface_provider( - new InterfaceProvider); - remote_interface_provider->Bind(std::move(remote_interfaces)); - connection->SetRemoteInterfaces(std::move(remote_interface_provider)); - - connector_->Connect(target, std::move(remote_request), - connection->GetConnectCallback()); - return std::move(connection); + connector_->StartServiceWithProcess( + identity, service.PassInterface().PassHandle(), + std::move(pid_receiver_request), + base::Bind(&ConnectorImpl::StartServiceCallback, + weak_factory_.GetWeakPtr())); } void ConnectorImpl::BindInterface( @@ -86,7 +70,8 @@ } connector_->BindInterface(target, interface_name, std::move(interface_pipe), - base::Bind(&EmptyBindCallback)); + base::Bind(&ConnectorImpl::StartServiceCallback, + weak_factory_.GetWeakPtr())); } std::unique_ptr<Connector> ConnectorImpl::Clone() { @@ -119,6 +104,15 @@ local_binder_overrides_.clear(); } +void ConnectorImpl::SetStartServiceCallback( + const Connector::StartServiceCallback& callback) { + start_service_callback_ = callback; +} + +void ConnectorImpl::ResetStartServiceCallback() { + start_service_callback_.Reset(); +} + bool ConnectorImpl::BindConnectorIfNecessary() { // Bind this object to the current thread the first time it is used to // connect. @@ -142,6 +136,12 @@ return true; } +void ConnectorImpl::StartServiceCallback(mojom::ConnectResult result, + const Identity& user_id) { + if (!start_service_callback_.is_null()) + start_service_callback_.Run(result, user_id); +} + std::unique_ptr<Connector> Connector::Create(mojom::ConnectorRequest* request) { mojom::ConnectorPtr proxy; *request = mojo::MakeRequest(&proxy);
diff --git a/services/service_manager/public/cpp/lib/connector_impl.h b/services/service_manager/public/cpp/lib/connector_impl.h index 6263f44..b07fb2b 100644 --- a/services/service_manager/public/cpp/lib/connector_impl.h +++ b/services/service_manager/public/cpp/lib/connector_impl.h
@@ -25,11 +25,11 @@ void OnConnectionError(); // Connector: + void StartService(const Identity& identity) override; + void StartService(const std::string& name) override; void StartService(const Identity& identity, mojom::ServicePtr service, mojom::PIDReceiverRequest pid_receiver_request) override; - std::unique_ptr<Connection> Connect(const std::string& name) override; - std::unique_ptr<Connection> Connect(const Identity& target) override; void BindInterface(const Identity& target, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; @@ -40,9 +40,15 @@ const std::string& interface_name, const TestApi::Binder& binder) override; void ClearBinderOverrides() override; + void SetStartServiceCallback(const StartServiceCallback& callback) override; + void ResetStartServiceCallback() override; bool BindConnectorIfNecessary(); + // Callback passed to mojom methods StartService()/BindInterface(). + void StartServiceCallback(mojom::ConnectResult result, + const Identity& user_id); + using BinderOverrideMap = std::map<std::string, TestApi::Binder>; mojom::ConnectorPtrInfo unbound_state_; @@ -51,8 +57,9 @@ base::ThreadChecker thread_checker_; std::map<std::string, BinderOverrideMap> local_binder_overrides_; + Connector::StartServiceCallback start_service_callback_; - base::WeakPtrFactory<Connector> weak_factory_; + base::WeakPtrFactory<ConnectorImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ConnectorImpl); };
diff --git a/services/service_manager/public/cpp/lib/identity.cc b/services/service_manager/public/cpp/lib/identity.cc index 4fa2ff2..409bee1 100644 --- a/services/service_manager/public/cpp/lib/identity.cc +++ b/services/service_manager/public/cpp/lib/identity.cc
@@ -5,10 +5,11 @@ #include "services/service_manager/public/cpp/identity.h" #include "base/guid.h" +#include "services/service_manager/public/interfaces/connector.mojom.h" namespace service_manager { -Identity::Identity() {} +Identity::Identity() : Identity("", mojom::kInheritUserID, "") {} Identity::Identity(const std::string& name, const std::string& user_id) : Identity(name, user_id, "") {}
diff --git a/services/service_manager/public/cpp/lib/interface_registry.cc b/services/service_manager/public/cpp/lib/interface_registry.cc index 9fb605d8..e74df3c 100644 --- a/services/service_manager/public/cpp/lib/interface_registry.cc +++ b/services/service_manager/public/cpp/lib/interface_registry.cc
@@ -9,7 +9,6 @@ #include "base/memory/ptr_util.h" #include "mojo/public/cpp/bindings/message.h" -#include "services/service_manager/public/cpp/connection.h" namespace service_manager { namespace {
diff --git a/services/service_manager/public/cpp/lib/service.cc b/services/service_manager/public/cpp/lib/service.cc index 2b40a6c..b6a20a03b 100644 --- a/services/service_manager/public/cpp/lib/service.cc +++ b/services/service_manager/public/cpp/lib/service.cc
@@ -6,8 +6,6 @@ #include "base/logging.h" #include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/interfaces/interface_provider.mojom.h" -#include "services/service_manager/public/interfaces/interface_provider_spec.mojom.h" namespace service_manager { @@ -17,30 +15,9 @@ void Service::OnStart() {} -bool Service::OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) { - return false; -} - void Service::OnBindInterface(const ServiceInfo& source_info, const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) { - // TODO(beng): Eliminate this implementation once everyone is migrated to - // OnBindInterface(). - mojom::InterfaceProviderPtr interface_provider; - InterfaceProviderSpec source_spec, target_spec; - GetInterfaceProviderSpec( - mojom::kServiceManager_ConnectorSpec, - service_context_->local_info().interface_provider_specs, - &target_spec); - GetInterfaceProviderSpec( - mojom::kServiceManager_ConnectorSpec, - source_info.interface_provider_specs, - &source_spec); - service_context_->CallOnConnect(source_info, source_spec, target_spec, - MakeRequest(&interface_provider)); - interface_provider->GetInterface(interface_name, std::move(interface_pipe)); -} + mojo::ScopedMessagePipeHandle interface_pipe) {} bool Service::OnServiceManagerConnectionLost() { return true; @@ -64,11 +41,6 @@ target_->OnStart(); } -bool ForwardingService::OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) { - return target_->OnConnect(remote_info, registry); -} - void ForwardingService::OnBindInterface( const ServiceInfo& remote_info, const std::string& interface_name,
diff --git a/services/service_manager/public/cpp/lib/service_context.cc b/services/service_manager/public/cpp/lib/service_context.cc index 6459459..0b53f8c 100644 --- a/services/service_manager/public/cpp/lib/service_context.cc +++ b/services/service_manager/public/cpp/lib/service_context.cc
@@ -7,15 +7,8 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "mojo/public/cpp/bindings/interface_ptr.h" #include "mojo/public/cpp/bindings/interface_request.h" -#include "services/service_manager/public/cpp/interface_provider_spec.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/lib/connector_impl.h" #include "services/service_manager/public/cpp/service.h" @@ -88,22 +81,6 @@ service_->OnStart(); } -void ServiceContext::OnConnect( - const ServiceInfo& source_info, - mojom::InterfaceProviderRequest interfaces, - const OnConnectCallback& callback) { - InterfaceProviderSpec source_spec, target_spec; - GetInterfaceProviderSpec(mojom::kServiceManager_ConnectorSpec, - local_info_.interface_provider_specs, &target_spec); - GetInterfaceProviderSpec(mojom::kServiceManager_ConnectorSpec, - source_info.interface_provider_specs, &source_spec); - - // Acknowledge the request regardless of whether it's accepted. - callback.Run(); - - CallOnConnect(source_info, source_spec, target_spec, std::move(interfaces)); -} - void ServiceContext::OnBindInterface( const ServiceInfo& source_info, const std::string& interface_name, @@ -119,26 +96,6 @@ //////////////////////////////////////////////////////////////////////////////// // ServiceContext, private: -void ServiceContext::CallOnConnect(const ServiceInfo& source_info, - const InterfaceProviderSpec& source_spec, - const InterfaceProviderSpec& target_spec, - mojom::InterfaceProviderRequest interfaces) { - auto registry = - base::MakeUnique<InterfaceRegistry>(mojom::kServiceManager_ConnectorSpec); - registry->Bind(std::move(interfaces), local_info_.identity, target_spec, - source_info.identity, source_spec); - - if (!service_->OnConnect(source_info, registry.get())) - return; - - InterfaceRegistry* raw_registry = registry.get(); - registry->AddConnectionLostClosure(base::Bind( - &ServiceContext::OnRegistryConnectionError, base::Unretained(this), - raw_registry)); - connection_interface_registries_.insert( - std::make_pair(raw_registry, std::move(registry))); -} - void ServiceContext::OnConnectionError() { if (service_->OnServiceManagerConnectionLost()) { // CAUTION: May delete |this|. @@ -146,21 +103,4 @@ } } -void ServiceContext::OnRegistryConnectionError(InterfaceRegistry* registry) { - // NOTE: We destroy the InterfaceRegistry asynchronously since it's calling - // into us from its own connection error handler which may continue to access - // the InterfaceRegistry's own state after we return. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&ServiceContext::DestroyConnectionInterfaceRegistry, - weak_factory_.GetWeakPtr(), registry)); -} - -void ServiceContext::DestroyConnectionInterfaceRegistry( - InterfaceRegistry* registry) { - auto it = connection_interface_registries_.find(registry); - CHECK(it != connection_interface_registries_.end()); - connection_interface_registries_.erase(it); -} - } // namespace service_manager
diff --git a/services/service_manager/public/cpp/lib/service_test.cc b/services/service_manager/public/cpp/lib/service_test.cc index 13689ad..30fd49b 100644 --- a/services/service_manager/public/cpp/lib/service_test.cc +++ b/services/service_manager/public/cpp/lib/service_test.cc
@@ -27,11 +27,10 @@ context()->identity().user_id()); } -bool ServiceTestClient::OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) { - return false; -} - +void ServiceTestClient::OnBindInterface( + const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) {} ServiceTest::ServiceTest() {}
diff --git a/services/service_manager/public/cpp/service.h b/services/service_manager/public/cpp/service.h index db5ad50..9d0c04e 100644 --- a/services/service_manager/public/cpp/service.h +++ b/services/service_manager/public/cpp/service.h
@@ -12,7 +12,6 @@ namespace service_manager { -class InterfaceRegistry; class ServiceContext; struct ServiceInfo; @@ -28,16 +27,6 @@ // will be made before this. virtual void OnStart(); - // Called each time a connection to this service is brokered by the Service - // Manager. Implement this to expose interfaces to other services. - // - // Return true if the connection should succeed or false if the connection - // should be rejected. - // - // The default implementation returns false. - virtual bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry); - // Called when the service identified by |source_info| requests this service // bind a request for |interface_name|. If this method has been called, the // service manager has already determined that policy permits this interface @@ -89,8 +78,6 @@ // Service: void OnStart() override; - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override; void OnBindInterface(const ServiceInfo& remote_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override;
diff --git a/services/service_manager/public/cpp/service_context.h b/services/service_manager/public/cpp/service_context.h index f843462..8cfea21 100644 --- a/services/service_manager/public/cpp/service_context.h +++ b/services/service_manager/public/cpp/service_context.h
@@ -108,33 +108,16 @@ private: friend class service_manager::Service; - using InterfaceRegistryMap = - std::map<InterfaceRegistry*, std::unique_ptr<InterfaceRegistry>>; - // mojom::Service: void OnStart(const ServiceInfo& info, const OnStartCallback& callback) override; - void OnConnect(const ServiceInfo& source_info, - mojom::InterfaceProviderRequest interfaces, - const OnConnectCallback& callback) override; void OnBindInterface( const ServiceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe, const OnBindInterfaceCallback& callback) override; - void CallOnConnect(const ServiceInfo& source_info, - const InterfaceProviderSpec& source_spec, - const InterfaceProviderSpec& target_spec, - mojom::InterfaceProviderRequest request); - void OnConnectionError(); - void OnRegistryConnectionError(InterfaceRegistry* registry); - void DestroyConnectionInterfaceRegistry(InterfaceRegistry* registry); - - // We track the lifetime of incoming connection registries as a convenience - // for the client. - InterfaceRegistryMap connection_interface_registries_; // A pending Connector request which will eventually be passed to the Service // Manager.
diff --git a/services/service_manager/public/cpp/service_test.h b/services/service_manager/public/cpp/service_test.h index 1ee7b9a9..a4bfc74 100644 --- a/services/service_manager/public/cpp/service_test.h +++ b/services/service_manager/public/cpp/service_test.h
@@ -43,8 +43,9 @@ protected: void OnStart() override; - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; private: ServiceTest* test_;
diff --git a/services/service_manager/public/interfaces/connector.mojom b/services/service_manager/public/interfaces/connector.mojom index 3c759cbb..63168e4a 100644 --- a/services/service_manager/public/interfaces/connector.mojom +++ b/services/service_manager/public/interfaces/connector.mojom
@@ -6,50 +6,51 @@ import "services/service_manager/public/interfaces/interface_provider.mojom"; +// TODO(beng): Determine who (if anyone) uses kRootUserID. const string kRootUserID = "505C0EE9-3013-43C0-82B0-A84F50CF8D84"; const string kInheritUserID = "D26290E4-4485-4EAE-81A2-66D1EEB40A9D"; const uint32 kInvalidInstanceID = 0; +// TODO(beng): Evalute the utility of this enum. There are some inconsistencies +// in its use with BindInterface/StartService. enum ConnectResult { - // The connection was established successfully. + // The operation was established successfully. SUCCEEDED, // The name or user id supplied was malformed, or the service specified by // |name| could not be loaded. INVALID_ARGUMENT, - // The connection was blocked by policy. Either connections to |name| are - // forbidden from this app by the CapabilityFilter, or the service attempted - // to connect using a user id other than its own, |kInheritUserID| or - // |kRootUserID|. + // Policy prevented the successful completion of this operation. Either + // requests to bind to |name| are forbidden from the calling service by its + // manifest, or the service attempted to connect using a user id other than + // its own, |kInheritUserID| or |kRootUserID|. ACCESS_DENIED }; // A collection of metadata that disambiguates instances in the service manager. struct Identity { - // A service: or exe: name identifying a service. + // A name identifying a service. string name; - // The user id of the target service instance to connect to. If no such - // instance exists, the service manager may start one. This user id will be - // passed to the new instance via Initialize(). + // The user id of the target service instance to bind to. If no such instance + // exists, the service manager may start one. This user id will be passed to + // the new instance via Initialize(). // - // When connecting to other services, services must generally pass - // kInheritUserID for this value, and the service manager will either connect - // to an existing instance matching the caller's user id, create a new - // instance matching the caller's user id, or connect to an existing instance - // running as kRootUserID. By default, services do not have the ability to set - // arbitrary values to this field, and doing so will result in a connection - // error on the remote service provider. + // When binding to other services, services must generally pass kInheritUserID + // for this value, and the service manager will either bind to an existing + // instance matching the caller's user id, create a new instance matching the + // caller's user id, or bind to an existing instance running as kRootUserID. + // By default, services do not have the ability to set arbitrary values to + // this field, and doing so will result in an error response. // // A service with the ability to launch other services with arbitrary user ids - // (e.g. a login service) may set this value to something meaningful to it. - // The user id string is a valid guid of the form - // "%08X-%04X-%04X-%04X-%012llX", and (aside from the root user whose - // guid is defined above) intended to be not-guessable. + // (e.g. a login service) may set this value. The user id string is a valid + // guid of the form "%08X-%04X-%04X-%04X-%012llX", and (aside from the root + // user whose guid is defined above) intended to be not-guessable. // - // When a service is initialized or receives a connection from another + // When a service is initialized or receives a bind request from another // service, this value is always the resolved user id, never |kInheritUserID|. string user_id; @@ -67,18 +68,85 @@ SetPID(uint32 pid); }; -// Encapsulates establishing connections with other Services. +// An interface that allows the holder to start other services & bind to +// interfaces exposed by them. interface Connector { - // Typically, the service manager will start a process for a service the first - // time it receives a connection request for it. This struct allows a client - // to start the process itself and provide the service manager the pipes it - // needs to communicate with it. When this function is called, the client owns - // the lifetime of the child process it started, not the service manager. The - // service manager binds the |service| pipe, and when it closes destroys the - // associated instance but the process stays alive. + // Asks the service manager to route a request to bind an implementation of + // the interface to a named service instance. + // + // A service's ability to bind interfaces exposed by another is controlled by + // policy set out in each service's manifest. See + // //services/service_manager/README.md for more information on manifests. + // If policy prevents the requesting service from binding the specified + // interface, the request pipe will be closed. // // Parameters: // + // target + // The identity of the service instance to route the request to. If no + // instance exists, the service will be started. + // + // interface_name + // The name of the interface to be bound. If the target service does not + // expose an interface of this name, the request pipe will be closed. + // + // interface_pipe + // A message pipe endpoint encapsulating a request for an interface named + // |interface_name|. + // + // Response parameters: + // + // result + // Indicates the result of the BindInterface() operation. + // + // identity + // The fully resolved identity of the instance in the service manager, with + // a resolved user id. Typically the client passes |kInheritUserID| as the + // user id to BindInterface(), which will be resolved by the service + // manager into a concrete user id. + // + BindInterface(Identity target, + string interface_name, + handle<message_pipe> interface_pipe) => + (ConnectResult result, Identity user_id); + + // Asks the service manager to create an instance for a service. No action is + // taken if an instance is already present. If the service is not yet running, + // it will be initialized and its OnStart() method will be called. A process + // may be allocated. + // + // Parameters: + // + // target + // The identity of the service to start. + // + // Response parameters: + // + // result + // Indicates the result of the StartService() operation. + // + // identity + // The fully resolved identity of the instance in the service manager, with + // a resolved user id. Typically the client passes |kInheritUserID| as the + // user id to BindInterface(), which will be resolved by the service + // manager into a concrete user id. + // + StartService(Identity target) => (ConnectResult result, Identity identity); + + // Typically, the service manager will start a process for a service the first + // time it receives a bind interface request for it, or when StartService() is + // called. This struct allows a client to start the process itself and provide + // the service manager the pipes it needs to communicate with it. When this + // function is called, the client owns the lifetime of the child process it + // started, not the service manager. The service manager binds the |service| + // pipe, and when it closes destroys the associated instance but the process + // stays alive. + // + // Parameters: + // + // target + // The identity of the service to create the instance for. + // // service // A pipe to an implementation of Service that the service manager can use // to communicate with the service. @@ -86,57 +154,13 @@ // pid_receiver_request // Allows the client process launcher to tell the service manager the PID of // the process it created (the pid isn't supplied directly here as the - // process may not have been launched by the time Connect() is called.) + // process may not have been launched by the time BindInterface() is + // called.) // - StartService(Identity name, - handle<message_pipe> service, - PIDReceiver& pid_receiver_request); - - // Requests a connection with another service. The service originating the - // request is referred to as the "source" and the one receiving the "target". - // - // The connection is embodied by a pair of message pipes binding the - // InterfaceProvider interface, which allows both the source and target - // services to export interfaces to one another. The interfaces bound via - // these InterfaceProviders are brokered by the service manager according to - // the security policy defined by each service in its manifest. - // - // If the target service is not running, the service manager will run it, - // calling its OnStart() method before completing the connection. - // - // Parameters: - // - // target - // Identifies the target service instance to connect to. - // - // remote_interfaces - // Allows the source service access to interface implementations exposed by - // the target service. The interfaces accessible via this InterfaceProvider - // are filtered by the security policy described by the source and target - // service manifests. - // - // Response parameters: - // - // result - // Indicates the result of the Connect() operation. - // - // user_id - // The user id the service manager ran the target service as. Typically a - // client passes |kInheritUserID| as the user id to Connect(), which is - // resolved by the service manager into a valid user id returned through - // this callback. - // - Connect(Identity target, InterfaceProvider&? remote_interfaces) => - (ConnectResult result, string user_id); - - // Variant of Connect() above. Will (gradually) replace it. Think of this like - // a combination of Connect() and InterfaceProvider::GetInteface() - requests - // a connection to a service and binds an interface in one step. - // TODO(beng): Update this comment once the implementation is complete. - BindInterface(Identity target, - string interface_name, - handle<message_pipe> interface_pipe) => - (ConnectResult result, string user_id); + StartServiceWithProcess(Identity target, + handle<message_pipe> service, + PIDReceiver& pid_receiver_request) => + (ConnectResult result, Identity identity); // Clones this Connector so it can be passed to another thread. Clone(Connector& request);
diff --git a/services/service_manager/public/interfaces/service.mojom b/services/service_manager/public/interfaces/service.mojom index 207da8cd..a0f14f4 100644 --- a/services/service_manager/public/interfaces/service.mojom +++ b/services/service_manager/public/interfaces/service.mojom
@@ -48,26 +48,6 @@ OnStart(ServiceInfo info) => (Connector&? connector_request, associated ServiceControl&? control_request); - // Called when another service attempts to open a connection to this - // service. A service implements this method to complete the exchange - // of interface implementations with the remote service. See also - // documentation in service_manager.mojom for Connect(). The service - // originating the request is referred to as the "source" and the one - // receiving the "target". - // - // The Service must respond to acknowledge receipt of the request. - // - // Parameters: - // - // source_info - // Contains the source identity and interface provider specs. - // - // interfaces - // A request for an InterfaceProvider by which the source service may - // seek to bind interface implementations exported by the target. - // - OnConnect(ServiceInfo source_info, InterfaceProvider&? interfaces) => (); - // Called when a request to bind an interface is received from another // ("source") service. This is the result of that service calling // BindInterface() on a Connector. By the time this method is called, the @@ -91,7 +71,6 @@ // the source's capability requirements to the target. This seems // undesirable. The metadata supplied here should be germane to // fulfilling this request and no more. - // TODO(beng): This should replace OnConnect(). OnBindInterface(ServiceInfo source_info, string interface_name, handle<message_pipe> interface_pipe) => ();
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc index 2a01504..d29b0c9 100644 --- a/services/service_manager/service_manager.cc +++ b/services/service_manager/service_manager.cc
@@ -51,30 +51,6 @@ return result == mojom::ConnectResult::SUCCEEDED; } -bool RunConnectCallback(ConnectParams* params, - mojom::ConnectResult result, - const std::string& user_id) { - if (!params->connect_callback().is_null()) { - params->connect_callback().Run(result, user_id); - return true; - } - return false; -} - -void RunBindInterfaceCallback(ConnectParams* params, - mojom::ConnectResult result, - const std::string& user_id) { - if (!params->bind_interface_callback().is_null()) - params->bind_interface_callback().Run(result, user_id); -} - -void RunCallback(ConnectParams* params, - mojom::ConnectResult result, - const std::string& user_id) { - if (!RunConnectCallback(params, result, user_id)) - RunBindInterfaceCallback(params, result, user_id); -} - } // namespace Identity CreateServiceManagerIdentity() { @@ -152,36 +128,10 @@ Stop(); } - bool CallOnConnect(std::unique_ptr<ConnectParams>* in_params) { - if (!service_.is_bound()) { - RunConnectCallback(in_params->get(), mojom::ConnectResult::ACCESS_DENIED, - identity_.user_id()); - return false; - } - - std::unique_ptr<ConnectParams> params(std::move(*in_params)); - RunConnectCallback(params.get(), mojom::ConnectResult::SUCCEEDED, - identity_.user_id()); - - InterfaceProviderSpecMap specs; - Instance* source = - service_manager_->GetExistingInstance(params->source()); - if (source) - specs = source->interface_provider_specs_; - - pending_service_connections_++; - service_->OnConnect(ServiceInfo(params->source(), specs), - params->TakeRemoteInterfaces(), - base::Bind(&Instance::OnConnectComplete, - base::Unretained(this))); - return true; - } - bool CallOnBindInterface(std::unique_ptr<ConnectParams>* in_params) { if (!service_.is_bound()) { - RunBindInterfaceCallback(in_params->get(), - mojom::ConnectResult::ACCESS_DENIED, - identity_.user_id()); + (*in_params) + ->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); return false; } @@ -206,15 +156,11 @@ << params->source().name() << " from binding interface: " << params->interface_name() << " exposed by: " << identity_.name(); LOG(ERROR) << ss.str(); - params->bind_interface_callback().Run(mojom::ConnectResult::ACCESS_DENIED, - identity_.user_id()); + params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); return false; } - if (!params->bind_interface_callback().is_null()) { - params->bind_interface_callback().Run(mojom::ConnectResult::SUCCEEDED, - identity_.user_id()); - } + params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_); pending_service_connections_++; service_->OnBindInterface( @@ -307,65 +253,67 @@ }; // mojom::Connector implementation: - void StartService( - const Identity& in_target, - mojo::ScopedMessagePipeHandle service_handle, - mojom::PIDReceiverRequest pid_receiver_request) override { - Identity target = in_target; - mojom::ConnectResult result = - ValidateConnectParams(&target, nullptr, nullptr); - if (!Succeeded(result)) - return; + void BindInterface(const service_manager::Identity& in_target, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe, + const BindInterfaceCallback& callback) override { + Identity target = in_target; + mojom::ConnectResult result = + ValidateConnectParams(&target, nullptr, nullptr); + if (!Succeeded(result)) { + callback.Run(result, Identity()); + return; + } - std::unique_ptr<ConnectParams> params(new ConnectParams); - params->set_source(identity_); - params->set_target(target); + std::unique_ptr<ConnectParams> params(new ConnectParams); + params->set_source(identity_); + params->set_target(target); + params->set_interface_request_info(interface_name, + std::move(interface_pipe)); + params->set_start_service_callback(callback); + service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); + } - mojom::ServicePtr service; - service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); - params->set_client_process_info(std::move(service), - std::move(pid_receiver_request)); - service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); - } + void StartService(const Identity& in_target, + const StartServiceCallback& callback) override { + Identity target = in_target; + mojom::ConnectResult result = + ValidateConnectParams(&target, nullptr, nullptr); + if (!Succeeded(result)) { + callback.Run(result, Identity()); + return; + } - void Connect(const service_manager::Identity& in_target, - mojom::InterfaceProviderRequest remote_interfaces, - const ConnectCallback& callback) override { - Identity target = in_target; - mojom::ConnectResult result = - ValidateConnectParams(&target, nullptr, nullptr); - if (!Succeeded(result)) { - callback.Run(result, mojom::kInheritUserID); - return; - } + std::unique_ptr<ConnectParams> params(new ConnectParams); + params->set_source(identity_); + params->set_target(target); + params->set_start_service_callback(callback); + service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); + } - std::unique_ptr<ConnectParams> params(new ConnectParams); - params->set_source(identity_); - params->set_target(target); - params->set_remote_interfaces(std::move(remote_interfaces)); - params->set_connect_callback(callback); - service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); - } + void StartServiceWithProcess( + const Identity& in_target, + mojo::ScopedMessagePipeHandle service_handle, + mojom::PIDReceiverRequest pid_receiver_request, + const StartServiceWithProcessCallback& callback) override { + Identity target = in_target; + mojom::ConnectResult result = + ValidateConnectParams(&target, nullptr, nullptr); + if (!Succeeded(result)) { + callback.Run(result, Identity()); + return; + } - void BindInterface(const service_manager::Identity& in_target, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe, - const BindInterfaceCallback& callback) override { - Identity target = in_target; - mojom::ConnectResult result = - ValidateConnectParams(&target, nullptr, nullptr); - if (!Succeeded(result)) { - callback.Run(result, mojom::kInheritUserID); - return; - } + std::unique_ptr<ConnectParams> params(new ConnectParams); + params->set_source(identity_); + params->set_target(target); - std::unique_ptr<ConnectParams> params(new ConnectParams); - params->set_source(identity_); - params->set_target(target); - params->set_interface_request_info(interface_name, - std::move(interface_pipe)); - params->set_bind_interface_callback(callback); - service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); + mojom::ServicePtr service; + service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); + params->set_client_process_info(std::move(service), + std::move(pid_receiver_request)); + params->set_start_service_callback(callback); + service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); } void Clone(mojom::ConnectorRequest request) override { @@ -533,14 +481,6 @@ OnServiceLost(service_manager_->GetWeakPtr()); } - void EmptyConnectCallback(mojom::ConnectResult result, - const std::string& user_id) {} - void BindCallbackWrapper(const BindInterfaceCallback& wrapped, - mojom::ConnectResult result, - const std::string& user_id) { - wrapped.Run(result, user_id); - } - service_manager::ServiceManager* const service_manager_; // An id that identifies this instance. Distinct from pid, as a single process @@ -560,7 +500,7 @@ base::ProcessId pid_ = base::kNullProcessId; State state_; - // The number of outstanding OnConnect requests which are in flight. + // The number of outstanding OnBindInterface requests which are in flight. int pending_service_connections_ = 0; base::WeakPtrFactory<Instance> weak_factory_; @@ -852,14 +792,12 @@ bool ServiceManager::ConnectToExistingInstance( std::unique_ptr<ConnectParams>* params) { Instance* instance = GetExistingInstance((*params)->target()); - if (instance) { - if ((*params)->HasInterfaceRequestInfo()) { - instance->CallOnBindInterface(params); - return true; - } - return instance->CallOnConnect(params); - } - return false; + if (!instance) + return false; + + if ((*params)->HasInterfaceRequestInfo()) + instance->CallOnBindInterface(params); + return true; } ServiceManager::Instance* ServiceManager::CreateInstance( @@ -944,7 +882,8 @@ // If name resolution failed, we drop the connection. if (!result) { LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); - RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); + params->set_response_data(mojom::ConnectResult::INVALID_ARGUMENT, + Identity()); return; } @@ -1011,7 +950,8 @@ LOG(ERROR) << "Error: The catalog was unable to read a manifest for service \"" << result->name << "\"."; - RunCallback(params.get(), mojom::ConnectResult::ACCESS_DENIED, ""); + params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, + Identity()); return; } @@ -1049,19 +989,17 @@ if (!instance->StartWithFilePath(package_path)) { OnInstanceError(instance); - RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); + params->set_response_data(mojom::ConnectResult::INVALID_ARGUMENT, + Identity()); return; } } } - // Now that the instance has a Service, we can connect to it. - if (params->HasInterfaceRequestInfo()) { + params->set_response_data(mojom::ConnectResult::SUCCEEDED, + instance->identity()); + if (params->HasInterfaceRequestInfo()) instance->CallOnBindInterface(¶ms); - } else { - bool connected = instance->CallOnConnect(¶ms); - DCHECK(connected); - } } base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
diff --git a/services/service_manager/service_manager.h b/services/service_manager/service_manager.h index ecba992..3596d8e 100644 --- a/services/service_manager/service_manager.h +++ b/services/service_manager/service_manager.h
@@ -188,8 +188,6 @@ DISALLOW_COPY_AND_ASSIGN(ServiceManager); }; -mojom::Connector::ConnectCallback EmptyConnectCallback(); - } // namespace service_manager #endif // SERVICES_SERVICE_MANAGER_SERVICE_MANAGER_H_
diff --git a/services/service_manager/standalone/context.cc b/services/service_manager/standalone/context.cc index 5b38d528..99860361 100644 --- a/services/service_manager/standalone/context.cc +++ b/services/service_manager/standalone/context.cc
@@ -156,13 +156,9 @@ void Context::Run(const std::string& name) { service_manager_->SetInstanceQuitCallback(base::Bind(&OnInstanceQuit, name)); - mojom::InterfaceProviderPtr remote_interfaces; - mojom::InterfaceProviderPtr local_interfaces; - std::unique_ptr<ConnectParams> params(new ConnectParams); params->set_source(CreateServiceManagerIdentity()); params->set_target(Identity(name, mojom::kRootUserID)); - params->set_remote_interfaces(mojo::MakeRequest(&remote_interfaces)); service_manager_->Connect(std::move(params)); }
diff --git a/services/service_manager/tests/connect/connect_test_app.cc b/services/service_manager/tests/connect/connect_test_app.cc index ad0a26e6..6203415 100644 --- a/services/service_manager/tests/connect/connect_test_app.cc +++ b/services/service_manager/tests/connect/connect_test_app.cc
@@ -11,9 +11,9 @@ #include "base/run_loop.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/c/main.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_runner.h" @@ -24,8 +24,14 @@ namespace { -void QuitLoop(base::RunLoop* loop) { +void QuitLoop(base::RunLoop* loop, + mojom::ConnectResult* out_result, + Identity* out_resolved_identity, + mojom::ConnectResult result, + const Identity& resolved_identity) { loop->Quit(); + *out_result = result; + *out_resolved_identity = resolved_identity; } void ReceiveString(std::string* string, @@ -61,31 +67,30 @@ standalone_bindings_.set_connection_error_handler( base::Bind(&ConnectTestApp::OnConnectionError, base::Unretained(this))); + registry_.AddInterface<test::mojom::ConnectTestService>(this); + registry_.AddInterface<test::mojom::StandaloneApp>(this); + registry_.AddInterface<test::mojom::BlockedInterface>(this); + registry_.AddInterface<test::mojom::UserIdTest>(this); } - - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<test::mojom::ConnectTestService>(this); - registry->AddInterface<test::mojom::StandaloneApp>(this); - registry->AddInterface<test::mojom::BlockedInterface>(this); - registry->AddInterface<test::mojom::UserIdTest>(this); - - test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); - state->connection_remote_name = remote_info.identity.name(); - state->connection_remote_userid = remote_info.identity.user_id(); - state->initialize_local_name = context()->identity().name(); - state->initialize_userid = context()->identity().user_id(); - - context()->connector()->BindInterface(remote_info.identity, &caller_); - caller_->ConnectionAccepted(std::move(state)); - - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<test::mojom::ConnectTestService>: void Create(const Identity& remote_identity, test::mojom::ConnectTestServiceRequest request) override { bindings_.AddBinding(this, std::move(request)); + test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); + state->connection_remote_name = remote_identity.name(); + state->connection_remote_userid = remote_identity.user_id(); + state->initialize_local_name = context()->identity().name(); + state->initialize_userid = context()->identity().user_id(); + + context()->connector()->BindInterface(remote_identity, &caller_); + caller_->ConnectionAccepted(std::move(state)); } // InterfaceFactory<test::mojom::StandaloneApp>: @@ -118,13 +123,11 @@ void ConnectToAllowedAppInBlockedPackage( const ConnectToAllowedAppInBlockedPackageCallback& callback) override { base::RunLoop run_loop; - std::unique_ptr<Connection> connection = - context()->connector()->Connect("connect_test_a"); - connection->SetConnectionLostClosure( - base::Bind(&ConnectTestApp::OnConnectionBlocked, - base::Unretained(this), callback, &run_loop)); test::mojom::ConnectTestServicePtr test_service; - connection->GetInterface(&test_service); + context()->connector()->BindInterface("connect_test_a", &test_service); + test_service.set_connection_error_handler( + base::Bind(&ConnectTestApp::OnConnectionBlocked, base::Unretained(this), + callback, &run_loop)); test_service->GetTitle( base::Bind(&ConnectTestApp::OnGotTitle, base::Unretained(this), callback, &run_loop)); @@ -138,10 +141,9 @@ } void ConnectToClassInterface( const ConnectToClassInterfaceCallback& callback) override { - std::unique_ptr<Connection> connection = - context()->connector()->Connect("connect_test_class_app"); test::mojom::ClassInterfacePtr class_interface; - connection->GetInterface(&class_interface); + context()->connector()->BindInterface("connect_test_class_app", + &class_interface); std::string ping_response; { base::RunLoop loop; @@ -151,7 +153,7 @@ loop.Run(); } test::mojom::ConnectTestServicePtr service; - connection->GetInterface(&service); + context()->connector()->BindInterface("connect_test_class_app", &service); std::string title_response; { base::RunLoop loop; @@ -172,17 +174,19 @@ void ConnectToClassAppAsDifferentUser( const service_manager::Identity& target, const ConnectToClassAppAsDifferentUserCallback& callback) override { - std::unique_ptr<Connection> connection = - context()->connector()->Connect(target); + context()->connector()->StartService(target); + mojom::ConnectResult result; + Identity resolved_identity; { base::RunLoop loop; - connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); + Connector::TestApi test_api(context()->connector()); + test_api.SetStartServiceCallback( + base::Bind(&QuitLoop, &loop, &result, &resolved_identity)); base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); loop.Run(); } - callback.Run(static_cast<int32_t>(connection->GetResult()), - connection->GetRemoteIdentity()); + callback.Run(static_cast<int32_t>(result), resolved_identity); } void OnConnectionBlocked( @@ -205,6 +209,7 @@ base::MessageLoop::current()->QuitWhenIdle(); } + BinderRegistry registry_; mojo::BindingSet<test::mojom::ConnectTestService> bindings_; mojo::BindingSet<test::mojom::StandaloneApp> standalone_bindings_; mojo::BindingSet<test::mojom::BlockedInterface> blocked_bindings_;
diff --git a/services/service_manager/tests/connect/connect_test_class_app.cc b/services/service_manager/tests/connect/connect_test_class_app.cc index 8e19e61..f5a26ca 100644 --- a/services/service_manager/tests/connect/connect_test_class_app.cc +++ b/services/service_manager/tests/connect/connect_test_class_app.cc
@@ -8,11 +8,12 @@ #include "base/run_loop.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/c/main.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context.h" +#include "services/service_manager/public/cpp/service_context_ref.h" #include "services/service_manager/public/cpp/service_runner.h" #include "services/service_manager/public/interfaces/connector.mojom.h" #include "services/service_manager/tests/connect/connect_test.mojom.h" @@ -28,31 +29,38 @@ public test::mojom::ConnectTestService, public test::mojom::ClassInterface { public: - ConnectTestClassApp() {} + ConnectTestClassApp() + : ref_factory_(base::Bind(&ConnectTestClassApp::HandleQuit, + base::Unretained(this))) { + bindings_.set_connection_error_handler(base::Bind( + &ConnectTestClassApp::HandleInterfaceClose, base::Unretained(this))); + class_interface_bindings_.set_connection_error_handler(base::Bind( + &ConnectTestClassApp::HandleInterfaceClose, base::Unretained(this))); + registry_.AddInterface<test::mojom::ConnectTestService>(this); + registry_.AddInterface<test::mojom::ClassInterface>(this); + } ~ConnectTestClassApp() override {} private: // service_manager::Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<test::mojom::ConnectTestService>(this); - registry->AddInterface<test::mojom::ClassInterface>(this); - inbound_connections_.insert(registry); - registry->AddConnectionLostClosure( - base::Bind(&ConnectTestClassApp::OnConnectionError, - base::Unretained(this), registry)); - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<test::mojom::ConnectTestService>: void Create(const Identity& remote_identity, test::mojom::ConnectTestServiceRequest request) override { + refs_.push_back(ref_factory_.CreateRef()); bindings_.AddBinding(this, std::move(request)); } // InterfaceFactory<test::mojom::ClassInterface>: void Create(const Identity& remote_identity, test::mojom::ClassInterfaceRequest request) override { + refs_.push_back(ref_factory_.CreateRef()); class_interface_bindings_.AddBinding(this, std::move(request)); } @@ -69,17 +77,15 @@ callback.Run("PONG"); } - void OnConnectionError(InterfaceRegistry* registry) { - auto it = inbound_connections_.find(registry); - DCHECK(it != inbound_connections_.end()); - inbound_connections_.erase(it); - if (inbound_connections_.empty()) - context()->QuitNow(); - } + void HandleQuit() { context()->QuitNow(); } - std::set<InterfaceRegistry*> inbound_connections_; + void HandleInterfaceClose() { refs_.pop_back(); } + + BinderRegistry registry_; mojo::BindingSet<test::mojom::ConnectTestService> bindings_; mojo::BindingSet<test::mojom::ClassInterface> class_interface_bindings_; + ServiceContextRefFactory ref_factory_; + std::vector<std::unique_ptr<ServiceContextRef>> refs_; DISALLOW_COPY_AND_ASSIGN(ConnectTestClassApp); };
diff --git a/services/service_manager/tests/connect/connect_test_package.cc b/services/service_manager/tests/connect/connect_test_package.cc index 974e387..2494479de 100644 --- a/services/service_manager/tests/connect/connect_test_package.cc +++ b/services/service_manager/tests/connect/connect_test_package.cc
@@ -16,9 +16,9 @@ #include "base/threading/simple_thread.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/c/main.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_runner.h" @@ -30,6 +30,19 @@ // the package's manifest and are thus registered with the PackageManager. namespace service_manager { +namespace { + +void QuitLoop(base::RunLoop* loop, + mojom::ConnectResult* out_result, + Identity* out_resolved_identity, + mojom::ConnectResult result, + const Identity& resolved_identity) { + loop->Quit(); + *out_result = result; + *out_resolved_identity = resolved_identity; +} + +} // namespace using GetTitleCallback = test::mojom::ConnectTestService::GetTitleCallback; @@ -60,30 +73,29 @@ bindings_.set_connection_error_handler( base::Bind(&ProvidedService::OnConnectionError, base::Unretained(this))); + registry_.AddInterface<test::mojom::ConnectTestService>(this); + registry_.AddInterface<test::mojom::BlockedInterface>(this); + registry_.AddInterface<test::mojom::UserIdTest>(this); } - - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<test::mojom::ConnectTestService>(this); - registry->AddInterface<test::mojom::BlockedInterface>(this); - registry->AddInterface<test::mojom::UserIdTest>(this); - - test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); - state->connection_remote_name = remote_info.identity.name(); - state->connection_remote_userid = remote_info.identity.user_id(); - state->initialize_local_name = context()->identity().name(); - state->initialize_userid = context()->identity().user_id(); - - context()->connector()->BindInterface(remote_info.identity, &caller_); - caller_->ConnectionAccepted(std::move(state)); - - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<test::mojom::ConnectTestService>: void Create(const Identity& remote_identity, test::mojom::ConnectTestServiceRequest request) override { bindings_.AddBinding(this, std::move(request)); + test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); + state->connection_remote_name = remote_identity.name(); + state->connection_remote_userid = remote_identity.user_id(); + state->initialize_local_name = context()->identity().name(); + state->initialize_userid = context()->identity().user_id(); + + context()->connector()->BindInterface(remote_identity, &caller_); + caller_->ConnectionAccepted(std::move(state)); } // InterfaceFactory<test::mojom::BlockedInterface>: @@ -116,17 +128,19 @@ void ConnectToClassAppAsDifferentUser( const service_manager::Identity& target, const ConnectToClassAppAsDifferentUserCallback& callback) override { - std::unique_ptr<Connection> connection = - context()->connector()->Connect(target); + context()->connector()->StartService(target); + mojom::ConnectResult result; + Identity resolved_identity; { base::RunLoop loop; - connection->AddConnectionCompletedClosure(loop.QuitClosure()); + Connector::TestApi test_api(context()->connector()); + test_api.SetStartServiceCallback( + base::Bind(&QuitLoop, &loop, &result, &resolved_identity)); base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); loop.Run(); } - callback.Run(static_cast<int32_t>(connection->GetResult()), - connection->GetRemoteIdentity()); + callback.Run(static_cast<int32_t>(result), resolved_identity); } // base::SimpleThread: @@ -147,6 +161,7 @@ const std::string title_; mojom::ServiceRequest request_; test::mojom::ExposedInterfacePtr caller_; + BinderRegistry registry_; mojo::BindingSet<test::mojom::ConnectTestService> bindings_; mojo::BindingSet<test::mojom::BlockedInterface> blocked_bindings_; mojo::BindingSet<test::mojom::UserIdTest> user_id_test_bindings_; @@ -172,13 +187,14 @@ base::Unretained(this)); bindings_.set_connection_error_handler(error_handler); service_factory_bindings_.set_connection_error_handler(error_handler); + registry_.AddInterface<ServiceFactory>(this); + registry_.AddInterface<test::mojom::ConnectTestService>(this); } - - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<ServiceFactory>(this); - registry->AddInterface<test::mojom::ConnectTestService>(this); - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } bool OnServiceManagerConnectionLost() override { @@ -226,6 +242,7 @@ std::vector<std::unique_ptr<Service>> delegates_; mojo::BindingSet<mojom::ServiceFactory> service_factory_bindings_; + BinderRegistry registry_; mojo::BindingSet<test::mojom::ConnectTestService> bindings_; std::list<std::unique_ptr<ProvidedService>> provided_services_;
diff --git a/services/service_manager/tests/connect/connect_test_singleton_app.cc b/services/service_manager/tests/connect/connect_test_singleton_app.cc index b9928d3..108225c 100644 --- a/services/service_manager/tests/connect/connect_test_singleton_app.cc +++ b/services/service_manager/tests/connect/connect_test_singleton_app.cc
@@ -15,12 +15,6 @@ ~ConnectTestSingletonApp() override {} private: - // service_manager::Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - return true; - } - DISALLOW_COPY_AND_ASSIGN(ConnectTestSingletonApp); };
diff --git a/services/service_manager/tests/connect/connect_unittest.cc b/services/service_manager/tests/connect/connect_unittest.cc index e4f978c..c3b2abf6 100644 --- a/services/service_manager/tests/connect/connect_unittest.cc +++ b/services/service_manager/tests/connect/connect_unittest.cc
@@ -16,8 +16,8 @@ #include "base/run_loop.h" #include "base/test/test_suite.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_test.h" #include "services/service_manager/public/interfaces/service_manager.mojom.h" #include "services/service_manager/tests/connect/connect_test.mojom.h" @@ -65,6 +65,19 @@ loop->Quit(); } +void StartServiceResponse(base::RunLoop* quit_loop, + mojom::ConnectResult* out_result, + Identity* out_resolved_identity, + mojom::ConnectResult result, + const Identity& resolved_identity) { + if (quit_loop) + quit_loop->Quit(); + if (out_result) + *out_result = result; + if (out_resolved_identity) + *out_resolved_identity = resolved_identity; +} + void QuitLoop(base::RunLoop* loop) { loop->Quit(); } @@ -79,14 +92,6 @@ ~ConnectTest() override {} protected: - std::unique_ptr<Connection> ConnectTo(const Identity& target) { - std::unique_ptr<Connection> connection = connector()->Connect(target); - base::RunLoop loop; - connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); - loop.Run(); - return connection; - } - void CompareConnectionState( const std::string& connection_local_name, const std::string& connection_remote_name, @@ -105,18 +110,22 @@ class TestService : public test::ServiceTestClient { public: explicit TestService(ConnectTest* connect_test) - : test::ServiceTestClient(connect_test), - connect_test_(connect_test) {} + : test::ServiceTestClient(connect_test), connect_test_(connect_test) { + registry_.AddInterface<test::mojom::ExposedInterface>(connect_test_); + } ~TestService() override {} private: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<test::mojom::ExposedInterface>(connect_test_); - return true; + void OnBindInterface( + const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } ConnectTest* connect_test_; + BinderRegistry registry_; DISALLOW_COPY_AND_ASSIGN(TestService); }; @@ -129,9 +138,7 @@ // package app's manifest and register aliases for the applications it // provides. test::mojom::ConnectTestServicePtr root_service; - std::unique_ptr<Connection> connection = - connector()->Connect(kTestPackageName); - connection->GetInterface(&root_service); + connector()->BindInterface(kTestPackageName, &root_service); base::RunLoop run_loop; std::string root_name; root_service->GetTitle( @@ -161,34 +168,29 @@ // Ensure the connection was properly established and that a round trip // method call/response is completed. -TEST_F(ConnectTest, Connect) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppName); +TEST_F(ConnectTest, BindInterface) { test::mojom::ConnectTestServicePtr service; - connection->GetInterface(&service); + connector()->BindInterface(kTestAppName, &service); base::RunLoop run_loop; std::string title; service->GetTitle(base::Bind(&ReceiveOneString, &title, &run_loop)); run_loop.Run(); EXPECT_EQ("APP", title); - EXPECT_FALSE(connection->IsPending()); - EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppName); } TEST_F(ConnectTest, Instances) { Identity identity_a(kTestAppName, mojom::kInheritUserID, "A"); - std::unique_ptr<Connection> connection_a1 = ConnectTo(identity_a); - std::unique_ptr<Connection> connection_a2 = ConnectTo(identity_a); std::string instance_a1, instance_a2; test::mojom::ConnectTestServicePtr service_a1; { - connection_a1->GetInterface(&service_a1); + connector()->BindInterface(identity_a, &service_a1); base::RunLoop loop; service_a1->GetInstance(base::Bind(&ReceiveOneString, &instance_a1, &loop)); loop.Run(); } test::mojom::ConnectTestServicePtr service_a2; { - connection_a2->GetInterface(&service_a2); + connector()->BindInterface(identity_a, &service_a2); base::RunLoop loop; service_a2->GetInstance(base::Bind(&ReceiveOneString, &instance_a2, &loop)); loop.Run(); @@ -196,11 +198,10 @@ EXPECT_EQ(instance_a1, instance_a2); Identity identity_b(kTestAppName, mojom::kInheritUserID, "B"); - std::unique_ptr<Connection> connection_b = ConnectTo(identity_b); std::string instance_b; test::mojom::ConnectTestServicePtr service_b; { - connection_b->GetInterface(&service_b); + connector()->BindInterface(identity_b, &service_b); base::RunLoop loop; service_b->GetInstance(base::Bind(&ReceiveOneString, &instance_b, &loop)); loop.Run(); @@ -212,10 +213,9 @@ // BlockedInterface should not be exposed to this application because it is not // in our CapabilityFilter whitelist. TEST_F(ConnectTest, BlockedInterface) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppName); base::RunLoop run_loop; test::mojom::BlockedInterfacePtr blocked; - connection->GetInterface(&blocked); + connector()->BindInterface(kTestAppName, &blocked); blocked.set_connection_error_handler(base::Bind(&QuitLoop, &run_loop)); std::string title = "unchanged"; blocked->GetTitleBlocked(base::Bind(&ReceiveOneString, &title, &run_loop)); @@ -225,16 +225,18 @@ // Connects to an app provided by a package. TEST_F(ConnectTest, PackagedApp) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppAName); test::mojom::ConnectTestServicePtr service_a; - connection->GetInterface(&service_a); + connector()->BindInterface(kTestAppAName, &service_a); + Connector::TestApi test_api(connector()); + Identity resolved_identity; + test_api.SetStartServiceCallback( + base::Bind(&StartServiceResponse, nullptr, nullptr, &resolved_identity)); base::RunLoop run_loop; std::string a_name; service_a->GetTitle(base::Bind(&ReceiveOneString, &a_name, &run_loop)); run_loop.Run(); EXPECT_EQ("A", a_name); - EXPECT_FALSE(connection->IsPending()); - EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppAName); + EXPECT_EQ(resolved_identity.name(), kTestAppAName); } // Ask the target application to attempt to connect to a third application @@ -243,9 +245,8 @@ // allowed regardless of the target's CapabilityFilter with respect to the // package. TEST_F(ConnectTest, BlockedPackage) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppName); test::mojom::StandaloneAppPtr standalone_app; - connection->GetInterface(&standalone_app); + connector()->BindInterface(kTestAppName, &standalone_app); base::RunLoop run_loop; std::string title; standalone_app->ConnectToAllowedAppInBlockedPackage( @@ -257,10 +258,9 @@ // BlockedInterface should not be exposed to this application because it is not // in our CapabilityFilter whitelist. TEST_F(ConnectTest, PackagedApp_BlockedInterface) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppAName); base::RunLoop run_loop; test::mojom::BlockedInterfacePtr blocked; - connection->GetInterface(&blocked); + connector()->BindInterface(kTestAppAName, &blocked); blocked.set_connection_error_handler(base::Bind(&QuitLoop, &run_loop)); run_loop.Run(); } @@ -268,20 +268,21 @@ // Connection to another application provided by the same package, blocked // because it's not in the capability filter whitelist. TEST_F(ConnectTest, BlockedPackagedApplication) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppBName); test::mojom::ConnectTestServicePtr service_b; - connection->GetInterface(&service_b); + connector()->BindInterface(kTestAppBName, &service_b); + Connector::TestApi test_api(connector()); + mojom::ConnectResult result; + test_api.SetStartServiceCallback( + base::Bind(&StartServiceResponse, nullptr, &result, nullptr)); base::RunLoop run_loop; - connection->SetConnectionLostClosure(base::Bind(&QuitLoop, &run_loop)); + service_b.set_connection_error_handler(run_loop.QuitClosure()); run_loop.Run(); - EXPECT_FALSE(connection->IsPending()); - EXPECT_EQ(mojom::ConnectResult::ACCESS_DENIED, connection->GetResult()); + EXPECT_EQ(mojom::ConnectResult::ACCESS_DENIED, result); } TEST_F(ConnectTest, CapabilityClasses) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppName); test::mojom::StandaloneAppPtr standalone_app; - connection->GetInterface(&standalone_app); + connector()->BindInterface(kTestAppName, &standalone_app); std::string string1, string2; base::RunLoop loop; standalone_app->ConnectToClassInterface( @@ -295,19 +296,16 @@ // We not be able to bind a ClassInterfacePtr since the connect_unittest app // does not explicitly request the "class" capability from // connect_test_class_app. This test will hang if it is bound. - std::unique_ptr<Connection> connection = - connector()->Connect(kTestClassAppName); test::mojom::ClassInterfacePtr class_interface; - connection->GetInterface(&class_interface); + connector()->BindInterface(kTestClassAppName, &class_interface); base::RunLoop loop; class_interface.set_connection_error_handler(base::Bind(&QuitLoop, &loop)); loop.Run(); } TEST_F(ConnectTest, ConnectAsDifferentUser_Allowed) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppName); test::mojom::UserIdTestPtr user_id_test; - connection->GetInterface(&user_id_test); + connector()->BindInterface(kTestAppName, &user_id_test); mojom::ConnectResult result; Identity target(kTestClassAppName, base::GenerateGUID()); Identity result_identity; @@ -323,9 +321,8 @@ } TEST_F(ConnectTest, ConnectAsDifferentUser_Blocked) { - std::unique_ptr<Connection> connection = connector()->Connect(kTestAppAName); test::mojom::UserIdTestPtr user_id_test; - connection->GetInterface(&user_id_test); + connector()->BindInterface(kTestAppAName, &user_id_test); mojom::ConnectResult result; Identity target(kTestClassAppName, base::GenerateGUID()); Identity result_identity; @@ -345,7 +342,7 @@ // process specifications. This is the only one for blocking. TEST_F(ConnectTest, ConnectToClientProcess_Blocked) { base::Process process; - std::unique_ptr<service_manager::Connection> connection = + mojom::ConnectResult result = service_manager::test::LaunchAndConnectToProcess( #if defined(OS_WIN) "connect_test_exe.exe", @@ -355,7 +352,7 @@ service_manager::Identity("connect_test_exe", service_manager::mojom::kInheritUserID), connector(), &process); - EXPECT_EQ(connection->GetResult(), mojom::ConnectResult::ACCESS_DENIED); + EXPECT_EQ(result, mojom::ConnectResult::ACCESS_DENIED); } // Verifies that a client with the "all_users" capability class can receive @@ -367,25 +364,28 @@ // synthetic user id for all-user singleton instances). const std::string singleton_userid = base::GenerateGUID(); Identity singleton_id(kTestSingletonAppName, singleton_userid); - std::unique_ptr<Connection> connection = connector()->Connect(singleton_id); + connector()->StartService(singleton_id); + Identity first_resolved_identity; { base::RunLoop loop; - connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); + Connector::TestApi test_api(connector()); + test_api.SetStartServiceCallback(base::Bind( + &StartServiceResponse, &loop, nullptr, &first_resolved_identity)); loop.Run(); - EXPECT_NE(connection->GetRemoteIdentity().user_id(), singleton_userid); + EXPECT_NE(first_resolved_identity.user_id(), singleton_userid); } // This connects using the current client's user_id. It should be bound to the // same service started above, with the same service manager-generated user // id. - std::unique_ptr<Connection> inherit_connection = - connector()->Connect(kTestSingletonAppName); + connector()->StartService(kTestSingletonAppName); { base::RunLoop loop; - inherit_connection->AddConnectionCompletedClosure( - base::Bind(&QuitLoop, &loop)); + Connector::TestApi test_api(connector()); + Identity resolved_identity; + test_api.SetStartServiceCallback( + base::Bind(&StartServiceResponse, &loop, nullptr, &resolved_identity)); loop.Run(); - EXPECT_EQ(inherit_connection->GetRemoteIdentity().user_id(), - connection->GetRemoteIdentity().user_id()); + EXPECT_EQ(resolved_identity.user_id(), first_resolved_identity.user_id()); } }
diff --git a/services/service_manager/tests/lifecycle/app_client.cc b/services/service_manager/tests/lifecycle/app_client.cc index 5e9467e..1ec9b3b 100644 --- a/services/service_manager/tests/lifecycle/app_client.cc +++ b/services/service_manager/tests/lifecycle/app_client.cc
@@ -5,20 +5,22 @@ #include "services/service_manager/tests/lifecycle/app_client.h" #include "base/macros.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_context.h" namespace service_manager { namespace test { -AppClient::AppClient() {} +AppClient::AppClient() { + registry_.AddInterface<mojom::LifecycleControl>(this); +} AppClient::~AppClient() {} -bool AppClient::OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) { - registry->AddInterface<mojom::LifecycleControl>(this); - return true; +void AppClient::OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } bool AppClient::OnServiceManagerConnectionLost() {
diff --git a/services/service_manager/tests/lifecycle/app_client.h b/services/service_manager/tests/lifecycle/app_client.h index 9d8baad..34100bf 100644 --- a/services/service_manager/tests/lifecycle/app_client.h +++ b/services/service_manager/tests/lifecycle/app_client.h
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/macros.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_runner.h" @@ -29,8 +30,9 @@ void set_runner(ServiceRunner* runner) { runner_ = runner; } // Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; bool OnServiceManagerConnectionLost() override; // InterfaceFactory<LifecycleControl>: @@ -49,6 +51,7 @@ void BindingLost(); ServiceRunner* runner_ = nullptr; + BinderRegistry registry_; mojo::BindingSet<mojom::LifecycleControl> bindings_; DISALLOW_COPY_AND_ASSIGN(AppClient);
diff --git a/services/service_manager/tests/service_manager/service_manager_unittest.cc b/services/service_manager/tests/service_manager/service_manager_unittest.cc index 08b3e94..bf79e683 100644 --- a/services/service_manager/tests/service_manager/service_manager_unittest.cc +++ b/services/service_manager/tests/service_manager/service_manager_unittest.cc
@@ -24,8 +24,8 @@ #include "mojo/edk/embedder/platform_channel_pair.h" #include "mojo/edk/embedder/scoped_platform_handle.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_test.h" #include "services/service_manager/public/interfaces/constants.mojom.h" @@ -43,7 +43,9 @@ public test::mojom::CreateInstanceTest { public: explicit ServiceManagerTestClient(test::ServiceTest* test) - : test::ServiceTestClient(test), binding_(this) {} + : test::ServiceTestClient(test), binding_(this) { + registry_.AddInterface<test::mojom::CreateInstanceTest>(this); + } ~ServiceManagerTestClient() override {} const Identity& target_identity() const { return target_identity_; } @@ -55,10 +57,11 @@ private: // test::ServiceTestClient: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<test::mojom::CreateInstanceTest>(this); - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<test::mojom::CreateInstanceTest>: @@ -79,6 +82,7 @@ service_manager::Identity target_identity_; std::unique_ptr<base::RunLoop> wait_for_target_identity_loop_; + BinderRegistry registry_; mojo::Binding<test::mojom::CreateInstanceTest> binding_; DISALLOW_COPY_AND_ASSIGN(ServiceManagerTestClient); @@ -187,11 +191,9 @@ service_manager::mojom::kInheritUserID); connector()->StartService(target, std::move(client), MakeRequest(&receiver)); - std::unique_ptr<service_manager::Connection> connection = - connector()->Connect(target); - connection->AddConnectionCompletedClosure( - base::Bind(&ServiceManagerTest::OnConnectionCompleted, - base::Unretained(this))); + Connector::TestApi test_api(connector()); + test_api.SetStartServiceCallback(base::Bind( + &ServiceManagerTest::OnConnectionCompleted, base::Unretained(this))); base::LaunchOptions options; #if defined(OS_WIN) @@ -255,7 +257,7 @@ } } - void OnConnectionCompleted() {} + void OnConnectionCompleted(mojom::ConnectResult, const Identity&) {} ServiceManagerTestClient* service_; mojo::Binding<mojom::ServiceManagerListener> binding_; @@ -333,11 +335,9 @@ &OnServiceFailedToStartCallback, &failed_to_start, loop.QuitClosure())); - std::unique_ptr<Connection> embedder_connection = - connector()->Connect("service_manager_unittest_embedder"); + connector()->StartService("service_manager_unittest_embedder"); loop.Run(); EXPECT_FALSE(failed_to_start); - EXPECT_FALSE(embedder_connection->IsPending()); EXPECT_EQ(1, start_count); EXPECT_EQ("service_manager_unittest_embedder", service_name); } @@ -355,11 +355,9 @@ &failed_to_start, loop.QuitClosure())); // Connect to the packaged singleton service. - std::unique_ptr<Connection> singleton_connection = - connector()->Connect("service_manager_unittest_singleton"); + connector()->StartService("service_manager_unittest_singleton"); loop.Run(); EXPECT_FALSE(failed_to_start); - EXPECT_FALSE(singleton_connection->IsPending()); EXPECT_EQ(1, start_count); EXPECT_EQ("service_manager_unittest_singleton", service_name); }
diff --git a/services/service_manager/tests/service_manager/target.cc b/services/service_manager/tests/service_manager/target.cc index bbfd5e7..509c893 100644 --- a/services/service_manager/tests/service_manager/target.cc +++ b/services/service_manager/tests/service_manager/target.cc
@@ -7,7 +7,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context.h"
diff --git a/services/service_manager/tests/shutdown/shutdown_client_app.cc b/services/service_manager/tests/shutdown/shutdown_client_app.cc index 9dd6942..bdac97a8 100644 --- a/services/service_manager/tests/shutdown/shutdown_client_app.cc +++ b/services/service_manager/tests/shutdown/shutdown_client_app.cc
@@ -6,9 +6,9 @@ #include "base/run_loop.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/c/main.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_runner.h" @@ -22,15 +22,18 @@ public mojom::ShutdownTestClientController, public mojom::ShutdownTestClient { public: - ShutdownClientApp() {} + ShutdownClientApp() { + registry_.AddInterface<mojom::ShutdownTestClientController>(this); + } ~ShutdownClientApp() override {} private: // service_manager::Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<mojom::ShutdownTestClientController>(this); - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<mojom::ShutdownTestClientController>: @@ -60,6 +63,7 @@ callback.Run(); } + BinderRegistry registry_; mojo::BindingSet<mojom::ShutdownTestClientController> bindings_; DISALLOW_COPY_AND_ASSIGN(ShutdownClientApp);
diff --git a/services/service_manager/tests/shutdown/shutdown_service_app.cc b/services/service_manager/tests/shutdown/shutdown_service_app.cc index 95134f7..1e1c8c7 100644 --- a/services/service_manager/tests/shutdown/shutdown_service_app.cc +++ b/services/service_manager/tests/shutdown/shutdown_service_app.cc
@@ -5,9 +5,10 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/c/main.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_info.h" #include "services/service_manager/public/cpp/service_runner.h" #include "services/service_manager/tests/shutdown/shutdown_unittest.mojom.h" @@ -21,15 +22,18 @@ public InterfaceFactory<mojom::ShutdownTestService>, public mojom::ShutdownTestService { public: - ShutdownServiceApp() {} + ShutdownServiceApp() { + registry_.AddInterface<mojom::ShutdownTestService>(this); + } ~ShutdownServiceApp() override {} private: // service_manager::Service: - bool OnConnect(const ServiceInfo& remote_info, - InterfaceRegistry* registry) override { - registry->AddInterface<mojom::ShutdownTestService>(this); - return true; + void OnBindInterface(const ServiceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } // InterfaceFactory<mojom::ShutdownTestService>: @@ -42,6 +46,7 @@ void SetClient(mojom::ShutdownTestClientPtr client) override {} void ShutDown() override { g_app->Quit(); } + BinderRegistry registry_; mojo::BindingSet<mojom::ShutdownTestService> bindings_; DISALLOW_COPY_AND_ASSIGN(ShutdownServiceApp);
diff --git a/services/service_manager/tests/util.cc b/services/service_manager/tests/util.cc index 081ce6c..b881f17 100644 --- a/services/service_manager/tests/util.cc +++ b/services/service_manager/tests/util.cc
@@ -17,7 +17,6 @@ #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/platform_channel_pair.h" #include "mojo/edk/embedder/scoped_platform_handle.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/interfaces/connector.mojom.h" #include "services/service_manager/public/interfaces/service_factory.mojom.h" @@ -28,13 +27,17 @@ namespace { -void QuitLoop(base::RunLoop* loop) { +void GrabConnectResult(base::RunLoop* loop, + mojom::ConnectResult* out_result, + mojom::ConnectResult result, + const Identity& resolved_identity) { loop->Quit(); + *out_result = result; } } // namespace -std::unique_ptr<Connection> LaunchAndConnectToProcess( +mojom::ConnectResult LaunchAndConnectToProcess( const std::string& target_exe_name, const Identity& target, service_manager::Connector* connector, @@ -70,11 +73,12 @@ service_manager::mojom::PIDReceiverPtr receiver; connector->StartService(target, std::move(client), MakeRequest(&receiver)); - std::unique_ptr<service_manager::Connection> connection = - connector->Connect(target); + mojom::ConnectResult result; { base::RunLoop loop; - connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); + Connector::TestApi test_api(connector); + test_api.SetStartServiceCallback( + base::Bind(&GrabConnectResult, &loop, &result)); base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); loop.Run(); @@ -92,7 +96,7 @@ pending_process.Connect( process->Handle(), mojo::edk::ConnectionParams(platform_channel_pair.PassServerHandle())); - return connection; + return result; } } // namespace test
diff --git a/services/service_manager/tests/util.h b/services/service_manager/tests/util.h index 6fe6bc3..e11c18b 100644 --- a/services/service_manager/tests/util.h +++ b/services/service_manager/tests/util.h
@@ -8,22 +8,23 @@ #include <memory> #include <string> +#include "services/service_manager/public/interfaces/connector.mojom.h" + namespace base { class Process; } namespace service_manager { -class Connection; class Connector; class Identity; namespace test { // Starts the process @ |target_exe_name| and connects to it as |target| using -// |connector|, returning the connection & the process. +// |connector|, returning a ConnectResult for the StartService() call. // This blocks until the connection is established/rejected by the service // manager. -std::unique_ptr<Connection> LaunchAndConnectToProcess( +service_manager::mojom::ConnectResult LaunchAndConnectToProcess( const std::string& target_exe_name, const Identity& target, service_manager::Connector* connector,
diff --git a/services/tracing/public/cpp/provider.cc b/services/tracing/public/cpp/provider.cc index 12e27bbb..c89aed2 100644 --- a/services/tracing/public/cpp/provider.cc +++ b/services/tracing/public/cpp/provider.cc
@@ -17,7 +17,6 @@ #include "base/time/time.h" #include "base/trace_event/trace_config.h" #include "base/trace_event/trace_event.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/tracing/public/cpp/switches.h" #include "services/tracing/public/interfaces/constants.mojom.h"
diff --git a/services/ui/demo/mus_demo_unittests.cc b/services/ui/demo/mus_demo_unittests.cc index 9fdb810..e89c167f 100644 --- a/services/ui/demo/mus_demo_unittests.cc +++ b/services/ui/demo/mus_demo_unittests.cc
@@ -40,7 +40,7 @@ } // namespace TEST_F(MusDemoTest, CheckMusDemoDraws) { - connector()->Connect("mus_demo"); + connector()->StartService("mus_demo"); ::ui::mojom::WindowServerTestPtr test_interface; connector()->BindInterface(ui::mojom::kServiceName, &test_interface);
diff --git a/services/ui/display/output_protection.h b/services/ui/display/output_protection.h index 48185289..eafd2cb 100644 --- a/services/ui/display/output_protection.h +++ b/services/ui/display/output_protection.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include "base/macros.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/ui/public/interfaces/display/output_protection.mojom.h"
diff --git a/services/ui/display/screen_manager_ozone_internal.h b/services/ui/display/screen_manager_ozone_internal.h index 7032bdbb..61c9920 100644 --- a/services/ui/display/screen_manager_ozone_internal.h +++ b/services/ui/display/screen_manager_ozone_internal.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/ui/display/screen_manager.h" #include "services/ui/display/viewport_metrics.h"
diff --git a/services/ui/ime/ime_server_impl.cc b/services/ui/ime/ime_server_impl.cc index 19c89b5b..7d26f0e 100644 --- a/services/ui/ime/ime_server_impl.cc +++ b/services/ui/ime/ime_server_impl.cc
@@ -17,7 +17,7 @@ void IMEServerImpl::Init(service_manager::Connector* connector, bool is_test_config) { if (is_test_config) - connector->Connect("test_ime_driver"); + connector->StartService("test_ime_driver"); // For non test configs we assume a client registers with us. }
diff --git a/services/ui/ime/ime_unittest.cc b/services/ui/ime/ime_unittest.cc index 582521f..f33275a6 100644 --- a/services/ui/ime/ime_unittest.cc +++ b/services/ui/ime/ime_unittest.cc
@@ -56,7 +56,7 @@ void SetUp() override { ServiceTest::SetUp(); // test_ime_driver will register itself as the current IMEDriver. - connector()->Connect("test_ime_driver"); + connector()->StartService("test_ime_driver"); connector()->BindInterface(ui::mojom::kServiceName, &ime_server_); }
diff --git a/services/ui/input_devices/input_device_server.h b/services/ui/input_devices/input_device_server.h index 0e858b4..1e7d91c 100644 --- a/services/ui/input_devices/input_device_server.h +++ b/services/ui/input_devices/input_device_server.h
@@ -8,7 +8,6 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/ui/public/interfaces/input_devices/input_device_server.mojom.h" #include "ui/events/devices/device_data_manager.h"
diff --git a/services/ui/service.cc b/services/ui/service.cc index aa4aa441..b7ff9691 100644 --- a/services/ui/service.cc +++ b/services/ui/service.cc
@@ -18,7 +18,6 @@ #include "services/catalog/public/cpp/resource_loader.h" #include "services/catalog/public/interfaces/constants.mojom.h" #include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service_context.h" @@ -58,7 +57,6 @@ #include "ui/ozone/public/ozone_platform.h" #endif -using service_manager::Connection; using mojo::InterfaceRequest; using ui::mojom::WindowServerTest; using ui::mojom::WindowTreeHostFactory;
diff --git a/services/ui/ws/drag_controller_unittest.cc b/services/ui/ws/drag_controller_unittest.cc index 4714ebea8..7bc192c0 100644 --- a/services/ui/ws/drag_controller_unittest.cc +++ b/services/ui/ws/drag_controller_unittest.cc
@@ -155,7 +155,7 @@ window->PerformOnDragDropStart( std::unordered_map<std::string, std::vector<uint8_t>>()); drag_operation_ = base::MakeUnique<DragController>( - this, this, window->window(), window, PointerEvent::kMousePointerId, + this, this, window->window(), window, MouseEvent::kMousePointerId, std::unordered_map<std::string, std::vector<uint8_t>>(), drag_operations); @@ -627,7 +627,7 @@ TEST_F(DragControllerTest, IgnoreEventsFromOtherPointers) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - // This starts the operation with PointerEvent::kMousePointerId. + // This starts the operation with MouseEvent::kMousePointerId. StartDragOperation(window.get(), ui::mojom::kDropEffectMove); // Ignore events from pointer 5.
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index 670e9977..a4710df 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -466,7 +466,7 @@ ui::ET_POINTER_EXITED, event.location(), event.root_location(), event.flags(), 0 /* changed_button_flags */, ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, - ui::PointerEvent::kMousePointerId), + ui::MouseEvent::kMousePointerId), event.time_stamp()); DispatchToPointerTarget(pointer_targets_[pointer_id], exit_event); }
diff --git a/services/ui/ws/gpu_host.cc b/services/ui/ws/gpu_host.cc index db35498e..85ac3aa 100644 --- a/services/ui/ws/gpu_host.cc +++ b/services/ui/ws/gpu_host.cc
@@ -14,7 +14,6 @@ #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/platform_handle.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/ui/common/server_gpu_memory_buffer_manager.h" #include "services/ui/ws/gpu_client.h" #include "services/ui/ws/gpu_host_delegate.h"
diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc index d7bad78..66d1e915 100644 --- a/services/ui/ws/window_manager_state.cc +++ b/services/ui/ws/window_manager_state.cc
@@ -184,7 +184,7 @@ DragTargetConnection* source_connection, const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data, uint32_t drag_operation) { - int32_t drag_pointer = PointerEvent::kMousePointerId; + int32_t drag_pointer = MouseEvent::kMousePointerId; if (in_flight_event_details_ && in_flight_event_details_->event->IsPointerEvent()) { drag_pointer =
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index b47276b..d012b886 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/stl_util.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/ui/ws/display.h" #include "services/ui/ws/display_manager.h" #include "services/ui/ws/frame_generator.h"
diff --git a/services/ui/ws/window_server_service_test_base.h b/services/ui/ws/window_server_service_test_base.h index e6be41d..8cff44c 100644 --- a/services/ui/ws/window_server_service_test_base.h +++ b/services/ui/ws/window_server_service_test_base.h
@@ -6,7 +6,6 @@ #define SERVICES_UI_WS_WINDOW_SERVER_SERVICE_TEST_BASE_H_ #include "base/macros.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/service_test.h" namespace ui {
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc index d70250c..06f6762 100644 --- a/services/ui/ws/window_tree_client_unittest.cc +++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -24,7 +24,6 @@ #include "services/ui/ws/test_change_tracker.h" #include "services/ui/ws/window_server_service_test_base.h" -using service_manager::Connection; using mojo::InterfaceRequest; using service_manager::Service; using ui::mojom::WindowDataPtr;
diff --git a/sql/recovery.cc b/sql/recovery.cc index a805c520..64eefa5 100644 --- a/sql/recovery.cc +++ b/sql/recovery.cc
@@ -126,6 +126,9 @@ // successfully deleted. RECOVERY_SUCCESS_AUTORECOVERDB_NOTADB_DELETE, + // Failed to find required [meta.version] information. + RECOVERY_FAILED_AUTORECOVERDB_META_VERSION, + // Add new items before this one, always keep this one at the end. RECOVERY_EVENT_MAX, }; @@ -602,8 +605,9 @@ // results indicate that everything is working reasonably. // // static -void Recovery::RecoverDatabase(Connection* db, - const base::FilePath& db_path) { +std::unique_ptr<Recovery> Recovery::BeginRecoverDatabase( + Connection* db, + const base::FilePath& db_path) { std::unique_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path); if (!recovery) { // Close the underlying sqlite* handle. Windows does not allow deleting @@ -620,7 +624,7 @@ probe_db.AttachDatabase(db_path, "corrupt") || probe_db.GetErrorCode() != SQLITE_NOTADB) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_BEGIN); - return; + return nullptr; } } @@ -629,7 +633,7 @@ // recoverable _with_ manual intervention). Clear away the broken database. if (!sql::Connection::Delete(db_path)) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NOTADB_DELETE); - return; + return nullptr; } // Windows deletion is complicated by file scanners and malware - sometimes @@ -639,18 +643,18 @@ Connection probe_db; if (!probe_db.Open(db_path)) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NOTADB_REOPEN); - return; + return nullptr; } if (!probe_db.Execute("PRAGMA auto_vacuum")) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NOTADB_QUERY); - return; + return nullptr; } } // The rest of the recovery code could be run on the re-opened database, but // the database is empty, so there would be no point. RecordRecoveryEvent(RECOVERY_SUCCESS_AUTORECOVERDB_NOTADB_DELETE); - return; + return nullptr; } #if DCHECK_IS_ON() @@ -682,7 +686,7 @@ !SchemaCopyHelper(recovery->db(), "CREATE UNIQUE INDEX ")) { // No RecordRecoveryEvent() here because SchemaCopyHelper() already did. Recovery::Rollback(std::move(recovery)); - return; + return nullptr; } // Run auto-recover against each table, skipping the sequence table. This is @@ -698,13 +702,13 @@ if (!recovery->AutoRecoverTable(name.c_str(), &rows_recovered)) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_TABLE); Recovery::Rollback(std::move(recovery)); - return; + return nullptr; } } if (!s.Succeeded()) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NAMESELECT); Recovery::Rollback(std::move(recovery)); - return; + return nullptr; } } @@ -715,7 +719,7 @@ if (!recovery->AutoRecoverTable("sqlite_sequence", &rows_recovered)) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_SEQUENCE); Recovery::Rollback(std::move(recovery)); - return; + return nullptr; } } @@ -728,10 +732,37 @@ if (!recovery->db()->Execute(kCreateMetaItems)) { RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_AUX); Recovery::Rollback(std::move(recovery)); - return; + return nullptr; } RecordRecoveryEvent(RECOVERY_SUCCESS_AUTORECOVERDB); + return recovery; +} + +void Recovery::RecoverDatabase(Connection* db, const base::FilePath& db_path) { + std::unique_ptr<sql::Recovery> recovery = BeginRecoverDatabase(db, db_path); + + // ignore_result() because BeginRecoverDatabase() and Recovered() already + // provide suitable histogram coverage. + if (recovery) + ignore_result(Recovery::Recovered(std::move(recovery))); +} + +void Recovery::RecoverDatabaseWithMetaVersion(Connection* db, + const base::FilePath& db_path) { + std::unique_ptr<sql::Recovery> recovery = BeginRecoverDatabase(db, db_path); + if (!recovery) + return; + + int version = 0; + if (!recovery->SetupMeta() || !recovery->GetMetaVersionNumber(&version)) { + sql::Recovery::Unrecoverable(std::move(recovery)); + RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_META_VERSION); + return; + } + + // ignore_result() because BeginRecoverDatabase() and Recovered() already + // provide suitable histogram coverage. ignore_result(Recovery::Recovered(std::move(recovery))); }
diff --git a/sql/recovery.h b/sql/recovery.h index efc69cbc..e5e4abf8 100644 --- a/sql/recovery.h +++ b/sql/recovery.h
@@ -156,18 +156,28 @@ bool GetMetaVersionNumber(int* version_number); // Attempt to recover the database by creating a new database with schema from - // |db|, then copying over as much data as possible. After this call, the - // |db| handle will be poisoned (though technically remaining open) so that - // future calls will return errors until the handle is re-opened. - // - // If a corrupt database contains tables without unique indices, the resulting - // table may contain duplication. If this is not acceptable, the client - // should use the manual process as described in the example at the top of the - // file, cleaning up data at the appropriate points. + // |db|, then copying over as much data as possible. If successful, the + // recovery handle is returned to allow the caller to make additional changes, + // such as validating constraints not expressed in the schema. // // In case of SQLITE_NOTADB, the database is deemed unrecoverable and deleted. + static std::unique_ptr<Recovery> BeginRecoverDatabase( + Connection* db, + const base::FilePath& db_path) WARN_UNUSED_RESULT; + + // Call BeginRecoverDatabase() to recover the database, then commit the + // changes using Recovered(). After this call, the |db| handle will be + // poisoned (though technically remaining open) so that future calls will + // return errors until the handle is re-opened. static void RecoverDatabase(Connection* db, const base::FilePath& db_path); + // Variant on RecoverDatabase() which requires that the database have a valid + // meta table with a version value. The meta version value is used by some + // clients to make assertions about the database schema. If this information + // cannot be determined, the database is considered unrecoverable. + static void RecoverDatabaseWithMetaVersion(Connection* db, + const base::FilePath& db_path); + // Returns true for SQLite errors which RecoverDatabase() can plausibly fix. // This does not guarantee that RecoverDatabase() will successfully recover // the database.
diff --git a/sql/recovery_unittest.cc b/sql/recovery_unittest.cc index 111a610..75268822 100644 --- a/sql/recovery_unittest.cc +++ b/sql/recovery_unittest.cc
@@ -834,6 +834,54 @@ EXPECT_EQ("", GetSchema(&db())); } +// Allow callers to validate the database between recovery and commit. +TEST_F(SQLRecoveryTest, BeginRecoverDatabase) { + // Create a table with a broken index. + ASSERT_TRUE(db().Execute("CREATE TABLE t (id INTEGER PRIMARY KEY, c TEXT)")); + ASSERT_TRUE(db().Execute("CREATE UNIQUE INDEX t_id ON t (id)")); + ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (1, 'hello world')")); + ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (2, 'testing')")); + ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (3, 'nope')")); + + // Inject corruption into the index. + db().Close(); + const char kDeleteSql[] = "DELETE FROM t WHERE id = 3"; + ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path(), "t_id", kDeleteSql)); + ASSERT_TRUE(Reopen()); + + // id as read from index. + const char kSelectIndexIdSql[] = "SELECT id FROM t INDEXED BY t_id"; + EXPECT_EQ("1,2,3", ExecuteWithResults(&db(), kSelectIndexIdSql, "|", ",")); + + // id as read from table. + const char kSelectTableIdSql[] = "SELECT id FROM t NOT INDEXED"; + EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectTableIdSql, "|", ",")); + + // Run recovery code, then rollback. Database remains the same. + { + std::unique_ptr<sql::Recovery> recovery = + sql::Recovery::BeginRecoverDatabase(&db(), db_path()); + ASSERT_TRUE(recovery); + sql::Recovery::Rollback(std::move(recovery)); + } + db().Close(); + ASSERT_TRUE(Reopen()); + EXPECT_EQ("1,2,3", ExecuteWithResults(&db(), kSelectIndexIdSql, "|", ",")); + EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectTableIdSql, "|", ",")); + + // Run recovery code, then commit. The failing row is dropped. + { + std::unique_ptr<sql::Recovery> recovery = + sql::Recovery::BeginRecoverDatabase(&db(), db_path()); + ASSERT_TRUE(recovery); + ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); + } + db().Close(); + ASSERT_TRUE(Reopen()); + EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectIndexIdSql, "|", ",")); + EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectTableIdSql, "|", ",")); +} + // Test histograms recorded when the invalid database cannot be attached. TEST_F(SQLRecoveryTest, AttachFailure) { // Create a valid database, then write junk over the header. This should lead
diff --git a/storage/browser/database/OWNERS b/storage/browser/database/OWNERS new file mode 100644 index 0000000..07618c5 --- /dev/null +++ b/storage/browser/database/OWNERS
@@ -0,0 +1,4 @@ +pwnall@chromium.org + +# TEAM: storage-dev@chromium.org +# COMPONENT: Blink>Storage>WebSQL
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 055ecb5..c84463e 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1495,6 +1495,10 @@ crbug.com/521124 crbug.com/410145 [ Win7 ] fast/css/font-weight-1.html [ Pass Failure ] crbug.com/521124 crbug.com/410145 [ Win7 ] virtual/sharedarraybuffer/fast/css/font-weight-1.html [ Pass Failure ] +crbug.com/710946 inspector-protocol/runtime/runtime-callFunctionOn-async.html [ NeedsManualRebaseline ] +crbug.com/710946 inspector-protocol/runtime/runtime-evaluate-async.html [ NeedsManualRebaseline ] +crbug.com/710946 inspector-protocol/runtime/runtime-runScript-async.html [ NeedsManualRebaseline ] + # Temporary, until we stop use_system_harfbuzz on Linux including non-official builds crbug.com/462689 [ Linux ] fast/text/unicode-variation-selector.html [ Failure ] @@ -1872,6 +1876,7 @@ crbug.com/710226 [ Win Mac10.9 Mac10.10 Mac10.11 Mac10.12 ] external/wpt/cssom-view/MediaQueryList-001.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/selectors4/focus-within-shadow-006.html [ Failure ] crbug.com/626703 [ Android Linux Win ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-item-vert-001b.html [ Failure ] crbug.com/626703 external/wpt/cssom-view/matchMedia.xht [ Timeout ] crbug.com/626703 external/wpt/css/css-display-3/display-contents-dynamic-before-after-001.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 9c54a29e..104475c 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -27055,6 +27055,18 @@ {} ] ], + "css/selectors4/focus-within-shadow-006.html": [ + [ + "/css/selectors4/focus-within-shadow-006.html", + [ + [ + "/css/selectors4/focus-within-shadow-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/selectors4/of-type-selectors.xhtml": [ [ "/css/selectors4/of-type-selectors.xhtml", @@ -38598,6 +38610,96 @@ {} ] ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-none-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-self-block-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin-expected.txt": [ + [ + {} + ] + ], + "content-security-policy/frame-ancestors/frame-ancestors-url-block-expected.txt": [ + [ + {} + ] + ], "content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html": [ [ {} @@ -49733,11 +49835,31 @@ {} ] ], + "cssom-view/cssom-getBoundingClientRect-002-expected.txt": [ + [ + {} + ] + ], + "cssom-view/cssom-view/media-query-list-interface-expected.txt": [ + [ + {} + ] + ], + "cssom-view/cssom-view/window-interface-expected.txt": [ + [ + {} + ] + ], "cssom-view/elementFromPoint-expected.txt": [ [ {} ] ], + "cssom-view/elementFromPosition-expected.txt": [ + [ + {} + ] + ], "cssom-view/elementsFromPoint-expected.txt": [ [ {} @@ -49748,6 +49870,11 @@ {} ] ], + "cssom-view/offsetParent_element_test-expected.txt": [ + [ + {} + ] + ], "cssom-view/scrollingElement-expected.txt": [ [ {} @@ -49983,11 +50110,56 @@ {} ] ], + "cssom/CSSStyleRule-expected.txt": [ + [ + {} + ] + ], "cssom/css-style-attribute-modifications-expected.txt": [ [ {} ] ], + "cssom/cssom-fontfacerule-expected.txt": [ + [ + {} + ] + ], + "cssom/index-002-expected.txt": [ + [ + {} + ] + ], + "cssom/inline-style-001-expected.txt": [ + [ + {} + ] + ], + "cssom/interfaces-expected.txt": [ + [ + {} + ] + ], + "cssom/medialist-interfaces-001-expected.txt": [ + [ + {} + ] + ], + "cssom/medialist-interfaces-002-expected.txt": [ + [ + {} + ] + ], + "cssom/medialist-interfaces-004-expected.txt": [ + [ + {} + ] + ], + "cssom/selectorSerialize-expected.txt": [ + [ + {} + ] + ], "cssom/serialize-values-expected.txt": [ [ {} @@ -49998,6 +50170,11 @@ {} ] ], + "cssom/style-sheet-interfaces-001-expected.txt": [ + [ + {} + ] + ], "cssom/stylesheet-same-origin.css": [ [ {} @@ -50228,6 +50405,11 @@ {} ] ], + "cssom/ttwf-cssom-doc-ext-load-count-expected.txt": [ + [ + {} + ] + ], "custom-elements/adopted-callback-expected.txt": [ [ {} @@ -66098,11 +66280,21 @@ {} ] ], + "service-workers/service-worker/register-link-element.https-expected.txt": [ + [ + {} + ] + ], "service-workers/service-worker/register-wait-forever-in-install-worker.https-expected.txt": [ [ {} ] ], + "service-workers/service-worker/registration.https-expected.txt": [ + [ + {} + ] + ], "service-workers/service-worker/resource-timing.https-expected.txt": [ [ {} @@ -89059,15 +89251,15 @@ {} ] ], - "media-capabilities/idlharness.html": [ + "media-capabilities/decodingInfo.html": [ [ - "/media-capabilities/idlharness.html", + "/media-capabilities/decodingInfo.html", {} ] ], - "media-capabilities/query.html": [ + "media-capabilities/idlharness.html": [ [ - "/media-capabilities/query.html", + "/media-capabilities/idlharness.html", {} ] ], @@ -102537,6 +102729,12 @@ {} ] ], + "web-animations/interfaces/Animation/idlharness.html": [ + [ + "/web-animations/interfaces/Animation/idlharness.html", + {} + ] + ], "web-animations/interfaces/Animation/oncancel.html": [ [ "/web-animations/interfaces/Animation/oncancel.html", @@ -102771,12 +102969,30 @@ {} ] ], + "web-animations/timing-model/animations/canceling-an-animation.html": [ + [ + "/web-animations/timing-model/animations/canceling-an-animation.html", + {} + ] + ], "web-animations/timing-model/animations/current-time.html": [ [ "/web-animations/timing-model/animations/current-time.html", {} ] ], + "web-animations/timing-model/animations/finishing-an-animation.html": [ + [ + "/web-animations/timing-model/animations/finishing-an-animation.html", + {} + ] + ], + "web-animations/timing-model/animations/pausing-an-animation.html": [ + [ + "/web-animations/timing-model/animations/pausing-an-animation.html", + {} + ] + ], "web-animations/timing-model/animations/playing-an-animation.html": [ [ "/web-animations/timing-model/animations/playing-an-animation.html", @@ -102813,12 +103029,6 @@ {} ] ], - "web-nfc/idlharness.https.html": [ - [ - "/web-nfc/idlharness.https.html", - {} - ] - ], "webmessaging/Channel_postMessage_DataCloneErr.htm": [ [ "/webmessaging/Channel_postMessage_DataCloneErr.htm", @@ -109428,10 +109638,18 @@ "888d3e58d3d094b767067e16494803af432ee057", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block-expected.txt": [ + "3111314ca9589e553a81bceb340dda251e3bc3a5", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block.html": [ "e96b19c03463de925f03a666a173e948c0908302", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block-expected.txt": [ + "998121ac3b7aa1650765732ce60997c89da8aa09", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block.html": [ "816ef071086019d9abed995370cb39a8542f3322", "testharness" @@ -109444,38 +109662,74 @@ "928e1285169b1d137550f67c083c6ba4eb532b6c", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block-expected.txt": [ + "215913ff317ebac84ce6d2dbc7f60b68fb85a641", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block.html": [ "46a056e57129f76eabf6b53b833a24b1a861ed91", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block-expected.txt": [ + "3111314ca9589e553a81bceb340dda251e3bc3a5", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block.html": [ "486eaffb8f7c9e28861adeef5e2af6777be73ee6", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block-expected.txt": [ + "998121ac3b7aa1650765732ce60997c89da8aa09", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block.html": [ "9c40ca204dae2de593f46b723dc7e6bfa8f8e8fd", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow-expected.txt": [ + "4d1561c84798d85eac541e1ae872b0d290f12590", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html": [ "03ea8e9bd6c19aff4ceac59b178b1ef065afeedc", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow-expected.txt": [ + "215913ff317ebac84ce6d2dbc7f60b68fb85a641", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html": [ "f7a44723534d82a650cf8853d6cb114b46f1b535", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block-expected.txt": [ + "215913ff317ebac84ce6d2dbc7f60b68fb85a641", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block.html": [ "37ead57a4f508fd817541ecb2b2576b7fe65532f", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block-expected.txt": [ + "4b282eae4435842fa3777ceff7d78d538385711a", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html": [ "4aee1e3833591c74694a3c960bd32c1047a8546f", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block-expected.txt": [ + "3111314ca9589e553a81bceb340dda251e3bc3a5", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block.html": [ "2a831ff6c6a9b0a7c63b427105a077ffedbb46e1", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block-expected.txt": [ + "998121ac3b7aa1650765732ce60997c89da8aa09", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block.html": [ "332a0a289180b90d14bdb1f4b13c8225b9a810f5", "testharness" @@ -109488,10 +109742,18 @@ "d8aa43dbab2fd38dd1b7b3ac004dddbf20b3a247", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block-expected.txt": [ + "215913ff317ebac84ce6d2dbc7f60b68fb85a641", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block.html": [ "e3ab2ece1d6db2be49a25a0f46c98d3fd07fa1e7", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block-expected.txt": [ + "3111314ca9589e553a81bceb340dda251e3bc3a5", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block.html": [ "035865df4a43600910890fed3856fadaf05fd7b7", "testharness" @@ -109508,10 +109770,18 @@ "c5d24d65811915fff1fafff89f29c6287abaf6d8", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block-expected.txt": [ + "215913ff317ebac84ce6d2dbc7f60b68fb85a641", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block.html": [ "c6d7b2b67f933e00feadefa00263cc3b17443395", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-none-block-expected.txt": [ + "45414ef3eda575ddab318619c29eb32f2f53ef52", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-none-block.html": [ "b5d0f5f0923f8c1e3400d91f6194f665d7a30a97", "testharness" @@ -109524,10 +109794,18 @@ "635dd6a6ae1cc8f51fad8b9c0cdcaf7d2b8322b4", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-self-block-expected.txt": [ + "ac2b4ae241595d763fd07b270e4324cb734e3518", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-self-block.html": [ "31b16e7e4c7113ec27cba6c0b880b2472fbc174b", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin-expected.txt": [ + "2f5ef349f841bdcd8820c9b57e44c7553327869b", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin.html": [ "6af460fa2c57111abbc8f3ceeb09b31993821b22", "testharness" @@ -109540,6 +109818,10 @@ "e0921d30fdb2e9739497849133e93d49486cd417", "testharness" ], + "content-security-policy/frame-ancestors/frame-ancestors-url-block-expected.txt": [ + "8088d89859ba7cd7bfe43acf8d893472e7f7a0f9", + "support" + ], "content-security-policy/frame-ancestors/frame-ancestors-url-block.html": [ "f7b54ddb5688e4706d078538af1f16f2b82d3375", "testharness" @@ -129980,6 +130262,10 @@ "99c5fcb361ae4903b4e87315dfb8ba80f0296037", "reftest" ], + "css/selectors4/focus-within-shadow-006.html": [ + "41341130ccf5756ba0bfe12bf9f7f22da8ad7fe0", + "reftest" + ], "css/selectors4/hover-001-manual.html": [ "ce45f6b6f483ae52c241acff168573a0907ca031", "manual" @@ -132392,6 +132678,10 @@ "7118495560adadebcca98e6add47a74669f87788", "testharness" ], + "cssom-view/cssom-getBoundingClientRect-002-expected.txt": [ + "3a77f2a2a04d37ae64ca7c4fb1a47534faa8bdee", + "support" + ], "cssom-view/cssom-getBoundingClientRect-002.html": [ "8dfaa313b4abad30281d07ce22ac06a61754cc06", "testharness" @@ -132408,10 +132698,18 @@ "8fb3e3327f8f657e2215c91c75f49fd739c15c57", "testharness" ], + "cssom-view/cssom-view/media-query-list-interface-expected.txt": [ + "e10c7bbf158a0652b0ee64b7f16408bad7f3b774", + "support" + ], "cssom-view/cssom-view/media-query-list-interface.xht": [ "3f867c6e608d318d870d3269b9eb886955c119fc", "testharness" ], + "cssom-view/cssom-view/window-interface-expected.txt": [ + "2d90834d824a27b9aada1b977630dfbb3879f215", + "support" + ], "cssom-view/cssom-view/window-interface.xht": [ "47aee3e273f90c1f1eb08884afecdef8a96630c5", "testharness" @@ -132428,6 +132726,10 @@ "e22ae99aa1fba51807aec245b810db5d584ac037", "testharness" ], + "cssom-view/elementFromPosition-expected.txt": [ + "40e5741bd552d42fd81b876f74332b8c281454fd", + "support" + ], "cssom-view/elementFromPosition.html": [ "d90dff8b15ec2977f341a7add9c7d627b62d9d0f", "testharness" @@ -132472,6 +132774,10 @@ "ad44e3f4ba132bfb4a522b14a4ff5356dbbbad14", "testharness" ], + "cssom-view/offsetParent_element_test-expected.txt": [ + "055aaddbbf5a444b0b5971f7e018a2934ad725ae", + "support" + ], "cssom-view/offsetParent_element_test.html": [ "6e7579de7add0162ac99f3326f070bbd6051932b", "testharness" @@ -132724,6 +133030,10 @@ "8d8b435c2398c7a9de5fd57584240e24b45b80bc", "testharness" ], + "cssom/CSSStyleRule-expected.txt": [ + "b6699c0ffd77348cb238e7885f789f84c5194f5f", + "support" + ], "cssom/CSSStyleRule.html": [ "b7cfe3da8454d5c64a25c440e0776c80d8c3a751", "testharness" @@ -132776,6 +133086,10 @@ "c064661df74571d374f49a693f3263fcf138e670", "testharness" ], + "cssom/cssom-fontfacerule-expected.txt": [ + "05cbaaccfc39fad2c6ecb579d66f9df02c7521ff", + "support" + ], "cssom/cssom-fontfacerule.html": [ "965a8f6289fa5c6e34bfd447de3b8ef86573fea1", "testharness" @@ -132804,6 +133118,10 @@ "ab9e9f102f5909d9b5587f2c0ea54c0c6b59868d", "testharness" ], + "cssom/index-002-expected.txt": [ + "ff8799530548cd7dd1ab3c497f507aa6e62d8b17", + "support" + ], "cssom/index-002.html": [ "fe12bc0005ccfccfafd4f23644b28fbb5f5e33d1", "testharness" @@ -132812,18 +133130,34 @@ "f55d9bc5b2e25b1af5169ecc164f62b6a95abfe5", "testharness" ], + "cssom/inline-style-001-expected.txt": [ + "854f4a7f81962431f6132acf5ff6b42ff3819c53", + "support" + ], "cssom/inline-style-001.html": [ "377c8610bc597d47a93f70a9cf95b3c7657d8319", "testharness" ], + "cssom/interfaces-expected.txt": [ + "337273323747da55e98d2fefdb1a15581b03b81e", + "support" + ], "cssom/interfaces.html": [ "5876c88acd95d18166fdd049bdb3f09cdde4eb3f", "testharness" ], + "cssom/medialist-interfaces-001-expected.txt": [ + "5b28fc21421358f35fe030552a13d3a44ebfcb3a", + "support" + ], "cssom/medialist-interfaces-001.html": [ "dfaea262508d72d123006409174e3e21832a305f", "testharness" ], + "cssom/medialist-interfaces-002-expected.txt": [ + "0e120d75caedff5879b4da464f4fe38333efe875", + "support" + ], "cssom/medialist-interfaces-002.html": [ "114fac94342afe2e7fe432a67c4b0bbf03d24bc4", "testharness" @@ -132832,6 +133166,10 @@ "b9ddd611cc585202b1e76382666b04197af334b0", "testharness" ], + "cssom/medialist-interfaces-004-expected.txt": [ + "435495326a27ba1596e043d89df62e6f66458ff6", + "support" + ], "cssom/medialist-interfaces-004.html": [ "e3cdc88670ca46b3752fd8118d94dae2cc95258d", "testharness" @@ -132840,6 +133178,10 @@ "199039706289f577652b968706fc1251398acd1c", "testharness" ], + "cssom/selectorSerialize-expected.txt": [ + "be841dc5ad7bb520ef21e922b0781d0e393bcb71", + "support" + ], "cssom/selectorSerialize.html": [ "002777c7c598eb1131ab625365ee3fe08650e830", "testharness" @@ -132868,6 +133210,10 @@ "bd514834dbd48c267c16a4329af6fec7f6cbc081", "testharness" ], + "cssom/style-sheet-interfaces-001-expected.txt": [ + "766e9c1b8a8daa003076511584bb695b1e1b5d66", + "support" + ], "cssom/style-sheet-interfaces-001.html": [ "15509e87505d5a22d4f6dbbffcc90c24fcee642a", "testharness" @@ -133064,6 +133410,10 @@ "078e1dd6dd61d36cec239ed75d02051f61fe60a5", "support" ], + "cssom/ttwf-cssom-doc-ext-load-count-expected.txt": [ + "8f765460a64800bc2ccc6d0067a3b9b65cc4d1b2", + "support" + ], "cssom/ttwf-cssom-doc-ext-load-count.html": [ "800db5cd4f7342d8c4e5309d4035182ce42f7251", "testharness" @@ -134609,7 +134959,7 @@ "support" ], "dom/nodes/case-expected.txt": [ - "04da91ce54c42bbd57496a60483553e45fd43947", + "77f3037f1d9f1da9bb8c51269af9564870099690", "support" ], "dom/nodes/case.html": [ @@ -136641,7 +136991,7 @@ "testharness" ], "fetch/api/headers/headers-basic-expected.txt": [ - "5cc5ace9951394fd264b9233cf32435cec55c57b", + "c7aa1da80c76986abd8e190ba07af702a4005565", "support" ], "fetch/api/headers/headers-basic.html": [ @@ -136681,7 +137031,7 @@ "testharness" ], "fetch/api/headers/headers-record-expected.txt": [ - "7dd187ab5cc9c185252088e470d9a4784fec14d0", + "d8d03a608ee0af8ba54c18dcc1e8040dbe4e86bd", "support" ], "fetch/api/headers/headers-record.html": [ @@ -151056,16 +151406,16 @@ "7d6ceec9a74d5485a6f7d51504f22e5eaf81bfee", "support" ], + "media-capabilities/decodingInfo.html": [ + "1d8f79cb9e47042aa7eff1b63fe72af4941830e2", + "testharness" + ], "media-capabilities/idlharness-expected.txt": [ - "36a770de2f25ca3e03f92ff615db45b2b3edec59", + "c7e0888b13bbf83dc7fc9baa33f46b822b02133d", "support" ], "media-capabilities/idlharness.html": [ - "d9a80463af2e0fc7bda0a4370a3ba0bbbb791897", - "testharness" - ], - "media-capabilities/query.html": [ - "a83f2c7a7d9c38c707c4f96c3cd74f77185b7e43", + "dbaa12b0278165d9152815b9d391a198b0ba610e", "testharness" ], "media/2048x1360-random.jpg": [ @@ -162196,6 +162546,10 @@ "864f5435fc40124dbe2c1ffb0e1942fee58228d2", "testharness" ], + "service-workers/service-worker/register-link-element.https-expected.txt": [ + "b132376709325573bb909b51afc67e7c5c1ac669", + "support" + ], "service-workers/service-worker/register-link-element.https.html": [ "fcd2a244ad1f12c954c231c479f89beaa3c145e6", "testharness" @@ -162236,6 +162590,10 @@ "73d662eafa93ca3dee4a4e5d34623cf069c2b8f8", "testharness" ], + "service-workers/service-worker/registration.https-expected.txt": [ + "36309067df5ff56185b6618affe450f7c298daaf", + "support" + ], "service-workers/service-worker/registration.https.html": [ "0a06c368a14c008c385c9df3cde35f090d96d58b", "testharness" @@ -163973,7 +164331,7 @@ "testharness" ], "streams/piping/pipe-through.js": [ - "8960662dd6a59e4950c1e8ee86d0ea21de5b1bf7", + "bf2cebbca84051b446f728d92c065869207299f2", "support" ], "streams/piping/pipe-through.serviceworker.https-expected.txt": [ @@ -165464,6 +165822,10 @@ "395dad4a877ef4af20649d6bcfece102a22b3059", "testharness" ], + "web-animations/interfaces/Animation/idlharness.html": [ + "bf61e9cb3d009b4d5ccbd70ec7397842e2d521d2", + "testharness" + ], "web-animations/interfaces/Animation/oncancel.html": [ "0477d2fef7fc64bbc969b29d4ba542574c4c3706", "testharness" @@ -165489,7 +165851,7 @@ "testharness" ], "web-animations/interfaces/Animation/ready.html": [ - "f79ea4e2bfc3bc83a7ac96634cbb2d5f21f6c1f5", + "b23b76881f4d38c07710d0e59c1f6c8569de9060", "testharness" ], "web-animations/interfaces/Animation/reverse-expected.txt": [ @@ -165724,6 +166086,10 @@ "53a4a6c6c6d07e00fecc50e5de831862e7bf4b2e", "testharness" ], + "web-animations/timing-model/animations/canceling-an-animation.html": [ + "079bc0e0f7ea60b94999ed1b4f92c1aa2fc2c7bb", + "testharness" + ], "web-animations/timing-model/animations/current-time-expected.txt": [ "a18dd6fac631dc2beee45b4f1f1a75ca1bed1e82", "support" @@ -165732,8 +166098,16 @@ "b1ea8e490cbfb69fd71b91a90e7e2d9ce99f42d3", "testharness" ], + "web-animations/timing-model/animations/finishing-an-animation.html": [ + "570ec579c6118866b888b1384e21977c9cfb0ec0", + "testharness" + ], + "web-animations/timing-model/animations/pausing-an-animation.html": [ + "a000d8f86fa62b90ec7a60c289066aaaa1758377", + "testharness" + ], "web-animations/timing-model/animations/playing-an-animation.html": [ - "88ab1d42390d50bcdf513bb12159c0c15d6278ff", + "2b4f51977d43f9bf90c066bfcc57728ae096b6e9", "testharness" ], "web-animations/timing-model/animations/set-the-animation-start-time-expected.txt": [ @@ -165772,10 +166146,6 @@ "66e2277c77e4bd7b2d8981a725fb5083a8f5e0f6", "testharness" ], - "web-nfc/idlharness.https.html": [ - "b44413f6709ec74f6fc809726d0e988c127ef02d", - "testharness" - ], "webmessaging/Channel_postMessage_DataCloneErr.htm": [ "a62fdac80932ca059c8853ca9a9f8edd13926f86", "testharness"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/selectors4/focus-within-shadow-006.html b/third_party/WebKit/LayoutTests/external/wpt/css/selectors4/focus-within-shadow-006.html new file mode 100644 index 0000000..39a2f70 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/selectors4/focus-within-shadow-006.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>Selectors Level 4: focus-within with shadow DOM</title> +<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-within-pseudo"> +<link rel="help" href="https://dom.spec.whatwg.org/#shadow-trees"> +<link rel="match" href="focus-within-shadow-001-ref.html"> +<meta name="flags" content="dom"> +<meta name="assert" content="Checks that ':focus-within' is propagated to the flat tree ancestors, even if it comes from a slotted element."> +<style> + /* Suppress things that cannot be reproduced in the reference file */ + :focus { + outline: none; + } + :focus-within { + border-color: green; + } +</style> +<p>Test passes if there is a green rectangle below.</p> + +<div id="log"></div> +<script> + if (!document.body.attachShadow) + document.getElementById("log").innerHTML = "<strong>Skip this test, shadow DOM is not supported.</strong>"; +</script> + +<div id="shadow-host"> + <div id="focusme" tabindex="1"></div> +</div> + +<script> + var shadowHost = document.getElementById("shadow-host"); + shadowHost.attachShadow({ mode: "open"}).innerHTML = + "<style>" + + " #shadow-div:focus-within { border: solid 15px green; }" + + "</style>" + + "<div id='shadow-div'>" + + " <slot></slot>" + + "</div>"; + var focusme = document.getElementById("focusme"); + focusme.focus(); + document.documentElement.classList.remove("reftest-wait"); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt index cb261c6..9b1cbbf 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt
@@ -6,5 +6,6 @@ PASS pipeThrough can handle calling a pipeTo that returns a non-promise object PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object PASS pipeThrough should mark a real promise from a fake readable as handled +PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt index cb261c6..9b1cbbf 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt
@@ -6,5 +6,6 @@ PASS pipeThrough can handle calling a pipeTo that returns a non-promise object PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object PASS pipeThrough should mark a real promise from a fake readable as handled +PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.js b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.js index 9299fce..bc4ac909 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.js +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.js
@@ -118,4 +118,30 @@ }, 'pipeThrough should mark a real promise from a fake readable as handled'); +test(() => { + let thenCalled = false + let catchCalled = false; + const dummy = { + pipeTo() { + const fakePromise = Object.create(Promise.prototype); + fakePromise.then = () => { + thenCalled = true; + }; + fakePromise.catch = () => { + catchCalled = true; + }; + assert_true(fakePromise instanceof Promise, 'fakePromise fools instanceof'); + return fakePromise; + } + }; + + // An incorrect implementation which uses an internal method to mark the promise as handled will throw or crash here. + ReadableStream.prototype.pipeThrough.call(dummy, { }); + + // An incorrect implementation that tries to mark the promise as handled by calling .then() or .catch() on the object + // will fail these tests. + assert_false(thenCalled, 'then should not be called'); + assert_false(catchCalled, 'catch should not be called'); +}, 'pipeThrough should not be fooled by an object whose instanceof Promise returns true'); + done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt index cbfe250..4bf888f6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt
@@ -7,5 +7,6 @@ PASS pipeThrough can handle calling a pipeTo that returns a non-promise object PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object PASS pipeThrough should mark a real promise from a fake readable as handled +PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt index cb261c6..9b1cbbf 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt
@@ -6,5 +6,6 @@ PASS pipeThrough can handle calling a pipeTo that returns a non-promise object PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object PASS pipeThrough should mark a real promise from a fake readable as handled +PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/idlharness-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/idlharness-expected.txt new file mode 100644 index 0000000..92f829e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/idlharness-expected.txt
@@ -0,0 +1,43 @@ +This is a testharness.js-based test. +PASS Animation interface automated IDL tests +FAIL Animation interface: existence and properties of interface object assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface object length assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface object name assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: existence and properties of interface prototype object assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute id assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute effect assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute timeline assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute startTime assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute currentTime assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute playbackRate assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute playState assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute ready assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute finished assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute onfinish assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: attribute oncancel assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: operation cancel() assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: operation finish() assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: operation play() assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: operation pause() assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation interface: operation reverse() assert_own_property: self does not have own property "Animation" expected property "Animation" missing +FAIL Animation must be primary interface of new Animation() assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Stringification of new Animation() assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "id" with the proper type (0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "effect" with the proper type (1) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "timeline" with the proper type (2) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "startTime" with the proper type (3) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "currentTime" with the proper type (4) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "playbackRate" with the proper type (5) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "playState" with the proper type (6) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "ready" with the proper type (7) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "finished" with the proper type (8) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "onfinish" with the proper type (9) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "oncancel" with the proper type (10) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "cancel" with the proper type (11) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "finish" with the proper type (12) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "play" with the proper type (13) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "pause" with the proper type (14) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +FAIL Animation interface: new Animation() must inherit property "reverse" with the proper type (15) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Animation is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/idlharness.html new file mode 100644 index 0000000..213958f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/idlharness.html
@@ -0,0 +1,51 @@ +<!doctype html> +<meta charset=utf-8> +<title>Animation interface automated IDL tests</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/WebIDLParser.js"></script> +<script src="/resources/idlharness.js"></script> +<script src="../../testcommon.js"></script> +<div id="log"></div> +<script type="text/plain" id="Animation-IDL"> +enum AnimationPlayState { "idle", "pending", "running", "paused", "finished" }; + +[Constructor (optional AnimationEffectReadOnly? effect = null, + optional AnimationTimeline? timeline)] +interface Animation : EventTarget { + attribute DOMString id; + attribute AnimationEffectReadOnly? effect; + attribute AnimationTimeline? timeline; + attribute double? startTime; + attribute double? currentTime; + attribute double playbackRate; + readonly attribute AnimationPlayState playState; + readonly attribute Promise<Animation> ready; + readonly attribute Promise<Animation> finished; + attribute EventHandler onfinish; + attribute EventHandler oncancel; + void cancel (); + void finish (); + void play (); + void pause (); + void reverse (); +}; +</script> +<script> +'use strict'; + +test(function(t) { + const idlArray = new IdlArray(); + + idlArray.add_untested_idls('interface AnimationTimeline {};'); + idlArray.add_untested_idls('interface EventHandler {};'); + idlArray.add_untested_idls('interface EventTarget {};'); + idlArray.add_idls( + document.getElementById('Animation-IDL').textContent); + + // const animation = createDiv(t).animate(null); + idlArray.add_objects( { Animation: ['new Animation()'] } ); + idlArray.test(); +}); + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/ready.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/ready.html index 86595c3..b61a3c49 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/ready.html +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Animation/ready.html
@@ -12,7 +12,7 @@ promise_test(function(t) { var div = createDiv(t); - var animation = div.animate({}, 100 * MS_PER_SEC); + var animation = div.animate(null, 100 * MS_PER_SEC); var originalReadyPromise = animation.ready; var pauseReadyPromise; @@ -35,7 +35,7 @@ promise_test(function(t) { var div = createDiv(t); - var animation = div.animate({}, 100 * MS_PER_SEC); + var animation = div.animate(null, 100 * MS_PER_SEC); return animation.ready.then(function() { var promiseBeforeCallingPlay = animation.ready; @@ -48,7 +48,7 @@ promise_test(function(t) { var div = createDiv(t); - var animation = div.animate({}, 100 * MS_PER_SEC); + var animation = div.animate(null, 100 * MS_PER_SEC); return animation.ready.then(function(resolvedAnimation) { assert_equals(resolvedAnimation, animation, @@ -57,40 +57,5 @@ }); }, 'The ready promise is fulfilled with its Animation'); -promise_test(function(t) { - var div = createDiv(t); - var animation = div.animate({}, 100 * MS_PER_SEC); - - var retPromise = animation.ready.then(function() { - assert_unreached('ready promise was fulfilled'); - }).catch(function(err) { - assert_equals(err.name, 'AbortError', - 'ready promise is rejected with AbortError'); - }); - - animation.cancel(); - - return retPromise; -}, 'ready promise is rejected when a play-pending animation is cancelled by' - + ' calling cancel()'); - -promise_test(function(t) { - var div = createDiv(t); - var animation = div.animate({}, 100 * MS_PER_SEC); - return animation.ready.then(function() { - animation.pause(); - // Set up listeners on pause-pending ready promise - var retPromise = animation.ready.then(function() { - assert_unreached('ready promise was fulfilled'); - }).catch(function(err) { - assert_equals(err.name, 'AbortError', - 'ready promise is rejected with AbortError'); - }); - animation.cancel(); - return retPromise; - }); -}, 'ready promise is rejected when a pause-pending animation is cancelled by' - + ' calling cancel()'); - </script> </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/canceling-an-animation-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/canceling-an-animation-expected.txt new file mode 100644 index 0000000..65d504e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/canceling-an-animation-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = The user aborted a request. +PASS A play-pending ready promise should be rejected when the animation is canceled +PASS A pause-pending ready promise should be rejected when the animation is canceled +PASS When an animation is canceled, it should create a resolved Promise +PASS The ready promise should be replaced when the animation is canceled +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/canceling-an-animation.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/canceling-an-animation.html new file mode 100644 index 0000000..5aa7de2b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/canceling-an-animation.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Canceling an animation</title> +<link rel="help" + href="https://w3c.github.io/web-animations/#canceling-an-animation-section"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../../testcommon.js"></script> +<body> +<div id="log"></div> +<script> +"use strict"; + +promise_test(function(t) { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + const retPromise = animation.ready.then(() => { + assert_unreached('ready promise was fulfilled'); + }).catch(err => { + assert_equals(err.name, 'AbortError', + 'ready promise is rejected with AbortError'); + }); + + animation.cancel(); + + return retPromise; +}, 'A play-pending ready promise should be rejected when the animation is' + + ' canceled'); + +promise_test(function(t) { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + return animation.ready.then(() => { + animation.pause(); + // Set up listeners on pause-pending ready promise + var retPromise = animation.ready.then(function() { + assert_unreached('ready promise was fulfilled'); + }).catch(err => { + assert_equals(err.name, 'AbortError', + 'ready promise is rejected with AbortError'); + }); + animation.cancel(); + return retPromise; + }); +}, 'A pause-pending ready promise should be rejected when the animation is' + + ' canceled'); + +promise_test(function(t) { + const animation = createDiv(t).animate(null); + animation.cancel(); + return animation.ready.then(function(p) { + assert_equals(p, animation); + }); +}, 'When an animation is canceled, it should create a resolved Promise'); + +test(function(t) { + const animation = createDiv(t).animate(null); + const promise = animation.ready; + animation.cancel(); + assert_not_equals(animation.ready, promise); +}, 'The ready promise should be replaced when the animation is canceled'); + +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html new file mode 100644 index 0000000..4890bd1b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Finishing an animation</title> +<link rel="help" + href="https://w3c.github.io/web-animations/#finishing-an-animation-section"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../../testcommon.js"></script> +<body> +<div id="log"></div> +<script> +'use strict'; + +promise_test(function(t) { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + const promise = animation.ready; + let readyResolved = false; + + animation.finish(); + animation.ready.then(() => { readyResolved = true; }); + + return animation.finished.then(p => { + assert_equals(p, animation); + assert_equals(animation.ready, promise); + assert_true(readyResolved); + }); +}, 'A pending ready promise should be resolved and not replaced when the' + + ' animation is finished'); + +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/pausing-an-animation.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/pausing-an-animation.html new file mode 100644 index 0000000..9a4da2e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/pausing-an-animation.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Pausing an animation</title> +<link rel="help" + href="https://w3c.github.io/web-animations/#finishing-an-animation-section"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../../testcommon.js"></script> +<body> +<div id="log"></div> +<script> +'use strict'; + +promise_test(function(t) { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + const promise = animation.ready; + animation.pause(); + return promise.then(p => { + assert_equals(p, animation); + assert_equals(animation.ready, promise); + assert_equals(animation.playState, 'paused'); + }); +}, 'A pending ready promise should be resolved and not replaced when the' + + ' animation is paused'); + +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/playing-an-animation.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/playing-an-animation.html index 185e206..1cf109d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/playing-an-animation.html +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/timing-model/animations/playing-an-animation.html
@@ -36,5 +36,24 @@ assert_times_equal(animation.currentTime, 100 * MS_PER_SEC); }, 'Playing a finished and reversed animation seeks to end'); +test(function(t) { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.cancel(); + const promise = animation.ready; + animation.play(); + assert_not_equals(animation.ready, promise); +}, 'The ready promise should be replaced if the animation is not already' + + ' pending'); + +promise_test(function(t) { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + const promise = animation.ready; + return promise.then(p => { + assert_equals(p, animation); + assert_equals(animation.ready, promise); + }); +}, 'A pending ready promise should be resolved and not replaced when the' + + ' animation enters the running state'); + </script> </body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt index 755e1dc..95c4aff0 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt
@@ -109,10 +109,6 @@ } exceptionId : 0 lineNumber : 0 - stackTrace : { - callFrames : [ - ] - } text : Uncaught (in promise) } result : {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt index 7e42eac8..a903a5f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt
@@ -23,10 +23,6 @@ exceptionId : 0 lineNumber : 0 scriptId : - stackTrace : { - callFrames : [ - ] - } text : Uncaught (in promise) } result : {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt index 47b1742..e719a27 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt
@@ -142,10 +142,6 @@ } exceptionId : 0 lineNumber : 0 - stackTrace : { - callFrames : [ - ] - } text : Uncaught (in promise) } result : {
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html b/third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html index 2a64972..585f8af 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html +++ b/third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html
@@ -17,12 +17,12 @@ var audit = Audit.createTaskRunner(); audit.defineTask("ref-distance-error", function (taskDone) { - testDistanceLimits({name: "refDistance"}); + testDistanceLimits({name: "refDistance", isZeroAllowed: true}); taskDone(); }); audit.defineTask("max-distance-error", function (taskDone) { - testDistanceLimits({name: "maxDistance"}); + testDistanceLimits({name: "maxDistance", isZeroAllowed: false}); taskDone(); }); @@ -39,11 +39,19 @@ new PannerNode(context, nodeOptions); }).throw("RangeError"); - success = Should(prefix + "0})", function () { - var nodeOptions = {}; - nodeOptions[attrName] = 0; - new PannerNode(context, nodeOptions); - }).throw("RangeError") && success; + if (options.isZeroAllowed) { + success = Should(prefix + "0})", function () { + var nodeOptions = {}; + nodeOptions[attrName] = 0; + new PannerNode(context, nodeOptions); + }).notThrow() && success; + } else { + success = Should(prefix + "0})", function () { + var nodeOptions = {}; + nodeOptions[attrName] = 0; + new PannerNode(context, nodeOptions); + }).throw("RangeError") && success; + } // The smallest representable positive single float. var leastPositiveDoubleFloat = 4.9406564584124654e-324; @@ -61,9 +69,15 @@ panner[attrName] = -1; }).throw("RangeError") && success; - success = Should(prefix + "0", function () { - panner[attrName] = 0; - }).throw("RangeError") && success; + if (options.isZeroAllowed) { + success = Should(prefix + "0", function () { + panner[attrName] = 0; + }).notThrow() && success; + } else { + success = Should(prefix + "0", function () { + panner[attrName] = 0; + }).throw("RangeError") && success; + } success = Should(prefix + leastPositiveDoubleFloat, function () { panner[attrName] = leastPositiveDoubleFloat;
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp index e08b11f..4074bca1 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp
@@ -5,7 +5,6 @@ #include "bindings/core/v8/ScriptState.h" #include "bindings/core/v8/V8Binding.h" -#include "core/dom/ExecutionContext.h" namespace blink { @@ -65,8 +64,4 @@ return ScriptValue(this, v8_value); } -ExecutionContext* ScriptState::GetExecutionContext() const { - return ExecutionContext::From(this); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h index 2e2ea9f..be40f2d 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h
@@ -17,7 +17,6 @@ namespace blink { class DOMWrapperWorld; -class ExecutionContext; class ScriptValue; // ScriptState is an abstraction class that holds all information about script @@ -136,8 +135,6 @@ v8::Isolate* GetIsolate() const { return isolate_; } DOMWrapperWorld& World() const { return *world_; } - // DEPRECATED: Use ExecutionContext::From instead - virtual ExecutionContext* GetExecutionContext() const; // This can return an empty handle if the v8::Context is gone. v8::Local<v8::Context> GetContext() const {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.cpp b/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.cpp index 902a2fd..88173956 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.cpp
@@ -26,10 +26,6 @@ PassRefPtr<DOMWrapperWorld> world) : ScriptState(context, std::move(world)) {} -ExecutionContext* ScriptStateForTesting::GetExecutionContext() const { - return execution_context_; -} - V8TestingScope::V8TestingScope() : holder_(DummyPageHolder::Create()), handle_scope_(GetIsolate()),
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.h b/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.h index f4effdb..1e6ae842 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8BindingForTesting.h
@@ -24,11 +24,8 @@ public: static PassRefPtr<ScriptStateForTesting> Create(v8::Local<v8::Context>, PassRefPtr<DOMWrapperWorld>); - ExecutionContext* GetExecutionContext() const override; - private: ScriptStateForTesting(v8::Local<v8::Context>, PassRefPtr<DOMWrapperWorld>); - Persistent<ExecutionContext> execution_context_; }; class V8TestingScope {
diff --git a/third_party/WebKit/Source/core/OWNERS b/third_party/WebKit/Source/core/OWNERS index 6c8eed29..3190ca49 100644 --- a/third_party/WebKit/Source/core/OWNERS +++ b/third_party/WebKit/Source/core/OWNERS
@@ -12,6 +12,8 @@ chrishtr@chromium.org dcheng@chromium.org dglazkov@chromium.org +# dtapuska reviews input-related changes +dtapuska@chromium.org dgozman@chromium.org dominicc@chromium.org dpranke@chromium.org @@ -48,7 +50,6 @@ pfeldman@chromium.org pkasting@chromium.org rego@igalia.com -# rbyers reviews input related changes (eg. event handling, mouse cursors, touch hit testing, scrolling coordinator) rbyers@chromium.org rob.buis@samsung.com robhogan@gmail.com
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index 5a28123..cbe4354 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -54,6 +54,7 @@ class DocumentMarker; class Element; class ExceptionState; +class ExecutionContext; class GCObservation; class HTMLInputElement; class HTMLMediaElement;
diff --git a/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp b/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp index 1c56c81..f66ead6 100644 --- a/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp +++ b/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp
@@ -50,7 +50,7 @@ blink::ScriptState* scriptState = blink::ScriptState::From(context); v8::Local<v8::Object> global = scriptState->GetContext()->Global(); blink::ExecutionContext* executionContext = - scriptState->GetExecutionContext(); + blink::ExecutionContext::From(scriptState); if (executionContext->IsDocument()) { return blink::ToV8(blink::Internals::Create(executionContext), global, scriptState->GetIsolate()); @@ -89,7 +89,7 @@ type, scriptState, prototypeObject, interfaceObject); blink::ExecutionContext* executionContext = - scriptState->GetExecutionContext(); + blink::ExecutionContext::From(scriptState); blink::OriginTrialContext* originTrialContext = blink::OriginTrialContext::From( executionContext, blink::OriginTrialContext::kDontCreateIfNotExists); @@ -110,7 +110,8 @@ blink::ScriptState* scriptState = blink::ScriptState::From(context); blink::ScriptState::Scope scope(scriptState); - blink::Document* document = ToDocument(scriptState->GetExecutionContext()); + blink::Document* document = + ToDocument(blink::ExecutionContext::From(scriptState)); DCHECK(document); blink::LocalFrame* frame = document->GetFrame(); // Should the document have been detached, the page is assumed being destroyed
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index 725b981e..2fe6ff0 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -443,6 +443,7 @@ "front_end/sass/SASSProcessor.js", "front_end/sass/SASSSourceMapFactory.js", "front_end/sass/SASSSupport.js", + "front_end/screencast/InputModel.js", "front_end/screencast/module.json", "front_end/screencast/ScreencastApp.js", "front_end/screencast/screencastView.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png index abab09a9..9e40e19 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png index 947338be..3d23b09 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes index edecedd..747c4f3b 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -4,7 +4,7 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", - "smallIcons.svg": "54000a76145196864f9dabac90afd2bf", + "smallIcons.svg": "55c46735baa910dbe8f6b9602eb2f464", "mediumIcons.svg": "e63ac6385b0a6efb783d9838517e5e44", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9",
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg index 55a7d36..ef36848 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg
@@ -1,162 +1,758 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="90" height="90" id="svg4185" version="1.1" inkscape:version="0.48.4 r9939" sodipodi:docname="smallIcons.svg"> - <metadata id="metadata4459"> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="90" + height="90" + id="svg4185" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="smallIcons.svg"> + <metadata + id="metadata4459"> <rdf:RDF> - <cc:Work rdf:about=""> + <cc:Work + rdf:about=""> <dc:format>image/svg+xml</dc:format> - <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> - <defs id="defs4457"/> - <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1278" inkscape:window-height="746" id="namedview4455" showgrid="true" inkscape:zoom="2.6222222" inkscape:cx="46.759258" inkscape:cy="55.570823" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="0" inkscape:current-layer="svg4185"> - <inkscape:grid type="xygrid" id="grid4461" empspacing="5" visible="true" enabled="true" snapvisiblegridlinesonly="true" spacingx="10px" spacingy="10px"/> + <defs + id="defs4457" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1986" + inkscape:window-height="1353" + id="namedview4455" + showgrid="true" + inkscape:zoom="10.488889" + inkscape:cx="52.875124" + inkscape:cy="43.09204" + inkscape:window-x="201" + inkscape:window-y="36" + inkscape:window-maximized="0" + inkscape:current-layer="svg4185"> + <inkscape:grid + type="xygrid" + id="grid4461" + empspacing="5" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingx="10px" + spacingy="10px" /> </sodipodi:namedview> - <g id="g4187"> - <path transform="translate(-80,-20)" d="m 80,20.995 c 0,-0.54974 0.45566,-0.9954 0.9954,-0.9954 h 8.0092 c 0.54974,0 0.9954,0.45566 0.9954,0.9954 v 8.0092 c 0,0.54974 -0.45566,0.9954 -0.9954,0.9954 H 80.9954 C 80.44566,29.9996 80,29.54394 80,29.0042 z m 5.1233,4.7444 c 2.5673,-0.42788 3.6267,-1.193 3.6267,-3.7398 h -1.5 c 0,1.6199 -0.44058,1.9381 -2.3733,2.2602 -2.5673,0.42788 -3.6267,1.193 -3.6267,3.7398 h 1.5 c 0,-1.6199 0.44058,-1.9381 2.3733,-2.2602 z" id="path4191" inkscape:connector-curvature="0"/> + <g + id="g4187"> + <path + transform="translate(-80,-20)" + d="m 80,20.995 c 0,-0.54974 0.45566,-0.9954 0.9954,-0.9954 h 8.0092 c 0.54974,0 0.9954,0.45566 0.9954,0.9954 v 8.0092 c 0,0.54974 -0.45566,0.9954 -0.9954,0.9954 H 80.9954 C 80.44566,29.9996 80,29.54394 80,29.0042 z m 5.1233,4.7444 c 2.5673,-0.42788 3.6267,-1.193 3.6267,-3.7398 h -1.5 c 0,1.6199 -0.44058,1.9381 -2.3733,2.2602 -2.5673,0.42788 -3.6267,1.193 -3.6267,3.7398 h 1.5 c 0,-1.6199 0.44058,-1.9381 2.3733,-2.2602 z" + id="path4191" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(20,0)" id="g4193"> - <path transform="translate(-128,-109)" d="m 131.65,116.21 -1.44,-2.03 -1.21,1.21 2.55,3.61 6.45,-7.67 -1.12,-1.33 z" id="path4197" inkscape:connector-curvature="0"/> + <g + transform="translate(20,0)" + id="g4193"> + <path + transform="translate(-128,-109)" + d="m 131.65,116.21 -1.44,-2.03 -1.21,1.21 2.55,3.61 6.45,-7.67 -1.12,-1.33 z" + id="path4197" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(0,20)" id="g4199"> - <path transform="translate(-40,-19)" d="m 46.5,25 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1" id="path4203" inkscape:connector-curvature="0" style="fill:#bababa"/><path transform="translate(-40,-19)" d="m 45.75,21.75 -3.5,3.25 3.5,3.25" id="path4205" inkscape:connector-curvature="0" style="fill:none;stroke:#bababa;stroke-width:1.5"/> + <g + transform="translate(0,20)" + id="g4199"> + <path + transform="translate(-40,-19)" + d="m 46.5,25 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1" + id="path4203" + inkscape:connector-curvature="0" + style="fill:#bababa" /> + <path + transform="translate(-40,-19)" + d="m 45.75,21.75 -3.5,3.25 3.5,3.25" + id="path4205" + inkscape:connector-curvature="0" + style="fill:none;stroke:#bababa;stroke-width:1.5" /> </g> - <g transform="translate(20,20)" id="g4207"> - <path transform="translate(-177,-98)" d="m 184.5,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z" id="path4211" inkscape:connector-curvature="0" style="fill-opacity:0.23999999"/><path transform="translate(-177,-98)" d="M 184.5,99.93 183.57,99 181,101.57 178.43,99 l -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z" id="path4213" inkscape:connector-curvature="0" style="fill:#676767"/> + <g + transform="translate(20,20)" + id="g4207"> + <path + transform="translate(-177,-98)" + d="m 184.5,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z" + id="path4211" + inkscape:connector-curvature="0" + style="fill-opacity:0.23999999" /> + <path + transform="translate(-177,-98)" + d="M 184.5,99.93 183.57,99 181,101.57 178.43,99 l -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z" + id="path4213" + inkscape:connector-curvature="0" + style="fill:#676767" /> </g> - <g transform="translate(40,0)" id="g4215"> - <path transform="translate(-100,0)" d="m 103.25,-4.7795e-7 c -0.7,0 -1.25,0.49999999795 -1.25,1.24999997795 v 7.5 c 0,0.7 0.5,1.25 1.25,1.25 h 3.5 c 0.7,0 1.25,-0.5 1.25,-1.25 v -7.5 C 108,0.54999952 107.5,-4.7795e-7 106.75,-4.7795e-7 z M 103,0.99999952 h 4 V 7.9999995 h -4 z m 2,7.24999998 c 0.4,0 0.75,0.3 0.75,0.75 0,0.4 -0.3,0.75 -0.75,0.75 -0.4,0 -0.75,-0.3 -0.75,-0.75 0,-0.4 0.3,-0.75 0.75,-0.75 z" id="path4219" inkscape:connector-curvature="0"/> + <g + transform="translate(40,0)" + id="g4215"> + <path + transform="translate(-100,0)" + d="m 103.25,-4.7795e-7 c -0.7,0 -1.25,0.49999999795 -1.25,1.24999997795 v 7.5 c 0,0.7 0.5,1.25 1.25,1.25 h 3.5 c 0.7,0 1.25,-0.5 1.25,-1.25 v -7.5 C 108,0.54999952 107.5,-4.7795e-7 106.75,-4.7795e-7 z M 103,0.99999952 h 4 V 7.9999995 h -4 z m 2,7.24999998 c 0.4,0 0.75,0.3 0.75,0.75 0,0.4 -0.3,0.75 -0.75,0.75 -0.4,0 -0.75,-0.3 -0.75,-0.75 0,-0.4 0.3,-0.75 0.75,-0.75 z" + id="path4219" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(40,20)" id="g4221"> - <path transform="translate(-20,0)" d="m 25,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 30,2.2399995 27.76,-4.7795e-7 25,-4.7795e-7" id="path4225" inkscape:connector-curvature="0" style="fill:url(#sprite6_a)"/><path transform="translate(-20,0)" d="m 20.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" id="path4227" inkscape:connector-curvature="0" style="fill:#eb3941"/><path transform="translate(-20,0)" d="m 23,3 4,4" id="path4229" inkscape:connector-curvature="0" style="stroke:#ffffff"/><path transform="translate(-20,0)" d="M 27,3 23,7" id="path4231" inkscape:connector-curvature="0" style="stroke:#ffffff"/><defs id="defs4233"> - <linearGradient id="sprite6_b"> - <stop stop-color="#d7687d" offset="0" id="stop4236"/> - <stop stop-color="#b21402" offset="1" id="stop4238"/> - </linearGradient> - <linearGradient id="sprite6_a" x2="24" gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)" gradientUnits="userSpaceOnUse" xlink:href="#sprite6_b"/> - </defs> + <g + transform="translate(40,20)" + id="g4221"> + <path + transform="translate(-20,0)" + d="m 25,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 30,2.2399995 27.76,-4.7795e-7 25,-4.7795e-7" + id="path4225" + inkscape:connector-curvature="0" + style="fill:url(#sprite6_a)" /> + <path + transform="translate(-20,0)" + d="m 20.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" + id="path4227" + inkscape:connector-curvature="0" + style="fill:#eb3941" /> + <path + transform="translate(-20,0)" + d="m 23,3 4,4" + id="path4229" + inkscape:connector-curvature="0" + style="stroke:#ffffff" /> + <path + transform="translate(-20,0)" + d="M 27,3 23,7" + id="path4231" + inkscape:connector-curvature="0" + style="stroke:#ffffff" /> + <defs + id="defs4233"> + <linearGradient + id="sprite6_b"> + <stop + stop-color="#d7687d" + offset="0" + id="stop4236" /> + <stop + stop-color="#b21402" + offset="1" + id="stop4238" /> + </linearGradient> + <linearGradient + id="sprite6_a" + x2="24" + gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite6_b" /> + </defs> </g> - <g transform="translate(0,40)" id="g4241"> - <path transform="matrix(-0.89336,0,0,0.81469,170.27,-15.367)" d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3.0004 z" id="path4245" inkscape:connector-curvature="0" style="fill:#adf2ad;stroke:#007200"/> + <path + style="fill:#adf2ad;stroke:#007200;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" + inkscape:connector-curvature="0" + id="path4245" + d="M 4.4998214,41.3 8.5,45.00025 4.4998214,48.7 l 0,-1.2 -3.0748614,0 0.07504,-5 3.0001787,0 z" + sodipodi:nodetypes="cccccccc" /> + <g + transform="translate(20,40)" + id="g4247"> + <path + transform="translate(-140,0)" + d="m 144.95,9.9997 c -2.7598,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.2899,-4.9797 5.0497,-4.9497 2.7598,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.2899,4.9797 -5.0497,4.9497 z" + id="path4251" + inkscape:connector-curvature="0" + style="fill:url(#sprite8_a)" /> + <path + transform="translate(-140,0)" + d="m 149.5,5.05 c -0.03,2.4898 -2.0599,4.4797 -4.5497,4.4497 -2.4898,-0.03 -4.4797,-2.0598 -4.4497,-4.5497 0.03,-2.4898 2.0599,-4.4797 4.5497,-4.4497 2.4898,0.03 4.4797,2.0598 4.4497,4.5497 z" + id="path4253" + inkscape:connector-curvature="0" + style="fill:#00be00" /> + <path + transform="translate(-140,0)" + d="m 145.08,0.5303 c 1.9699,0.02 3.5498,1.0599 3.5398,2.3198 -0.01,1.26 -1.6199,2.2599 -3.5898,2.2399 -1.9699,-0.02 -3.5498,-1.0599 -3.5398,-2.3199 0.01,-1.2599 1.6199,-2.2598 3.5898,-2.2398 z" + id="path4255" + inkscape:connector-curvature="0" + style="fill:url(#sprite8_b)" /> + <path + transform="translate(-140,0)" + d="m 144.98,9.4097 c 1.6599,0.02 3.0098,-0.6799 3.0198,-1.5599 0.01,-0.8799 -1.3299,-1.6099 -2.9798,-1.6299 -1.6599,-0.02 -3.0098,0.68 -3.0198,1.5599 -0.01,0.88 1.3299,1.6099 2.9798,1.6299 z" + id="path4257" + inkscape:connector-curvature="0" + style="fill:url(#sprite8_c)" /> + <defs + id="defs4259"> + <linearGradient + id="sprite8_j"> + <stop + stop-color="#00d600" + stop-opacity="0" + offset="0" + id="stop4262" /> + <stop + stop-color="#d8fc7b" + stop-opacity=".81" + offset="1" + id="stop4264" /> + </linearGradient> + <linearGradient + id="sprite8_k"> + <stop + stop-color="#00ba00" + offset="0" + id="stop4267" /> + <stop + stop-color="#fff" + stop-opacity=".91" + offset="1" + id="stop4269" /> + </linearGradient> + <linearGradient + id="sprite8_l"> + <stop + stop-color="#00a104" + offset="0" + id="stop4272" /> + <stop + stop-color="#00c605" + offset="1" + id="stop4274" /> + </linearGradient> + <linearGradient + id="sprite8_c" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(-0.0048,0.4396,0.78038,0.00853,65.608,-94.834)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite8_j" /> + <linearGradient + id="sprite8_b" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(0.00687,-0.62923,0.9267,0.01012,47.871,147.44)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite8_k" /> + <linearGradient + id="sprite8_a" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(-0.01507,1.3791,-1.3006,-0.0142,282.66,-312.8)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite8_l" /> + </defs> </g> - <g transform="translate(20,40)" id="g4247"> - <path transform="translate(-140,0)" d="m 144.95,9.9997 c -2.7598,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.2899,-4.9797 5.0497,-4.9497 2.7598,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.2899,4.9797 -5.0497,4.9497 z" id="path4251" inkscape:connector-curvature="0" style="fill:url(#sprite8_a)"/><path transform="translate(-140,0)" d="m 149.5,5.05 c -0.03,2.4898 -2.0599,4.4797 -4.5497,4.4497 -2.4898,-0.03 -4.4797,-2.0598 -4.4497,-4.5497 0.03,-2.4898 2.0599,-4.4797 4.5497,-4.4497 2.4898,0.03 4.4797,2.0598 4.4497,4.5497 z" id="path4253" inkscape:connector-curvature="0" style="fill:#00be00"/><path transform="translate(-140,0)" d="m 145.08,0.5303 c 1.9699,0.02 3.5498,1.0599 3.5398,2.3198 -0.01,1.26 -1.6199,2.2599 -3.5898,2.2399 -1.9699,-0.02 -3.5498,-1.0599 -3.5398,-2.3199 0.01,-1.2599 1.6199,-2.2598 3.5898,-2.2398 z" id="path4255" inkscape:connector-curvature="0" style="fill:url(#sprite8_b)"/><path transform="translate(-140,0)" d="m 144.98,9.4097 c 1.6599,0.02 3.0098,-0.6799 3.0198,-1.5599 0.01,-0.8799 -1.3299,-1.6099 -2.9798,-1.6299 -1.6599,-0.02 -3.0098,0.68 -3.0198,1.5599 -0.01,0.88 1.3299,1.6099 2.9798,1.6299 z" id="path4257" inkscape:connector-curvature="0" style="fill:url(#sprite8_c)"/><defs id="defs4259"> - <linearGradient id="sprite8_j"> - <stop stop-color="#00d600" stop-opacity="0" offset="0" id="stop4262"/> - <stop stop-color="#d8fc7b" stop-opacity=".81" offset="1" id="stop4264"/> - </linearGradient> - <linearGradient id="sprite8_k"> - <stop stop-color="#00ba00" offset="0" id="stop4267"/> - <stop stop-color="#fff" stop-opacity=".91" offset="1" id="stop4269"/> - </linearGradient> - <linearGradient id="sprite8_l"> - <stop stop-color="#00a104" offset="0" id="stop4272"/> - <stop stop-color="#00c605" offset="1" id="stop4274"/> - </linearGradient> - <linearGradient id="sprite8_c" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(-0.0048,0.4396,0.78038,0.00853,65.608,-94.834)" gradientUnits="userSpaceOnUse" xlink:href="#sprite8_j"/> - <linearGradient id="sprite8_b" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(0.00687,-0.62923,0.9267,0.01012,47.871,147.44)" gradientUnits="userSpaceOnUse" xlink:href="#sprite8_k"/> - <linearGradient id="sprite8_a" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(-0.01507,1.3791,-1.3006,-0.0142,282.66,-312.8)" gradientUnits="userSpaceOnUse" xlink:href="#sprite8_l"/> - </defs> + <g + transform="translate(40,40)" + id="g4279"> + <path + transform="translate(-80,0)" + d="m 85,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 90,2.2399995 87.76,-4.7795e-7 85,-4.7795e-7" + id="path4283" + inkscape:connector-curvature="0" + style="fill:url(#sprite9_a)" /> + <path + transform="translate(-80,0)" + d="m 80.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" + id="path4285" + inkscape:connector-curvature="0" + style="fill:#2a53cd" /> + <path + transform="translate(-80,0)" + d="m 83.93,2.14 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 C 84.09,2.71 83.93,2.43 83.93,2.14 z m 1.7,5.46 H 86.3 V 8.13 H 83.41 V 7.6 h 0.66 V 3.99 H 83.41 V 3.46 h 2.22 V 7.6 z" + id="path4287" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <defs + id="defs4289"> + <linearGradient + id="sprite9_d"> + <stop + stop-color="#606eda" + offset="0" + id="stop4292" /> + <stop + stop-color="#021db2" + offset="1" + id="stop4294" /> + </linearGradient> + <linearGradient + id="sprite9_a" + x1="113" + x2="127" + y1="104" + y2="104" + gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite9_d" /> + </defs> </g> - <g transform="translate(40,40)" id="g4279"> - <path transform="translate(-80,0)" d="m 85,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 90,2.2399995 87.76,-4.7795e-7 85,-4.7795e-7" id="path4283" inkscape:connector-curvature="0" style="fill:url(#sprite9_a)"/><path transform="translate(-80,0)" d="m 80.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" id="path4285" inkscape:connector-curvature="0" style="fill:#2a53cd"/><path transform="translate(-80,0)" d="m 83.93,2.14 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 C 84.09,2.71 83.93,2.43 83.93,2.14 z m 1.7,5.46 H 86.3 V 8.13 H 83.41 V 7.6 h 0.66 V 3.99 H 83.41 V 3.46 h 2.22 V 7.6 z" id="path4287" inkscape:connector-curvature="0" style="fill:#ffffff"/><defs id="defs4289"> - <linearGradient id="sprite9_d"> - <stop stop-color="#606eda" offset="0" id="stop4292"/> - <stop stop-color="#021db2" offset="1" id="stop4294"/> - </linearGradient> - <linearGradient id="sprite9_a" x1="113" x2="127" y1="104" y2="104" gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)" gradientUnits="userSpaceOnUse" xlink:href="#sprite9_d"/> - </defs> + <g + transform="translate(60,0)" + id="g4297"> + <path + transform="translate(-160,-20)" + d="m 160.45,20.467 v 9.079 h 5.373 l 3.5821,-4.5398 -3.5821,-4.5392 z" + id="path4301" + inkscape:connector-curvature="0" + style="fill:#698cfe;stroke:#4073f4;stroke-width:0.90799999" /> </g> - <g transform="translate(60,0)" id="g4297"> - <path transform="translate(-160,-20)" d="m 160.45,20.467 v 9.079 h 5.373 l 3.5821,-4.5398 -3.5821,-4.5392 z" id="path4301" inkscape:connector-curvature="0" style="fill:#698cfe;stroke:#4073f4;stroke-width:0.90799999"/> + <g + transform="translate(60,20)" + id="g4303"> + <path + transform="translate(-140,-20)" + d="m 140.45,20.467 v 9.0791 h 5.3718 l 3.5813,-4.54 -3.5813,-4.5391 z" + id="path4307" + inkscape:connector-curvature="0" + style="fill:#ef9d0d;stroke:#a36c01;stroke-width:0.90799999" /> </g> - <g transform="translate(60,20)" id="g4303"> - <path transform="translate(-140,-20)" d="m 140.45,20.467 v 9.0791 h 5.3718 l 3.5813,-4.54 -3.5813,-4.5391 z" id="path4307" inkscape:connector-curvature="0" style="fill:#ef9d0d;stroke:#a36c01;stroke-width:0.90799999"/> + <g + transform="translate(60,40)" + id="g4309"> + <path + transform="translate(-160,0)" + d="m 165,10 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" + id="path4313" + inkscape:connector-curvature="0" + style="fill:#e5a600" /> + <path + transform="translate(-160,0)" + d="m 169.5,5 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" + id="path4315" + inkscape:connector-curvature="0" + style="fill:#ffbd00" /> + <path + transform="translate(-160,0)" + d="m 165.03,0.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" + id="path4317" + inkscape:connector-curvature="0" + style="fill:url(#sprite12_a)" /> + <path + transform="translate(-160,0)" + d="m 164.99,9.42 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" + id="path4319" + inkscape:connector-curvature="0" + style="fill:url(#sprite12_b)" /> + <defs + id="defs4321"> + <linearGradient + id="sprite12_l"> + <stop + stop-color="#ffa801" + stop-opacity="0" + offset="0" + id="stop4324" /> + <stop + stop-color="#f0fb3d" + offset="1" + id="stop4326" /> + </linearGradient> + <linearGradient + id="sprite12_m"> + <stop + stop-color="#ffbd00" + stop-opacity=".65" + offset="0" + id="stop4329" /> + <stop + stop-color="#fff" + stop-opacity=".91" + offset="1" + id="stop4331" /> + </linearGradient> + <linearGradient + id="sprite12_b" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(0,0.43966,0.78049,0,84.444,-93.924)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite12_l" /> + <linearGradient + id="sprite12_a" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(0,-0.62931,0.92683,0,69.47,148.53)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite12_m" /> + </defs> </g> - <g transform="translate(60,40)" id="g4309"> - <path transform="translate(-160,0)" d="m 165,10 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" id="path4313" inkscape:connector-curvature="0" style="fill:#e5a600"/><path transform="translate(-160,0)" d="m 169.5,5 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" id="path4315" inkscape:connector-curvature="0" style="fill:#ffbd00"/><path transform="translate(-160,0)" d="m 165.03,0.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" id="path4317" inkscape:connector-curvature="0" style="fill:url(#sprite12_a)"/><path transform="translate(-160,0)" d="m 164.99,9.42 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" id="path4319" inkscape:connector-curvature="0" style="fill:url(#sprite12_b)"/><defs id="defs4321"> - <linearGradient id="sprite12_l"> - <stop stop-color="#ffa801" stop-opacity="0" offset="0" id="stop4324"/> - <stop stop-color="#f0fb3d" offset="1" id="stop4326"/> - </linearGradient> - <linearGradient id="sprite12_m"> - <stop stop-color="#ffbd00" stop-opacity=".65" offset="0" id="stop4329"/> - <stop stop-color="#fff" stop-opacity=".91" offset="1" id="stop4331"/> - </linearGradient> - <linearGradient id="sprite12_b" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(0,0.43966,0.78049,0,84.444,-93.924)" gradientUnits="userSpaceOnUse" xlink:href="#sprite12_l"/> - <linearGradient id="sprite12_a" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(0,-0.62931,0.92683,0,69.47,148.53)" gradientUnits="userSpaceOnUse" xlink:href="#sprite12_m"/> - </defs> + <g + transform="translate(0,60)" + id="g4335"> + <path + transform="translate(-120,0)" + d="m 125,10 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" + id="path4339" + inkscape:connector-curvature="0" + style="fill:url(#sprite13_a)" /> + <path + transform="translate(-120,0)" + d="m 129.5,5 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" + id="path4341" + inkscape:connector-curvature="0" + style="fill:#dd0000" /> + <path + transform="translate(-120,0)" + d="m 125.03,0.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" + id="path4343" + inkscape:connector-curvature="0" + style="fill:url(#sprite13_b)" /> + <path + transform="translate(-120,0)" + d="m 125.03,9.47 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" + id="path4345" + inkscape:connector-curvature="0" + style="fill:url(#sprite13_c)" /> + <defs + id="defs4347"> + <linearGradient + id="sprite13_g"> + <stop + stop-color="red" + stop-opacity="0" + offset="0" + id="stop4350" /> + <stop + stop-color="#f0cb68" + stop-opacity=".71" + offset="1" + id="stop4352" /> + </linearGradient> + <linearGradient + id="sprite13_h"> + <stop + stop-color="#e60000" + stop-opacity=".65" + offset="0" + id="stop4355" /> + <stop + stop-color="#fff" + stop-opacity=".91" + offset="1" + id="stop4357" /> + </linearGradient> + <linearGradient + id="sprite13_i"> + <stop + stop-color="#a10000" + offset="0" + id="stop4360" /> + <stop + stop-color="#c60000" + offset="1" + id="stop4362" /> + </linearGradient> + <linearGradient + id="sprite13_c" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(0,0.43966,0.78049,0,44.488,-93.88)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite13_g" /> + <linearGradient + id="sprite13_b" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(0,-0.62931,0.92683,0,29.47,148.53)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite13_h" /> + <linearGradient + id="sprite13_a" + x1="227.88" + x2="235.12" + y1="103.16" + y2="103.16" + gradientTransform="matrix(0,1.3793,-1.3008,0,259.08,-314.35)" + gradientUnits="userSpaceOnUse" + xlink:href="#sprite13_i" /> + </defs> </g> - <g transform="translate(0,60)" id="g4335"> - <path transform="translate(-120,0)" d="m 125,10 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" id="path4339" inkscape:connector-curvature="0" style="fill:url(#sprite13_a)"/><path transform="translate(-120,0)" d="m 129.5,5 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" id="path4341" inkscape:connector-curvature="0" style="fill:#dd0000"/><path transform="translate(-120,0)" d="m 125.03,0.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" id="path4343" inkscape:connector-curvature="0" style="fill:url(#sprite13_b)"/><path transform="translate(-120,0)" d="m 125.03,9.47 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" id="path4345" inkscape:connector-curvature="0" style="fill:url(#sprite13_c)"/><defs id="defs4347"> - <linearGradient id="sprite13_g"> - <stop stop-color="red" stop-opacity="0" offset="0" id="stop4350"/> - <stop stop-color="#f0cb68" stop-opacity=".71" offset="1" id="stop4352"/> - </linearGradient> - <linearGradient id="sprite13_h"> - <stop stop-color="#e60000" stop-opacity=".65" offset="0" id="stop4355"/> - <stop stop-color="#fff" stop-opacity=".91" offset="1" id="stop4357"/> - </linearGradient> - <linearGradient id="sprite13_i"> - <stop stop-color="#a10000" offset="0" id="stop4360"/> - <stop stop-color="#c60000" offset="1" id="stop4362"/> - </linearGradient> - <linearGradient id="sprite13_c" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(0,0.43966,0.78049,0,44.488,-93.88)" gradientUnits="userSpaceOnUse" xlink:href="#sprite13_g"/> - <linearGradient id="sprite13_b" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(0,-0.62931,0.92683,0,29.47,148.53)" gradientUnits="userSpaceOnUse" xlink:href="#sprite13_h"/> - <linearGradient id="sprite13_a" x1="227.88" x2="235.12" y1="103.16" y2="103.16" gradientTransform="matrix(0,1.3793,-1.3008,0,259.08,-314.35)" gradientUnits="userSpaceOnUse" xlink:href="#sprite13_i"/> - </defs> + <g + transform="translate(20,60)" + id="g4367"> + <path + transform="translate(-60,-20)" + d="M 60,20 H 70 V 30 H 60 z" + id="path4371" + inkscape:connector-curvature="0" + style="fill:none" /> + <path + transform="translate(-60,-20)" + d="M 67.5,22.5 V 20 H 60 v 7.5 h 2.5 V 30 H 70 V 22.5 z M 61,21 h 5.5 v 5.5 H 61 z m 2.5,6.5 h 4 v -4 H 69 V 29 h -5.5 z" + id="path4373" + inkscape:connector-curvature="0" /> + <path + d="m 3.5,7.5 h 4 v -4 H 9 V 9 H 3.5 z" + id="path4375" + inkscape:connector-curvature="0" + style="fill-opacity:0.25" /> </g> - <g transform="translate(20,60)" id="g4367"> - <path transform="translate(-60,-20)" d="M 60,20 H 70 V 30 H 60 z" id="path4371" inkscape:connector-curvature="0" style="fill:none"/><path transform="translate(-60,-20)" d="M 67.5,22.5 V 20 H 60 v 7.5 h 2.5 V 30 H 70 V 22.5 z M 61,21 h 5.5 v 5.5 H 61 z m 2.5,6.5 h 4 v -4 H 69 V 29 h -5.5 z" id="path4373" inkscape:connector-curvature="0"/><path d="m 3.5,7.5 h 4 v -4 H 9 V 9 H 3.5 z" id="path4375" inkscape:connector-curvature="0" style="fill-opacity:0.25"/> + <g + id="g4383" + style="fill:#acf2ae;stroke:#007200;stroke-width:2.5769999" + transform="translate(40,60)"> + <path + transform="matrix(0.29356,0,0,0.2909,-37.35,6.864)" + d="m 144.95,9.9997 c -2.7598,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.2899,-4.9797 5.0497,-4.9497 2.7598,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.2899,4.9797 -5.0497,4.9497 z" + id="path4385" + inkscape:connector-curvature="0" /> + <path + transform="matrix(0.29356,0,0,0.2909,-37.35,6.864)" + d="m 149.5,5.05 c -0.03,2.4898 -2.0599,4.4797 -4.5497,4.4497 -2.4898,-0.03 -4.4797,-2.0598 -4.4497,-4.5497 0.03,-2.4898 2.0599,-4.4797 4.5497,-4.4497 2.4898,0.03 4.4797,2.0598 4.4497,4.5497 z" + id="path4387" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(40,60)" id="g4377"> - <g id="g4381" style="stroke:#007200"> - <g id="g4383" style="fill:#acf2ae;stroke-width:2.5769999"> - <path transform="matrix(0.29356,0,0,0.2909,-37.35,6.864)" d="m 144.95,9.9997 c -2.7598,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.2899,-4.9797 5.0497,-4.9497 2.7598,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.2899,4.9797 -5.0497,4.9497 z" id="path4385" inkscape:connector-curvature="0"/> - <path transform="matrix(0.29356,0,0,0.2909,-37.35,6.864)" d="m 149.5,5.05 c -0.03,2.4898 -2.0599,4.4797 -4.5497,4.4497 -2.4898,-0.03 -4.4797,-2.0598 -4.4497,-4.5497 0.03,-2.4898 2.0599,-4.4797 4.5497,-4.4497 2.4898,0.03 4.4797,2.0598 4.4497,4.5497 z" id="path4387" inkscape:connector-curvature="0"/> - </g> - <path transform="matrix(0,-0.67745,-0.62037,0,20.72,128.46)" d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3.0004 z" id="path4389" inkscape:connector-curvature="0" style="fill:#adf2ad;stroke-width:1.31599998"/> - </g> + <path + d="M 48.3126,62.499864 45.21075,66 42.1089,62.499864 l 1.24074,0 0,-1.919464 3.72222,0 0,1.919735 z" + id="path4389" + inkscape:connector-curvature="0" + style="fill:#adf2ad;stroke:#007200;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" + sodipodi:nodetypes="cccccccc" /> + <path + d="m 66.5375,68.5145 c -0.0088,0.72431 -0.6047,1.3032 -1.3356,1.2945 -0.73092,-0.0087 -1.3151,-0.59922 -1.3063,-1.3236 0.0088,-0.7243 0.6047,-1.3032 1.3356,-1.2945 0.73092,0.0087 1.3151,0.59922 1.3063,1.3235 z" + id="path4397" + inkscape:connector-curvature="0" + style="fill:#acf2ae;stroke:#007200;stroke-width:0.75300002" /> + <path + d="m 62.1084,63.500135 3.10185,-2.981685 3.10185,2.981685 -1.24074,0 0,1.999865 -3.72222,0 0,-2.000136 z" + id="path4399" + inkscape:connector-curvature="0" + style="fill:#adf2ad;stroke:#007200;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" + sodipodi:nodetypes="cccccccc" /> + <g + transform="translate(80,0)" + id="g4401"> + <path + transform="translate(-20,-20)" + d="m 23.25,21.75 3.5,3.25 -3.5,3.25" + id="path4405" + inkscape:connector-curvature="0" + style="fill:none;stroke:#367cf1;stroke-width:1.5" /> </g> - <g transform="translate(60,60)" id="g4391"> - <g id="g4395" style="stroke:#007200"> - <path d="M 6.5375,8.5145 C 6.5287,9.23881 5.9328,9.8177 5.2019,9.809 4.47098,9.8003 3.8868,9.20978 3.8956,8.4854 3.9044,7.7611 4.5003,7.1822 5.2312,7.1909 5.96212,7.1996 6.5463,7.79012 6.5375,8.5144 z" id="path4397" inkscape:connector-curvature="0" style="fill:#acf2ae;stroke-width:0.75300002"/> - <path transform="matrix(0,0.67745,0.62037,0,-10.299,-122.1)" d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3.0004 z" id="path4399" inkscape:connector-curvature="0" style="fill:#adf2ad;stroke-width:1.31599998"/> - </g> + <g + transform="translate(80,20)" + id="g4407"> + <path + transform="translate(-180,-20)" + d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3 z" + id="path4411" + inkscape:connector-curvature="0" + style="fill:#4688f1" /> </g> - <g transform="translate(80,0)" id="g4401"> - <path transform="translate(-20,-20)" d="m 23.25,21.75 3.5,3.25 -3.5,3.25" id="path4405" inkscape:connector-curvature="0" style="fill:none;stroke:#367cf1;stroke-width:1.5"/> + <g + transform="translate(80,40)" + id="g4413"> + <path + transform="matrix(-1,0,0,1,190,-19.955)" + d="m 186,19.955 -5,5 5,5.0225 0,-2.045 3,0.0225 0,-6 -3,0 z" + id="path4417" + inkscape:connector-curvature="0" + style="fill:#4688f1" + sodipodi:nodetypes="cccccccc" /> </g> - <g transform="translate(80,20)" id="g4407"> - <path transform="translate(-180,-20)" d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3 z" id="path4411" inkscape:connector-curvature="0" style="fill:#4688f1"/> + <g + transform="translate(80,60)" + id="g4419"> + <path + transform="translate(-20,-98)" + d="m 24,106 4,-7 h -8" + id="path4423" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(80,40)" id="g4413"> - <path transform="matrix(-1,0,0,1,190,-19.955)" d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3 z" id="path4417" inkscape:connector-curvature="0" style="fill:#4688f1"/> + <g + transform="translate(0,80)" + id="g4425"> + <path + transform="translate(-4,-98)" + d="M 12,102 5,98 v 8" + id="path4429" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(80,60)" id="g4419"> - <path transform="translate(-20,-98)" d="m 24,106 4,-7 h -8" id="path4423" inkscape:connector-curvature="0"/> + <g + transform="translate(20,80)" + id="g4431"> + <path + transform="translate(-4,-111)" + d="m 8,111 4,7 H 4" + id="path4435" + inkscape:connector-curvature="0" /> </g> - <g transform="translate(0,80)" id="g4425"> - <path transform="translate(-4,-98)" d="M 12,102 5,98 v 8" id="path4429" inkscape:connector-curvature="0"/> + <g + transform="translate(40,80)" + id="g4437"> + <path + transform="translate(0,-19)" + d="m 3.2503,21.75 3.5,3.25 -3.5,3.25" + id="path4441" + inkscape:connector-curvature="0" + style="fill:none;stroke:#939393;stroke-width:1.5" /> </g> - <g transform="translate(20,80)" id="g4431"> - <path transform="translate(-4,-111)" d="m 8,111 4,7 H 4" id="path4435" inkscape:connector-curvature="0"/> + <g + transform="translate(60,80)" + id="g4443"> + <path + transform="translate(-60,0)" + d="m 61,9 4,-8 4,8 z" + id="path4447" + inkscape:connector-curvature="0" + style="stroke:#c19600;stroke-width:2;stroke-linejoin:round" /> + <path + transform="translate(-60,0)" + d="m 61,9 4,-8 4,8 z" + id="path4449" + inkscape:connector-curvature="0" + style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round" /> + <path + transform="translate(-60,0)" + d="m 63.75,2.75 h 2.5 v 2.5 L 65.75,7 h -1.5 l -0.5,-1.75 v -2.5 m 0,5.25 h 2.5 v 1.25 h -2.5" + id="path4451" + inkscape:connector-curvature="0" + style="fill:#ad8601" /> + <path + transform="translate(-60,0)" + d="m 64,3 h 2 V 5.25 L 65.5,7 h -1 L 64,5.25 V 3 m 0,5 h 2 v 1 h -2" + id="path4453" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> </g> - <g transform="translate(40,80)" id="g4437"> - <path transform="translate(0,-19)" d="m 3.2503,21.75 3.5,3.25 -3.5,3.25" id="path4441" inkscape:connector-curvature="0" style="fill:none;stroke:#939393;stroke-width:1.5"/> - </g> - <g transform="translate(60,80)" id="g4443"> - <path transform="translate(-60,0)" d="m 61,9 4,-8 4,8 z" id="path4447" inkscape:connector-curvature="0" style="stroke:#c19600;stroke-width:2;stroke-linejoin:round"/><path transform="translate(-60,0)" d="m 61,9 4,-8 4,8 z" id="path4449" inkscape:connector-curvature="0" style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round"/><path transform="translate(-60,0)" d="m 63.75,2.75 h 2.5 v 2.5 L 65.75,7 h -1.5 l -0.5,-1.75 v -2.5 m 0,5.25 h 2.5 v 1.25 h -2.5" id="path4451" inkscape:connector-curvature="0" style="fill:#ad8601"/><path transform="translate(-60,0)" d="m 64,3 h 2 V 5.25 L 65.5,7 h -1 L 64,5.25 V 3 m 0,5 h 2 v 1 h -2" id="path4453" inkscape:connector-curvature="0" style="fill:#ffffff"/> - </g> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="3.0508475" y="98.386719" id="text5191" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193" x="3.0508475" y="98.386719">a</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="23.050848" y="98.386719" id="text5191-1" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-7" x="23.050848" y="98.386719">b</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="43.050846" y="98.386719" id="text5191-7" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-1" x="43.050846" y="98.386719">c</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="63.050854" y="98.386719" id="text5191-15" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-9" x="63.050854" y="98.386719">d</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="83.05085" y="98.386719" id="text5191-77" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-6" x="83.05085" y="98.386719">e</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="-7.0260201" y="87.817795" id="text5191-73" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-65" x="-7.0260201" y="87.817795">1</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="-6.8189888" y="67.880318" id="text5191-6" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-3" x="-6.8189888" y="67.880318">2</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="-6.7564888" y="47.991673" id="text5191-9" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-4" x="-6.7564888" y="47.991673">3</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="-6.9166451" y="27.993652" id="text5191-8" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-12" x="-6.9166451" y="27.993652">4</tspan></text> - <text xml:space="preserve" style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" x="-7.1080513" y="8.0561762" id="text5191-93" sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan5193-90" x="-7.1080513" y="8.0561762">5</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="3.0508475" + y="98.386719" + id="text5191" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193" + x="3.0508475" + y="98.386719">a</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="23.050848" + y="98.386719" + id="text5191-1" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-7" + x="23.050848" + y="98.386719">b</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="43.050846" + y="98.386719" + id="text5191-7" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-1" + x="43.050846" + y="98.386719">c</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="63.050854" + y="98.386719" + id="text5191-15" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-9" + x="63.050854" + y="98.386719">d</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="83.05085" + y="98.386719" + id="text5191-77" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-6" + x="83.05085" + y="98.386719">e</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="-7.0260201" + y="87.817795" + id="text5191-73" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-65" + x="-7.0260201" + y="87.817795">1</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="-6.8189888" + y="67.880318" + id="text5191-6" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-3" + x="-6.8189888" + y="67.880318">2</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="-6.7564888" + y="47.991673" + id="text5191-9" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-4" + x="-6.7564888" + y="47.991673">3</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="-6.9166451" + y="27.993652" + id="text5191-8" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-12" + x="-6.9166451" + y="27.993652">4</tspan></text> + <text + xml:space="preserve" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none;font-family:Sans" + x="-7.1080513" + y="8.0561762" + id="text5191-93" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan5193-90" + x="-7.1080513" + y="8.0561762">5</tspan></text> </svg> -
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes index edecedd..747c4f3b 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -4,7 +4,7 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", - "smallIcons.svg": "54000a76145196864f9dabac90afd2bf", + "smallIcons.svg": "55c46735baa910dbe8f6b9602eb2f464", "mediumIcons.svg": "e63ac6385b0a6efb783d9838517e5e44", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9",
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js index 1662efc..bdd4fbc 100644 --- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js +++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
@@ -142,8 +142,9 @@ return this._protocolService.detach().then(_ => { this._auditRunning = false; this._updateButton(); - if (this._inspectedURL !== SDK.targetManager.mainTarget().inspectedURL()) - SDK.targetManager.mainTarget().pageAgent().navigate(this._inspectedURL); + var resourceTreeModel = SDK.targetManager.mainTarget().model(SDK.ResourceTreeModel); + if (resourceTreeModel && this._inspectedURL !== SDK.targetManager.mainTarget().inspectedURL()) + resourceTreeModel.navigate(this._inspectedURL); }); }
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js index cfb46ea..a6911fb7 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Main.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -135,7 +135,7 @@ Runtime.experiments.enableForTest('liveSASS'); } - Runtime.experiments.setDefaultExperiments(['persistenceValidation', 'persistence2']); + Runtime.experiments.setDefaultExperiments(['persistenceValidation', 'persistence2', 'continueToLocationMarkers']); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/screencast/InputModel.js b/third_party/WebKit/Source/devtools/front_end/screencast/InputModel.js new file mode 100644 index 0000000..fc96e7e0 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/screencast/InputModel.js
@@ -0,0 +1,116 @@ +// 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. + +Screencast.InputModel = class extends SDK.SDKModel { + /** + * @param {!SDK.Target} target + */ + constructor(target) { + super(target); + this._inputAgent = target.inputAgent(); + /** @type {?number} */ + this._activeTouchOffsetTop = null; + this._activeTouchParams = null; + } + + /** + * @param {!Event} event + */ + emitKeyEvent(event) { + var type; + switch (event.type) { + case 'keydown': + type = 'keyDown'; + break; + case 'keyup': + type = 'keyUp'; + break; + case 'keypress': + type = 'char'; + break; + default: + return; + } + + var text = event.type === 'keypress' ? String.fromCharCode(event.charCode) : undefined; + this._inputAgent.invoke_dispatchKeyEvent({ + type: type, + modifiers: this._modifiersForEvent(event), + timestamp: event.timeStamp / 1000, + text: text, + unmodifiedText: text ? text.toLowerCase() : undefined, + keyIdentifier: event.keyIdentifier, + code: event.code, + key: event.key, + windowsVirtualKeyCode: event.keyCode, + nativeVirtualKeyCode: event.keyCode, + autoRepeat: false, + isKeypad: false, + isSystemKey: false + }); + } + + /** + * @param {!Event} event + * @param {number} offsetTop + * @param {number} zoom + */ + emitTouchFromMouseEvent(event, offsetTop, zoom) { + var buttons = {0: 'none', 1: 'left', 2: 'middle', 3: 'right'}; + var types = { + 'mousedown': 'mousePressed', + 'mouseup': 'mouseReleased', + 'mousemove': 'mouseMoved', + 'mousewheel': 'mouseWheel' + }; + if (!(event.type in types) || !(event.which in buttons)) + return; + if (event.type !== 'mousewheel' && buttons[event.which] === 'none') + return; + + if (event.type === 'mousedown' || this._activeTouchOffsetTop === null) + this._activeTouchOffsetTop = offsetTop; + + var x = Math.round(event.offsetX / zoom); + var y = Math.round(event.offsetY / zoom); + y = Math.round(y - this._activeTouchOffsetTop); + var params = { + type: types[event.type], + x: x, + y: y, + modifiers: this._modifiersForEvent(event), + timestamp: event.timeStamp / 1000, + button: buttons[event.which], + clickCount: 0 + }; + if (event.type === 'mousewheel') { + params.deltaX = event.wheelDeltaX / zoom; + params.deltaY = event.wheelDeltaY / zoom; + } else { + this._activeTouchParams = params; + } + if (event.type === 'mouseup') + this._activeTouchOffsetTop = null; + this._inputAgent.invoke_emulateTouchFromMouseEvent(params); + } + + cancelTouch() { + if (this._activeTouchOffsetTop !== null) { + var params = this._activeTouchParams; + this._activeTouchParams = null; + params.type = 'mouseReleased'; + this._inputAgent.invoke_emulateTouchFromMouseEvent(params); + } + } + + /** + * @param {!Event} event + * @return {number} + */ + _modifiersForEvent(event) { + return (event.altKey ? 1 : 0) | (event.ctrlKey ? 2 : 0) | (event.metaKey ? 4 : 0) | (event.shiftKey ? 8 : 0); + } +}; + +SDK.SDKModel.register(Screencast.InputModel, SDK.Target.Capability.Input, false);
diff --git a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js index 7e627659..91bbe66 100644 --- a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js +++ b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
@@ -37,10 +37,11 @@ */ constructor(screenCaptureModel) { super(); - this._target = screenCaptureModel.target(); this._screenCaptureModel = screenCaptureModel; - this._domModel = this._target.model(SDK.DOMModel); - this._resourceTreeModel = this._target.model(SDK.ResourceTreeModel); + this._domModel = screenCaptureModel.target().model(SDK.DOMModel); + this._resourceTreeModel = screenCaptureModel.target().model(SDK.ResourceTreeModel); + this._networkManager = screenCaptureModel.target().model(SDK.NetworkManager); + this._inputModel = screenCaptureModel.target().model(Screencast.InputModel); this.setMinimumSize(150, 150); this.registerRequiredCSS('screencast/screencastView.css'); @@ -221,7 +222,8 @@ return; if (!this._inspectModeConfig || event.type === 'mousewheel') { - this._simulateTouchForMouseEvent(event); + if (this._inputModel) + this._inputModel.emitTouchFromMouseEvent(event, this._screenOffsetTop, this._screenZoom); event.preventDefault(); if (event.type === 'mousedown') this._canvasElement.focus(); @@ -266,37 +268,8 @@ return; } - var type; - switch (event.type) { - case 'keydown': - type = 'keyDown'; - break; - case 'keyup': - type = 'keyUp'; - break; - case 'keypress': - type = 'char'; - break; - default: - return; - } - - var text = event.type === 'keypress' ? String.fromCharCode(event.charCode) : undefined; - this._target.inputAgent().invoke_dispatchKeyEvent({ - type: type, - modifiers: this._modifiersForEvent(event), - timestamp: event.timeStamp / 1000, - text: text, - unmodifiedText: text ? text.toLowerCase() : undefined, - keyIdentifier: event.keyIdentifier, - code: event.code, - key: event.key, - windowsVirtualKeyCode: event.keyCode, - nativeVirtualKeyCode: event.keyCode, - autoRepeat: false, - isKeypad: false, - isSystemKey: false - }); + if (this._inputModel) + this._inputModel.emitKeyEvent(event); event.consume(); this._canvasElement.focus(); } @@ -311,68 +284,9 @@ /** * @param {!Event} event */ - _simulateTouchForMouseEvent(event) { - const buttons = {0: 'none', 1: 'left', 2: 'middle', 3: 'right'}; - const types = { - 'mousedown': 'mousePressed', - 'mouseup': 'mouseReleased', - 'mousemove': 'mouseMoved', - 'mousewheel': 'mouseWheel' - }; - if (!(event.type in types) || !(event.which in buttons)) - return; - if (event.type !== 'mousewheel' && buttons[event.which] === 'none') - return; - - if (event.type === 'mousedown' || typeof this._eventScreenOffsetTop === 'undefined') - this._eventScreenOffsetTop = this._screenOffsetTop; - - var modifiers = - (event.altKey ? 1 : 0) | (event.ctrlKey ? 2 : 0) | (event.metaKey ? 4 : 0) | (event.shiftKey ? 8 : 0); - - var convertedPosition = this._zoomIntoScreenSpace(event); - convertedPosition.y = Math.round(convertedPosition.y - this._eventScreenOffsetTop); - var params = { - type: types[event.type], - x: convertedPosition.x, - y: convertedPosition.y, - modifiers: modifiers, - timestamp: event.timeStamp / 1000, - button: buttons[event.which], - clickCount: 0 - }; - if (event.type === 'mousewheel') { - params.deltaX = event.wheelDeltaX / this._screenZoom; - params.deltaY = event.wheelDeltaY / this._screenZoom; - } else { - this._eventParams = params; - } - if (event.type === 'mouseup') - delete this._eventScreenOffsetTop; - this._target.inputAgent().invoke_emulateTouchFromMouseEvent(params); - } - - /** - * @param {!Event} event - */ _handleBlurEvent(event) { - if (typeof this._eventScreenOffsetTop !== 'undefined') { - var params = this._eventParams; - delete this._eventParams; - params.type = 'mouseReleased'; - this._target.inputAgent().invoke_emulateTouchFromMouseEvent(params); - } - } - - /** - * @param {!Event} event - * @return {!{x: number, y: number}} - */ - _zoomIntoScreenSpace(event) { - var position = {}; - position.x = Math.round(event.offsetX / this._screenZoom); - position.y = Math.round(event.offsetY / this._screenZoom); - return position; + if (this._inputModel) + this._inputModel.cancelTouch(); } /** @@ -380,29 +294,13 @@ * @return {!{x: number, y: number}} */ _convertIntoScreenSpace(event) { - var position = this._zoomIntoScreenSpace(event); - position.y = Math.round(position.y - this._screenOffsetTop); + var position = {}; + position.x = Math.round(event.offsetX / this._screenZoom); + position.y = Math.round(event.offsetY / this._screenZoom - this._screenOffsetTop); return position; } /** - * @param {!Event} event - * @return {number} - */ - _modifiersForEvent(event) { - var modifiers = 0; - if (event.altKey) - modifiers = 1; - if (event.ctrlKey) - modifiers += 2; - if (event.metaKey) - modifiers += 4; - if (event.shiftKey) - modifiers += 8; - return modifiers; - } - - /** * @override */ onResize() { @@ -709,43 +607,47 @@ _createNavigationBar() { this._navigationBar = this.element.createChild('div', 'screencast-navigation'); - this._navigationBack = this._navigationBar.createChild('button', 'back'); this._navigationBack.disabled = true; - this._navigationBack.addEventListener('click', this._navigateToHistoryEntry.bind(this, -1), false); - this._navigationForward = this._navigationBar.createChild('button', 'forward'); this._navigationForward.disabled = true; - this._navigationForward.addEventListener('click', this._navigateToHistoryEntry.bind(this, 1), false); - this._navigationReload = this._navigationBar.createChild('button', 'reload'); - this._navigationReload.addEventListener('click', this._navigateReload.bind(this), false); - this._navigationUrl = this._navigationBar.createChild('input'); this._navigationUrl.type = 'text'; - this._navigationUrl.addEventListener('keyup', this._navigationUrlKeyUp.bind(this), true); + this._navigationProgressBar = new Screencast.ScreencastView.ProgressTracker( + this._resourceTreeModel, this._networkManager, this._navigationBar.createChild('div', 'progress')); - this._navigationProgressBar = - new Screencast.ScreencastView.ProgressTracker(this._navigationBar.createChild('div', 'progress')); - - this._requestNavigationHistory(); - SDK.targetManager.addEventListener( - SDK.TargetManager.Events.InspectedURLChanged, this._requestNavigationHistory, this); + if (this._resourceTreeModel) { + this._navigationBack.addEventListener('click', this._navigateToHistoryEntry.bind(this, -1), false); + this._navigationForward.addEventListener('click', this._navigateToHistoryEntry.bind(this, 1), false); + this._navigationReload.addEventListener('click', this._navigateReload.bind(this), false); + this._navigationUrl.addEventListener('keyup', this._navigationUrlKeyUp.bind(this), true); + this._requestNavigationHistory(); + this._resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.MainFrameNavigated, this._requestNavigationHistory, this); + this._resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._requestNavigationHistory, this); + } } + /** + * @param {number} offset + */ _navigateToHistoryEntry(offset) { var newIndex = this._historyIndex + offset; if (newIndex < 0 || newIndex >= this._historyEntries.length) return; - this._target.pageAgent().navigateToHistoryEntry(this._historyEntries[newIndex].id); + this._resourceTreeModel.navigateToHistoryEntry(this._historyEntries[newIndex]); this._requestNavigationHistory(); } _navigateReload() { - if (this._resourceTreeModel) - this._resourceTreeModel.reloadPage(); + this._resourceTreeModel.reloadPage(); } + /** + * @param {!Event} event + */ _navigationUrlKeyUp(event) { if (event.key !== 'Enter') return; @@ -754,25 +656,22 @@ return; if (!url.match(Screencast.ScreencastView._SchemeRegex)) url = 'http://' + url; - this._target.pageAgent().navigate(url); + this._resourceTreeModel.navigate(url); this._canvasElement.focus(); } - _requestNavigationHistory() { - this._target.pageAgent().getNavigationHistory(this._onNavigationHistory.bind(this)); - } - - _onNavigationHistory(error, currentIndex, entries) { - if (error) + async _requestNavigationHistory() { + var history = await this._resourceTreeModel.navigationHistory(); + if (!history) return; - this._historyIndex = currentIndex; - this._historyEntries = entries; + this._historyIndex = history.currentIndex; + this._historyEntries = history.entries; - this._navigationBack.disabled = currentIndex === 0; - this._navigationForward.disabled = currentIndex === (entries.length - 1); + this._navigationBack.disabled = this._historyIndex === 0; + this._navigationForward.disabled = this._historyIndex === (this._historyEntries.length - 1); - var url = entries[currentIndex].url; + var url = this._historyEntries[this._historyIndex].url; var match = url.match(Screencast.ScreencastView._HttpRegex); if (match) url = match[1]; @@ -800,18 +699,21 @@ */ Screencast.ScreencastView.ProgressTracker = class { /** + * @param {?SDK.ResourceTreeModel} resourceTreeModel + * @param {?SDK.NetworkManager} networkManager * @param {!Element} element */ - constructor(element) { + constructor(resourceTreeModel, networkManager, element) { this._element = element; - - SDK.targetManager.addModelListener( - SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this); - SDK.targetManager.addModelListener(SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._onLoad, this); - SDK.targetManager.addModelListener( - SDK.NetworkManager, SDK.NetworkManager.Events.RequestStarted, this._onRequestStarted, this); - SDK.targetManager.addModelListener( - SDK.NetworkManager, SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this); + if (resourceTreeModel) { + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this); + resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, this._onLoad, this); + } + if (networkManager) { + networkManager.addEventListener(SDK.NetworkManager.Events.RequestStarted, this._onRequestStarted, this); + networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this); + } } _onMainFrameNavigated() {
diff --git a/third_party/WebKit/Source/devtools/front_end/screencast/module.json b/third_party/WebKit/Source/devtools/front_end/screencast/module.json index b6eb136a..7ae80c0a 100644 --- a/third_party/WebKit/Source/devtools/front_end/screencast/module.json +++ b/third_party/WebKit/Source/devtools/front_end/screencast/module.json
@@ -24,6 +24,7 @@ "emulation" ], "scripts": [ + "InputModel.js", "ScreencastApp.js", "ScreencastView.js" ],
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js index d49669a..5932d668 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
@@ -376,6 +376,31 @@ } /** + * @param {string} url + */ + navigate(url) { + this._agent.navigate(url, undefined, (error, frameId) => undefined); + } + + /** + * @return {!Promise<?{currentIndex: number, entries: !Protocol.Page.NavigationEntry}>} + */ + navigationHistory() { + return this._agent.getNavigationHistory((error, currentIndex, entries) => { + if (error) + return null; + return {currentIndex: currentIndex, entries: entries}; + }); + } + + /** + * @param {!Protocol.Page.NavigationEntry} entry + */ + navigateToHistoryEntry(entry) { + this._agent.navigateToHistoryEntry(entry.id); + } + + /** * @param {function(string, ?string,!Array<!Protocol.Page.AppManifestError>)} callback */ fetchAppManifest(callback) {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/Target.js b/third_party/WebKit/Source/devtools/front_end/sdk/Target.js index 0865f0e..6cad69ee 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/Target.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/Target.js
@@ -210,10 +210,11 @@ Tracing: 1 << 7, TouchEmulation: 1 << 8, Security: 1 << 9, + Input: 1 << 10, None: 0, - AllForTests: (1 << 10) - 1 + AllForTests: (1 << 11) - 1 }; /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js index 9449346..74f4631 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
@@ -334,7 +334,7 @@ var capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS | SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target | SDK.Target.Capability.ScreenCapture | SDK.Target.Capability.Tracing | SDK.Target.Capability.TouchEmulation | - SDK.Target.Capability.Security; + SDK.Target.Capability.Security | SDK.Target.Capability.Input; if (Runtime.queryParam('isSharedWorker')) { capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target; @@ -443,7 +443,7 @@ if (type === 'iframe') { return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS | SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target | - SDK.Target.Capability.Tracing | SDK.Target.Capability.TouchEmulation; + SDK.Target.Capability.Tracing | SDK.Target.Capability.TouchEmulation | SDK.Target.Capability.Input; } if (type === 'node') return SDK.Target.Capability.JS;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js index 1d4627f2..de2ac73 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -52,6 +52,14 @@ 'scroll', this._popoverHelper.hidePopover.bind(this._popoverHelper), true); this.textEditor.element.addEventListener('keydown', this._onKeyDown.bind(this), true); + this.textEditor.element.addEventListener('keyup', this._onKeyUp.bind(this), true); + this.textEditor.element.addEventListener('mousemove', this._onMouseMove.bind(this), false); + if (Runtime.experiments.isEnabled('continueToLocationMarkers')) { + this.textEditor.element.addEventListener('wheel', event => { + if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event)) + event.preventDefault(); + }, true); + } this.textEditor.addEventListener( SourceFrame.SourcesTextEditor.Events.GutterClick, this._handleGutterClick.bind(this), this); @@ -165,8 +173,6 @@ // We need SourcesTextEditor to be initialized prior to this call. @see crbug.com/499889 setImmediate(() => { this._generateValuesInSource(); - if (Runtime.experiments.isEnabled('continueToLocationMarkers')) - this._showContinueToLocations(); }); } } @@ -470,13 +476,48 @@ }; } + /** + * @param {!KeyboardEvent} event + */ _onKeyDown(event) { if (event.key === 'Escape') { if (this._popoverHelper.isPopoverVisible()) { this._popoverHelper.hidePopover(); event.consume(); } + return; } + if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event) && this._executionLocation) { + if (!this._continueToLocationShown) { + this._showContinueToLocations(); + this._continueToLocationShown = true; + } + } + } + + /** + * @param {!MouseEvent} event + */ + _onMouseMove(event) { + if (this._executionLocation && UI.KeyboardShortcut.eventHasCtrlOrMeta(event)) { + if (!this._continueToLocationShown) { + this._showContinueToLocations(); + this._continueToLocationShown = true; + } + return; + } + } + + /** + * @param {!KeyboardEvent} event + */ + _onKeyUp(event) { + if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event)) + return; + if (!this._continueToLocationShown) + return; + this._clearContinueToLocations(); + this._continueToLocationShown = false; } /** @@ -541,8 +582,10 @@ // We need SourcesTextEditor to be initialized prior to this call. @see crbug.com/506566 setImmediate(() => { this._generateValuesInSource(); - if (Runtime.experiments.isEnabled('continueToLocationMarkers')) - this._showContinueToLocations(); + if (Runtime.experiments.isEnabled('continueToLocationMarkers')) { + if (this._continueToLocationShown) + this._showContinueToLocations(); + } }); } } @@ -571,6 +614,8 @@ } _showContinueToLocations() { + if (!Runtime.experiments.isEnabled('continueToLocationMarkers')) + return; var executionContext = UI.context.flavor(SDK.ExecutionContext); if (!executionContext) return; @@ -592,7 +637,6 @@ var executionLocation = callFrame.location(); debuggerModel.getPossibleBreakpoints(start, end, true) .then(locations => this.textEditor.operation(renderLocations.bind(this, locations))); - /** * @param {!Array<!SDK.DebuggerModel.BreakLocation>} locations * @this {Sources.JavaScriptSourceFrame} @@ -806,6 +850,8 @@ } _clearContinueToLocations() { + if (!Runtime.experiments.isEnabled('continueToLocationMarkers')) + return; delete this._clearContinueToLocationsTimer; var bookmarks = this.textEditor.bookmarks( this.textEditor.fullRange(), Sources.JavaScriptSourceFrame.continueToLocationDecorationSymbol);
diff --git a/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css b/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css index e3632a8..27b5118 100644 --- a/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css +++ b/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css
@@ -162,7 +162,7 @@ .cm-continue-to-location { cursor: pointer; - opacity: 0.5; + opacity: 0.8; position: relative; top: 2px; }
diff --git a/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py b/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py index a29f53e..4680fb9 100755 --- a/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py +++ b/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py
@@ -52,6 +52,7 @@ "CSS", "Emulation", "HeapProfiler", + "Page", "Profiler", "LayerTree", "Tracing"
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h index 0a013f98..99b882b6 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h +++ b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h
@@ -39,6 +39,7 @@ namespace blink { class Dictionary; +class ExecutionContext; class MediaTrackConstraints; namespace MediaConstraintsImpl {
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp b/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp index fadef15b..556a7efa 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp
@@ -41,7 +41,7 @@ MediaDevicesRequest::MediaDevicesRequest(ScriptState* state, UserMediaController* controller) - : ContextLifecycleObserver(state->GetExecutionContext()), + : ContextLifecycleObserver(ExecutionContext::From(state)), controller_(controller), resolver_(ScriptPromiseResolver::Create(state)) {}
diff --git a/third_party/WebKit/Source/modules/permissions/Permissions.h b/third_party/WebKit/Source/modules/permissions/Permissions.h index 4fe6793..c929b54 100644 --- a/third_party/WebKit/Source/modules/permissions/Permissions.h +++ b/third_party/WebKit/Source/modules/permissions/Permissions.h
@@ -13,6 +13,7 @@ namespace blink { class Dictionary; +class ExecutionContext; class ScriptPromiseResolver; class ScriptState;
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp b/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp index d7ffad3..6b6abe8 100644 --- a/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp
@@ -748,7 +748,7 @@ void PannerNode::setRefDistance(double distance, ExceptionState& exception_state) { - if (distance <= 0) { + if (distance < 0) { exception_state.ThrowDOMException( kV8RangeError, ExceptionMessages::IndexExceedsMinimumBound<double>( "refDistance", distance, 0));
diff --git a/third_party/WebKit/Source/platform/audio/Distance.cpp b/third_party/WebKit/Source/platform/audio/Distance.cpp index af25bef..99c5a022 100644 --- a/third_party/WebKit/Source/platform/audio/Distance.cpp +++ b/third_party/WebKit/Source/platform/audio/Distance.cpp
@@ -67,11 +67,17 @@ } double DistanceEffect::InverseGain(double distance) { + if (ref_distance_ == 0) + return 0; + return ref_distance_ / (ref_distance_ + clampTo(rolloff_factor_, 0.0) * (distance - ref_distance_)); } double DistanceEffect::ExponentialGain(double distance) { + if (ref_distance_ == 0) + return 0; + return pow(distance / ref_distance_, -clampTo(rolloff_factor_, 0.0)); }
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp index c4c14299..89b5cb6f 100644 --- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp +++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
@@ -399,13 +399,14 @@ change_size_for_next_commit_ = false; } + compositor_has_pending_frame_ = true; sink_->SubmitCompositorFrame(current_local_surface_id_, std::move(frame)); } void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck( const cc::ReturnedResourceArray& resources) { ReclaimResources(resources); - // TODO(fsamuel): Implement this. + compositor_has_pending_frame_ = false; } void OffscreenCanvasFrameDispatcherImpl::SetNeedsBeginFrame( @@ -419,10 +420,19 @@ void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( const cc::BeginFrameArgs& begin_frame_args) { DCHECK(Client()); + // TODO(eseckler): Set correct |latest_confirmed_sequence_number|. current_begin_frame_ack_ = cc::BeginFrameAck( begin_frame_args.source_id, begin_frame_args.sequence_number, begin_frame_args.sequence_number, false); + + if (compositor_has_pending_frame_ || + (begin_frame_args.type == cc::BeginFrameArgs::MISSED && + base::TimeTicks::Now() > begin_frame_args.deadline)) { + sink_->BeginFrameDidNotSwap(current_begin_frame_ack_); + return; + } + Client()->BeginFrame(); // TODO(eseckler): Tell |m_sink| if we did not draw during the BeginFrame. current_begin_frame_ack_.sequence_number =
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h index 108a22a..9bfbbbb 100644 --- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h +++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h
@@ -64,6 +64,7 @@ int height_; bool change_size_for_next_commit_; bool needs_begin_frame_; + bool compositor_has_pending_frame_ = false; unsigned next_resource_id_; HashMap<unsigned, RefPtr<StaticBitmapImage>> cached_images_;
diff --git a/third_party/WebKit/Source/web/StorageQuotaClientImpl.cpp b/third_party/WebKit/Source/web/StorageQuotaClientImpl.cpp index b02f5de..514fca27 100644 --- a/third_party/WebKit/Source/web/StorageQuotaClientImpl.cpp +++ b/third_party/WebKit/Source/web/StorageQuotaClientImpl.cpp
@@ -52,7 +52,7 @@ unsigned long long new_quota_in_bytes, StorageQuotaCallback* success_callback, StorageErrorCallback* error_callback) { - ExecutionContext* execution_context = script_state->GetExecutionContext(); + ExecutionContext* execution_context = ExecutionContext::From(script_state); DCHECK(execution_context); DCHECK(execution_context->IsDocument()) << "Quota requests are not supported in workers";
diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.cpp b/third_party/WebKit/Source/web/WebInputEventConversion.cpp index 7b9defc..b3007436 100644 --- a/third_party/WebKit/Source/web/WebInputEventConversion.cpp +++ b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
@@ -195,9 +195,17 @@ if (event.NativeEvent()) { *static_cast<WebMouseEvent*>(this) = event.NativeEvent()->FlattenTransform(); - WebFloatPoint absolute_root_frame_location = PositionInRootFrame(); - IntPoint local_point = RoundedIntPoint(layout_item.AbsoluteToLocal( - absolute_root_frame_location, kUseTransforms)); + WebFloatPoint absolute_location = PositionInRootFrame(); + + // TODO(dtapuska): |plugin_parent| should never be null. Remove this + // conditional code. + // Translate the root frame position to content coordinates. + if (plugin_parent) { + absolute_location = plugin_parent->RootFrameToContents(absolute_location); + } + + IntPoint local_point = RoundedIntPoint( + layout_item.AbsoluteToLocal(absolute_location, kUseTransforms)); SetPositionInWidget(local_point.X(), local_point.Y()); return; }
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index a312501..c5c5029 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -710,6 +710,8 @@ // in the call to HandleEvent. See http://b/issue?id=1362948 FrameView* parent_view = ToFrameView(Parent()); + // TODO(dtapuska): Move WebMouseEventBuilder into the anonymous namespace + // in this class. WebMouseEventBuilder transformed_event( ToFrameView(Parent()), LayoutItem(element_->GetLayoutObject()), *event); if (transformed_event.GetType() == WebInputEvent::kUndefined) @@ -765,11 +767,17 @@ } void WebPluginContainerImpl::HandleWheelEvent(WheelEvent* event) { - WebFloatPoint absolute_root_frame_location = - event->NativeEvent().PositionInRootFrame(); + WebFloatPoint absolute_location = event->NativeEvent().PositionInRootFrame(); + + FrameView* view = ToFrameView(Parent()); + // Translate the root frame position to content coordinates. + if (view) { + absolute_location = view->RootFrameToContents(absolute_location); + } + IntPoint local_point = RoundedIntPoint(element_->GetLayoutObject()->AbsoluteToLocal( - absolute_root_frame_location, kUseTransforms)); + absolute_location, kUseTransforms)); WebMouseWheelEvent translated_event = event->NativeEvent().FlattenTransform(); translated_event.SetPositionInWidget(local_point.X(), local_point.Y()); @@ -830,12 +838,19 @@ WebTouchEvent transformed_event = event->NativeEvent()->FlattenTransform(); + FrameView* view = ToFrameView(Parent()); + for (unsigned i = 0; i < transformed_event.touches_length; ++i) { - WebFloatPoint absolute_root_frame_location = - transformed_event.touches[i].position; + WebFloatPoint absolute_location = transformed_event.touches[i].position; + + // Translate the root frame position to content coordinates. + if (view) { + absolute_location = view->RootFrameToContents(absolute_location); + } + IntPoint local_point = RoundedIntPoint(element_->GetLayoutObject()->AbsoluteToLocal( - absolute_root_frame_location, kUseTransforms)); + absolute_location, kUseTransforms)); transformed_event.touches[i].position.x = local_point.X(); transformed_event.touches[i].position.y = local_point.Y(); }
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp index 3dd69fa..dadd454 100644 --- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -51,6 +51,7 @@ #include "public/platform/WebLayer.h" #include "public/platform/WebMouseWheelEvent.h" #include "public/platform/WebThread.h" +#include "public/platform/WebTouchEvent.h" #include "public/platform/WebURLLoaderMockFactory.h" #include "public/web/WebDocument.h" #include "public/web/WebElement.h" @@ -464,19 +465,30 @@ event.GetType() == WebInputEvent::kMouseWheel) { const WebMouseEvent& mouse_event = static_cast<const WebMouseEvent&>(event); - last_mouse_event_location_ = IntPoint(mouse_event.PositionInWidget().x, - mouse_event.PositionInWidget().y); + last_event_location_ = IntPoint(mouse_event.PositionInWidget().x, + mouse_event.PositionInWidget().y); + } else if (WebInputEvent::IsTouchEventType(event.GetType())) { + const WebTouchEvent& touch_event = + static_cast<const WebTouchEvent&>(event); + if (touch_event.touches_length == 1) { + last_event_location_ = IntPoint(touch_event.touches[0].position.x, + touch_event.touches[0].position.y); + } else { + last_event_location_ = IntPoint(); + } } return WebInputEventResult::kHandledSystem; } WebInputEvent::Type GetLastInputEventType() { return last_event_type_; } - IntPoint GetLastMouseEventLocation() { return last_mouse_event_location_; } + IntPoint GetLastEventLocation() { return last_event_location_; } + + void ClearLastEventType() { last_event_type_ = WebInputEvent::kUndefined; } private: WebInputEvent::Type last_event_type_; - IntPoint last_mouse_event_location_; + IntPoint last_event_location_; }; TEST_F(WebPluginContainerTest, GestureLongPressReachesPlugin) { @@ -560,8 +572,258 @@ RunPendingTasks(); EXPECT_EQ(WebInputEvent::kMouseWheel, test_plugin->GetLastInputEventType()); - EXPECT_EQ(rect.width / 2, test_plugin->GetLastMouseEventLocation().X()); - EXPECT_EQ(rect.height / 2, test_plugin->GetLastMouseEventLocation().Y()); + EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); +} + +TEST_F(WebPluginContainerTest, TouchEventScrolled) { + RegisterMockedURL("plugin_scroll.html"); + CustomPluginWebFrameClient<EventTestPlugin> + plugin_web_frame_client; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper web_view_helper; + WebView* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + DCHECK(web_view); + web_view->GetSettings()->SetPluginsEnabled(true); + web_view->Resize(WebSize(300, 300)); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + web_view->SmoothScroll(0, 200, 0); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebElement plugin_container_one_element = + web_view->MainFrame()->GetDocument().GetElementById( + WebString::FromUTF8("scrolled-plugin")); + plugin_container_one_element.PluginContainer()->RequestTouchEventType( + WebPluginContainer::kTouchEventRequestTypeRaw); + WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( + plugin_container_one_element.PluginContainer()) + ->Plugin(); + EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); + + WebTouchEvent event(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + event.touches_length = 1; + WebRect rect = plugin_container_one_element.BoundsInViewport(); + event.touches[0].state = WebTouchPoint::kStatePressed; + event.touches[0].position = + WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2); + + web_view->HandleInputEvent(WebCoalescedInputEvent(event)); + RunPendingTasks(); + + EXPECT_EQ(WebInputEvent::kTouchStart, test_plugin->GetLastInputEventType()); + EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); +} + +TEST_F(WebPluginContainerTest, MouseWheelEventScrolled) { + RegisterMockedURL("plugin_scroll.html"); + CustomPluginWebFrameClient<EventTestPlugin> + plugin_web_frame_client; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper web_view_helper; + WebView* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + DCHECK(web_view); + web_view->GetSettings()->SetPluginsEnabled(true); + web_view->Resize(WebSize(300, 300)); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + web_view->SmoothScroll(0, 200, 0); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebElement plugin_container_one_element = + web_view->MainFrame()->GetDocument().GetElementById( + WebString::FromUTF8("scrolled-plugin")); + plugin_container_one_element.PluginContainer()->RequestTouchEventType( + WebPluginContainer::kTouchEventRequestTypeRaw); + WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( + plugin_container_one_element.PluginContainer()) + ->Plugin(); + EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); + + WebMouseWheelEvent event(WebInputEvent::kMouseWheel, + WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + + WebRect rect = plugin_container_one_element.BoundsInViewport(); + event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); + + web_view->HandleInputEvent(WebCoalescedInputEvent(event)); + RunPendingTasks(); + + EXPECT_EQ(WebInputEvent::kMouseWheel, test_plugin->GetLastInputEventType()); + EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); +} + +TEST_F(WebPluginContainerTest, MouseEventScrolled) { + RegisterMockedURL("plugin_scroll.html"); + CustomPluginWebFrameClient<EventTestPlugin> + plugin_web_frame_client; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper web_view_helper; + WebView* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + DCHECK(web_view); + web_view->GetSettings()->SetPluginsEnabled(true); + web_view->Resize(WebSize(300, 300)); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + web_view->SmoothScroll(0, 200, 0); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebElement plugin_container_one_element = + web_view->MainFrame()->GetDocument().GetElementById( + WebString::FromUTF8("scrolled-plugin")); + plugin_container_one_element.PluginContainer()->RequestTouchEventType( + WebPluginContainer::kTouchEventRequestTypeRaw); + WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( + plugin_container_one_element.PluginContainer()) + ->Plugin(); + EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); + + WebMouseEvent event(WebInputEvent::kMouseMove, WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + + WebRect rect = plugin_container_one_element.BoundsInViewport(); + event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); + + web_view->HandleInputEvent(WebCoalescedInputEvent(event)); + RunPendingTasks(); + + EXPECT_EQ(WebInputEvent::kMouseMove, test_plugin->GetLastInputEventType()); + EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); +} + +TEST_F(WebPluginContainerTest, MouseEventZoomed) { + RegisterMockedURL("plugin_scroll.html"); + CustomPluginWebFrameClient<EventTestPlugin> + plugin_web_frame_client; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper web_view_helper; + WebView* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + DCHECK(web_view); + web_view->GetSettings()->SetPluginsEnabled(true); + web_view->Resize(WebSize(300, 300)); + web_view->SetPageScaleFactor(2); + web_view->SmoothScroll(0, 300, 0); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebElement plugin_container_one_element = + web_view->MainFrame()->GetDocument().GetElementById( + WebString::FromUTF8("scrolled-plugin")); + plugin_container_one_element.PluginContainer()->RequestTouchEventType( + WebPluginContainer::kTouchEventRequestTypeRaw); + WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( + plugin_container_one_element.PluginContainer()) + ->Plugin(); + EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); + + WebMouseEvent event(WebInputEvent::kMouseMove, WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + + WebRect rect = plugin_container_one_element.BoundsInViewport(); + event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); + + web_view->HandleInputEvent(WebCoalescedInputEvent(event)); + RunPendingTasks(); + + // rect.width/height divided by 4 because the rect is in viewport bounds and + // there is a scale of 2 set. + EXPECT_EQ(WebInputEvent::kMouseMove, test_plugin->GetLastInputEventType()); + EXPECT_EQ(rect.width / 4, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 4, test_plugin->GetLastEventLocation().Y()); +} + +TEST_F(WebPluginContainerTest, MouseWheelEventZoomed) { + RegisterMockedURL("plugin_scroll.html"); + CustomPluginWebFrameClient<EventTestPlugin> + plugin_web_frame_client; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper web_view_helper; + WebView* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + DCHECK(web_view); + web_view->GetSettings()->SetPluginsEnabled(true); + web_view->Resize(WebSize(300, 300)); + web_view->SetPageScaleFactor(2); + web_view->SmoothScroll(0, 300, 0); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebElement plugin_container_one_element = + web_view->MainFrame()->GetDocument().GetElementById( + WebString::FromUTF8("scrolled-plugin")); + plugin_container_one_element.PluginContainer()->RequestTouchEventType( + WebPluginContainer::kTouchEventRequestTypeRaw); + WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( + plugin_container_one_element.PluginContainer()) + ->Plugin(); + EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); + + WebMouseWheelEvent event(WebInputEvent::kMouseWheel, + WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + + WebRect rect = plugin_container_one_element.BoundsInViewport(); + event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); + + web_view->HandleInputEvent(WebCoalescedInputEvent(event)); + RunPendingTasks(); + + // rect.width/height divided by 4 because the rect is in viewport bounds and + // there is a scale of 2 set. + EXPECT_EQ(WebInputEvent::kMouseWheel, test_plugin->GetLastInputEventType()); + EXPECT_EQ(rect.width / 4, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 4, test_plugin->GetLastEventLocation().Y()); +} + +TEST_F(WebPluginContainerTest, TouchEventZoomed) { + RegisterMockedURL("plugin_scroll.html"); + CustomPluginWebFrameClient<EventTestPlugin> + plugin_web_frame_client; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper web_view_helper; + WebView* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + DCHECK(web_view); + web_view->GetSettings()->SetPluginsEnabled(true); + web_view->Resize(WebSize(300, 300)); + web_view->SetPageScaleFactor(2); + web_view->SmoothScroll(0, 300, 0); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebElement plugin_container_one_element = + web_view->MainFrame()->GetDocument().GetElementById( + WebString::FromUTF8("scrolled-plugin")); + plugin_container_one_element.PluginContainer()->RequestTouchEventType( + WebPluginContainer::kTouchEventRequestTypeRaw); + WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( + plugin_container_one_element.PluginContainer()) + ->Plugin(); + EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); + + WebTouchEvent event(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + event.touches_length = 1; + WebRect rect = plugin_container_one_element.BoundsInViewport(); + + event.touches[0].state = WebTouchPoint::kStatePressed; + event.touches[0].position = + WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2); + + web_view->HandleInputEvent(WebCoalescedInputEvent(event)); + RunPendingTasks(); + + // rect.width/height divided by 4 because the rect is in viewport bounds and + // there is a scale of 2 set. + EXPECT_EQ(WebInputEvent::kTouchStart, test_plugin->GetLastInputEventType()); + EXPECT_EQ(rect.width / 4, test_plugin->GetLastEventLocation().X()); + EXPECT_EQ(rect.height / 4, test_plugin->GetLastEventLocation().Y()); } // Verify that isRectTopmost returns false when the document is detached.
diff --git a/third_party/WebKit/Source/web/tests/data/plugin_scroll.html b/third_party/WebKit/Source/web/tests/data/plugin_scroll.html new file mode 100644 index 0000000..af1dc64 --- /dev/null +++ b/third_party/WebKit/Source/web/tests/data/plugin_scroll.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <style type="text/css"> + body { margin: 0; padding: 0; } + </style> +</head> +<body> + <div style="width: 30px; height: 400px;"></div> + <object id="scrolled-plugin" + border=0 + type="application/x-webkit-test-webplugin" + width="40" + height="40"> + </object> + +</body> +</html>
diff --git a/third_party/adobe/OWNERS b/third_party/adobe/OWNERS index 06a45bd..7b931968 100644 --- a/third_party/adobe/OWNERS +++ b/third_party/adobe/OWNERS
@@ -1,7 +1,6 @@ cpu@chromium.org jschuh@chromium.org raymes@chromium.org -shess@chromium.org viettrungluu@chromium.org yzshen@chromium.org zelidrag@chromium.org
diff --git a/third_party/tlslite/README.chromium b/third_party/tlslite/README.chromium index c2d1f27..c6104f5 100644 --- a/third_party/tlslite/README.chromium +++ b/third_party/tlslite/README.chromium
@@ -56,3 +56,4 @@ - patches/token_binding_version.patch: Update Token Binding version number. - patches/renegotiation_indication.patch: Implement the renegotiation indication extension (RFC 5746) without supporting renegotiation. +- patches/tls13_intolerance.patch: Extend the intolerance simulation to TLS 1.3.
diff --git a/third_party/tlslite/patches/tls13_intolerance.patch b/third_party/tlslite/patches/tls13_intolerance.patch new file mode 100644 index 0000000..6f19571 --- /dev/null +++ b/third_party/tlslite/patches/tls13_intolerance.patch
@@ -0,0 +1,66 @@ +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index 82e8c075fe2a..8fb75d0948e4 100644 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -58,6 +58,7 @@ class ExtensionType: # RFC 6066 / 4366 + signed_cert_timestamps = 18 # RFC 6962 + extended_master_secret = 23 # RFC 7627 + token_binding = 24 # draft-ietf-tokbind-negotiation ++ supported_versions = 43 # draft-ietf-tls-tls13-18 + tack = 0xF300 + supports_npn = 13172 + channel_id = 30032 +diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py +index ac7e563021d9..b29db939c2a8 100644 +--- a/third_party/tlslite/tlslite/messages.py ++++ b/third_party/tlslite/tlslite/messages.py +@@ -140,6 +140,7 @@ class ClientHello(HandshakeMsg): + self.tb_client_params = [] + self.support_signed_cert_timestamps = False + self.status_request = False ++ self.has_supported_versions = False + self.ri = False + + def create(self, version, random, session_id, cipher_suites, +@@ -251,6 +252,11 @@ class ClientHello(HandshakeMsg): + if extLength != 1 or p.getFixBytes(extLength)[0] != 0: + raise SyntaxError() + self.ri = True ++ elif extType == ExtensionType.supported_versions: ++ # Ignore the extension, but make a note of it for ++ # intolerance simulation. ++ self.has_supported_versions = True ++ _ = p.getFixBytes(extLength) + else: + _ = p.getFixBytes(extLength) + index2 = p.index +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index 8ba1c6e636ab..2309d4fa8f3a 100644 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -1457,6 +1457,15 @@ class TLSConnection(TLSRecordLayer): + self._handshakeDone(resumed=False) + + ++ def _isIntolerant(self, settings, clientHello): ++ if settings.tlsIntolerant is None: ++ return False ++ clientVersion = clientHello.client_version ++ if clientHello.has_supported_versions: ++ clientVersion = (3, 4) ++ return clientVersion >= settings.tlsIntolerant ++ ++ + def _serverGetClientHello(self, settings, certChain, verifierDB, + sessionCache, anon, fallbackSCSV): + #Tentatively set version to most-desirable version, so if an error +@@ -1480,8 +1489,7 @@ class TLSConnection(TLSRecordLayer): + yield result + + #If simulating TLS intolerance, reject certain TLS versions. +- elif (settings.tlsIntolerant is not None and +- clientHello.client_version >= settings.tlsIntolerant): ++ elif self._isIntolerant(settings, clientHello): + if settings.tlsIntoleranceType == "alert": + for result in self._sendError(\ + AlertDescription.handshake_failure):
diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py index 82e8c075..8fb75d0 100644 --- a/third_party/tlslite/tlslite/constants.py +++ b/third_party/tlslite/tlslite/constants.py
@@ -58,6 +58,7 @@ signed_cert_timestamps = 18 # RFC 6962 extended_master_secret = 23 # RFC 7627 token_binding = 24 # draft-ietf-tokbind-negotiation + supported_versions = 43 # draft-ietf-tls-tls13-18 tack = 0xF300 supports_npn = 13172 channel_id = 30032
diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py index ac7e563..b29db93 100644 --- a/third_party/tlslite/tlslite/messages.py +++ b/third_party/tlslite/tlslite/messages.py
@@ -140,6 +140,7 @@ self.tb_client_params = [] self.support_signed_cert_timestamps = False self.status_request = False + self.has_supported_versions = False self.ri = False def create(self, version, random, session_id, cipher_suites, @@ -251,6 +252,11 @@ if extLength != 1 or p.getFixBytes(extLength)[0] != 0: raise SyntaxError() self.ri = True + elif extType == ExtensionType.supported_versions: + # Ignore the extension, but make a note of it for + # intolerance simulation. + self.has_supported_versions = True + _ = p.getFixBytes(extLength) else: _ = p.getFixBytes(extLength) index2 = p.index
diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py index 8ba1c6e..2309d4f 100644 --- a/third_party/tlslite/tlslite/tlsconnection.py +++ b/third_party/tlslite/tlslite/tlsconnection.py
@@ -1457,6 +1457,15 @@ self._handshakeDone(resumed=False) + def _isIntolerant(self, settings, clientHello): + if settings.tlsIntolerant is None: + return False + clientVersion = clientHello.client_version + if clientHello.has_supported_versions: + clientVersion = (3, 4) + return clientVersion >= settings.tlsIntolerant + + def _serverGetClientHello(self, settings, certChain, verifierDB, sessionCache, anon, fallbackSCSV): #Tentatively set version to most-desirable version, so if an error @@ -1480,8 +1489,7 @@ yield result #If simulating TLS intolerance, reject certain TLS versions. - elif (settings.tlsIntolerant is not None and - clientHello.client_version >= settings.tlsIntolerant): + elif self._isIntolerant(settings, clientHello): if settings.tlsIntoleranceType == "alert": for result in self._sendError(\ AlertDescription.handshake_failure):
diff --git a/tools/chrome_proxy/webdriver/bypass.py b/tools/chrome_proxy/webdriver/bypass.py index 2b3259fe..7eb98e1c5 100644 --- a/tools/chrome_proxy/webdriver/bypass.py +++ b/tools/chrome_proxy/webdriver/bypass.py
@@ -126,14 +126,17 @@ self.assertNotHasChromeProxyViaHeader(response) self.assertEqual(u'http/1.1', response.protocol) - # Check that the BlockTypePrimary histogram has a single entry in the + # Check that the BlockTypePrimary histogram has at least one entry in the # MissingViaHeader4xx category (which is enum value 4), to make sure that # the bypass was caused by the missing via header logic and not something - # else. + # else. The favicon for this URL may also be fetched, but will return a + # 404. histogram = test_driver.GetHistogram( "DataReductionProxy.BlockTypePrimary") - self.assertEqual(1, histogram['count']) - self.assertIn({'count': 1, 'high': 5, 'low': 4}, histogram['buckets']) + self.assertNotEqual(0, histogram['count']) + self.assertEqual(1, len(histogram['buckets'])) + self.assertEqual(5, histogram['buckets'][0]['high']) + self.assertEqual(4, histogram['buckets'][0]['low']) # Verify that the Data Reduction Proxy understands the "exp" directive. def testExpDirectiveBypass(self): @@ -172,6 +175,23 @@ for response in responses: self.assertHasChromeProxyViaHeader(response) + # Data Saver uses a HTTPS proxy by default, if that fails it will fall back to + # a HTTP proxy. + def testBadHTTPSFallback(self): + with TestDriver() as test_driver: + test_driver.AddChromeArg('--enable-spdy-proxy-auth') + # Set the primary (HTTPS) proxy to a bad one. + # That will force Data Saver to the HTTP proxy for normal page requests. + test_driver.AddChromeArg('--spdy-proxy-auth-origin=' + 'https://nonexistent.googlezip.net') + test_driver.AddChromeArg('--data-reduction-proxy-http-proxies=' + 'http://compress.googlezip.net') + + test_driver.LoadURL('http://check.googlezip.net/fallback/') + responses = test_driver.GetHTTPResponses() + self.assertNotEqual(0, len(responses)) + for response in responses: + self.assertEqual(80, response.port) if __name__ == '__main__': IntegrationTest.RunAllTests()
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9d3890930..18ad474 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -22498,6 +22498,9 @@ </histogram> <histogram name="History.FaviconsRecoveredPercentage" units="%"> + <obsolete> + No longer tracked as of March 2017. + </obsolete> <owner>rpop@google.com</owner> <summary> Size of the recovered Favicons database relative to the original corrupt @@ -22509,6 +22512,9 @@ </histogram> <histogram name="History.FaviconsRecoveredRowsFaviconBitmaps"> + <obsolete> + No longer tracked as of March 2017. + </obsolete> <owner>rpop@google.com</owner> <summary> Rows recovered from [favicon_bitmaps] table in Favicons recovery. @@ -22516,11 +22522,17 @@ </histogram> <histogram name="History.FaviconsRecoveredRowsFavicons"> + <obsolete> + No longer tracked as of March 2017. + </obsolete> <owner>rpop@google.com</owner> <summary>Rows recovered from [favicons] table in Favicons recovery.</summary> </histogram> <histogram name="History.FaviconsRecoveredRowsIconMapping"> + <obsolete> + No longer tracked as of March 2017. + </obsolete> <owner>rpop@google.com</owner> <summary> Rows recovered from [icon_mapping] table in Favicons recovery. @@ -22528,6 +22540,9 @@ </histogram> <histogram name="History.FaviconsRecovery" enum="HistoryFaviconsRecoveryEnum"> + <obsolete> + No longer tracked as of March 2017. + </obsolete> <owner>rpop@google.com</owner> <summary> Track results of SQLite database recovery code in thumbnail_database.cc. @@ -25765,6 +25780,9 @@ </histogram> <histogram name="Media.Android.NumMediaServerCrashes"> + <obsolete> + Deprecated as of 04/2017 + </obsolete> <owner>qinmin@chromium.org</owner> <summary> Android: Number of consecutive media server crashes monitored before it is @@ -25775,6 +25793,9 @@ <histogram name="Media.Android.ThrottleInfobarResponse" enum="ThrottleInfobarResponse"> + <obsolete> + Deprecated as of 04/2017 + </obsolete> <owner>qinmin@chromium.org</owner> <summary> Android: The distribution of responses to the media throttle infobar prompt. @@ -38277,6 +38298,22 @@ </summary> </histogram> +<histogram name="Net.SSLVersionInterferenceError" enum="NetErrorCodes"> + <owner>davidben@chromium.org</owner> + <summary> + For each detected SSL version interference, what network error the original + failed connection reported. + </summary> +</histogram> + +<histogram name="Net.SSLVersionInterferenceProbeTrigger" enum="NetErrorCodes"> + <owner>davidben@chromium.org</owner> + <summary> + For each SSL version interference probe, what network error triggered it. + Probes are only triggered for a small set of network errors. + </summary> +</histogram> + <histogram name="Net.TCP_Connection_Idle_Sockets"> <obsolete> Deprecated 04/2016 as doesn't have data nor owner. @@ -86427,6 +86464,8 @@ <int value="-202" label="CERT_AUTHORITY_INVALID"/> <int value="-201" label="CERT_DATE_INVALID"/> <int value="-200" label="CERT_COMMON_NAME_INVALID"/> + <int value="-175" label="SSL_VERSION_INTERFERENCE"/> + <int value="-174" label="READ_IF_READY_NOT_IMPLEMENTED"/> <int value="-173" label="WS_UPGRADE"/> <int value="-172" label="SSL_OBSOLETE_CIPHER"/> <int value="-171" label="CT_CONSISTENCY_PROOF_PARSING_FAILED"/> @@ -97843,6 +97882,9 @@ <enum name="HistoryFaviconsRecoveryEnum" type="int"> <summary>Error states noted in thumbnail_database.cc recovery code.</summary> + <obsolete> + History.FaviconsRecovery no longer tracked as of March 2017. + </obsolete> <int value="0" label="RECOVERY_EVENT_RECOVERED">Successful recovery.</int> <int value="1" label="RECOVERY_EVENT_FAILED_SCOPER"> sql::Recovery failed init. @@ -97941,7 +97983,7 @@ <int value="1" label="RECOVERY_EVENT_DEPRECATED"> Recovery found deprecated version and razed. </int> - <int value="2" label="RECOVERY_EVENT_FAILED_SCOPER"> + <int value="2" label="RECOVERY_EVENT_FAILED_SCOPER (obsolete Mar 2017)"> sql::Recovery failed init. </int> <int value="3" label="RECOVERY_EVENT_FAILED_META_VERSION"> @@ -97950,13 +97992,14 @@ <int value="4" label="RECOVERY_EVENT_FAILED_META_WRONG_VERSION"> Recovery meta table has an unexpected version. </int> - <int value="5" label="RECOVERY_EVENT_FAILED_META_INIT"> + <int value="5" label="RECOVERY_EVENT_FAILED_META_INIT (obsolete Mar 2017)"> Failed sql::MetaTable::Init(). </int> - <int value="6" label="RECOVERY_EVENT_FAILED_SCHEMA_INIT"> + <int value="6" label="RECOVERY_EVENT_FAILED_SCHEMA_INIT (obsolete Mar 2017)"> Failed to init target schema. </int> - <int value="7" label="RECOVERY_EVENT_FAILED_AUTORECOVER_THUMBNAILS"> + <int value="7" + label="RECOVERY_EVENT_FAILED_AUTORECOVER_THUMBNAILS (obsolete Mar 2017)"> Failed recovery on thumbnails table. </int> <int value="8" label="RECOVERY_EVENT_FAILED_COMMIT"> @@ -104344,6 +104387,8 @@ <int value="171" label="CT_CONSISTENCY_PROOF_PARSING_FAILED"/> <int value="172" label="SSL_OBSOLETE_CIPHER"/> <int value="173" label="WS_UPGRADE"/> + <int value="174" label="READ_IF_READY_NOT_IMPLEMENTED"/> + <int value="175" label="SSL_VERSION_INTERFERENCE"/> <int value="200" label="CERT_COMMON_NAME_INVALID"/> <int value="201" label="CERT_DATE_INVALID"/> <int value="202" label="CERT_AUTHORITY_INVALID"/> @@ -112666,6 +112711,10 @@ Autorecover failed setup with NOTADB, then successfully deleted the unrecoverable db and verified that it now works. </int> + <int value="32" label="RECOVERY_FAILED_AUTORECOVERDB_META_VERSION"> + Autorecover failed because required version information was missing from the + [meta] table. + </int> </enum> <enum name="SqliteStatsEnum" type="int">
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py index 06b1d8b7..f37ce44 100644 --- a/tools/perf/benchmarks/media.py +++ b/tools/perf/benchmarks/media.py
@@ -66,8 +66,6 @@ category_filter.AddIncludedCategory('rail') options = timeline_based_measurement.Options(category_filter) - options.config.enable_atrace_trace = True - options.config.atrace_config.categories = ['sched'] options.config.enable_battor_trace = True options.SetTimelineBasedMetrics(['powerMetric', 'cpuTimeMetric']) return options @@ -142,10 +140,7 @@ @classmethod def ShouldDisable(cls, possible_browser): - # crbug.com/707286: This benchmark is having issues with devices other - # than Nexus 5X. Disabling on those devices until we figure out the cause. - return (cls.IsSvelte(possible_browser) or - possible_browser.platform.GetDeviceTypeName() != 'Nexus 5X') + return cls.IsSvelte(possible_browser) @classmethod def Name(cls):
diff --git a/tools/perf/benchmarks/tab_switching.py b/tools/perf/benchmarks/tab_switching.py index ed75b50..0b485fbc 100644 --- a/tools/perf/benchmarks/tab_switching.py +++ b/tools/perf/benchmarks/tab_switching.py
@@ -9,9 +9,10 @@ from telemetry import benchmark -@benchmark.Enabled('has tabs') +#@benchmark.Enabled('has tabs') @benchmark.Disabled('mac-reference') # http://crbug.com/612774 @benchmark.Disabled('android') # http://crbug.com/460084 +@benchmark.Disabled('all') # http://crbug.com/710524 class TabSwitchingTypical25(perf_benchmark.PerfBenchmark): """This test records the MPArch.RWH_TabSwitchPaintDuration histogram.
diff --git a/ui/events/blink/web_input_event_builders_win.cc b/ui/events/blink/web_input_event_builders_win.cc index 56afe59..148d6e468 100644 --- a/ui/events/blink/web_input_event_builders_win.cc +++ b/ui/events/blink/web_input_event_builders_win.cc
@@ -167,7 +167,7 @@ WebMouseEvent result(type, modifiers, time_stamp); result.pointer_type = pointer_type; result.button = button; - result.id = ui::PointerEvent::kMousePointerId; + result.id = ui::MouseEvent::kMousePointerId; // set position fields: result.SetPositionInWidget(static_cast<short>(LOWORD(lparam)),
diff --git a/ui/events/blink/web_input_event_unittest.cc b/ui/events/blink/web_input_event_unittest.cc index c48280c..8803cb01 100644 --- a/ui/events/blink/web_input_event_unittest.cc +++ b/ui/events/blink/web_input_event_unittest.cc
@@ -429,9 +429,6 @@ { // Stylus values for PointerDetails. base::TimeTicks timestamp = EventTimeForNow(); - MouseEvent ui_event(ET_MOUSE_PRESSED, gfx::Point(123, 321), - gfx::Point(123, 321), timestamp, EF_LEFT_MOUSE_BUTTON, - EF_LEFT_MOUSE_BUTTON); PointerDetails pointer_details(EventPointerType::POINTER_TYPE_PEN, /* id */ 63, /* radius_x */ 0.0f, @@ -441,7 +438,9 @@ /* tilt_y */ -89.5f, /* tangential_pressure */ 0.6f, /* twist */ 269); - ui_event.set_pointer_details(pointer_details); + MouseEvent ui_event(ET_MOUSE_PRESSED, gfx::Point(123, 321), + gfx::Point(123, 321), timestamp, EF_LEFT_MOUSE_BUTTON, + EF_LEFT_MOUSE_BUTTON, pointer_details); blink::WebMouseEvent webkit_event = MakeWebMouseEvent(ui_event, base::Bind(&GetScreenLocationFromEvent));
diff --git a/ui/events/event.cc b/ui/events/event.cc index 64f06d0c..07c1753c 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc
@@ -533,7 +533,7 @@ id(pointer_id) { if (pointer_id == PointerDetails::kUnknownPointerId) { id = pointer_type == EventPointerType::POINTER_TYPE_MOUSE - ? PointerEvent::kMousePointerId + ? MouseEvent::kMousePointerId : 0; } } @@ -625,14 +625,15 @@ const gfx::Point& root_location, base::TimeTicks time_stamp, int flags, - int changed_button_flags) + int changed_button_flags, + const PointerDetails& pointer_details) : LocatedEvent(type, gfx::PointF(location), gfx::PointF(root_location), time_stamp, flags), changed_button_flags_(changed_button_flags), - pointer_details_(PointerDetails(EventPointerType::POINTER_TYPE_MOUSE)) { + pointer_details_(pointer_details) { DCHECK_NE(ET_MOUSEWHEEL, type); latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); if (this->type() == ET_MOUSE_MOVED && IsAnyButton()) @@ -757,14 +758,7 @@ set_flags(f); } -void MouseEvent::set_pointer_details(const PointerDetails& details) { - DCHECK_NE(EventPointerType::POINTER_TYPE_TOUCH, - pointer_details_.pointer_type); - DCHECK_NE(EventPointerType::POINTER_TYPE_TOUCH, details.pointer_type); - DCHECK(pointer_details_.id == PointerEvent::kMousePointerId || - details.id != PointerEvent::kMousePointerId); - pointer_details_ = details; -} +const int MouseEvent::kMousePointerId = std::numeric_limits<int32_t>::max(); //////////////////////////////////////////////////////////////////////////////// // MouseWheelEvent @@ -1086,8 +1080,6 @@ latency()->set_source_event_type(ui::SourceEventType::OTHER); } -const int PointerEvent::kMousePointerId = std::numeric_limits<int32_t>::max(); - //////////////////////////////////////////////////////////////////////////////// // KeyEvent
diff --git a/ui/events/event.h b/ui/events/event.h index 16dce04e..b6ffd82 100644 --- a/ui/events/event.h +++ b/ui/events/event.h
@@ -481,6 +481,8 @@ class EVENTS_EXPORT MouseEvent : public LocatedEvent { public: + static const int32_t kMousePointerId; + explicit MouseEvent(const base::NativeEvent& native_event); // |pointer_event.IsMousePointerEvent()| must be true. @@ -519,7 +521,10 @@ const gfx::Point& root_location, base::TimeTicks time_stamp, int flags, - int changed_button_flags); + int changed_button_flags, + const PointerDetails& pointer_details = + PointerDetails(EventPointerType::POINTER_TYPE_MOUSE, + kMousePointerId)); // Conveniences to quickly test what button is down bool IsOnlyLeftMouseButton() const { @@ -581,7 +586,6 @@ // Event details common to MouseEvent and TouchEvent. const PointerDetails& pointer_details() const { return pointer_details_; } - void set_pointer_details(const PointerDetails& details); private: FRIEND_TEST_ALL_PREFIXES(EventTest, DoubleClickRequiresRelease); @@ -733,8 +737,6 @@ class EVENTS_EXPORT PointerEvent : public LocatedEvent { public: - static const int32_t kMousePointerId; - // Returns true if a PointerEvent can be constructed from |event|. Currently, // only mouse and touch events can be converted to pointer events. static bool CanConvertFrom(const Event& event);
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc index 9a6a779..29e5048a 100644 --- a/ui/events/event_unittest.cc +++ b/ui/events/event_unittest.cc
@@ -708,8 +708,6 @@ } TEST(EventTest, PointerDetailsStylus) { - ui::MouseEvent stylus_event(ET_MOUSE_PRESSED, gfx::Point(0, 0), - gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0); ui::PointerDetails pointer_details(EventPointerType::POINTER_TYPE_PEN, /* pointer_id*/ 0, /* radius_x */ 0.0f, @@ -720,7 +718,9 @@ /* tangential_pressure */ 0.7f, /* twist */ 196); - stylus_event.set_pointer_details(pointer_details); + ui::MouseEvent stylus_event(ET_MOUSE_PRESSED, gfx::Point(0, 0), + gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0, + pointer_details); EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN, stylus_event.pointer_details().pointer_type); EXPECT_EQ(21.0f, stylus_event.pointer_details().force); @@ -856,7 +856,7 @@ gfx::Point(0, 0), base::TimeTicks(), 0, 0); ui::PointerEvent pointer_event(mouse_event); EXPECT_EQ(pointer_event.pointer_details().id, - ui::PointerEvent::kMousePointerId); + ui::MouseEvent::kMousePointerId); } for (int touch_id = 0; touch_id < 8; touch_id++) {
diff --git a/ui/events/events_default.cc b/ui/events/events_default.cc index fac6472..c609e14902 100644 --- a/ui/events/events_default.cc +++ b/ui/events/events_default.cc
@@ -54,7 +54,7 @@ static_cast<const ui::MouseEvent*>(native_event); DCHECK(event->IsMouseEvent() || event->IsScrollEvent()); PointerDetails pointer_detail = event->pointer_details(); - pointer_detail.id = PointerEvent::kMousePointerId; + pointer_detail.id = MouseEvent::kMousePointerId; return pointer_detail; }
diff --git a/ui/events/mojo/event_struct_traits.cc b/ui/events/mojo/event_struct_traits.cc index 1a5180fa..d2a66cb 100644 --- a/ui/events/mojo/event_struct_traits.cc +++ b/ui/events/mojo/event_struct_traits.cc
@@ -295,9 +295,9 @@ static_cast<int>(pointer_data->wheel_data->delta_x), static_cast<int>( pointer_data->wheel_data->delta_y)), - ui::PointerEvent::kMousePointerId) + ui::MouseEvent::kMousePointerId) : ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, - ui::PointerEvent::kMousePointerId), + ui::MouseEvent::kMousePointerId), ui::EventTimeForNow())); break; }
diff --git a/ui/events/mojo/struct_traits_unittest.cc b/ui/events/mojo/struct_traits_unittest.cc index 5f2ba7b..3ec4376 100644 --- a/ui/events/mojo/struct_traits_unittest.cc +++ b/ui/events/mojo/struct_traits_unittest.cc
@@ -83,22 +83,22 @@ // Mouse pointer events: {ET_POINTER_DOWN, gfx::Point(10, 10), gfx::Point(20, 30), EF_NONE, 0, PointerDetails(EventPointerType::POINTER_TYPE_MOUSE, - PointerEvent::kMousePointerId), + MouseEvent::kMousePointerId), base::TimeTicks()}, {ET_POINTER_MOVED, gfx::Point(1, 5), gfx::Point(5, 1), EF_LEFT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON, PointerDetails(EventPointerType::POINTER_TYPE_MOUSE, - PointerEvent::kMousePointerId), + MouseEvent::kMousePointerId), base::TimeTicks()}, {ET_POINTER_UP, gfx::Point(411, 130), gfx::Point(20, 30), EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON, EF_RIGHT_MOUSE_BUTTON, PointerDetails(EventPointerType::POINTER_TYPE_MOUSE, - PointerEvent::kMousePointerId), + MouseEvent::kMousePointerId), base::TimeTicks()}, {ET_POINTER_EXITED, gfx::Point(10, 10), gfx::Point(20, 30), EF_BACK_MOUSE_BUTTON, 0, PointerDetails(EventPointerType::POINTER_TYPE_MOUSE, - PointerEvent::kMousePointerId), + MouseEvent::kMousePointerId), base::TimeTicks()}, // Touch pointer events:
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc index c071853..00b18819 100644 --- a/ui/events/ozone/evdev/event_factory_evdev.cc +++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -218,11 +218,10 @@ MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), params.timestamp, modifiers_.GetModifierFlags() | params.flags, - /* changed_button_flags */ 0); + /* changed_button_flags */ 0, details); event.set_location_f(location); event.set_root_location_f(location); event.set_source_device_id(params.device_id); - event.set_pointer_details(details); DispatchUiEvent(&event); } @@ -279,11 +278,10 @@ MouseEvent event(params.down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), params.timestamp, modifiers_.GetModifierFlags() | flag | params.flags, - /* changed_button_flags */ flag); + /* changed_button_flags */ flag, details); event.set_location_f(location); event.set_root_location_f(location); event.set_source_device_id(params.device_id); - event.set_pointer_details(details); DispatchUiEvent(&event); } @@ -341,7 +339,6 @@ touch_event.set_location_f(location); touch_event.set_root_location_f(location); touch_event.set_source_device_id(params.device_id); - touch_event.set_pointer_details(details); DispatchUiEvent(&touch_event); if (params.type == ET_TOUCH_RELEASED || params.type == ET_TOUCH_CANCELLED) {
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index 8faec76..06bec8a9 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "services/service_manager/public/cpp/connection.h" #include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/drm_buffer.h" #include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h index fe3864e..be12617 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.h +++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -14,7 +14,6 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" #include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/connection.h" #include "ui/gfx/native_pixmap_handle.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/vsync_provider.h"
diff --git a/ui/views/accessibility/ax_view_obj_wrapper.cc b/ui/views/accessibility/ax_view_obj_wrapper.cc index 37c2af3..2a22590 100644 --- a/ui/views/accessibility/ax_view_obj_wrapper.cc +++ b/ui/views/accessibility/ax_view_obj_wrapper.cc
@@ -51,7 +51,7 @@ out_node_data->id = GetID(); - if (view_->IsFocusable()) + if (view_->IsAccessibilityFocusable()) out_node_data->state |= 1 << ui::AX_STATE_FOCUSABLE; if (!view_->visible()) out_node_data->state |= 1 << ui::AX_STATE_INVISIBLE;
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc index ee16fd9..136424b6 100644 --- a/ui/views/mus/mus_client.cc +++ b/ui/views/mus/mus_client.cc
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/threading/thread.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/cpp/gpu/gpu.h" #include "services/ui/public/cpp/property_type_converters.h"
diff --git a/ui/views/mus/screen_mus.cc b/ui/views/mus/screen_mus.cc index a8790496..8618d1b 100644 --- a/ui/views/mus/screen_mus.cc +++ b/ui/views/mus/screen_mus.cc
@@ -8,7 +8,6 @@ #include "ui/views/mus/screen_mus.h" -#include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/interfaces/constants.mojom.h" #include "ui/aura/env.h"
diff --git a/ui/views/mus/views_mus_test_suite.cc b/ui/views/mus/views_mus_test_suite.cc index 8483a258..1773510 100644 --- a/ui/views/mus/views_mus_test_suite.cc +++ b/ui/views/mus/views_mus_test_suite.cc
@@ -205,7 +205,7 @@ // ui/views/mus requires a WindowManager running, so launch test_wm. service_manager::Connector* connector = context_->connector(); - connector->Connect("test_wm"); + connector->StartService("test_wm"); service_manager_connector_ = connector->Clone(); service_manager_identity_ = context_->identity(); wait->Signal();
diff --git a/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/ui/views/widget/desktop_aura/x11_desktop_handler.cc index 0e9dec7..4d9ba57 100644 --- a/ui/views/widget/desktop_aura/x11_desktop_handler.cc +++ b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
@@ -40,6 +40,11 @@ return g_handler; } +// static +X11DesktopHandler* X11DesktopHandler::get_dont_create() { + return g_handler; +} + X11DesktopHandler::X11DesktopHandler() : xdisplay_(gfx::GetXDisplay()), x_root_window_(DefaultRootWindow(xdisplay_)),
diff --git a/ui/views/widget/desktop_aura/x11_desktop_handler.h b/ui/views/widget/desktop_aura/x11_desktop_handler.h index 06d78ba8..00484b2 100644 --- a/ui/views/widget/desktop_aura/x11_desktop_handler.h +++ b/ui/views/widget/desktop_aura/x11_desktop_handler.h
@@ -38,9 +38,14 @@ class VIEWS_EXPORT X11DesktopHandler : public ui::PlatformEventDispatcher, public aura::EnvObserver { public: - // Returns the singleton handler. + // Returns the singleton handler. Creates one if one has not + // already been created. static X11DesktopHandler* get(); + // Returns the singleton handler, or nullptr if one has not already + // been created. + static X11DesktopHandler* get_dont_create(); + // Adds/removes X11DesktopHandlerObservers. void AddObserver(X11DesktopHandlerObserver* observer); void RemoveObserver(X11DesktopHandlerObserver* observer);
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 8d690aac..7590741f 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -1749,12 +1749,11 @@ default: NOTREACHED(); } - ui::MouseEvent event(event_type, point, point, base::TimeTicks::Now(), flag, - flag); ui::PointerDetails pointer_details( input_type, pointer_id, /* radius_x */ 0.0f, /* radius_y */ 0.0f, pressure, tilt_x, tilt_y, /* tangential_pressure */ 0.0f, rotation); - event.set_pointer_details(pointer_details); + ui::MouseEvent event(event_type, point, point, base::TimeTicks::Now(), flag, + flag, pointer_details); event.SetClickCount(click_count); // There are cases where the code handling the message destroys the