diff --git a/DEPS b/DEPS index cc5f825..776f9a86 100644 --- a/DEPS +++ b/DEPS
@@ -48,7 +48,7 @@ # 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. - 'swarming_revision': 'a941a089ff1000403078b74cb628eb430f07d271', + 'swarming_revision': '5c4eed8883548ba78c886ef26986b81b1be723a4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # 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': '1bbcb35e4e5593998837c832eabf16a91a695387', + 'pdfium_revision': 'fb9c11b49ee4fe6c18703d661dcaee498085c4c5', # 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. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '239f08ec63f401050f448ae3ca4cba48606682cf', + 'catapult_revision': '95d73385835dd1347cacacd1e25efa48938ee90a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 1641768..1d7c3e6a 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1172,6 +1172,8 @@ "laser/laser_pointer_points_unittest.cc", "laser/laser_segment_utils_unittest.cc", "login/lock_screen_controller_unittest.cc", + "login/mock_lock_screen_client.cc", + "login/mock_lock_screen_client.h", "metrics/desktop_task_switch_metric_recorder_unittest.cc", "metrics/pointer_metrics_recorder_unittest.cc", "metrics/task_switch_metrics_recorder_unittest.cc",
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 0e592a0..9ca596b 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -45,7 +45,6 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" -#include "ash/wm_window.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/strings/string_split.h" @@ -424,10 +423,10 @@ } bool CanHandleWindowSnap() { - WmWindow* active_window = WmWindow::Get(wm::GetActiveWindow()); + aura::Window* active_window = wm::GetActiveWindow(); if (!active_window) return false; - wm::WindowState* window_state = active_window->GetWindowState(); + wm::WindowState* window_state = wm::GetWindowState(active_window); // Disable window snapping shortcut key for full screen window due to // http://crbug.com/135487. return (window_state && window_state->IsUserPositionable() && @@ -443,9 +442,9 @@ const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_LEFT ? wm::WM_EVENT_CYCLE_SNAP_LEFT : wm::WM_EVENT_CYCLE_SNAP_RIGHT); - WmWindow* active_window = WmWindow::Get(wm::GetActiveWindow()); + aura::Window* active_window = wm::GetActiveWindow(); DCHECK(active_window); - active_window->GetWindowState()->OnWMEvent(&event); + wm::GetWindowState(active_window)->OnWMEvent(&event); } void HandleWindowMinimize() {
diff --git a/ash/accelerators/accelerator_delegate.cc b/ash/accelerators/accelerator_delegate.cc index d2c252fb..762ed102 100644 --- a/ash/accelerators/accelerator_delegate.cc +++ b/ash/accelerators/accelerator_delegate.cc
@@ -5,7 +5,6 @@ #include "ash/accelerators/accelerator_delegate.h" #include "ash/accelerators/accelerator_router.h" -#include "ash/wm_window.h" #include "ui/aura/window.h" #include "ui/events/event.h" @@ -19,8 +18,7 @@ const ui::KeyEvent& key_event, const ui::Accelerator& accelerator) { return router_->ProcessAccelerator( - WmWindow::Get(static_cast<aura::Window*>(key_event.target())), key_event, - accelerator); + static_cast<aura::Window*>(key_event.target()), key_event, accelerator); } } // namespace ash
diff --git a/ash/accelerators/accelerator_router.cc b/ash/accelerators/accelerator_router.cc index 553bd24..20e67d7 100644 --- a/ash/accelerators/accelerator_router.cc +++ b/ash/accelerators/accelerator_router.cc
@@ -8,11 +8,12 @@ #include "ash/shell.h" #include "ash/shell_port.h" #include "ash/wm/window_state.h" -#include "ash/wm_window.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" +#include "ui/aura/window.h" #include "ui/base/accelerators/accelerator.h" #include "ui/events/event.h" +#include "ui/wm/core/window_util.h" namespace ash { @@ -43,7 +44,7 @@ AcceleratorRouter::~AcceleratorRouter() {} -bool AcceleratorRouter::ProcessAccelerator(WmWindow* target, +bool AcceleratorRouter::ProcessAccelerator(aura::Window* target, const ui::KeyEvent& key_event, const ui::Accelerator& accelerator) { // Callers should never supply null. @@ -85,16 +86,16 @@ } } -bool AcceleratorRouter::CanConsumeSystemKeys(WmWindow* target, +bool AcceleratorRouter::CanConsumeSystemKeys(aura::Window* target, const ui::KeyEvent& event) { // Uses the top level window so if the target is a web contents window the // containing parent window will be checked for the property. - WmWindow* top_level = target->GetToplevelWindowForFocus(); - return top_level && top_level->GetWindowState()->can_consume_system_keys(); + aura::Window* top_level = ::wm::GetToplevelWindow(target); + return top_level && wm::GetWindowState(top_level)->can_consume_system_keys(); } bool AcceleratorRouter::ShouldProcessAcceleratorNow( - WmWindow* target, + aura::Window* target, const ui::KeyEvent& event, const ui::Accelerator& accelerator) { // Callers should never supply null. @@ -104,7 +105,7 @@ if (accelerator.IsCmdDown()) return true; - if (base::ContainsValue(ShellPort::Get()->GetAllRootWindows(), target)) + if (base::ContainsValue(Shell::GetAllRootWindows(), target)) return true; AcceleratorController* accelerator_controller = @@ -116,8 +117,8 @@ // A full screen window has a right to handle all key events including the // reserved ones. - WmWindow* top_level = target->GetToplevelWindowForFocus(); - if (top_level && top_level->GetWindowState()->IsFullscreen()) { + aura::Window* top_level = ::wm::GetToplevelWindow(target); + if (top_level && wm::GetWindowState(top_level)->IsFullscreen()) { // On ChromeOS, fullscreen windows are either browser or apps, which // send key events to a web content first, then will process keys // if the web content didn't consume them.
diff --git a/ash/accelerators/accelerator_router.h b/ash/accelerators/accelerator_router.h index a849d5a..9734811c 100644 --- a/ash/accelerators/accelerator_router.h +++ b/ash/accelerators/accelerator_router.h
@@ -9,6 +9,10 @@ #include "base/macros.h" #include "base/time/time.h" +namespace aura { +class Window; +} + namespace ui { class Accelerator; class KeyEvent; @@ -16,8 +20,6 @@ namespace ash { -class WmWindow; - // AcceleratorRouter does a minimal amount of processing before routing the // accelerator to the AcceleratorController. AcceleratorRouter may also decide // not to process certain accelerators. @@ -28,17 +30,17 @@ // Returns true if event should be consumed. |target| is the target of the // event. - bool ProcessAccelerator(WmWindow* target, + bool ProcessAccelerator(aura::Window* target, const ui::KeyEvent& event, const ui::Accelerator& accelerator); private: // Returns true if the window should be allowed a chance to handle // system keys. - bool CanConsumeSystemKeys(WmWindow* target, const ui::KeyEvent& event); + bool CanConsumeSystemKeys(aura::Window* target, const ui::KeyEvent& event); // Returns true if the |accelerator| should be processed now. - bool ShouldProcessAcceleratorNow(WmWindow* target, + bool ShouldProcessAcceleratorNow(aura::Window* target, const ui::KeyEvent& event, const ui::Accelerator& accelerator);
diff --git a/ash/aura/shell_port_classic.cc b/ash/aura/shell_port_classic.cc index e1b66fa..d27eb274 100644 --- a/ash/aura/shell_port_classic.cc +++ b/ash/aura/shell_port_classic.cc
@@ -112,11 +112,11 @@ display::DisplayManager::UNIFIED; } -void ShellPortClassic::SetDisplayWorkAreaInsets(WmWindow* window, +void ShellPortClassic::SetDisplayWorkAreaInsets(aura::Window* window, const gfx::Insets& insets) { Shell::Get() ->window_tree_host_manager() - ->UpdateWorkAreaOfDisplayNearestWindow(window->aura_window(), insets); + ->UpdateWorkAreaOfDisplayNearestWindow(window, insets); } std::unique_ptr<display::TouchTransformSetter> @@ -191,7 +191,7 @@ } std::unique_ptr<WorkspaceEventHandler> -ShellPortClassic::CreateWorkspaceEventHandler(WmWindow* workspace_window) { +ShellPortClassic::CreateWorkspaceEventHandler(aura::Window* workspace_window) { return base::MakeUnique<WorkspaceEventHandlerAura>(workspace_window); }
diff --git a/ash/aura/shell_port_classic.h b/ash/aura/shell_port_classic.h index f2e02a15..2143ee8d 100644 --- a/ash/aura/shell_port_classic.h +++ b/ash/aura/shell_port_classic.h
@@ -43,7 +43,7 @@ display::Display GetFirstDisplay() const override; bool IsInUnifiedMode() const override; bool IsInUnifiedModeIgnoreMirroring() const override; - void SetDisplayWorkAreaInsets(WmWindow* window, + void SetDisplayWorkAreaInsets(aura::Window* window, const gfx::Insets& insets) override; std::unique_ptr<display::TouchTransformSetter> CreateTouchTransformDelegate() override; @@ -65,7 +65,7 @@ std::unique_ptr<wm::TabletModeEventHandler> CreateTabletModeEventHandler() override; std::unique_ptr<WorkspaceEventHandler> CreateWorkspaceEventHandler( - WmWindow* workspace_window) override; + aura::Window* workspace_window) override; std::unique_ptr<ScopedDisableInternalMouseAndKeyboard> CreateScopedDisableInternalMouseAndKeyboard() override; std::unique_ptr<ImmersiveFullscreenController>
diff --git a/ash/login/lock_screen_controller_unittest.cc b/ash/login/lock_screen_controller_unittest.cc index cc3f8d4..3e42c9e 100644 --- a/ash/login/lock_screen_controller_unittest.cc +++ b/ash/login/lock_screen_controller_unittest.cc
@@ -4,58 +4,38 @@ #include "ash/login/lock_screen_controller.h" +#include "ash/login/mock_lock_screen_client.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/run_loop.h" -#include "chromeos/cryptohome/system_salt_getter.h" + +using ::testing::_; namespace ash { namespace { - -class TestLockScreenClient : public mojom::LockScreenClient { - public: - TestLockScreenClient() : binding_(this) {} - ~TestLockScreenClient() override = default; - - mojom::LockScreenClientPtr CreateInterfacePtrAndBind() { - return binding_.CreateInterfacePtrAndBind(); - } - - // mojom::LockScreenClient: - void AuthenticateUser(const AccountId& account_id, - const std::string& password, - bool authenticated_by_pin) override { - ++autentication_requests_count_; - } - - int authentication_requests_count() const { - return autentication_requests_count_; - } - - private: - mojo::Binding<ash::mojom::LockScreenClient> binding_; - int autentication_requests_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(TestLockScreenClient); -}; - using LockScreenControllerTest = test::AshTestBase; - } // namespace TEST_F(LockScreenControllerTest, RequestAuthentication) { - LockScreenController* lock_screen_controller = - Shell::Get()->lock_screen_controller(); - TestLockScreenClient lock_screen_client; - lock_screen_controller->SetClient( - lock_screen_client.CreateInterfacePtrAndBind()); - EXPECT_EQ(0, lock_screen_client.authentication_requests_count()); + LockScreenController* controller = Shell::Get()->lock_screen_controller(); + std::unique_ptr<MockLockScreenClient> client = BindMockLockScreenClient(); AccountId id = AccountId::FromUserEmail("user1@test.com"); - lock_screen_controller->AuthenticateUser(id, std::string(), false); + + // We hardcode the hashed password. This is fine because the password hash + // algorithm should never accidently change; if it does we will need to + // have cryptohome migration code and one failing test isn't a problem. + std::string password = "password"; + std::string hashed_password = "40c7b00f3bccc7675ec5b732de4bfbe4"; + EXPECT_NE(password, hashed_password); + + // Verify AuthenticateUser mojo call is run with the same account id, a + // (hashed) password, and the correct PIN state. + EXPECT_CALL(*client, AuthenticateUser(id, hashed_password, false)); + controller->AuthenticateUser(id, password, false); + base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, lock_screen_client.authentication_requests_count()); } } // namespace ash
diff --git a/ash/login/mock_lock_screen_client.cc b/ash/login/mock_lock_screen_client.cc new file mode 100644 index 0000000..364f90c --- /dev/null +++ b/ash/login/mock_lock_screen_client.cc
@@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/login/mock_lock_screen_client.h" + +#include "ash/login/lock_screen_controller.h" +#include "ash/shell.h" + +namespace ash { + +MockLockScreenClient::MockLockScreenClient() : binding_(this) {} + +MockLockScreenClient::~MockLockScreenClient() = default; + +mojom::LockScreenClientPtr MockLockScreenClient::CreateInterfacePtrAndBind() { + return binding_.CreateInterfacePtrAndBind(); +} + +std::unique_ptr<MockLockScreenClient> BindMockLockScreenClient() { + LockScreenController* lock_screen_controller = + Shell::Get()->lock_screen_controller(); + auto lock_screen_client = base::MakeUnique<MockLockScreenClient>(); + lock_screen_controller->SetClient( + lock_screen_client->CreateInterfacePtrAndBind()); + return lock_screen_client; +} + +} // namespace ash
diff --git a/ash/login/mock_lock_screen_client.h b/ash/login/mock_lock_screen_client.h new file mode 100644 index 0000000..52874b35 --- /dev/null +++ b/ash/login/mock_lock_screen_client.h
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_LOGIN_MOCK_LOCK_SCREEN_CLIENT_H_ +#define ASH_LOGIN_MOCK_LOCK_SCREEN_CLIENT_H_ + +#include "ash/public/interfaces/lock_screen.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace ash { + +class MockLockScreenClient : public mojom::LockScreenClient { + public: + MockLockScreenClient(); + ~MockLockScreenClient() override; + + mojom::LockScreenClientPtr CreateInterfacePtrAndBind(); + + // mojom::LockScreenClient: + MOCK_METHOD3(AuthenticateUser, + void(const AccountId& account_id, + const std::string& password, + bool authenticated_by_pin)); + + private: + mojo::Binding<ash::mojom::LockScreenClient> binding_; + + DISALLOW_COPY_AND_ASSIGN(MockLockScreenClient); +}; + +// Helper method to bind a lock screen client so it receives all mojo calls. +std::unique_ptr<MockLockScreenClient> BindMockLockScreenClient(); + +} // namespace ash + +#endif // ASH_LOGIN_MOCK_LOCK_SCREEN_CLIENT_H_ \ No newline at end of file
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn index 1409ea7..96714f3ee 100644 --- a/ash/mus/BUILD.gn +++ b/ash/mus/BUILD.gn
@@ -32,6 +32,8 @@ "context_menu_mus.h", "disconnected_app_handler.cc", "disconnected_app_handler.h", + "display_synchronizer.cc", + "display_synchronizer.h", "drag_window_resizer.cc", "drag_window_resizer.h", "frame/detached_title_area_renderer.cc",
diff --git a/ash/mus/accelerators/accelerator_controller_registrar.cc b/ash/mus/accelerators/accelerator_controller_registrar.cc index 6f0c197..bff6040 100644 --- a/ash/mus/accelerators/accelerator_controller_registrar.cc +++ b/ash/mus/accelerators/accelerator_controller_registrar.cc
@@ -14,7 +14,6 @@ #include "ash/shell.h" #include "ash/wm/window_cycle_controller.h" #include "ash/wm/window_util.h" -#include "ash/wm_window.h" #include "base/logging.h" #include "services/ui/common/accelerator_util.h" #include "services/ui/public/cpp/property_type_converters.h" @@ -96,8 +95,8 @@ if (!target_window) target_window = Shell::GetRootWindowForNewWindows(); DCHECK(target_window); - if (router_->ProcessAccelerator(WmWindow::Get(target_window), - *(event.AsKeyEvent()), accelerator)) { + if (router_->ProcessAccelerator(target_window, *(event.AsKeyEvent()), + accelerator)) { return ui::mojom::EventResult::HANDLED; } if (accelerator_controller->IsActionForAcceleratorEnabled(accelerator)) {
diff --git a/ash/mus/bridge/shell_port_mash.cc b/ash/mus/bridge/shell_port_mash.cc index 61c9646..cdca83b5 100644 --- a/ash/mus/bridge/shell_port_mash.cc +++ b/ash/mus/bridge/shell_port_mash.cc
@@ -20,6 +20,7 @@ #include "ash/mus/ash_window_tree_host_mus.h" #include "ash/mus/bridge/immersive_handler_factory_mus.h" #include "ash/mus/bridge/workspace_event_handler_mus.h" +#include "ash/mus/display_synchronizer.h" #include "ash/mus/drag_window_resizer.h" #include "ash/mus/keyboard_ui_mus.h" #include "ash/mus/screen_mus.h" @@ -161,6 +162,8 @@ } void ShellPortMash::Shutdown() { + display_synchronizer_.reset(); + if (added_display_observer_) Shell::Get()->window_tree_host_manager()->RemoveObserver(this); @@ -258,15 +261,15 @@ return false; } -void ShellPortMash::SetDisplayWorkAreaInsets(WmWindow* window, +void ShellPortMash::SetDisplayWorkAreaInsets(aura::Window* window, const gfx::Insets& insets) { if (GetAshConfig() == Config::MUS) { Shell::Get() ->window_tree_host_manager() - ->UpdateWorkAreaOfDisplayNearestWindow(window->aura_window(), insets); + ->UpdateWorkAreaOfDisplayNearestWindow(window, insets); return; } - window_manager_->screen()->SetWorkAreaInsets(window->aura_window(), insets); + window_manager_->screen()->SetWorkAreaInsets(window, insets); } std::unique_ptr<display::TouchTransformSetter> @@ -398,12 +401,11 @@ } std::unique_ptr<WorkspaceEventHandler> -ShellPortMash::CreateWorkspaceEventHandler(WmWindow* workspace_window) { +ShellPortMash::CreateWorkspaceEventHandler(aura::Window* workspace_window) { if (GetAshConfig() == Config::MUS) return base::MakeUnique<WorkspaceEventHandlerAura>(workspace_window); - return base::MakeUnique<WorkspaceEventHandlerMus>( - WmWindow::GetAuraWindow(workspace_window)); + return base::MakeUnique<WorkspaceEventHandlerMus>(workspace_window); } std::unique_ptr<ImmersiveFullscreenController> @@ -525,8 +527,7 @@ std::unique_ptr<AshWindowTreeHost> ShellPortMash::CreateAshWindowTreeHost( const AshWindowTreeHostInitParams& init_params) { - // TODO(sky): make this work for mash too. - if (GetAshConfig() != Config::MUS) + if (!Shell::ShouldEnableSimplifiedDisplayManagement()) return nullptr; std::unique_ptr<aura::DisplayInitParams> display_params = @@ -544,7 +545,6 @@ display_params->display = base::MakeUnique<display::Display>(mirrored_display); } - // TODO: wire update is_primary_display correctly. display_params->is_primary_display = true; aura::WindowTreeHostMusInitParams aura_init_params = window_manager_->window_manager_client()->CreateInitParamsForNewDisplay(); @@ -576,8 +576,10 @@ } void ShellPortMash::InitHosts(const ShellInitParams& init_params) { - if (GetAshConfig() == Config::MUS) { + if (Shell::ShouldEnableSimplifiedDisplayManagement()) { Shell::Get()->window_tree_host_manager()->InitHosts(); + display_synchronizer_ = base::MakeUnique<DisplaySynchronizer>( + window_manager_->window_manager_client()); } else { window_manager_->CreatePrimaryRootWindowController( base::WrapUnique(init_params.primary_window_tree_host));
diff --git a/ash/mus/bridge/shell_port_mash.h b/ash/mus/bridge/shell_port_mash.h index 2624227..be47cb2 100644 --- a/ash/mus/bridge/shell_port_mash.h +++ b/ash/mus/bridge/shell_port_mash.h
@@ -25,6 +25,7 @@ namespace ash { class AcceleratorControllerDelegateAura; +class DisplaySynchronizer; class PointerWatcherAdapter; class RootWindowController; @@ -70,7 +71,7 @@ display::Display GetFirstDisplay() const override; bool IsInUnifiedMode() const override; bool IsInUnifiedModeIgnoreMirroring() const override; - void SetDisplayWorkAreaInsets(WmWindow* window, + void SetDisplayWorkAreaInsets(aura::Window* window, const gfx::Insets& insets) override; std::unique_ptr<display::TouchTransformSetter> CreateTouchTransformDelegate() override; @@ -92,7 +93,7 @@ std::unique_ptr<wm::TabletModeEventHandler> CreateTabletModeEventHandler() override; std::unique_ptr<WorkspaceEventHandler> CreateWorkspaceEventHandler( - WmWindow* workspace_window) override; + aura::Window* workspace_window) override; std::unique_ptr<ScopedDisableInternalMouseAndKeyboard> CreateScopedDisableInternalMouseAndKeyboard() override; std::unique_ptr<ImmersiveFullscreenController> @@ -160,6 +161,8 @@ std::unique_ptr<SessionStateDelegate> session_state_delegate_; + std::unique_ptr<DisplaySynchronizer> display_synchronizer_; + bool added_display_observer_ = false; base::ObserverList<WmDisplayObserver> display_observers_;
diff --git a/ash/mus/display_synchronizer.cc b/ash/mus/display_synchronizer.cc new file mode 100644 index 0000000..f948e2f --- /dev/null +++ b/ash/mus/display_synchronizer.cc
@@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/mus/display_synchronizer.h" + +#include "ash/shell.h" +#include "ui/aura/mus/window_manager_delegate.h" +#include "ui/display/manager/display_manager.h" +#include "ui/display/manager/managed_display_info.h" + +namespace ash { + +DisplaySynchronizer::DisplaySynchronizer( + aura::WindowManagerClient* window_manager_client) + : window_manager_client_(window_manager_client) { + Shell::Get()->window_tree_host_manager()->AddObserver(this); + SendDisplayConfigurationToServer(); +} + +DisplaySynchronizer::~DisplaySynchronizer() { + Shell::Get()->window_tree_host_manager()->RemoveObserver(this); +} + +void DisplaySynchronizer::SendDisplayConfigurationToServer() { + display::DisplayManager* display_manager = Shell::Get()->display_manager(); + const size_t display_count = display_manager->GetNumDisplays(); + if (display_count == 0) + return; + + std::vector<display::Display> displays; + std::vector<ui::mojom::WmViewportMetricsPtr> metrics; + for (size_t i = 0; i < display_count; ++i) { + displays.push_back(display_manager->GetDisplayAt(i)); + ui::mojom::WmViewportMetricsPtr viewport_metrics = + ui::mojom::WmViewportMetrics::New(); + const display::ManagedDisplayInfo& display_info = + display_manager->GetDisplayInfo(displays.back().id()); + viewport_metrics->bounds_in_pixels = display_info.bounds_in_native(); + viewport_metrics->device_scale_factor = display_info.device_scale_factor(); + viewport_metrics->ui_scale_factor = display_info.configured_ui_scale(); + metrics.push_back(std::move(viewport_metrics)); + } + window_manager_client_->SetDisplayConfiguration( + displays, std::move(metrics), + WindowTreeHostManager::GetPrimaryDisplayId()); +} + +void DisplaySynchronizer::OnDisplaysInitialized() { + SendDisplayConfigurationToServer(); +} + +void DisplaySynchronizer::OnDisplayConfigurationChanged() { + SendDisplayConfigurationToServer(); +} + +} // namespace ash
diff --git a/ash/mus/display_synchronizer.h b/ash/mus/display_synchronizer.h new file mode 100644 index 0000000..791fffe3 --- /dev/null +++ b/ash/mus/display_synchronizer.h
@@ -0,0 +1,40 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_MUS_DISPLAY_SYNCHRONIZER_H_ +#define ASH_MUS_DISPLAY_SYNCHRONIZER_H_ + +#include "ash/display/window_tree_host_manager.h" +#include "base/macros.h" + +namespace aura { +class WindowManagerClient; +} + +namespace ash { + +// DisplaySynchronizer keeps the display state in mus in sync with ash's display +// state. As ash controls the overall display state this synchronization is one +// way (from ash to mus). +class DisplaySynchronizer : public ash::WindowTreeHostManager::Observer { + public: + explicit DisplaySynchronizer( + aura::WindowManagerClient* window_manager_client); + ~DisplaySynchronizer() override; + + private: + void SendDisplayConfigurationToServer(); + + // WindowTreeHostManager::Observer: + void OnDisplaysInitialized() override; + void OnDisplayConfigurationChanged() override; + + aura::WindowManagerClient* window_manager_client_; + + DISALLOW_COPY_AND_ASSIGN(DisplaySynchronizer); +}; + +} // namespace ash + +#endif // ASH_MUS_DISPLAY_SYNCHRONIZER_H_
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc index 9a4fb29..b068bc9 100644 --- a/ash/mus/shell_delegate_mus.cc +++ b/ash/mus/shell_delegate_mus.cc
@@ -71,7 +71,7 @@ return false; } -bool ShellDelegateMus::CanShowWindowForUser(WmWindow* window) const { +bool ShellDelegateMus::CanShowWindowForUser(aura::Window* window) const { NOTIMPLEMENTED(); return true; }
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h index c5cadea..514db36 100644 --- a/ash/mus/shell_delegate_mus.h +++ b/ash/mus/shell_delegate_mus.h
@@ -26,7 +26,7 @@ bool IsIncognitoAllowed() const override; bool IsMultiProfilesEnabled() const override; bool IsRunningInForcedAppMode() const override; - bool CanShowWindowForUser(WmWindow* window) const override; + bool CanShowWindowForUser(aura::Window* window) const override; bool IsForceMaximizeOnFirstRun() const override; void PreInit() override; void PreShutdown() override;
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index b9ea19f..08d115ca 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -126,30 +126,22 @@ DCHECK_EQ(nullptr, ash::Shell::window_tree_client()); ash::Shell::set_window_tree_client(window_tree_client_.get()); - // TODO(sky): remove and use MUS code. + // TODO(sky): remove and use MUS code. This should really be + // ShouldEnableSimplifiedDisplayManagement(), but as ShellPort hasn't been + // created yet it can't be used here. if (config_ == Config::MASH) { // |connector_| is null in some tests. if (connector_) connector_->BindInterface(ui::mojom::kServiceName, &display_controller_); screen_ = base::MakeUnique<ScreenMus>(display_controller_.get()); display::Screen::SetScreenInstance(screen_.get()); + InstallFrameDecorationValues(); } pointer_watcher_event_router_ = base::MakeUnique<views::PointerWatcherEventRouter>( window_tree_client_.get()); - ui::mojom::FrameDecorationValuesPtr frame_decoration_values = - ui::mojom::FrameDecorationValues::New(); - const gfx::Insets client_area_insets = - NonClientFrameController::GetPreferredClientAreaInsets(); - frame_decoration_values->normal_client_area_insets = client_area_insets; - frame_decoration_values->maximized_client_area_insets = client_area_insets; - frame_decoration_values->max_title_bar_button_width = - NonClientFrameController::GetMaxTitleBarButtonWidth(); - window_manager_client_->SetFrameDecorationValues( - std::move(frame_decoration_values)); - // Notify PointerWatcherEventRouter and CaptureSynchronizer that the capture // client has been set. aura::client::CaptureClient* capture_client = wm_state_->capture_controller(); @@ -261,6 +253,19 @@ root_window_controllers_.insert(std::move(root_window_controller)); } +void WindowManager::InstallFrameDecorationValues() { + ui::mojom::FrameDecorationValuesPtr frame_decoration_values = + ui::mojom::FrameDecorationValues::New(); + const gfx::Insets client_area_insets = + NonClientFrameController::GetPreferredClientAreaInsets(); + frame_decoration_values->normal_client_area_insets = client_area_insets; + frame_decoration_values->maximized_client_area_insets = client_area_insets; + frame_decoration_values->max_title_bar_button_width = + NonClientFrameController::GetMaxTitleBarButtonWidth(); + window_manager_client_->SetFrameDecorationValues( + std::move(frame_decoration_values)); +} + void WindowManager::DestroyRootWindowController( RootWindowController* root_window_controller, bool in_shutdown) { @@ -341,6 +346,7 @@ CreateShell(nullptr); if (show_primary_host_on_connect_) Shell::GetPrimaryRootWindow()->GetHost()->Show(); + InstallFrameDecorationValues(); } void WindowManager::OnWmSetBounds(aura::Window* window,
diff --git a/ash/mus/window_manager.h b/ash/mus/window_manager.h index daf1592..35a7f89b 100644 --- a/ash/mus/window_manager.h +++ b/ash/mus/window_manager.h
@@ -138,6 +138,9 @@ const display::Display& display, ash::RootWindowController::RootWindowType root_window_type); + // Sets the frame decoration values on the server. + void InstallFrameDecorationValues(); + // Deletes the specified RootWindowController. Called when a display is // removed. |in_shutdown| is true if called from Shutdown(). void DestroyRootWindowController(RootWindowController* root_window_controller,
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index c9bfdf3..70450454 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -25,7 +25,6 @@ #include "ash/wm/mru_window_tracker.h" #include "ash/wm/screen_pinning_controller.h" #include "ash/wm/window_state.h" -#include "ash/wm_window.h" #include "base/auto_reset.h" #include "base/command_line.h" #include "base/i18n/rtl.h" @@ -452,8 +451,8 @@ // window. if (Shell::Get()->session_controller()->IsUserSessionBlocked() && keyboard_is_about_to_hide) { - WmWindow* window = WmWindow::Get(shelf_widget_->GetNativeWindow()); - ShellPort::Get()->SetDisplayWorkAreaInsets(window, gfx::Insets()); + ShellPort::Get()->SetDisplayWorkAreaInsets(shelf_widget_->GetNativeWindow(), + gfx::Insets()); } } @@ -642,8 +641,8 @@ // if keyboard is not shown. if (!state_.IsAddingSecondaryUser() || !keyboard_bounds_.IsEmpty()) insets = target_bounds.work_area_insets; - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow()); - ShellPort::Get()->SetDisplayWorkAreaInsets(shelf_window, insets); + ShellPort::Get()->SetDisplayWorkAreaInsets( + shelf_widget_->GetNativeWindow(), insets); } }
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc index abddb3d2..6176fede 100644 --- a/ash/shelf/shelf_tooltip_manager.cc +++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -10,7 +10,7 @@ #include "ash/shelf/shelf_view.h" #include "ash/shell_port.h" #include "ash/system/tray/tray_constants.h" -#include "ash/wm_window.h" +#include "ash/wm/window_util.h" #include "base/bind.h" #include "base/strings/string16.h" #include "base/threading/thread_task_runner_handle.h" @@ -23,6 +23,7 @@ #include "ui/views/controls/label.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/widget/widget.h" +#include "ui/wm/core/window_animations.h" namespace ash { namespace { @@ -108,8 +109,7 @@ void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, views::Widget* bubble_widget) const override { // Place the bubble in the same display as the anchor. - WmWindow::Get(anchor_widget()->GetNativeWindow()) - ->GetRootWindowController() + RootWindowController::ForWindow(anchor_widget()->GetNativeWindow()) ->ConfigureWidgetInitParamsForContainer( bubble_widget, kShellWindowId_SettingBubbleContainer, params); } @@ -132,16 +132,16 @@ ShelfTooltipManager::~ShelfTooltipManager() { ShellPort::Get()->RemovePointerWatcher(this); shelf_view_->shelf()->RemoveObserver(this); - WmWindow* window = nullptr; + aura::Window* window = nullptr; if (shelf_view_->GetWidget()) - window = WmWindow::Get(shelf_view_->GetWidget()->GetNativeWindow()); + window = shelf_view_->GetWidget()->GetNativeWindow(); if (window) - window->RemoveLimitedPreTargetHandler(this); + wm::RemoveLimitedPreTargetHandlerForWindow(this, window); } void ShelfTooltipManager::Init() { - WmWindow* window = WmWindow::Get(shelf_view_->GetWidget()->GetNativeWindow()); - window->AddLimitedPreTargetHandler(this); + wm::AddLimitedPreTargetHandlerForWindow( + this, shelf_view_->GetWidget()->GetNativeWindow()); } void ShelfTooltipManager::Close() { @@ -163,8 +163,8 @@ timer_.Stop(); if (bubble_) { // Cancel the hiding animation to hide the old bubble immediately. - WmWindow::Get(bubble_->GetWidget()->GetNativeWindow()) - ->SetVisibilityAnimationTransition(::wm::ANIMATE_NONE); + ::wm::SetWindowVisibilityAnimationTransition( + bubble_->GetWidget()->GetNativeWindow(), ::wm::ANIMATE_NONE); Close(); } @@ -187,10 +187,10 @@ base::string16 text = shelf_view_->GetTitleForView(view); bubble_ = new ShelfTooltipBubble(view, arrow, text); - WmWindow* window = WmWindow::Get(bubble_->GetWidget()->GetNativeWindow()); - window->SetVisibilityAnimationType( - ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); - window->SetVisibilityAnimationTransition(::wm::ANIMATE_HIDE); + aura::Window* window = bubble_->GetWidget()->GetNativeWindow(); + ::wm::SetWindowVisibilityAnimationType( + window, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); + ::wm::SetWindowVisibilityAnimationTransition(window, ::wm::ANIMATE_HIDE); bubble_->GetWidget()->Show(); }
diff --git a/ash/shelf/shelf_window_watcher.cc b/ash/shelf/shelf_window_watcher.cc index ec2fde2..c1112f4 100644 --- a/ash/shelf/shelf_window_watcher.cc +++ b/ash/shelf/shelf_window_watcher.cc
@@ -197,9 +197,9 @@ item.id.launch_id = base::IntToString(id++); } - model_->SetShelfItemDelegate(item.id, - base::MakeUnique<ShelfWindowWatcherItemDelegate>( - item.id, WmWindow::Get(window))); + model_->SetShelfItemDelegate( + item.id, + base::MakeUnique<ShelfWindowWatcherItemDelegate>(item.id, window)); // Panels are inserted on the left so as not to push all existing panels over. model_->AddAt(item.type == TYPE_APP_PANEL ? 0 : model_->item_count(), item); }
diff --git a/ash/shelf/shelf_window_watcher_item_delegate.cc b/ash/shelf/shelf_window_watcher_item_delegate.cc index 001b25f..c10440b 100644 --- a/ash/shelf/shelf_window_watcher_item_delegate.cc +++ b/ash/shelf/shelf_window_watcher_item_delegate.cc
@@ -12,9 +12,10 @@ #include "ash/shell.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "ash/wm_window.h" +#include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/events/event_constants.h" +#include "ui/wm/core/window_animations.h" namespace ash { @@ -30,7 +31,7 @@ ShelfWindowWatcherItemDelegate::ShelfWindowWatcherItemDelegate( const ShelfID& id, - WmWindow* window) + aura::Window* window) : ShelfItemDelegate(id), window_(window) { DCHECK(!id.IsNull()); DCHECK(window_); @@ -45,24 +46,24 @@ ItemSelectedCallback callback) { // Move panels attached on another display to the current display. if (GetShelfItemType(shelf_id()) == TYPE_APP_PANEL && - window_->aura_window()->GetProperty(kPanelAttachedKey) && - wm::MoveWindowToDisplay(window_->aura_window(), display_id)) { - window_->Activate(); + window_->GetProperty(kPanelAttachedKey) && + wm::MoveWindowToDisplay(window_, display_id)) { + wm::ActivateWindow(window_); std::move(callback).Run(SHELF_ACTION_WINDOW_ACTIVATED, base::nullopt); return; } - if (window_->IsActive()) { + if (wm::IsActiveWindow(window_)) { if (event && event->type() == ui::ET_KEY_RELEASED) { - window_->Animate(::wm::WINDOW_ANIMATION_TYPE_BOUNCE); + ::wm::AnimateWindow(window_, ::wm::WINDOW_ANIMATION_TYPE_BOUNCE); std::move(callback).Run(SHELF_ACTION_NONE, base::nullopt); return; } - window_->Minimize(); + window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); std::move(callback).Run(SHELF_ACTION_WINDOW_MINIMIZED, base::nullopt); return; } - window_->Activate(); + wm::ActivateWindow(window_); std::move(callback).Run(SHELF_ACTION_WINDOW_ACTIVATED, base::nullopt); } @@ -70,7 +71,7 @@ int32_t event_flags) {} void ShelfWindowWatcherItemDelegate::Close() { - window_->CloseWidget(); + wm::CloseWidgetForWindow(window_); } } // namespace ash
diff --git a/ash/shelf/shelf_window_watcher_item_delegate.h b/ash/shelf/shelf_window_watcher_item_delegate.h index 64e8af5..00bbd6a 100644 --- a/ash/shelf/shelf_window_watcher_item_delegate.h +++ b/ash/shelf/shelf_window_watcher_item_delegate.h
@@ -8,15 +8,17 @@ #include "ash/public/cpp/shelf_item_delegate.h" #include "base/macros.h" -namespace ash { +namespace aura { +class Window; +} -class WmWindow; +namespace ash { // ShelfItemDelegate for the items created by ShelfWindowWatcher, for example: // The Chrome OS settings window, task manager window, and panel windows. class ShelfWindowWatcherItemDelegate : public ShelfItemDelegate { public: - ShelfWindowWatcherItemDelegate(const ShelfID& id, WmWindow* window); + ShelfWindowWatcherItemDelegate(const ShelfID& id, aura::Window* window); ~ShelfWindowWatcherItemDelegate() override; private: @@ -29,7 +31,7 @@ void Close() override; // The window associated with this item. Not owned. - WmWindow* window_; + aura::Window* window_; DISALLOW_COPY_AND_ASSIGN(ShelfWindowWatcherItemDelegate); };
diff --git a/ash/shell.cc b/ash/shell.cc index 338f3d47c9..3ddcef2 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -339,7 +339,7 @@ void Shell::SetDisplayWorkAreaInsets(Window* contains, const gfx::Insets& insets) { - shell_port_->SetDisplayWorkAreaInsets(WmWindow::Get(contains), insets); + shell_port_->SetDisplayWorkAreaInsets(contains, insets); } void Shell::OnCastingSessionStartedOrStopped(bool started) {
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 1a4a4eb..e9112ba 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -102,7 +102,7 @@ return false; } -bool ShellDelegateImpl::CanShowWindowForUser(WmWindow* window) const { +bool ShellDelegateImpl::CanShowWindowForUser(aura::Window* window) const { return true; }
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h index dbc15971..f768cea 100644 --- a/ash/shell/shell_delegate_impl.h +++ b/ash/shell/shell_delegate_impl.h
@@ -28,7 +28,7 @@ bool IsIncognitoAllowed() const override; bool IsMultiProfilesEnabled() const override; bool IsRunningInForcedAppMode() const override; - bool CanShowWindowForUser(WmWindow* window) const override; + bool CanShowWindowForUser(aura::Window* window) const override; bool IsForceMaximizeOnFirstRun() const override; void PreInit() override; void PreShutdown() override;
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index 218e00b..3022a58 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -15,6 +15,10 @@ class GURL; class PrefService; +namespace aura { +class Window; +} + namespace gfx { class Image; } @@ -41,7 +45,6 @@ struct ShelfItem; class SystemTrayDelegate; class WallpaperDelegate; -class WmWindow; // Delegate of the Shell. class ASH_EXPORT ShellDelegate { @@ -64,7 +67,7 @@ // Returns true if |window| can be shown for the delegate's concept of current // user. - virtual bool CanShowWindowForUser(WmWindow* window) const = 0; + virtual bool CanShowWindowForUser(aura::Window* window) const = 0; // Returns true if the first window shown on first run should be // unconditionally maximized, overriding the heuristic that normally chooses
diff --git a/ash/shell_port.h b/ash/shell_port.h index 8f56b7f5..1c3376a 100644 --- a/ash/shell_port.h +++ b/ash/shell_port.h
@@ -112,7 +112,7 @@ bool IsForceMaximizeOnFirstRun(); // Sets work area insets of the display containing |window|, pings observers. - virtual void SetDisplayWorkAreaInsets(WmWindow* window, + virtual void SetDisplayWorkAreaInsets(aura::Window* window, const gfx::Insets& insets) = 0; // Returns true if a system-modal dialog window is currently open. @@ -171,7 +171,7 @@ CreateTabletModeEventHandler() = 0; virtual std::unique_ptr<WorkspaceEventHandler> CreateWorkspaceEventHandler( - WmWindow* workspace_window) = 0; + aura::Window* workspace_window) = 0; virtual std::unique_ptr<ScopedDisableInternalMouseAndKeyboard> CreateScopedDisableInternalMouseAndKeyboard() = 0;
diff --git a/ash/system/bluetooth/tray_bluetooth.cc b/ash/system/bluetooth/tray_bluetooth.cc index cf6a5f9..58cd1aa 100644 --- a/ash/system/bluetooth/tray_bluetooth.cc +++ b/ash/system/bluetooth/tray_bluetooth.cc
@@ -331,26 +331,13 @@ HoverHighlightView* container = AddScrollListItem(icon, device.display_name); if (device.connected) - SetupConnectedItem(container); + SetupConnectedScrollListItem(container); else if (device.connecting) - SetupConnectingItem(container); + SetupConnectingScrollListItem(container); device_map_[container] = device.address; } } - void SetupConnectedItem(HoverHighlightView* container) { - container->SetSubText(l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED)); - TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::CAPTION); - style.set_color_style(TrayPopupItemStyle::ColorStyle::CONNECTED); - style.SetupLabel(container->sub_text_label()); - } - - void SetupConnectingItem(HoverHighlightView* container) { - container->SetSubText(l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING)); - } - // Returns true if the device with |device_id| is found in |device_list|. bool FoundDevice(const std::string& device_id, const BluetoothDeviceList& device_list) { @@ -368,7 +355,7 @@ if (FoundDevice(device_id, paired_not_connected_devices_)) { HoverHighlightView* container = static_cast<HoverHighlightView*>(item_container); - SetupConnectingItem(container); + SetupConnectingScrollListItem(container); scroll_content()->SizeToPreferredSize(); scroller()->Layout(); }
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc index 7c4c3f9..b462bbd 100644 --- a/ash/system/network/network_list.cc +++ b/ash/system/network/network_list.cc
@@ -82,29 +82,6 @@ network->guid(), network->profile_path(), nullptr /* onc_source */); } -// TODO(varkha|mohsen): Consolidate with a similar method in -// BluetoothDetailedView (see https://crbug.com/686924). -void SetupConnectedItem(HoverHighlightView* container, - const base::string16& text, - const gfx::ImageSkia& image) { - container->AddIconAndLabels( - image, text, - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED)); - TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::CAPTION); - style.set_color_style(TrayPopupItemStyle::ColorStyle::CONNECTED); - style.SetupLabel(container->sub_text_label()); -} - -// TODO(varkha|mohsen): Consolidate with a similar method in -// BluetoothDetailedView (see https://crbug.com/686924). -void SetupConnectingItem(HoverHighlightView* container, - const base::string16& text, - const gfx::ImageSkia& image) { - container->AddIconAndLabels( - image, text, - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING)); -} - } // namespace // A header row for sections in network detailed view which contains a title and @@ -612,35 +589,18 @@ return new_guids; } -HoverHighlightView* NetworkListView::CreateViewForNetwork( - const NetworkInfo& info) { - HoverHighlightView* container = new HoverHighlightView(this); - if (info.connected) - SetupConnectedItem(container, info.label, info.image); - else if (info.connecting) - SetupConnectingItem(container, info.label, info.image); - else - container->AddIconAndLabel(info.image, info.label); - container->SetTooltipText(info.tooltip); - views::View* controlled_icon = CreateControlledByExtensionView(info); - if (controlled_icon) - container->AddRightView(controlled_icon); - return container; -} - void NetworkListView::UpdateViewForNetwork(HoverHighlightView* view, const NetworkInfo& info) { - DCHECK(!view->is_populated()); + view->Reset(); + view->AddIconAndLabel(info.image, info.label); if (info.connected) - SetupConnectedItem(view, info.label, info.image); + SetupConnectedScrollListItem(view); else if (info.connecting) - SetupConnectingItem(view, info.label, info.image); - else - view->AddIconAndLabel(info.image, info.label); - views::View* controlled_icon = CreateControlledByExtensionView(info); + SetupConnectingScrollListItem(view); view->SetTooltipText(info.tooltip); + views::View* controlled_icon = CreateControlledByExtensionView(info); if (controlled_icon) - view->AddChildView(controlled_icon); + view->AddRightView(controlled_icon); } views::View* NetworkListView::CreateControlledByExtensionView( @@ -681,15 +641,12 @@ HoverHighlightView* network_view = nullptr; NetworkGuidMap::const_iterator found = network_guid_map_.find(info->guid); if (found == network_guid_map_.end()) { - network_view = CreateViewForNetwork(*info); + network_view = new HoverHighlightView(this); + UpdateViewForNetwork(network_view, *info); } else { network_view = found->second; - if (NeedUpdateViewForNetwork(*info)) { - network_view->Reset(); + if (NeedUpdateViewForNetwork(*info)) UpdateViewForNetwork(network_view, *info); - network_view->Layout(); - network_view->SchedulePaint(); - } } PlaceViewAtIndex(network_view, index); if (info->disable) @@ -702,6 +659,7 @@ if (view->parent() != scroll_content()) { scroll_content()->AddChildViewAt(view, index); } else { + // No re-order and re-layout is necessary if |view| is already at |index|. if (scroll_content()->child_at(index) == view) return; scroll_content()->ReorderChildView(view, index);
diff --git a/ash/system/network/network_list.h b/ash/system/network/network_list.h index ba6beed..98436f3 100644 --- a/ash/system/network/network_list.h +++ b/ash/system/network/network_list.h
@@ -71,11 +71,7 @@ // being used. TriView* CreateConnectionWarning(); - // Creates and returns a View with the information in |info|. - HoverHighlightView* CreateViewForNetwork(const NetworkInfo& info); - - // Updates |view| with the information in |info|. Note that |view| is - // guaranteed to be a View returned from |CreateViewForNetwork()|. + // Updates |view| with the information in |info|. void UpdateViewForNetwork(HoverHighlightView* view, const NetworkInfo& info); // Creates the view of an extra icon appearing next to the network name
diff --git a/ash/system/network/vpn_list_view.cc b/ash/system/network/vpn_list_view.cc index 5714e65..1a1625e 100644 --- a/ash/system/network/vpn_list_view.cc +++ b/ash/system/network/vpn_list_view.cc
@@ -120,7 +120,7 @@ class VPNListNetworkEntry : public HoverHighlightView, public network_icon::AnimationObserver { public: - VPNListNetworkEntry(ViewClickListener* listener, + VPNListNetworkEntry(VPNListView* vpn_list_view, const chromeos::NetworkState* network); ~VPNListNetworkEntry() override; @@ -132,11 +132,8 @@ private: void UpdateFromNetworkState(const chromeos::NetworkState* network); - void SetupConnectedItem(const base::string16& text, - const gfx::ImageSkia& image); - void SetupConnectingItem(const base::string16& text, - const gfx::ImageSkia& image); + VPNListView* const owner_; const std::string guid_; views::LabelButton* disconnect_button_ = nullptr; @@ -144,9 +141,9 @@ DISALLOW_COPY_AND_ASSIGN(VPNListNetworkEntry); }; -VPNListNetworkEntry::VPNListNetworkEntry(ViewClickListener* listener, +VPNListNetworkEntry::VPNListNetworkEntry(VPNListView* owner, const chromeos::NetworkState* network) - : HoverHighlightView(listener), guid_(network->guid()) { + : HoverHighlightView(owner), owner_(owner), guid_(network->guid()) { UpdateFromNetworkState(network); } @@ -189,46 +186,24 @@ network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST); base::string16 label = network_icon::GetLabelForNetwork( network, network_icon::ICON_TYPE_MENU_LIST); - if (network->IsConnectedState()) - SetupConnectedItem(label, image); - else if (network->IsConnectingState()) - SetupConnectingItem(label, image); - else - AddIconAndLabel(image, label); - + AddIconAndLabel(image, label); if (network->IsConnectedState()) { + owner_->SetupConnectedScrollListItem(this); disconnect_button_ = TrayPopupUtils::CreateTrayPopupButton( this, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_VPN_DISCONNECT)); - tri_view()->AddView(TriView::Container::END, disconnect_button_); - tri_view()->SetContainerVisible(TriView::Container::END, true); + AddRightView(disconnect_button_); tri_view()->SetContainerBorder( TriView::Container::END, - views::CreateEmptyBorder(0, 0, 0, kTrayPopupButtonEndMargin)); + views::CreateEmptyBorder( + 0, kTrayPopupButtonEndMargin - kTrayPopupLabelHorizontalPadding, 0, + kTrayPopupButtonEndMargin)); + } else if (network->IsConnectingState()) { + owner_->SetupConnectingScrollListItem(this); } + Layout(); } -// TODO(varkha|mohsen): Consolidate with a similar method in -// BluetoothDetailedView. See https://crbug.com/686924. -void VPNListNetworkEntry::SetupConnectedItem(const base::string16& text, - const gfx::ImageSkia& image) { - AddIconAndLabels( - image, text, - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED)); - TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::CAPTION); - style.set_color_style(TrayPopupItemStyle::ColorStyle::CONNECTED); - style.SetupLabel(sub_text_label()); -} - -// TODO(varkha|mohsen): Consolidate with a similar method in -// BluetoothDetailedView. See https://crbug.com/686924. -void VPNListNetworkEntry::SetupConnectingItem(const base::string16& text, - const gfx::ImageSkia& image) { - AddIconAndLabels( - image, text, - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING)); -} - } // namespace VPNListView::VPNListView(SystemTrayItem* owner, LoginStatus login)
diff --git a/ash/system/network/vpn_list_view.h b/ash/system/network/vpn_list_view.h index 8b3a2b86..ef52389 100644 --- a/ash/system/network/vpn_list_view.h +++ b/ash/system/network/vpn_list_view.h
@@ -43,6 +43,10 @@ VPNListView(SystemTrayItem* owner, LoginStatus login); ~VPNListView() override; + // Make following functions publicly accessible for VPNListNetworkEntry. + using NetworkStateListDetailedView::SetupConnectedScrollListItem; + using NetworkStateListDetailedView::SetupConnectingScrollListItem; + // NetworkStateListDetailedView: void UpdateNetworkList() override; bool IsNetworkEntry(views::View* view, std::string* guid) const override;
diff --git a/ash/system/tray/tray_details_view.cc b/ash/system/tray/tray_details_view.cc index b0e6690d..f334fc5 100644 --- a/ash/system/tray/tray_details_view.cc +++ b/ash/system/tray/tray_details_view.cc
@@ -338,6 +338,23 @@ return AddScrollListCheckableItem(gfx::kNoneIcon, text, checked); } +void TrayDetailsView::SetupConnectedScrollListItem(HoverHighlightView* view) { + DCHECK(view->is_populated()); + + view->SetSubText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED)); + TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::CAPTION); + style.set_color_style(TrayPopupItemStyle::ColorStyle::CONNECTED); + style.SetupLabel(view->sub_text_label()); +} + +void TrayDetailsView::SetupConnectingScrollListItem(HoverHighlightView* view) { + DCHECK(view->is_populated()); + + view->SetSubText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING)); +} + TriView* TrayDetailsView::AddScrollListSubHeader(const gfx::VectorIcon& icon, int text_id) { TriView* header = TrayPopupUtils::CreateSubHeaderRowView(!icon.is_empty());
diff --git a/ash/system/tray/tray_details_view.h b/ash/system/tray/tray_details_view.h index 1822067..3761ba7 100644 --- a/ash/system/tray/tray_details_view.h +++ b/ash/system/tray/tray_details_view.h
@@ -85,6 +85,12 @@ HoverHighlightView* AddScrollListCheckableItem(const base::string16& text, bool checked); + // Adds connected sub label to the |view| with appropriate style. + void SetupConnectedScrollListItem(HoverHighlightView* view); + + // Adds connecting sub label to the |view| with appropriate style. + void SetupConnectingScrollListItem(HoverHighlightView* view); + // Adds a sticky sub header to |scroll_content_| containing |icon| and a text // represented by |text_id| resource id. TriView* AddScrollListSubHeader(const gfx::VectorIcon& icon, int text_id);
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc index 204b3a3d..329897d4 100644 --- a/ash/test/test_shell_delegate.cc +++ b/ash/test/test_shell_delegate.cc
@@ -79,7 +79,7 @@ return false; } -bool TestShellDelegate::CanShowWindowForUser(WmWindow* window) const { +bool TestShellDelegate::CanShowWindowForUser(aura::Window* window) const { return true; }
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h index ec26985..23cadccbc 100644 --- a/ash/test/test_shell_delegate.h +++ b/ash/test/test_shell_delegate.h
@@ -41,7 +41,7 @@ bool IsIncognitoAllowed() const override; bool IsMultiProfilesEnabled() const override; bool IsRunningInForcedAppMode() const override; - bool CanShowWindowForUser(WmWindow* window) const override; + bool CanShowWindowForUser(aura::Window* window) const override; bool IsForceMaximizeOnFirstRun() const override; void PreInit() override; void PreShutdown() override;
diff --git a/ash/wm/focus_rules.cc b/ash/wm/focus_rules.cc index 519bc0b..b1ca005 100644 --- a/ash/wm/focus_rules.cc +++ b/ash/wm/focus_rules.cc
@@ -8,7 +8,6 @@ #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/wm/window_state.h" -#include "ash/wm_window.h" #include "ui/aura/window.h" namespace ash { @@ -38,8 +37,7 @@ DCHECK(window); // If the |window| doesn't belong to the current active user and also doesn't // show for the current active user, then it should not be activated. - if (!Shell::Get()->shell_delegate()->CanShowWindowForUser( - WmWindow::Get(window))) + if (!Shell::Get()->shell_delegate()->CanShowWindowForUser(window)) return false; if (window->IsVisible())
diff --git a/ash/wm/overview/cleanup_animation_observer_unittest.cc b/ash/wm/overview/cleanup_animation_observer_unittest.cc index 1cfc762..b0542b5c 100644 --- a/ash/wm/overview/cleanup_animation_observer_unittest.cc +++ b/ash/wm/overview/cleanup_animation_observer_unittest.cc
@@ -8,7 +8,7 @@ #include "ash/test/ash_test_base.h" #include "ash/wm/overview/window_selector_delegate.h" -#include "ash/wm_window.h" +#include "ui/aura/window.h" #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/scoped_layer_animation_settings.h" @@ -124,10 +124,10 @@ TestWindowSelectorDelegate delegate; std::unique_ptr<views::Widget> widget( CreateWindowWidget(gfx::Rect(0, 0, 40, 40))); - WmWindow* widget_window = WmWindow::Get(widget->GetNativeWindow()); + aura::Window* widget_window = widget->GetNativeWindow(); { ui::ScopedLayerAnimationSettings animation_settings( - widget_window->GetLayer()->GetAnimator()); + widget_window->layer()->GetAnimator()); animation_settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(1000)); animation_settings.SetPreemptionStrategy( @@ -155,14 +155,14 @@ TestWindowSelectorDelegate delegate; std::unique_ptr<views::Widget> widget( CreateWindowWidget(gfx::Rect(0, 0, 40, 40))); - WmWindow* widget_window = WmWindow::Get(widget->GetNativeWindow()); + aura::Window* widget_window = widget->GetNativeWindow(); { // Normal animations for tests have ZERO_DURATION, make sure we are actually // animating the movement. ui::ScopedAnimationDurationScaleMode animation_scale_mode( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); ui::ScopedLayerAnimationSettings animation_settings( - widget_window->GetLayer()->GetAnimator()); + widget_window->layer()->GetAnimator()); animation_settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(1000)); animation_settings.SetPreemptionStrategy(
diff --git a/ash/wm/overview/scoped_transform_overview_window.cc b/ash/wm/overview/scoped_transform_overview_window.cc index 5186465..933c8b4 100644 --- a/ash/wm/overview/scoped_transform_overview_window.cc +++ b/ash/wm/overview/scoped_transform_overview_window.cc
@@ -13,7 +13,6 @@ #include "ash/wm/window_mirror_view.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "ash/wm_window.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" @@ -434,9 +433,9 @@ } void ScopedTransformOverviewWindow::CloseWidget() { - WmWindow* parent_window = WmWindow::Get(GetTransientRoot(window_)); + aura::Window* parent_window = GetTransientRoot(window_); if (parent_window) - parent_window->CloseWidget(); + wm::CloseWidgetForWindow(parent_window); } // static
diff --git a/ash/wm/overview/window_grid.cc b/ash/wm/overview/window_grid.cc index a8bdebf..e1448593 100644 --- a/ash/wm/overview/window_grid.cc +++ b/ash/wm/overview/window_grid.cc
@@ -22,7 +22,6 @@ #include "ash/wm/overview/window_selector_delegate.h" #include "ash/wm/overview/window_selector_item.h" #include "ash/wm/window_state.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "base/i18n/string_search.h" #include "base/memory/ptr_util.h"
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc index 6ca3edb..78a978d 100644 --- a/ash/wm/overview/window_selector.cc +++ b/ash/wm/overview/window_selector.cc
@@ -27,7 +27,6 @@ #include "ash/wm/switchable_windows.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "ash/wm_window.h" #include "base/auto_reset.h" #include "base/command_line.h" #include "base/metrics/histogram_macros.h"
diff --git a/ash/wm/overview/window_selector_controller.cc b/ash/wm/overview/window_selector_controller.cc index 80efd79..19b12afa 100644 --- a/ash/wm/overview/window_selector_controller.cc +++ b/ash/wm/overview/window_selector_controller.cc
@@ -13,7 +13,6 @@ #include "ash/wm/overview/window_selector.h" #include "ash/wm/screen_pinning_controller.h" #include "ash/wm/window_state.h" -#include "ash/wm_window.h" #include "base/metrics/histogram_macros.h" namespace ash {
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc index 60eadcd..46b9696 100644 --- a/ash/wm/overview/window_selector_item.cc +++ b/ash/wm/overview/window_selector_item.cc
@@ -20,7 +20,6 @@ #include "ash/wm/overview/window_selector.h" #include "ash/wm/overview/window_selector_controller.h" #include "ash/wm/window_state.h" -#include "ash/wm_window.h" #include "base/auto_reset.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h"
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 0bec0e49..c69caf24 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -27,7 +27,6 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "ash/wm/workspace/workspace_window_resizer.h" -#include "ash/wm_window.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/test/user_action_tester.h" @@ -136,10 +135,9 @@ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; widget->Init(params); widget->Show(); - WmWindow* window = WmWindow::Get(widget->GetNativeWindow()); - window->aura_window()->SetProperty(aura::client::kTopViewInset, - kHeaderHeight); - ParentWindowInPrimaryRootWindow(widget->GetNativeWindow()); + aura::Window* window = widget->GetNativeWindow(); + window->SetProperty(aura::client::kTopViewInset, kHeaderHeight); + ParentWindowInPrimaryRootWindow(window); return widget; } @@ -834,9 +832,8 @@ params.parent = window1->parent(); widget->Init(params); widget->Show(); - WmWindow* window = WmWindow::Get(widget->GetNativeWindow()); - window->aura_window()->SetProperty(aura::client::kTopViewInset, - kHeaderHeight); + aura::Window* window = widget->GetNativeWindow(); + window->SetProperty(aura::client::kTopViewInset, kHeaderHeight); ASSERT_EQ(root_windows[1], window1->GetRootWindow());
diff --git a/ash/wm/panels/panel_layout_manager_unittest.cc b/ash/wm/panels/panel_layout_manager_unittest.cc index 25c10fa7..30b2b1b0 100644 --- a/ash/wm/panels/panel_layout_manager_unittest.cc +++ b/ash/wm/panels/panel_layout_manager_unittest.cc
@@ -22,7 +22,6 @@ #include "ash/wm/mru_window_tracker.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/i18n/rtl.h"
diff --git a/ash/wm/tablet_mode/tablet_mode_event_handler.cc b/ash/wm/tablet_mode/tablet_mode_event_handler.cc index 9267e15..73aead1 100644 --- a/ash/wm/tablet_mode/tablet_mode_event_handler.cc +++ b/ash/wm/tablet_mode/tablet_mode_event_handler.cc
@@ -9,7 +9,6 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" -#include "ash/wm_window.h" #include "ui/events/event.h" namespace ash { @@ -38,18 +37,18 @@ } // Find the active window (from the primary screen) to un-fullscreen. - WmWindow* window = WmWindow::Get(GetActiveWindow()); + aura::Window* window = GetActiveWindow(); if (!window) return false; - WindowState* window_state = window->GetWindowState(); + WindowState* window_state = GetWindowState(window); if (!window_state->IsFullscreen() || window_state->in_immersive_fullscreen()) return false; // Test that the touch happened in the top or bottom lines. int y = event.y(); if (y >= kLeaveFullScreenAreaHeightInPixel && - y < (window->GetBounds().height() - kLeaveFullScreenAreaHeightInPixel)) { + y < (window->bounds().height() - kLeaveFullScreenAreaHeightInPixel)) { return false; } @@ -58,7 +57,7 @@ return false; WMEvent toggle_fullscreen(WM_EVENT_TOGGLE_FULLSCREEN); - window->GetWindowState()->OnWMEvent(&toggle_fullscreen); + GetWindowState(window)->OnWMEvent(&toggle_fullscreen); return true; }
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc index 4413dc5..e59ffbb 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc
@@ -24,7 +24,6 @@ #include "ash/wm/window_state_observer.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h"
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.cc b/ash/wm/tablet_mode/tablet_mode_window_state.cc index d3ba65f8..ab0e7bc 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_state.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_state.cc
@@ -15,7 +15,6 @@ #include "ash/wm/window_properties.h" #include "ash/wm/window_state_util.h" #include "ash/wm/wm_event.h" -#include "ash/wm_window.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/compositor/layer.h"
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc index 0ef0d81..6c033a6 100644 --- a/ash/wm/window_util.cc +++ b/ash/wm/window_util.cc
@@ -7,16 +7,21 @@ #include <vector> #include "ash/ash_constants.h" +#include "ash/public/cpp/config.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/shell_port.h" +#include "ash/wm/widget_finder.h" #include "ash/wm/window_properties.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/capture_client.h" #include "ui/aura/client/focus_client.h" +#include "ui/aura/mus/window_manager_delegate.h" +#include "ui/aura/mus/window_port_mus.h" +#include "ui/aura/mus/window_tree_client.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_event_dispatcher.h" @@ -140,5 +145,35 @@ : HTNOWHERE; } +void CloseWidgetForWindow(aura::Window* window) { + if (Shell::GetAshConfig() == Config::MASH && + window->GetProperty(kWidgetCreationTypeKey) == + WidgetCreationType::FOR_CLIENT) { + // NOTE: in the FOR_CLIENT case there is not necessarily a widget associated + // with the window. Mash only creates widgets for top level windows if mash + // renders the non-client frame. + DCHECK(Shell::window_manager_client()); + Shell::window_manager_client()->RequestClose(window); + return; + } + views::Widget* widget = GetInternalWidgetForWindow(window); + DCHECK(widget); + widget->Close(); +} + +void AddLimitedPreTargetHandlerForWindow(ui::EventHandler* handler, + aura::Window* window) { + // In mus AddPreTargetHandler() only works for windows created by this client. + DCHECK(Shell::GetAshConfig() != Config::MASH || + Shell::window_tree_client()->WasCreatedByThisClient( + aura::WindowMus::Get(window))); + window->AddPreTargetHandler(handler); +} + +void RemoveLimitedPreTargetHandlerForWindow(ui::EventHandler* handler, + aura::Window* window) { + window->RemovePreTargetHandler(handler); +} + } // namespace wm } // namespace ash
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h index d1b95504..1697eebc 100644 --- a/ash/wm/window_util.h +++ b/ash/wm/window_util.h
@@ -21,6 +21,7 @@ namespace ui { class Event; +class EventHandler; } namespace ash { @@ -76,6 +77,23 @@ ASH_EXPORT int GetNonClientComponent(aura::Window* window, const gfx::Point& location); +// Requests the |window| to close and destroy itself. This is intended to +// forward to an associated widget. +ASH_EXPORT void CloseWidgetForWindow(aura::Window* window); + +// Adds or removes a handler to receive events targeted at this window, before +// this window handles the events itself; the handler does not receive events +// from embedded windows. This only supports windows with internal widgets; +// see ash::GetInternalWidgetForWindow(). Ownership of the handler is not +// transferred. +// +// Also note that the target of these events is always an aura::Window. +ASH_EXPORT void AddLimitedPreTargetHandlerForWindow(ui::EventHandler* handler, + aura::Window* window); +ASH_EXPORT void RemoveLimitedPreTargetHandlerForWindow( + ui::EventHandler* handler, + aura::Window* window); + } // namespace wm } // namespace ash
diff --git a/ash/wm/workspace/backdrop_controller.cc b/ash/wm/workspace/backdrop_controller.cc index b423977..b73113f0 100644 --- a/ash/wm/workspace/backdrop_controller.cc +++ b/ash/wm/workspace/backdrop_controller.cc
@@ -12,7 +12,6 @@ #include "ash/system/tray/system_tray_notifier.h" #include "ash/wm/window_util.h" #include "ash/wm/workspace/backdrop_delegate.h" -#include "ash/wm_window.h" #include "base/auto_reset.h" #include "chromeos/audio/chromeos_sounds.h" #include "ui/aura/client/aura_constants.h"
diff --git a/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/ash/wm/workspace/multi_window_resize_controller_unittest.cc index 5d96e5e2..c79504c 100644 --- a/ash/wm/workspace/multi_window_resize_controller_unittest.cc +++ b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
@@ -13,7 +13,6 @@ #include "ash/test/workspace_event_handler_test_helper.h" #include "ash/wm/window_util.h" #include "ash/wm/workspace_controller.h" -#include "ash/wm_window.h" #include "base/stl_util.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h"
diff --git a/ash/wm/workspace/workspace_event_handler_aura.cc b/ash/wm/workspace/workspace_event_handler_aura.cc index a0113099..55c663a7 100644 --- a/ash/wm/workspace/workspace_event_handler_aura.cc +++ b/ash/wm/workspace/workspace_event_handler_aura.cc
@@ -4,19 +4,20 @@ #include "ash/wm/workspace/workspace_event_handler_aura.h" -#include "ash/wm_window.h" +#include "ash/wm/window_util.h" #include "ui/aura/window.h" #include "ui/events/event.h" namespace ash { -WorkspaceEventHandlerAura::WorkspaceEventHandlerAura(WmWindow* workspace_window) +WorkspaceEventHandlerAura::WorkspaceEventHandlerAura( + aura::Window* workspace_window) : workspace_window_(workspace_window) { - workspace_window_->AddLimitedPreTargetHandler(this); + wm::AddLimitedPreTargetHandlerForWindow(this, workspace_window_); } WorkspaceEventHandlerAura::~WorkspaceEventHandlerAura() { - workspace_window_->RemoveLimitedPreTargetHandler(this); + wm::RemoveLimitedPreTargetHandlerForWindow(this, workspace_window_); } void WorkspaceEventHandlerAura::OnMouseEvent(ui::MouseEvent* event) {
diff --git a/ash/wm/workspace/workspace_event_handler_aura.h b/ash/wm/workspace/workspace_event_handler_aura.h index 86f163d..6215870 100644 --- a/ash/wm/workspace/workspace_event_handler_aura.h +++ b/ash/wm/workspace/workspace_event_handler_aura.h
@@ -10,14 +10,16 @@ #include "base/macros.h" #include "ui/events/event_handler.h" -namespace ash { +namespace aura { +class Window; +} -class WmWindow; +namespace ash { class ASH_EXPORT WorkspaceEventHandlerAura : public ui::EventHandler, public WorkspaceEventHandler { public: - explicit WorkspaceEventHandlerAura(WmWindow* workspace_window); + explicit WorkspaceEventHandlerAura(aura::Window* workspace_window); ~WorkspaceEventHandlerAura() override; // ui::EventHandler: @@ -25,7 +27,7 @@ void OnGestureEvent(ui::GestureEvent* event) override; private: - WmWindow* workspace_window_; + aura::Window* workspace_window_; DISALLOW_COPY_AND_ASSIGN(WorkspaceEventHandlerAura); };
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index 940ce02..fc67e50 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -23,7 +23,6 @@ #include "ash/wm/wm_event.h" #include "ash/wm/workspace/backdrop_controller.h" #include "ash/wm/workspace/backdrop_delegate.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "ui/aura/client/aura_constants.h" #include "ui/base/ui_base_switches.h"
diff --git a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc index b604c6d..dcdaaac 100644 --- a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
@@ -22,7 +22,6 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "ash/wm/workspace/workspace_window_resizer.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_types.h" @@ -64,14 +63,13 @@ restore_work_area_insets_ = display::Screen::GetScreen()->GetPrimaryDisplay().GetWorkAreaInsets(); ShellPort::Get()->SetDisplayWorkAreaInsets( - WmWindow::Get(Shell::GetPrimaryRootWindow()), + Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, keyboard_bounds_.height(), 0)); } void HideKeyboard() { - ShellPort::Get()->SetDisplayWorkAreaInsets( - WmWindow::Get(Shell::GetPrimaryRootWindow()), - restore_work_area_insets_); + ShellPort::Get()->SetDisplayWorkAreaInsets(Shell::GetPrimaryRootWindow(), + restore_work_area_insets_); layout_manager_->OnKeyboardBoundsChanging(gfx::Rect()); }
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index 6cde773..e237be4 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -35,7 +35,6 @@ #include "ash/wm/wm_event.h" #include "ash/wm/workspace/backdrop_delegate.h" #include "ash/wm/workspace/workspace_window_resizer.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "base/run_loop.h" #include "chromeos/audio/chromeos_sounds.h" @@ -425,10 +424,10 @@ nullptr, aura::client::WINDOW_TYPE_NORMAL)); window->Init(ui::LAYER_TEXTURED); wm::GetWindowState(window.get())->Maximize(); - WmWindow* default_container = - Shell::GetPrimaryRootWindowController()->GetWmContainer( + aura::Window* default_container = + Shell::GetPrimaryRootWindowController()->GetContainer( kShellWindowId_DefaultContainer); - default_container->aura_window()->AddChild(window.get()); + default_container->AddChild(window.get()); window->Show(); gfx::Rect work_area( display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); @@ -577,8 +576,7 @@ CreateTestWindow(gfx::Rect(10, 20, 100, 200))); wm::WindowState* window_state = wm::GetWindowState(window.get()); gfx::Insets insets(0, 0, 50, 0); - ShellPort::Get()->SetDisplayWorkAreaInsets(WmWindow::Get(window.get()), - insets); + ShellPort::Get()->SetDisplayWorkAreaInsets(window.get(), insets); const wm::WMEvent snap_left(wm::WM_EVENT_SNAP_LEFT); window_state->OnWMEvent(&snap_left); EXPECT_EQ(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType()); @@ -594,12 +592,11 @@ // The following two SetDisplayWorkAreaInsets calls simulate the case of // crbug.com/673803 that work area first becomes fullscreen and then returns // to the original state. - ShellPort::Get()->SetDisplayWorkAreaInsets(WmWindow::Get(window.get()), + ShellPort::Get()->SetDisplayWorkAreaInsets(window.get(), gfx::Insets(0, 0, 0, 0)); ui::LayerAnimator* animator = window->layer()->GetAnimator(); EXPECT_TRUE(animator->is_animating()); - ShellPort::Get()->SetDisplayWorkAreaInsets(WmWindow::Get(window.get()), - insets); + ShellPort::Get()->SetDisplayWorkAreaInsets(window.get(), insets); animator->StopAnimating(); EXPECT_FALSE(animator->is_animating()); EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString()); @@ -623,7 +620,7 @@ window2->Show(); gfx::Rect expected_bounds = window2->bounds(); - ShellPort::Get()->SetDisplayWorkAreaInsets(WmWindow::Get(window.get()), + ShellPort::Get()->SetDisplayWorkAreaInsets(window.get(), gfx::Insets(50, 0, 0, 0)); EXPECT_EQ(expected_bounds.ToString(), window2->bounds().ToString()); } @@ -1405,14 +1402,13 @@ restore_work_area_insets_ = display::Screen::GetScreen()->GetPrimaryDisplay().GetWorkAreaInsets(); ShellPort::Get()->SetDisplayWorkAreaInsets( - WmWindow::Get(Shell::GetPrimaryRootWindow()), + Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, keyboard_bounds_.height(), 0)); } void HideKeyboard() { - ShellPort::Get()->SetDisplayWorkAreaInsets( - WmWindow::Get(Shell::GetPrimaryRootWindow()), - restore_work_area_insets_); + ShellPort::Get()->SetDisplayWorkAreaInsets(Shell::GetPrimaryRootWindow(), + restore_work_area_insets_); layout_manager_->OnKeyboardBoundsChanging(gfx::Rect()); }
diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc index 57c4fdb..c3cc31a3 100644 --- a/ash/wm/workspace/workspace_window_resizer_unittest.cc +++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc
@@ -17,7 +17,6 @@ #include "ash/wm/wm_event.h" #include "ash/wm/workspace/phantom_window_controller.h" #include "ash/wm/workspace_controller.h" -#include "ash/wm_window.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h"
diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc index 4687dfc..8017164f 100644 --- a/ash/wm/workspace_controller.cc +++ b/ash/wm/workspace_controller.cc
@@ -17,10 +17,10 @@ #include "ash/wm/workspace/backdrop_delegate.h" #include "ash/wm/workspace/workspace_event_handler.h" #include "ash/wm/workspace/workspace_layout_manager.h" -#include "ash/wm_window.h" #include "ui/aura/window.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/wm/core/window_animations.h" namespace ash { namespace { @@ -36,8 +36,7 @@ WorkspaceController::WorkspaceController(aura::Window* viewport) : viewport_(viewport), - event_handler_(ShellPort::Get()->CreateWorkspaceEventHandler( - WmWindow::Get(viewport))), + event_handler_(ShellPort::Get()->CreateWorkspaceEventHandler(viewport)), layout_manager_(new WorkspaceLayoutManager(viewport)) { viewport_->AddObserver(this); ::wm::SetWindowVisibilityAnimationTransition(viewport_, ::wm::ANIMATE_NONE);
diff --git a/ash/wm_window.cc b/ash/wm_window.cc index 59e78410..256a1ab 100644 --- a/ash/wm_window.cc +++ b/ash/wm_window.cc
@@ -447,22 +447,6 @@ window_->Show(); } -void WmWindow::CloseWidget() { - if (Shell::GetAshConfig() == Config::MASH && - aura_window()->GetProperty(kWidgetCreationTypeKey) == - WidgetCreationType::FOR_CLIENT) { - // NOTE: in the FOR_CLIENT case there is not necessarily a widget associated - // with the window. Mash only creates widgets for top level windows if mash - // renders the non-client frame. - DCHECK(Shell::window_manager_client()); - Shell::window_manager_client()->RequestClose(aura_window()); - return; - } - views::Widget* widget = GetInternalWidgetForWindow(window_); - DCHECK(widget); - widget->Close(); -} - void WmWindow::SetFocused() { aura::client::GetFocusClient(window_)->FocusWindow(window_); } @@ -565,18 +549,6 @@ } } -void WmWindow::AddLimitedPreTargetHandler(ui::EventHandler* handler) { - // In mus AddPreTargetHandler() only works for windows created by this client. - DCHECK(Shell::GetAshConfig() != Config::MASH || - Shell::window_tree_client()->WasCreatedByThisClient( - aura::WindowMus::Get(window_))); - window_->AddPreTargetHandler(handler); -} - -void WmWindow::RemoveLimitedPreTargetHandler(ui::EventHandler* handler) { - window_->RemovePreTargetHandler(handler); -} - WmWindow::WmWindow(aura::Window* window) : window_(window) { window_->SetProperty(kWmWindowKey, this); }
diff --git a/ash/wm_window.h b/ash/wm_window.h index e81d8566..2e6595a 100644 --- a/ash/wm_window.h +++ b/ash/wm_window.h
@@ -31,7 +31,6 @@ } namespace ui { -class EventHandler; class Layer; } @@ -249,10 +248,6 @@ void Hide(); void Show(); - // Requests the window to close and destroy itself. This is intended to - // forward to an associated widget. - void CloseWidget(); - void SetFocused(); bool IsFocused() const; @@ -290,16 +285,6 @@ void AddTransientWindowObserver(WmTransientWindowObserver* observer); void RemoveTransientWindowObserver(WmTransientWindowObserver* observer); - // Adds or removes a handler to receive events targeted at this window, before - // this window handles the events itself; the handler does not recieve events - // from embedded windows. This only supports windows with internal widgets; - // see ash::GetInternalWidgetForWindow(). Ownership of the handler is not - // transferred. - // - // Also note that the target of these events is always an aura::Window. - void AddLimitedPreTargetHandler(ui::EventHandler* handler); - void RemoveLimitedPreTargetHandler(ui::EventHandler* handler); - private: explicit WmWindow(aura::Window* window);
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index 0507c0b4..77c3823 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -20,62 +20,34 @@ #include <sys/resource.h> #include <sys/time.h> -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif #endif // defined(OS_POSIX) +#if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) + namespace { + template <typename T> std::unique_ptr<T[]> WrapArrayUnique(T* ptr) { return std::unique_ptr<T[]>(ptr); } -} // namespace - -#if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) - -namespace base { - -namespace { const size_t kTestMaxAllocation = 4096; -SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; -PartitionAllocatorGeneric generic_allocator; -const size_t kTestAllocSize = 16; -#if !DCHECK_IS_ON() -const size_t kPointerOffset = 0; -const size_t kExtraAllocSize = 0; -#else -const size_t kPointerOffset = kCookieSize; -const size_t kExtraAllocSize = kCookieSize * 2; -#endif -const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize; -const size_t kTestBucketIndex = kRealAllocSize >> kBucketShift; - -const char* type_name = nullptr; - -void TestSetup() { - // Zero the allocator structs to clear out traces - // from previous test. - memset(&allocator, 0, sizeof(allocator)); - memset(&generic_allocator, 0, sizeof(generic_allocator)); - - allocator.init(); - generic_allocator.init(); +bool IsLargeMemoryDevice() { + return base::SysInfo::AmountOfPhysicalMemory() >= 2LL * 1024 * 1024 * 1024; } -#if !defined(ARCH_CPU_64_BITS) || defined(OS_POSIX) bool SetAddressSpaceLimit() { -#if !defined(ARCH_CPU_64_BITS) +#if !defined(ARCH_CPU_64_BITS) || !defined(OS_POSIX) // 32 bits => address space is limited already. return true; #elif defined(OS_POSIX) && !defined(OS_MACOSX) - // Mac will accept RLIMIT_AS changes but it is not enforced. - // See https://crbug.com/435269 and rdar://17576114. - // Note: this number must be not less than 6 GB, because with - // sanitizer_coverage_flags=edge, it reserves > 5 GB of address - // space, see https://crbug.com/674665. + // macOS will accept, but not enforce, |RLIMIT_AS| changes. See + // https://crbug.com/435269 and rdar://17576114. + // + // Note: This number must be not less than 6 GB, because with + // sanitizer_coverage_flags=edge, it reserves > 5 GB of address space. See + // https://crbug.com/674665. const size_t kAddressSpaceLimit = static_cast<size_t>(6144) * 1024 * 1024; struct rlimit limit; if (getrlimit(RLIMIT_AS, &limit) != 0) @@ -92,7 +64,7 @@ } bool ClearAddressSpaceLimit() { -#if !defined(ARCH_CPU_64_BITS) +#if !defined(ARCH_CPU_64_BITS) || !defined(OS_POSIX) return true; #elif defined(OS_POSIX) struct rlimit limit; @@ -106,36 +78,159 @@ return false; #endif } -#endif -PartitionPage* GetFullPage(size_t size) { - size_t real_size = size + kExtraAllocSize; - size_t bucket_index = real_size >> kBucketShift; - PartitionBucket* bucket = &allocator.root()->buckets()[bucket_index]; - size_t num_slots = - (bucket->num_system_pages_per_slot_span * kSystemPageSize) / real_size; - void* first = 0; - void* last = 0; - size_t i; - for (i = 0; i < num_slots; ++i) { - void* ptr = PartitionAlloc(allocator.root(), size, type_name); - EXPECT_TRUE(ptr); - if (!i) - first = PartitionCookieFreePointerAdjust(ptr); - else if (i == num_slots - 1) - last = PartitionCookieFreePointerAdjust(ptr); +} // namespace + +namespace base { + +const size_t kTestAllocSize = 16; +#if !DCHECK_IS_ON() +const size_t kPointerOffset = 0; +const size_t kExtraAllocSize = 0; +#else +const size_t kPointerOffset = kCookieSize; +const size_t kExtraAllocSize = kCookieSize * 2; +#endif +const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize; +const size_t kTestBucketIndex = kRealAllocSize >> kBucketShift; + +const char* type_name = nullptr; + +class PartitionAllocTest : public testing::Test { + protected: + PartitionAllocTest() {} + + ~PartitionAllocTest() override {} + + void SetUp() override { + // TODO(crbug.com/722911): These calls to |memset| should perhaps not be + // necessary. + memset(&allocator, 0, sizeof(allocator)); + memset(&generic_allocator, 0, sizeof(generic_allocator)); + allocator.init(); + generic_allocator.init(); } - EXPECT_EQ(PartitionPointerToPage(first), PartitionPointerToPage(last)); - if (bucket->num_system_pages_per_slot_span == kNumSystemPagesPerPartitionPage) - EXPECT_EQ(reinterpret_cast<size_t>(first) & kPartitionPageBaseMask, - reinterpret_cast<size_t>(last) & kPartitionPageBaseMask); - EXPECT_EQ(num_slots, static_cast<size_t>( - bucket->active_pages_head->num_allocated_slots)); - EXPECT_EQ(0, bucket->active_pages_head->freelist_head); - EXPECT_TRUE(bucket->active_pages_head); - EXPECT_TRUE(bucket->active_pages_head != &PartitionRootGeneric::gSeedPage); - return bucket->active_pages_head; -} + + PartitionPage* GetFullPage(size_t size) { + size_t real_size = size + kExtraAllocSize; + size_t bucket_index = real_size >> kBucketShift; + PartitionBucket* bucket = &allocator.root()->buckets()[bucket_index]; + size_t num_slots = + (bucket->num_system_pages_per_slot_span * kSystemPageSize) / real_size; + void* first = 0; + void* last = 0; + size_t i; + for (i = 0; i < num_slots; ++i) { + void* ptr = PartitionAlloc(allocator.root(), size, type_name); + EXPECT_TRUE(ptr); + if (!i) + first = PartitionCookieFreePointerAdjust(ptr); + else if (i == num_slots - 1) + last = PartitionCookieFreePointerAdjust(ptr); + } + EXPECT_EQ(PartitionPointerToPage(first), PartitionPointerToPage(last)); + if (bucket->num_system_pages_per_slot_span == + kNumSystemPagesPerPartitionPage) + EXPECT_EQ(reinterpret_cast<size_t>(first) & kPartitionPageBaseMask, + reinterpret_cast<size_t>(last) & kPartitionPageBaseMask); + EXPECT_EQ(num_slots, static_cast<size_t>( + bucket->active_pages_head->num_allocated_slots)); + EXPECT_EQ(0, bucket->active_pages_head->freelist_head); + EXPECT_TRUE(bucket->active_pages_head); + EXPECT_TRUE(bucket->active_pages_head != &PartitionRootGeneric::gSeedPage); + return bucket->active_pages_head; + } + + void CycleFreeCache(size_t size) { + size_t real_size = size + kExtraAllocSize; + size_t bucket_index = real_size >> kBucketShift; + PartitionBucket* bucket = &allocator.root()->buckets()[bucket_index]; + DCHECK(!bucket->active_pages_head->num_allocated_slots); + + for (size_t i = 0; i < kMaxFreeableSpans; ++i) { + void* ptr = PartitionAlloc(allocator.root(), size, type_name); + EXPECT_EQ(1, bucket->active_pages_head->num_allocated_slots); + PartitionFree(ptr); + EXPECT_EQ(0, bucket->active_pages_head->num_allocated_slots); + EXPECT_NE(-1, bucket->active_pages_head->empty_cache_index); + } + } + + void CycleGenericFreeCache(size_t size) { + for (size_t i = 0; i < kMaxFreeableSpans; ++i) { + void* ptr = + PartitionAllocGeneric(generic_allocator.root(), size, type_name); + PartitionPage* page = + PartitionPointerToPage(PartitionCookieFreePointerAdjust(ptr)); + PartitionBucket* bucket = page->bucket; + EXPECT_EQ(1, bucket->active_pages_head->num_allocated_slots); + PartitionFreeGeneric(generic_allocator.root(), ptr); + EXPECT_EQ(0, bucket->active_pages_head->num_allocated_slots); + EXPECT_NE(-1, bucket->active_pages_head->empty_cache_index); + } + } + + void DoReturnNullTest(size_t allocSize) { + // TODO(crbug.com/678782): Where necessary and possible, disable the + // platform's OOM-killing behavior. OOM-killing makes this test flaky on + // low-memory devices. + if (!IsLargeMemoryDevice()) { + LOG(WARNING) + << "Skipping test on this device because of crbug.com/678782"; + return; + } + + EXPECT_TRUE(SetAddressSpaceLimit()); + + // Work out the number of allocations for 6 GB of memory. + const int numAllocations = (6 * 1024 * 1024) / (allocSize / 1024); + + void** ptrs = reinterpret_cast<void**>(PartitionAllocGeneric( + generic_allocator.root(), numAllocations * sizeof(void*), type_name)); + int i; + + for (i = 0; i < numAllocations; ++i) { + ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), + PartitionAllocReturnNull, allocSize, + type_name); + if (!i) + EXPECT_TRUE(ptrs[0]); + if (!ptrs[i]) { + ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), + PartitionAllocReturnNull, + allocSize, type_name); + EXPECT_FALSE(ptrs[i]); + break; + } + } + + // We shouldn't succeed in allocating all 6 GB of memory. If we do, then + // we're not actually testing anything here. + EXPECT_LT(i, numAllocations); + + // Free, reallocate and free again each block we allocated. We do this to + // check that freeing memory also works correctly after a failed allocation. + for (--i; i >= 0; --i) { + PartitionFreeGeneric(generic_allocator.root(), ptrs[i]); + ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), + PartitionAllocReturnNull, allocSize, + type_name); + EXPECT_TRUE(ptrs[i]); + PartitionFreeGeneric(generic_allocator.root(), ptrs[i]); + } + + PartitionFreeGeneric(generic_allocator.root(), ptrs); + + EXPECT_TRUE(ClearAddressSpaceLimit()); + } + + SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; + PartitionAllocatorGeneric generic_allocator; +}; + +class PartitionAllocDeathTest : public PartitionAllocTest {}; + +namespace { void FreeFullPage(PartitionPage* page) { size_t size = page->bucket->slot_size; @@ -150,35 +245,6 @@ } } -void CycleFreeCache(size_t size) { - size_t real_size = size + kExtraAllocSize; - size_t bucket_index = real_size >> kBucketShift; - PartitionBucket* bucket = &allocator.root()->buckets()[bucket_index]; - DCHECK(!bucket->active_pages_head->num_allocated_slots); - - for (size_t i = 0; i < kMaxFreeableSpans; ++i) { - void* ptr = PartitionAlloc(allocator.root(), size, type_name); - EXPECT_EQ(1, bucket->active_pages_head->num_allocated_slots); - PartitionFree(ptr); - EXPECT_EQ(0, bucket->active_pages_head->num_allocated_slots); - EXPECT_NE(-1, bucket->active_pages_head->empty_cache_index); - } -} - -void CycleGenericFreeCache(size_t size) { - for (size_t i = 0; i < kMaxFreeableSpans; ++i) { - void* ptr = - PartitionAllocGeneric(generic_allocator.root(), size, type_name); - PartitionPage* page = - PartitionPointerToPage(PartitionCookieFreePointerAdjust(ptr)); - PartitionBucket* bucket = page->bucket; - EXPECT_EQ(1, bucket->active_pages_head->num_allocated_slots); - PartitionFreeGeneric(generic_allocator.root(), ptr); - EXPECT_EQ(0, bucket->active_pages_head->num_allocated_slots); - EXPECT_NE(-1, bucket->active_pages_head->empty_cache_index); - } -} - void CheckPageInCore(void* ptr, bool inCore) { #if defined(OS_LINUX) unsigned char ret; @@ -187,10 +253,6 @@ #endif } -bool IsLargeMemoryDevice() { - return base::SysInfo::AmountOfPhysicalMemory() >= 2LL * 1024 * 1024 * 1024; -} - class MockPartitionStatsDumper : public PartitionStatsDumper { public: MockPartitionStatsDumper() @@ -245,8 +307,7 @@ } // anonymous namespace // Check that the most basic of allocate / free pairs work. -TEST(PartitionAllocTest, Basic) { - TestSetup(); +TEST_F(PartitionAllocTest, Basic) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; PartitionPage* seedPage = &PartitionRootGeneric::gSeedPage; @@ -271,9 +332,7 @@ } // Test multiple allocations, and freelist handling. -TEST(PartitionAllocTest, MultiAlloc) { - TestSetup(); - +TEST_F(PartitionAllocTest, MultiAlloc) { char* ptr1 = reinterpret_cast<char*>( PartitionAlloc(allocator.root(), kTestAllocSize, type_name)); char* ptr2 = reinterpret_cast<char*>( @@ -309,8 +368,7 @@ } // Test a bucket with multiple pages. -TEST(PartitionAllocTest, MultiPages) { - TestSetup(); +TEST_F(PartitionAllocTest, MultiPages) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; PartitionPage* page = GetFullPage(kTestAllocSize); @@ -351,8 +409,7 @@ } // Test some finer aspects of internal page transitions. -TEST(PartitionAllocTest, PageTransitions) { - TestSetup(); +TEST_F(PartitionAllocTest, PageTransitions) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; PartitionPage* page1 = GetFullPage(kTestAllocSize); @@ -412,8 +469,7 @@ // Test some corner cases relating to page transitions in the internal // free page list metadata bucket. -TEST(PartitionAllocTest, FreePageListPageTransitions) { - TestSetup(); +TEST_F(PartitionAllocTest, FreePageListPageTransitions) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; size_t numToFillFreeListPage = @@ -455,8 +511,7 @@ // Test a large series of allocations that cross more than one underlying // 64KB super page allocation. -TEST(PartitionAllocTest, MultiPageAllocs) { - TestSetup(); +TEST_F(PartitionAllocTest, MultiPageAllocs) { // This is guaranteed to cross a super page boundary because the first // partition page "slot" will be taken up by a guard page. size_t numPagesNeeded = kNumPartitionPagesPerSuperPage; @@ -491,9 +546,7 @@ // Test the generic allocation functions that can handle arbitrary sizes and // reallocing etc. -TEST(PartitionAllocTest, GenericAlloc) { - TestSetup(); - +TEST_F(PartitionAllocTest, GenericAlloc) { void* ptr = PartitionAllocGeneric(generic_allocator.root(), 1, type_name); EXPECT_TRUE(ptr); PartitionFreeGeneric(generic_allocator.root(), ptr); @@ -585,9 +638,7 @@ // Test the generic allocation functions can handle some specific sizes of // interest. -TEST(PartitionAllocTest, GenericAllocSizes) { - TestSetup(); - +TEST_F(PartitionAllocTest, GenericAllocSizes) { void* ptr = PartitionAllocGeneric(generic_allocator.root(), 0, type_name); EXPECT_TRUE(ptr); PartitionFreeGeneric(generic_allocator.root(), ptr); @@ -681,9 +732,7 @@ } // Test that we can fetch the real allocated size after an allocation. -TEST(PartitionAllocTest, GenericAllocGetSize) { - TestSetup(); - +TEST_F(PartitionAllocTest, GenericAllocGetSize) { void* ptr; size_t requestedSize, actualSize, predictedSize; @@ -752,9 +801,7 @@ } // Test the realloc() contract. -TEST(PartitionAllocTest, Realloc) { - TestSetup(); - +TEST_F(PartitionAllocTest, Realloc) { // realloc(0, size) should be equivalent to malloc(). void* ptr = PartitionReallocGeneric(generic_allocator.root(), 0, kTestAllocSize, type_name); @@ -824,9 +871,7 @@ } // Tests the handing out of freelists for partial pages. -TEST(PartitionAllocTest, PartialPageFreelists) { - TestSetup(); - +TEST_F(PartitionAllocTest, PartialPageFreelists) { size_t big_size = allocator.root()->max_allocation - kExtraAllocSize; EXPECT_EQ(kSystemPageSize - kAllocationGranularity, big_size + kExtraAllocSize); @@ -980,8 +1025,7 @@ } // Test some of the fragmentation-resistant properties of the allocator. -TEST(PartitionAllocTest, PageRefilling) { - TestSetup(); +TEST_F(PartitionAllocTest, PageRefilling) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; // Grab two full pages and a non-full page. @@ -1015,9 +1059,7 @@ } // Basic tests to ensure that allocations work for partial page buckets. -TEST(PartitionAllocTest, PartialPages) { - TestSetup(); - +TEST_F(PartitionAllocTest, PartialPages) { // Find a size that is backed by a partial partition page. size_t size = sizeof(void*); PartitionBucket* bucket = 0; @@ -1037,8 +1079,7 @@ } // Test correct handling if our mapping collides with another. -TEST(PartitionAllocTest, MappingCollision) { - TestSetup(); +TEST_F(PartitionAllocTest, MappingCollision) { // The -2 is because the first and last partition pages in a super page are // guard pages. size_t numPartitionPagesNeeded = kNumPartitionPagesPerSuperPage - 2; @@ -1119,9 +1160,7 @@ } // Tests that pages in the free page cache do get freed as appropriate. -TEST(PartitionAllocTest, FreeCache) { - TestSetup(); - +TEST_F(PartitionAllocTest, FreeCache) { EXPECT_EQ(0U, allocator.root()->total_size_of_committed_pages); size_t big_size = allocator.root()->max_allocation - kExtraAllocSize; @@ -1172,9 +1211,7 @@ } // Tests for a bug we had with losing references to free pages. -TEST(PartitionAllocTest, LostFreePagesBug) { - TestSetup(); - +TEST_F(PartitionAllocTest, LostFreePagesBug) { size_t size = kPartitionPageSize - kExtraAllocSize; void* ptr = PartitionAllocGeneric(generic_allocator.root(), size, type_name); @@ -1236,60 +1273,6 @@ #if !defined(ARCH_CPU_64_BITS) || defined(OS_POSIX) -static void DoReturnNullTest(size_t allocSize) { - // TODO(crbug.com/678782): Where necessary and possible, disable the - // platform's OOM-killing behavior. OOM-killing makes this test flaky on - // low-memory devices. - if (!IsLargeMemoryDevice()) { - LOG(WARNING) << "Skipping test on this device because of crbug.com/678782"; - return; - } - - TestSetup(); - - EXPECT_TRUE(SetAddressSpaceLimit()); - - // Work out the number of allocations for 6 GB of memory. - const int numAllocations = (6 * 1024 * 1024) / (allocSize / 1024); - - void** ptrs = reinterpret_cast<void**>(PartitionAllocGeneric( - generic_allocator.root(), numAllocations * sizeof(void*), type_name)); - int i; - - for (i = 0; i < numAllocations; ++i) { - ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), - PartitionAllocReturnNull, allocSize, - type_name); - if (!i) - EXPECT_TRUE(ptrs[0]); - if (!ptrs[i]) { - ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), - PartitionAllocReturnNull, allocSize, - type_name); - EXPECT_FALSE(ptrs[i]); - break; - } - } - - // We shouldn't succeed in allocating all 6 GB of memory. If we do, then - // we're not actually testing anything here. - EXPECT_LT(i, numAllocations); - - // Free, reallocate and free again each block we allocated. We do this to - // check that freeing memory also works correctly after a failed allocation. - for (--i; i >= 0; --i) { - PartitionFreeGeneric(generic_allocator.root(), ptrs[i]); - ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), - PartitionAllocReturnNull, allocSize, - type_name); - EXPECT_TRUE(ptrs[i]); - PartitionFreeGeneric(generic_allocator.root(), ptrs[i]); - } - - PartitionFreeGeneric(generic_allocator.root(), ptrs); - - EXPECT_TRUE(ClearAddressSpaceLimit()); -} // Unit tests that check if an allocation fails in "return null" mode, // repeating it doesn't crash, and still returns null. The tests need to @@ -1311,7 +1294,7 @@ #else #define MAYBE_RepeatedReturnNullDirect RepeatedReturnNullDirect #endif -TEST(PartitionAllocTest, MAYBE_RepeatedReturnNullDirect) { +TEST_F(PartitionAllocTest, MAYBE_RepeatedReturnNullDirect) { // A direct-mapped allocation size. DoReturnNullTest(32 * 1024 * 1024); } @@ -1325,7 +1308,7 @@ #else #define MAYBE_RepeatedReturnNull RepeatedReturnNull #endif -TEST(PartitionAllocTest, MAYBE_RepeatedReturnNull) { +TEST_F(PartitionAllocTest, MAYBE_RepeatedReturnNull) { // A single-slot but non-direct-mapped allocation size. DoReturnNullTest(512 * 1024); } @@ -1338,8 +1321,7 @@ // Make sure that malloc(-1) dies. // In the past, we had an integer overflow that would alias malloc(-1) to // malloc(0), which is not good. -TEST(PartitionAllocDeathTest, LargeAllocs) { - TestSetup(); +TEST_F(PartitionAllocDeathTest, LargeAllocs) { // Largest alloc. EXPECT_DEATH(PartitionAllocGeneric(generic_allocator.root(), static_cast<size_t>(-1), type_name), @@ -1352,9 +1334,7 @@ } // Check that our immediate double-free detection works. -TEST(PartitionAllocDeathTest, ImmediateDoubleFree) { - TestSetup(); - +TEST_F(PartitionAllocDeathTest, ImmediateDoubleFree) { void* ptr = PartitionAllocGeneric(generic_allocator.root(), kTestAllocSize, type_name); EXPECT_TRUE(ptr); @@ -1364,9 +1344,7 @@ } // Check that our refcount-based double-free detection works. -TEST(PartitionAllocDeathTest, RefcountDoubleFree) { - TestSetup(); - +TEST_F(PartitionAllocDeathTest, RefcountDoubleFree) { void* ptr = PartitionAllocGeneric(generic_allocator.root(), kTestAllocSize, type_name); EXPECT_TRUE(ptr); @@ -1382,9 +1360,7 @@ } // Check that guard pages are present where expected. -TEST(PartitionAllocDeathTest, GuardPages) { - TestSetup(); - +TEST_F(PartitionAllocDeathTest, GuardPages) { // PartitionAlloc adds kPartitionPageSize to the requested size // (for metadata), and then rounds that size to kPageAllocationGranularity. // To be able to reliably write one past a direct allocation, choose a size @@ -1418,9 +1394,7 @@ // Check that a bad free() is caught where the free() refers to an unused // partition page of a large allocation. -TEST(PartitionAllocDeathTest, FreeWrongPartitionPage) { - TestSetup(); - +TEST_F(PartitionAllocDeathTest, FreeWrongPartitionPage) { // This large size will result in a direct mapped allocation with guard // pages at either end. void* ptr = PartitionAllocGeneric(generic_allocator.root(), @@ -1435,25 +1409,23 @@ #endif // !defined(OS_ANDROID) && !defined(OS_IOS) -// Tests that PartitionDumpStatsGeneric and PartitionDumpStats runs without -// crashing and returns non zero values when memory is allocated. -TEST(PartitionAllocTest, DumpMemoryStats) { - TestSetup(); +// Tests that |PartitionDumpStatsGeneric| and |PartitionDumpStats| run without +// crashing and return non-zero values when memory is allocated. +TEST_F(PartitionAllocTest, DumpMemoryStats) { { void* ptr = PartitionAlloc(allocator.root(), kTestAllocSize, type_name); MockPartitionStatsDumper mockStatsDumper; PartitionDumpStats(allocator.root(), "mock_allocator", false /* detailed dump */, &mockStatsDumper); EXPECT_TRUE(mockStatsDumper.IsMemoryAllocationRecorded()); - PartitionFree(ptr); } // This series of tests checks the active -> empty -> decommitted states. { - void* genericPtr = PartitionAllocGeneric(generic_allocator.root(), - 2048 - kExtraAllocSize, type_name); { + void* ptr = PartitionAllocGeneric(generic_allocator.root(), + 2048 - kExtraAllocSize, type_name); MockPartitionStatsDumper dumper; PartitionDumpStatsGeneric(generic_allocator.root(), "mock_generic_allocator", @@ -1472,10 +1444,9 @@ EXPECT_EQ(1u, stats->num_active_pages); EXPECT_EQ(0u, stats->num_empty_pages); EXPECT_EQ(0u, stats->num_decommitted_pages); + PartitionFreeGeneric(generic_allocator.root(), ptr); } - PartitionFreeGeneric(generic_allocator.root(), genericPtr); - { MockPartitionStatsDumper dumper; PartitionDumpStatsGeneric(generic_allocator.root(), @@ -1497,6 +1468,9 @@ EXPECT_EQ(0u, stats->num_decommitted_pages); } + // TODO(crbug.com/722911): Commenting this out causes this test to fail when + // run singly (--gtest_filter=PartitionAllocTest.DumpMemoryStats), but not + // when run with the others (--gtest_filter=PartitionAllocTest.*). CycleGenericFreeCache(kTestAllocSize); { @@ -1612,8 +1586,8 @@ PartitionFreeGeneric(generic_allocator.root(), ptr2); PartitionFreeGeneric(generic_allocator.root(), ptr); - // Whilst we're here, allocate again and free with different ordering - // to give a workout to our linked list code. + // Whilst we're here, allocate again and free with different ordering to + // give a workout to our linked list code. ptr = PartitionAllocGeneric(generic_allocator.root(), size_smaller, type_name); ptr2 = @@ -1710,9 +1684,7 @@ } // Tests the API to purge freeable memory. -TEST(PartitionAllocTest, Purge) { - TestSetup(); - +TEST_F(PartitionAllocTest, Purge) { char* ptr = reinterpret_cast<char*>(PartitionAllocGeneric( generic_allocator.root(), 2048 - kExtraAllocSize, type_name)); PartitionFreeGeneric(generic_allocator.root(), ptr); @@ -1762,9 +1734,7 @@ // Tests that we prefer to allocate into a non-empty partition page over an // empty one. This is an important aspect of minimizing memory usage for some // allocation sizes, particularly larger ones. -TEST(PartitionAllocTest, PreferActiveOverEmpty) { - TestSetup(); - +TEST_F(PartitionAllocTest, PreferActiveOverEmpty) { size_t size = (kSystemPageSize * 2) - kExtraAllocSize; // Allocate 3 full slot spans worth of 8192-byte allocations. // Each slot span for this size is 16384 bytes, or 1 partition page and 2 @@ -1813,9 +1783,7 @@ } // Tests the API to purge discardable memory. -TEST(PartitionAllocTest, PurgeDiscardable) { - TestSetup(); - +TEST_F(PartitionAllocTest, PurgeDiscardable) { // Free the second of two 4096 byte allocations and then purge. { void* ptr1 = PartitionAllocGeneric( @@ -2088,9 +2056,7 @@ } } -TEST(PartitionAllocTest, ReallocMovesCookies) { - TestSetup(); - +TEST_F(PartitionAllocTest, ReallocMovesCookies) { // Resize so as to be sure to hit a "resize in place" case, and ensure that // use of the entire result is compatible with the debug mode's cookies, even // when the bucket size is large enough to span more than one partition page
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index aff0e3d..882f183 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn
@@ -264,13 +264,17 @@ } # Dependencies that all executables and shared libraries should have. -# All targets that currently depend on //build/config/sanitizers:deps -# are being made to depend on this target instead -# (https://crbug.com/723069). group("exe_and_shlib_deps") { - public_deps = [ - "//build/config/sanitizers:deps", - ] + public_deps = [] + if (using_sanitizer) { + public_deps += [ "//build/config/sanitizers:deps" ] + } + if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++:libcxx_proxy" ] + } + if (use_afl) { + public_deps += [ "//third_party/afl" ] + } } # Executable configs -----------------------------------------------------------
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index f6b88c7..67d9568c 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -18,9 +18,6 @@ # "//build/config:exe_and_shlib_deps" to pull in this target. group("deps") { visibility = [ "//build/config:exe_and_shlib_deps" ] - public_deps = [ - ":deps_no_options", - ] if (using_sanitizer) { public_configs = [ ":sanitizer_options_link_helper", @@ -33,32 +30,15 @@ deps = [ ":options_sources", ] - } - if (use_afl) { - deps += [ "//third_party/afl" ] - } -} - -group("deps_no_options") { - if (using_sanitizer) { - public_configs = [ - # Even when a target removes default_sanitizer_flags, it may be depending - # on a library that did not remove default_sanitizer_flags. Thus, we need - # to add the ldflags here as well as in default_sanitizer_flags. - ":default_sanitizer_ldflags", - ] - deps = [] - public_deps = [] - - data = [ - "//tools/valgrind/asan/", - ] if (is_win) { exe = ".exe" } else { exe = "" } - data += [ "$clang_base_path/bin/llvm-symbolizer${exe}" ] + data = [ + "//tools/valgrind/asan/", + "$clang_base_path/bin/llvm-symbolizer${exe}", + ] if (is_linux) { # llvm-symbolizer needs this. data += [ "$clang_base_path/lib/libstdc++.so.6" ] @@ -68,10 +48,6 @@ use_locally_built_instrumented_libraries) { deps += [ "//third_party/instrumented_libraries:deps" ] } - if (use_custom_libcxx) { - public_deps += [ "//buildtools/third_party/libc++:libcxx_proxy" ] - data += [ "$root_out_dir/libc++.so" ] - } # ASAN is supported on iOS but the runtime library depends on the compiler # used (Chromium version of clang versus Xcode version of clang). Only copy @@ -82,7 +58,9 @@ ] } if (is_mac || (is_ios && !use_xcode_clang)) { - public_deps += [ ":asan_runtime_bundle_data" ] + public_deps = [ + ":asan_runtime_bundle_data", + ] } } } @@ -275,7 +253,6 @@ config("common_sanitizer_flags") { cflags = [] - cflags_cc = [] # Sanitizers need line table info for stack traces. They don't need type info # or variable info, so we can leave that out to speed up the build (unless @@ -303,11 +280,14 @@ cflags += [ "/Oy-" ] } } +} +# TODO(thomasanderson): Move this out of build/config/sanitizers. +config("libcxx_flags") { if (use_custom_libcxx) { prefix = "//buildtools/third_party" include = "trunk/include" - cflags_cc += [ + cflags_cc = [ "-nostdinc++", "-isystem" + rebase_path("$prefix/libc++/$include", root_build_dir), "-isystem" + rebase_path("$prefix/libc++abi/$include", root_build_dir), @@ -558,6 +538,7 @@ all_sanitizer_configs = [ ":common_sanitizer_flags", + ":libcxx_flags", ":coverage_flags", ":default_sanitizer_ldflags", ":asan_flags",
diff --git a/build/sanitizers/sanitizer_options.cc b/build/sanitizers/sanitizer_options.cc index 1f425011..e7e42798 100644 --- a/build/sanitizers/sanitizer_options.cc +++ b/build/sanitizers/sanitizer_options.cc
@@ -82,24 +82,16 @@ "check_printf=1 use_sigaltstack=1 " "strip_path_prefix=/../../ fast_unwind_on_fatal=1 " "detect_stack_use_after_return=1 detect_odr_violation=0 "; -static const char kNaClDefaultOptions[] = "handle_segv=0"; -static const char kNaClFlag[] = "--type=nacl-loader"; #endif // OS_LINUX #if defined(OS_LINUX) || defined(OS_MACOSX) +// Allow NaCl to override the default asan options. +extern const char* kAsanDefaultOptionsNaCl; +__attribute__((weak)) const char* kAsanDefaultOptionsNaCl = nullptr; + SANITIZER_HOOK_ATTRIBUTE const char *__asan_default_options() { -#if defined(OS_MACOSX) - char*** argvp = _NSGetArgv(); - int* argcp = _NSGetArgc(); - if (!argvp || !argcp) return kAsanDefaultOptions; - char** argv = *argvp; - int argc = *argcp; - for (int i = 0; i < argc; ++i) { - if (strcmp(argv[i], kNaClFlag) == 0) { - return kNaClDefaultOptions; - } - } -#endif + if (kAsanDefaultOptionsNaCl) + return kAsanDefaultOptionsNaCl; return kAsanDefaultOptions; }
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index bb8f96c..31af518 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -342,8 +342,8 @@ # Update 3 final with patches with 10.0.14393.0 SDK. return ['d3cb0e37bdd120ad0ac4650b674b09e81be45616'] if env_version == '2017': - # VS 2017 RTM with 10.0.14393.0 SDK and dbghelp.dll fixes. - return ['4e8a360587a3c8ff3fa46aa9271e982bf3e948ec'] + # VS 2017 Update 3 Preview 1 with 10.0.14393.0 SDK and patched statreg.h. + return ['3915730f76bd9c6155aed871b944b0a25c18f15e'] raise Exception('Unsupported VS version %s' % env_version)
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index e40b570..e0605290 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -81,7 +81,7 @@ needs_push_properties_(false), scrollbars_hidden_(false), needs_show_scrollbars_(false), - raster_even_if_not_in_rsll_(false) { + raster_even_if_not_drawn_(false) { DCHECK_GT(layer_id_, 0); DCHECK(layer_tree_impl_);
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index c32c208..10474cf 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -440,12 +440,10 @@ void set_needs_show_scrollbars(bool yes) { needs_show_scrollbars_ = yes; } bool needs_show_scrollbars() { return needs_show_scrollbars_; } - void set_raster_even_if_not_in_rsll(bool yes) { - raster_even_if_not_in_rsll_ = yes; + void set_raster_even_if_not_drawn(bool yes) { + raster_even_if_not_drawn_ = yes; } - bool raster_even_if_not_in_rsll() const { - return raster_even_if_not_in_rsll_; - } + bool raster_even_if_not_drawn() const { return raster_even_if_not_drawn_; } protected: LayerImpl(LayerTreeImpl* layer_impl, @@ -564,7 +562,11 @@ // layers) and consumed by LayerTreeImpl::PushPropertiesTo during activation. bool needs_show_scrollbars_ : 1; - bool raster_even_if_not_in_rsll_ : 1; + // This is set for layers that have a property because of which they are not + // drawn (singular transforms), but they can become visible soon (the property + // is being animated). For this reason, while these layers are not drawn, they + // are still rasterized. + bool raster_even_if_not_drawn_ : 1; DISALLOW_COPY_AND_ASSIGN(LayerImpl); };
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index f43c977..f7d061fb 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -515,9 +515,13 @@ // The reason for this is that we should be able to activate sooner and get a // more up to date recording, so we don't run out of recording on the active // tree. - bool can_require_tiles_for_activation = - !only_used_low_res_last_append_quads_ || RequiresHighResToDraw() || - !layer_tree_impl()->SmoothnessTakesPriority(); + // A layer must be a drawing layer for it to require tiles for activation. + bool can_require_tiles_for_activation = false; + if (contributes_to_drawn_render_surface()) { + can_require_tiles_for_activation = + !only_used_low_res_last_append_quads_ || RequiresHighResToDraw() || + !layer_tree_impl()->SmoothnessTakesPriority(); + } static const Occlusion kEmptyOcclusion; const Occlusion& occlusion_in_content_space = @@ -1458,8 +1462,8 @@ } bool PictureLayerImpl::HasValidTilePriorities() const { - return IsOnActiveOrPendingTree() && (contributes_to_drawn_render_surface() || - raster_even_if_not_in_rsll()); + return IsOnActiveOrPendingTree() && + (contributes_to_drawn_render_surface() || raster_even_if_not_drawn()); } void PictureLayerImpl::InvalidateRegionForImages(
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc index 270978d..7db16d60b 100644 --- a/cc/layers/picture_layer_impl_perftest.cc +++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -86,7 +86,7 @@ int count = num_tiles; std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + pending_layer_->picture_layer_tiling_set(), false, true)); while (count--) { ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count; ASSERT_TRUE(queue->Top().tile()) << "count: " << count; @@ -114,7 +114,7 @@ do { std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + pending_layer_->picture_layer_tiling_set(), false, true)); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired());
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index d7d28d053..877b460 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -1659,7 +1659,7 @@ int num_offscreen = 0; std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false, false)); for (; !queue->IsEmpty(); queue->Pop()) { const PrioritizedTile& prioritized_tile = queue->Top(); DCHECK(prioritized_tile.tile()); @@ -2753,7 +2753,7 @@ int high_res_tile_count = 0u; int high_res_now_tiles = 0u; std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false, false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); TilePriority priority = prioritized_tile.priority(); @@ -2824,7 +2824,7 @@ unique_tiles.clear(); high_res_tile_count = 0u; queue.reset(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false, false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); TilePriority priority = prioritized_tile.priority(); @@ -2861,7 +2861,7 @@ } queue.reset(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), true)); + pending_layer()->picture_layer_tiling_set(), true, false)); EXPECT_TRUE(queue->IsEmpty()); } @@ -3715,7 +3715,7 @@ // No occlusion. int unoccluded_tile_count = 0; std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false, false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -3749,7 +3749,7 @@ unoccluded_tile_count = 0; queue.reset(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false, false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -3774,7 +3774,7 @@ unoccluded_tile_count = 0; queue.reset(new TilingSetRasterQueueAll( - pending_layer()->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false, false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile();
diff --git a/cc/tiles/picture_layer_tiling.h b/cc/tiles/picture_layer_tiling.h index d49d22e..d9c33a0 100644 --- a/cc/tiles/picture_layer_tiling.h +++ b/cc/tiles/picture_layer_tiling.h
@@ -126,6 +126,9 @@ void set_can_require_tiles_for_activation(bool can_require_tiles) { can_require_tiles_for_activation_ = can_require_tiles; } + bool can_require_tiles_for_activation() const { + return can_require_tiles_for_activation_; + } const scoped_refptr<RasterSource>& raster_source() const { return raster_source_;
diff --git a/cc/tiles/raster_tile_priority_queue_all.cc b/cc/tiles/raster_tile_priority_queue_all.cc index 0d54a59..c09da4a 100644 --- a/cc/tiles/raster_tile_priority_queue_all.cc +++ b/cc/tiles/raster_tile_priority_queue_all.cc
@@ -16,15 +16,22 @@ explicit RasterOrderComparator(TreePriority tree_priority) : tree_priority_(tree_priority) {} + // Note that in this function, we have to return true if and only if + // a is strictly lower priority than b. bool operator()( const std::unique_ptr<TilingSetRasterQueueAll>& a_queue, const std::unique_ptr<TilingSetRasterQueueAll>& b_queue) const { - // Note that in this function, we have to return true if and only if - // a is strictly lower priority than b. const TilePriority& a_priority = a_queue->Top().priority(); const TilePriority& b_priority = b_queue->Top().priority(); bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; + // If the priority bin is the same but one of the tiles is from a + // non-drawing layer, then the drawing layer has a higher priority. + if (b_priority.priority_bin == a_priority.priority_bin && + b_queue->is_drawing_layer() != a_queue->is_drawing_layer()) { + return b_queue->is_drawing_layer(); + } + // If the bin is the same but the resolution is not, then the order will be // determined by whether we prioritize low res or not. // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile @@ -63,8 +70,9 @@ PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set(); bool prioritize_low_res = tree_priority == SMOOTHNESS_TAKES_PRIORITY; std::unique_ptr<TilingSetRasterQueueAll> tiling_set_queue = - base::MakeUnique<TilingSetRasterQueueAll>(tiling_set, - prioritize_low_res); + base::MakeUnique<TilingSetRasterQueueAll>( + tiling_set, prioritize_low_res, + layer->contributes_to_drawn_render_surface()); // Queues will only contain non empty tiling sets. if (!tiling_set_queue->IsEmpty()) queues->push_back(std::move(tiling_set_queue));
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 6b22667..3b61ba6 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -1170,7 +1170,7 @@ // marked as ready to draw. for (int i = 0; i < 3; ++i) { std::unique_ptr<TilingSetRasterQueueAll> queue( - new TilingSetRasterQueueAll(tiling_set.get(), false)); + new TilingSetRasterQueueAll(tiling_set.get(), false, false)); // There are 3 bins in TilePriority. bool have_tiles[3] = {}; @@ -1282,7 +1282,7 @@ int eventually_bin_order_correct_count = 0; int eventually_bin_order_incorrect_count = 0; std::unique_ptr<TilingSetRasterQueueAll> queue( - new TilingSetRasterQueueAll(tiling_set.get(), false)); + new TilingSetRasterQueueAll(tiling_set.get(), false, false)); for (; !queue->IsEmpty(); queue->Pop()) { if (!last_tile.tile()) last_tile = queue->Top(); @@ -1439,7 +1439,7 @@ intersecting_rect, // Soon rect. intersecting_rect); // Eventually rect. std::unique_ptr<TilingSetRasterQueueAll> queue( - new TilingSetRasterQueueAll(tiling_set.get(), false)); + new TilingSetRasterQueueAll(tiling_set.get(), false, false)); EXPECT_FALSE(queue->IsEmpty()); } { @@ -1449,7 +1449,7 @@ intersecting_rect, // Soon rect. intersecting_rect); // Eventually rect. std::unique_ptr<TilingSetRasterQueueAll> queue( - new TilingSetRasterQueueAll(tiling_set.get(), false)); + new TilingSetRasterQueueAll(tiling_set.get(), false, false)); EXPECT_FALSE(queue->IsEmpty()); } { @@ -1459,7 +1459,7 @@ non_intersecting_rect, // Soon rect. intersecting_rect); // Eventually rect. std::unique_ptr<TilingSetRasterQueueAll> queue( - new TilingSetRasterQueueAll(tiling_set.get(), false)); + new TilingSetRasterQueueAll(tiling_set.get(), false, false)); EXPECT_FALSE(queue->IsEmpty()); } }
diff --git a/cc/tiles/tiling_set_raster_queue_all.cc b/cc/tiles/tiling_set_raster_queue_all.cc index adae8a8..f2c1916 100644 --- a/cc/tiles/tiling_set_raster_queue_all.cc +++ b/cc/tiles/tiling_set_raster_queue_all.cc
@@ -22,8 +22,11 @@ TilingSetRasterQueueAll::TilingSetRasterQueueAll( PictureLayerTilingSet* tiling_set, - bool prioritize_low_res) - : tiling_set_(tiling_set), current_stage_(0) { + bool prioritize_low_res, + bool is_drawing_layer) + : tiling_set_(tiling_set), + current_stage_(0), + is_drawing_layer_(is_drawing_layer) { DCHECK(tiling_set_); // Early out if the tiling set has no tilings.
diff --git a/cc/tiles/tiling_set_raster_queue_all.h b/cc/tiles/tiling_set_raster_queue_all.h index 73bb4c9e..e29736d 100644 --- a/cc/tiles/tiling_set_raster_queue_all.h +++ b/cc/tiles/tiling_set_raster_queue_all.h
@@ -22,12 +22,14 @@ class CC_EXPORT TilingSetRasterQueueAll { public: TilingSetRasterQueueAll(PictureLayerTilingSet* tiling_set, - bool prioritize_low_res); + bool prioritize_low_res, + bool is_drawing_layer); ~TilingSetRasterQueueAll(); const PrioritizedTile& Top() const; void Pop(); bool IsEmpty() const; + bool is_drawing_layer() const { return is_drawing_layer_; } private: // Helper base class for individual region iterators. @@ -190,6 +192,7 @@ // ideal pending high res. base::StackVector<IterationStage, 6> stages_; TilingIterator iterators_[NUM_ITERATORS]; + bool is_drawing_layer_ = false; DISALLOW_COPY_AND_ASSIGN(TilingSetRasterQueueAll); };
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index e289a34..f561445 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc
@@ -377,8 +377,8 @@ bool skip_layer = !is_root && (skip_draw_properties_computation || skip_for_invertibility); - layer->set_raster_even_if_not_in_rsll(skip_for_invertibility && - !skip_draw_properties_computation); + layer->set_raster_even_if_not_drawn(skip_for_invertibility && + !skip_draw_properties_computation); if (skip_layer) continue;
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index a26ee7f..3c50e689 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -8347,7 +8347,7 @@ // Since animated has singular transform, it is not be part of render // surface layer list but should be rastered. EXPECT_FALSE(animated->contributes_to_drawn_render_surface()); - EXPECT_TRUE(animated->raster_even_if_not_in_rsll()); + EXPECT_TRUE(animated->raster_even_if_not_drawn()); // The animated layer has a singular transform and maps to a non-empty rect in // clipped target space, so is treated as fully visible. @@ -8387,7 +8387,7 @@ // Since animated has singular transform, it is not be part of render // surface layer list but should be rastered. - EXPECT_TRUE(animated->raster_even_if_not_in_rsll()); + EXPECT_TRUE(animated->raster_even_if_not_drawn()); EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect()); }
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index b978d05..d90ce99 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -12414,5 +12414,136 @@ EXPECT_EQ(host_impl_->GetRasterColorSpace(), gfx::ColorSpace::CreateSRGB()); } +TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { + gfx::Size layer_bounds(500, 500); + + host_impl_->SetViewportSize(layer_bounds); + host_impl_->CreatePendingTree(); + std::unique_ptr<LayerImpl> scoped_root = + LayerImpl::Create(host_impl_->pending_tree(), 1); + scoped_root->SetBounds(layer_bounds); + LayerImpl* root = scoped_root.get(); + host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + + scoped_refptr<FakeRasterSource> raster_source( + FakeRasterSource::CreateFilled(layer_bounds)); + std::unique_ptr<FakePictureLayerImpl> scoped_animated_transform_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 2, raster_source); + scoped_animated_transform_layer->SetBounds(layer_bounds); + scoped_animated_transform_layer->SetDrawsContent(true); + gfx::Transform singular; + singular.Scale3d(6.f, 6.f, 0.f); + scoped_animated_transform_layer->test_properties()->transform = singular; + FakePictureLayerImpl* animated_transform_layer = + scoped_animated_transform_layer.get(); + root->test_properties()->AddChild(std::move(scoped_animated_transform_layer)); + + // A layer with a non-invertible transform is not drawn or rasterized. Since + // this layer is not rasterized, we shouldn't be creating any tilings for it. + host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + EXPECT_FALSE(animated_transform_layer->HasValidTilePriorities()); + EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); + host_impl_->pending_tree()->UpdateDrawProperties(false); + EXPECT_FALSE(animated_transform_layer->raster_even_if_not_drawn()); + EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); + EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); + + // Now add a transform animation to this layer. While we don't drawn layers + // with non-invertible transforms, we still raster them if there is a + // transform animation. + host_impl_->pending_tree()->SetElementIdsForTesting(); + TransformOperations start_transform_operations; + start_transform_operations.AppendMatrix(singular); + TransformOperations end_transform_operations; + AddAnimatedTransformToElementWithPlayer( + animated_transform_layer->element_id(), timeline(), 10.0, + start_transform_operations, end_transform_operations); + + // The layer is still not drawn, but it will be rasterized. Since the layer is + // rasterized, we should be creating tilings for it in UpdateDrawProperties. + // However, none of these tiles should be required for activation. + host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + host_impl_->pending_tree()->UpdateDrawProperties(false); + EXPECT_TRUE(animated_transform_layer->raster_even_if_not_drawn()); + EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); + EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 1u); + EXPECT_FALSE(animated_transform_layer->tilings() + ->tiling_at(0) + ->can_require_tiles_for_activation()); +} + +TEST_F(LayerTreeHostImplTest, RasterTilePrioritizationForNonDrawingLayers) { + gfx::Size layer_bounds(500, 500); + + host_impl_->SetViewportSize(layer_bounds); + host_impl_->CreatePendingTree(); + std::unique_ptr<LayerImpl> scoped_root = + LayerImpl::Create(host_impl_->pending_tree(), 1); + scoped_root->SetBounds(layer_bounds); + LayerImpl* root = scoped_root.get(); + host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + + scoped_refptr<FakeRasterSource> raster_source( + FakeRasterSource::CreateFilled(layer_bounds)); + + std::unique_ptr<FakePictureLayerImpl> scoped_hidden_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 2, raster_source); + scoped_hidden_layer->SetBounds(layer_bounds); + scoped_hidden_layer->SetDrawsContent(true); + scoped_hidden_layer->set_contributes_to_drawn_render_surface(true); + FakePictureLayerImpl* hidden_layer = scoped_hidden_layer.get(); + root->test_properties()->AddChild(std::move(scoped_hidden_layer)); + + std::unique_ptr<FakePictureLayerImpl> scoped_drawing_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 3, raster_source); + scoped_drawing_layer->SetBounds(layer_bounds); + scoped_drawing_layer->SetDrawsContent(true); + scoped_drawing_layer->set_contributes_to_drawn_render_surface(true); + FakePictureLayerImpl* drawing_layer = scoped_drawing_layer.get(); + root->test_properties()->AddChild(std::move(scoped_drawing_layer)); + + gfx::Rect layer_rect(0, 0, 500, 500); + gfx::Rect empty_rect(0, 0, 0, 0); + host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + + hidden_layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source); + PictureLayerTiling* hidden_tiling = hidden_layer->tilings()->tiling_at(0); + hidden_tiling->set_resolution(TileResolution::LOW_RESOLUTION); + hidden_tiling->CreateAllTilesForTesting(); + hidden_tiling->SetTilePriorityRectsForTesting( + layer_rect, // Visible rect. + layer_rect, // Skewport rect. + layer_rect, // Soon rect. + layer_rect); // Eventually rect. + + drawing_layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source); + PictureLayerTiling* drawing_tiling = drawing_layer->tilings()->tiling_at(0); + drawing_tiling->set_resolution(TileResolution::HIGH_RESOLUTION); + drawing_tiling->CreateAllTilesForTesting(); + drawing_tiling->SetTilePriorityRectsForTesting( + layer_rect, // Visible rect. + layer_rect, // Skewport rect. + layer_rect, // Soon rect. + layer_rect); // Eventually rect. + + // Both layers are drawn. Since the hidden layer has a low resolution tiling, + // in smoothness priority mode its tile is higher priority. + std::unique_ptr<RasterTilePriorityQueue> queue = + host_impl_->BuildRasterQueue(TreePriority::SMOOTHNESS_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); + EXPECT_EQ(queue->Top().tile()->layer_id(), 2); + + // Hide the hidden layer and set it to so it still rasters. Now the drawing + // layer should be prioritized over the hidden layer. + hidden_layer->set_contributes_to_drawn_render_surface(false); + hidden_layer->set_raster_even_if_not_drawn(true); + queue = host_impl_->BuildRasterQueue(TreePriority::SMOOTHNESS_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); + EXPECT_EQ(queue->Top().tile()->layer_id(), 3); +} + } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index abf3277..945b5ec 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -1155,7 +1155,7 @@ size_t layers_updated_count = 0; bool tile_priorities_updated = false; for (PictureLayerImpl* layer : picture_layers_) { - if (!layer->contributes_to_drawn_render_surface()) + if (!layer->HasValidTilePriorities()) continue; ++layers_updated_count; tile_priorities_updated |= layer->UpdateTiles();
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 25d2f1eb..3eec53a 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -94,10 +94,10 @@ "//components/strings:components_strings_grd", "//content/public/android:content_java_resources", "//third_party/android_data_chart:android_data_chart_java_resources", + "//third_party/android_media:android_media_resources", "//third_party/android_tools:android_support_design_java", "//third_party/android_tools:android_support_transition_java", "//third_party/android_tools:android_support_v7_appcompat_java", - "//third_party/android_tools:android_support_v7_mediarouter_java", "//third_party/android_tools:android_support_v7_recyclerview_java", ] custom_package = "org.chromium.chrome" @@ -217,6 +217,7 @@ "//third_party/WebKit/public:android_mojo_bindings_java", "//third_party/WebKit/public:blink_headers_java", "//third_party/android_data_chart:android_data_chart_java", + "//third_party/android_media:android_media_java", "//third_party/android_protobuf:protobuf_nano_javalib", "//third_party/android_swipe_refresh:android_swipe_refresh_java", "//third_party/android_tools:android_gcm_java",
diff --git a/chrome/android/java/res/layout/expanded_cast_controller.xml b/chrome/android/java/res/layout/expanded_cast_controller.xml index 64856f6..340cef16 100644 --- a/chrome/android/java/res/layout/expanded_cast_controller.xml +++ b/chrome/android/java/res/layout/expanded_cast_controller.xml
@@ -32,4 +32,10 @@ android:textSize="14sp" android:textStyle="bold" android:textColor="@color/cast_media_controller_text" /> + <org.chromium.third_party.android.media.MediaController + android:id="@+id/cast_media_controller" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom"> + </org.chromium.third_party.android.media.MediaController> </FrameLayout>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index a4dc391..4a74410 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -221,5 +221,5 @@ <color name="selectable_list_item_highlight_color">#804281f4</color> <color name="media_viewer_bg">#000000</color> <color name="image_viewer_bg">#0e0e0e</color> - <color name="cast_media_controller_text">#bebebe</color> + </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java index 1d7416f..017c3c65 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java
@@ -11,6 +11,7 @@ import android.os.Bundle; import android.os.Handler; import android.support.v4.app.FragmentActivity; +import android.support.v4.media.session.PlaybackStateCompat; import android.text.TextUtils; import android.view.KeyEvent; import android.view.View; @@ -18,8 +19,6 @@ import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; -import android.widget.MediaController; -import android.widget.MediaController.MediaPlayerControl; import android.widget.TextView; import com.google.android.gms.cast.CastMediaControlIntent; @@ -27,6 +26,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; import org.chromium.chrome.browser.metrics.MediaNotificationUma; +import org.chromium.third_party.android.media.MediaController; /** * The activity that's opened by clicking the video flinging (casting) notification. @@ -39,48 +39,10 @@ // The alpha value for the poster/placeholder image, an integer between 0 and 256 (opaque). private static final int POSTER_IMAGE_ALPHA = 200; - // Subclass of {@link android.widget.MediaController} that never hides itself. - class AlwaysShownMediaController extends MediaController { - public AlwaysShownMediaController(Context context) { - super(context); - } - - @Override - public void show(int timeout) { - // Never auto-hide the controls. - super.show(0); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - int keyCode = event.getKeyCode(); - // MediaController hides the controls when back or menu are pressed. - // Close the activity on back and ignore menu. - if (keyCode == KeyEvent.KEYCODE_BACK) { - finish(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_MENU) { - return true; - } - return super.dispatchKeyEvent(event); - } - - @Override - public void hide() { - // Don't allow the controls to hide until explicitly asked to do so from the host - // activity. - } - - /** - * Actually hides the controls which prevents some window leaks. - */ - public void cleanup() { - super.hide(); - } - }; - private Handler mHandler; - private AlwaysShownMediaController mMediaController; + // We don't use the standard android.media.MediaController, but a custom one. + // See the class itself for details. + private MediaController mMediaController; private FullscreenMediaRouteButton mMediaRouteButton; private MediaRouteController mMediaRouteController; private RemoteVideoInfo mVideoInfo; @@ -89,51 +51,14 @@ /** * Handle actions from on-screen media controls. */ - private MediaPlayerControl mMediaPlayerControl = new MediaPlayerControl() { + private MediaController.Delegate mControllerDelegate = new MediaController.Delegate() { @Override - public boolean canPause() { - return true; - } - - @Override - public boolean canSeekBackward() { - return getDuration() > 0 && getCurrentPosition() > 0; - } - - @Override - public boolean canSeekForward() { - return getDuration() > 0 && getCurrentPosition() < getDuration(); - } - - @Override - public int getAudioSessionId() { - // TODO(avayvod): not sure 0 is a valid value to return. - return 0; - } - - @Override - public int getBufferPercentage() { - int duration = getDuration(); - if (duration == 0) return 0; - return (getCurrentPosition() * 100) / duration; - } - - @Override - public int getCurrentPosition() { - if (mMediaRouteController == null) return 0; - return (int) mMediaRouteController.getPosition(); - } - - @Override - public int getDuration() { - if (mMediaRouteController == null) return 0; - return (int) mMediaRouteController.getDuration(); - } - - @Override - public boolean isPlaying() { - if (mMediaRouteController == null) return false; - return mMediaRouteController.isPlaying(); + public void play() { + if (mMediaRouteController == null) return; + mMediaRouteController.resume(); + RecordCastAction.recordFullscreenControlsAction( + RecordCastAction.FULLSCREEN_CONTROLS_RESUME, + mMediaRouteController.getMediaStateListener() != null); } @Override @@ -146,28 +71,54 @@ } @Override - public void start() { - if (mMediaRouteController == null) return; - mMediaRouteController.resume(); - RecordCastAction.recordFullscreenControlsAction( - RecordCastAction.FULLSCREEN_CONTROLS_RESUME, - mMediaRouteController.getMediaStateListener() != null); + public long getDuration() { + if (mMediaRouteController == null) return 0; + return mMediaRouteController.getDuration(); } @Override - public void seekTo(int pos) { + public long getPosition() { + if (mMediaRouteController == null) return 0; + return mMediaRouteController.getPosition(); + } + + @Override + public void seekTo(long pos) { if (mMediaRouteController == null) return; mMediaRouteController.seekTo(pos); RecordCastAction.recordFullscreenControlsAction( RecordCastAction.FULLSCREEN_CONTROLS_SEEK, mMediaRouteController.getMediaStateListener() != null); } + + @Override + public boolean isPlaying() { + if (mMediaRouteController == null) return false; + return mMediaRouteController.isPlaying(); + } + + @Override + public long getActionFlags() { + long flags = + PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD; + if (mMediaRouteController != null && mMediaRouteController.isPlaying()) { + flags |= PlaybackStateCompat.ACTION_PAUSE; + } else { + flags |= PlaybackStateCompat.ACTION_PLAY; + } + return flags; + } }; - private Runnable mControlsUpdater = new Runnable() { + private Runnable mProgressUpdater = new Runnable() { @Override public void run() { - mMediaController.show(); + if (mMediaRouteController.isPlaying()) { + mMediaController.updateProgress(); + mHandler.postDelayed(this, PROGRESS_UPDATE_PERIOD_IN_MS); + } else { + mHandler.removeCallbacks(this); + } } }; @@ -201,10 +152,8 @@ mMediaRouteController.addUiListener(this); // Create and initialize the media control UI. - mMediaController = new AlwaysShownMediaController(this); - mMediaController.setEnabled(true); - mMediaController.setMediaPlayer(mMediaPlayerControl); - mMediaController.setAnchorView(rootView); + mMediaController = (MediaController) findViewById(R.id.cast_media_controller); + mMediaController.setDelegate(mControllerDelegate); View button = getLayoutInflater().inflate(R.layout.cast_controller_media_route_button, rootView, false); @@ -219,13 +168,16 @@ } // Initialize the video info. - mVideoInfo = new RemoteVideoInfo(null, 0, RemoteVideoInfo.PlayerState.STOPPED, 0, null); + setVideoInfo(new RemoteVideoInfo(null, 0, RemoteVideoInfo.PlayerState.STOPPED, 0, null)); + + mMediaController.refresh(); + + scheduleProgressUpdate(); } @Override protected void onResume() { super.onResume(); - if (mVideoInfo.state == PlayerState.FINISHED) finish(); if (mMediaRouteController == null) return; @@ -241,9 +193,6 @@ Bitmap posterBitmap = mMediaRouteController.getPoster(); if (posterBitmap != null) iv.setImageBitmap(posterBitmap); iv.setImageAlpha(POSTER_IMAGE_ALPHA); - - // Can't show the media controller until attached to window. - scheduleControlsUpdate(); } @Override @@ -264,12 +213,10 @@ } private void cleanup() { - if (mHandler != null) mHandler.removeCallbacks(mControlsUpdater); + if (mHandler != null) mHandler.removeCallbacks(mProgressUpdater); if (mMediaRouteController != null) mMediaRouteController.removeUiListener(this); mMediaRouteController = null; - mControlsUpdater = null; - mMediaController.cleanup(); - mMediaController = null; + mProgressUpdater = null; } /** @@ -279,12 +226,14 @@ if ((mVideoInfo == null) ? (videoInfo == null) : mVideoInfo.equals(videoInfo)) return; mVideoInfo = videoInfo; - updateUi(); + onVideoInfoChanged(); } - private void scheduleControlsUpdate() { - mHandler.removeCallbacks(mControlsUpdater); - mHandler.post(mControlsUpdater); + private void scheduleProgressUpdate() { + mHandler.removeCallbacks(mProgressUpdater); + if (mMediaRouteController.isPlaying()) { + mHandler.post(mProgressUpdater); + } } /** @@ -294,6 +243,14 @@ if (TextUtils.equals(mScreenName, screenName)) return; mScreenName = screenName; + onScreenNameChanged(); + } + + private void onVideoInfoChanged() { + updateUi(); + } + + private void onScreenNameChanged() { updateUi(); } @@ -308,7 +265,7 @@ TextView castTextView = (TextView) findViewById(R.id.cast_screen_title); castTextView.setText(castText); - scheduleControlsUpdate(); + mMediaController.refresh(); } @Override @@ -337,7 +294,7 @@ videoInfo.state = newState; setVideoInfo(videoInfo); - scheduleControlsUpdate(); + scheduleProgressUpdate(); if (newState == PlayerState.FINISHED || newState == PlayerState.INVALIDATED) { // If we are switching to a finished state, stop the notifications.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 67b5bd8e..1f6d25d 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -3589,6 +3589,9 @@ <message name="IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS" desc="Permission string for access to data on all websites."> Read and change all your data on the websites you visit </message> + <message name="IDS_EXTENSION_PROMPT_WARNING_CURRENT_HOST" desc="Permission string for access to data on current website."> + Read and change all your data on the current website when invoked + </message> <message name="IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS_READ_ONLY" desc="Permission string for read-only access to data on all websites."> Read all your data on the websites you visit </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 4bc606a..c66a68d1 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -401,14 +401,8 @@ "external_protocol/external_protocol_handler.h", "external_protocol/external_protocol_observer.cc", "external_protocol/external_protocol_observer.h", - "favicon/chrome_fallback_icon_client.cc", - "favicon/chrome_fallback_icon_client.h", - "favicon/chrome_fallback_icon_client_factory.cc", - "favicon/chrome_fallback_icon_client_factory.h", "favicon/chrome_favicon_client.cc", "favicon/chrome_favicon_client.h", - "favicon/fallback_icon_service_factory.cc", - "favicon/fallback_icon_service_factory.h", "favicon/favicon_service_factory.cc", "favicon/favicon_service_factory.h", "favicon/favicon_utils.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 588d5e6..bb25ae82 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2967,6 +2967,11 @@ kOmniboxUIMaxAutocompleteMatchesVariations, "OmniboxUIMaxAutocompleteVariations")}, + {"omnibox-ui-vertical-layout", + flag_descriptions::kOmniboxUIVerticalLayoutName, + flag_descriptions::kOmniboxUIVerticalLayoutDescription, kOsDesktop, + FEATURE_VALUE_TYPE(omnibox::kUIExperimentVerticalLayout)}, + {"omnibox-ui-vertical-margin", flag_descriptions::kOmniboxUIVerticalMarginName, flag_descriptions::kOmniboxUIVerticalMarginDescription, kOsDesktop,
diff --git a/chrome/browser/android/vr_shell/color_scheme.cc b/chrome/browser/android/vr_shell/color_scheme.cc index a662ed8..d39d5e5 100644 --- a/chrome/browser/android/vr_shell/color_scheme.cc +++ b/chrome/browser/android/vr_shell/color_scheme.cc
@@ -16,16 +16,16 @@ return; ColorScheme& normal_scheme = kColorSchemes[ColorScheme::kModeNormal]; - normal_scheme.horizon = {0.89, 0.89, 0.89, 1.0}; - normal_scheme.floor = {0.811, 0.811, 0.811, 1.0}; - normal_scheme.ceiling = {0.859, 0.859, 0.859, 1.0}; - normal_scheme.floor_grid = {1.0, 1.0, 1.0, 1.0}; + normal_scheme.horizon = 0xFFE3E3E3; + normal_scheme.floor = 0xFFCFCFCF; + normal_scheme.ceiling = 0xFFDBDBDB; + normal_scheme.floor_grid = SK_ColorWHITE; ColorScheme& fullscreen_scheme = kColorSchemes[ColorScheme::kModeFullscreen]; - fullscreen_scheme.horizon = {0.039215686, 0.0, 0.082352941, 1.0}; - fullscreen_scheme.floor = {0.02745098, 0.058823529, 0.109803922, 1.0}; - fullscreen_scheme.ceiling = {0.015686275, 0.031372549, 0.058823529, 1.0}; - fullscreen_scheme.floor_grid = {0.639215686, 0.878431373, 1.0, 0.5}; + fullscreen_scheme.horizon = 0xFF0A0015; + fullscreen_scheme.floor = 0xFF070F1C; + fullscreen_scheme.ceiling = 0xFF04080F; + fullscreen_scheme.floor_grid = 0x80A3E0FF; initialized = true; }
diff --git a/chrome/browser/android/vr_shell/color_scheme.h b/chrome/browser/android/vr_shell/color_scheme.h index 1d304397..76bb78013 100644 --- a/chrome/browser/android/vr_shell/color_scheme.h +++ b/chrome/browser/android/vr_shell/color_scheme.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_ANDROID_VR_SHELL_COLOR_SCHEME_H_ #define CHROME_BROWSER_ANDROID_VR_SHELL_COLOR_SCHEME_H_ -#include "device/vr/vr_types.h" +#include "third_party/skia/include/core/SkColor.h" namespace vr_shell { @@ -21,12 +21,10 @@ // These colors should be named generically, if possible, so that they can be // meaningfully reused by multiple elements. - // TODO(vollick): we should replace all use of vr::Colorf with SkColor (see - // crbug.com/726363). - vr::Colorf horizon; - vr::Colorf floor; - vr::Colorf ceiling; - vr::Colorf floor_grid; + SkColor horizon; + SkColor floor; + SkColor ceiling; + SkColor floor_grid; }; } // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.cc b/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.cc index 8935b98..8e938c20 100644 --- a/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.cc +++ b/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.cc
@@ -6,13 +6,17 @@ #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" #include "device/vr/vr_math.h" +#include "third_party/skia/include/core/SkColor.h" namespace vr_shell { -ScreenDimmer::ScreenDimmer() - : inner_color_({0.05f, 0.05f, 0.05f, 0.8f}), - outer_color_({0, 0, 0, 0.9f}), - opacity_(0.9f) {} +namespace { +static const SkColor kDimmerInnerColor = 0xCC0D0D0D; +static const SkColor kDimmerOuterColor = 0xE6000000; +static const float kDimmerOpacity = 0.9f; +} // namespace + +ScreenDimmer::ScreenDimmer() {} ScreenDimmer::~ScreenDimmer() = default; @@ -25,8 +29,8 @@ vr::Mat4f m; vr::SetIdentityM(&m); vr::ScaleM(m, {2.0f, 2.0f, 1.0f}, &m); - renderer->GetGradientQuadRenderer()->Draw(m, outer_color_, inner_color_, - opacity_); + renderer->GetGradientQuadRenderer()->Draw(m, kDimmerOuterColor, + kDimmerInnerColor, kDimmerOpacity); } } // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.h b/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.h index 1e1c958..c2e83f9 100644 --- a/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.h +++ b/chrome/browser/android/vr_shell/ui_elements/screen_dimmer.h
@@ -7,7 +7,6 @@ #include "base/macros.h" #include "chrome/browser/android/vr_shell/ui_elements/ui_element.h" -#include "device/vr/vr_types.h" namespace vr_shell { @@ -22,11 +21,6 @@ void Render(VrShellRenderer* renderer, vr::Mat4f view_proj_matrix) const final; - private: - vr::Colorf inner_color_; - vr::Colorf outer_color_; - float opacity_; - DISALLOW_COPY_AND_ASSIGN(ScreenDimmer); };
diff --git a/chrome/browser/android/vr_shell/ui_elements/ui_element.h b/chrome/browser/android/vr_shell/ui_elements/ui_element.h index a954948..71dd842c 100644 --- a/chrome/browser/android/vr_shell/ui_elements/ui_element.h +++ b/chrome/browser/android/vr_shell/ui_elements/ui_element.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "chrome/browser/android/vr_shell/ui_elements/ui_element_debug_id.h" #include "device/vr/vr_types.h" +#include "third_party/skia/include/core/SkColor.h" namespace base { class TimeTicks; @@ -205,13 +206,11 @@ Fill fill() const { return fill_; } void set_fill(Fill fill) { fill_ = fill; } - vr::Colorf edge_color() const { return edge_color_; } - void set_edge_color(const vr::Colorf& edge_color) { - edge_color_ = edge_color; - } + SkColor edge_color() const { return edge_color_; } + void set_edge_color(const SkColor& edge_color) { edge_color_ = edge_color; } - vr::Colorf center_color() const { return center_color_; } - void set_center_color(const vr::Colorf& center_color) { + SkColor center_color() const { return center_color_; } + void set_center_color(const SkColor& center_color) { center_color_ = center_color; } @@ -299,8 +298,8 @@ Fill fill_ = Fill::NONE; - vr::Colorf edge_color_ = {1.0f, 1.0f, 1.0f, 1.0f}; - vr::Colorf center_color_ = {1.0f, 1.0f, 1.0f, 1.0f}; + SkColor edge_color_ = SK_ColorWHITE; + SkColor center_color_ = SK_ColorWHITE; int gridline_count_ = 1;
diff --git a/chrome/browser/android/vr_shell/ui_scene.cc b/chrome/browser/android/vr_shell/ui_scene.cc index 31348537..39fd3aa 100644 --- a/chrome/browser/android/vr_shell/ui_scene.cc +++ b/chrome/browser/android/vr_shell/ui_scene.cc
@@ -175,11 +175,11 @@ return !GetHeadLockedElements().empty(); } -void UiScene::SetBackgroundColor(const vr::Colorf& color) { +void UiScene::SetBackgroundColor(const SkColor& color) { background_color_ = color; } -const vr::Colorf& UiScene::GetBackgroundColor() const { +const SkColor& UiScene::GetBackgroundColor() const { return background_color_; }
diff --git a/chrome/browser/android/vr_shell/ui_scene.h b/chrome/browser/android/vr_shell/ui_scene.h index 5a313fd1..119fec70 100644 --- a/chrome/browser/android/vr_shell/ui_scene.h +++ b/chrome/browser/android/vr_shell/ui_scene.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "chrome/browser/android/vr_shell/ui_elements/ui_element_debug_id.h" -#include "device/vr/vr_types.h" +#include "third_party/skia/include/core/SkColor.h" namespace base { class ListValue; @@ -66,8 +66,8 @@ std::vector<const UiElement*> GetHeadLockedElements() const; bool HasVisibleHeadLockedElements() const; - void SetBackgroundColor(const vr::Colorf& color); - const vr::Colorf& GetBackgroundColor() const; + void SetBackgroundColor(const SkColor& color); + const SkColor& GetBackgroundColor() const; void SetBackgroundDistance(float distance); float GetBackgroundDistance() const; @@ -85,7 +85,7 @@ std::vector<std::unique_ptr<UiElement>> ui_elements_; UiElement* content_element_ = nullptr; - vr::Colorf background_color_ = {0.1f, 0.1f, 0.1f, 1.0f}; + SkColor background_color_ = 0xFF1A1A1A; float background_distance_ = 10.0f; bool webvr_rendering_enabled_ = true; bool gl_initialized_ = false;
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc index d064981..8a242b1 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager.cc +++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -364,8 +364,7 @@ floor_->set_center_color(color_scheme().floor); floor_->set_edge_color(color_scheme().horizon); floor_grid_->set_center_color(color_scheme().floor_grid); - vr::Colorf floor_grid_edge_color = color_scheme().floor_grid; - floor_grid_edge_color.a = 0.0; + SkColor floor_grid_edge_color = SkColorSetA(color_scheme().floor_grid, 0); floor_grid_->set_edge_color(floor_grid_edge_color); }
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc b/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc index 5afb29e..bf7078e 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc +++ b/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc
@@ -84,11 +84,6 @@ std::unique_ptr<MockBrowserInterface> browser_; std::unique_ptr<UiScene> scene_; std::unique_ptr<UiSceneManager> manager_; - - bool ColorEquals(vr::Colorf expected, vr::Colorf actual) { - return (expected.r == actual.r) && (expected.g == actual.g) && - (expected.b == actual.b) && (expected.a == actual.a); - } }; TEST_F(UiSceneManagerTest, ExitPresentAndFullscreenOnAppButtonClick) { @@ -158,7 +153,7 @@ MakeManager(kNotInCct, kNotInWebVr); // Hold onto the background color to make sure it changes. - vr::Colorf initial_background = scene_->GetBackgroundColor(); + SkColor initial_background = scene_->GetBackgroundColor(); for (const auto& element : scene_->GetUiElements()) { SCOPED_TRACE(element->debug_id()); @@ -181,7 +176,7 @@ { SCOPED_TRACE("Entered Fullsceen"); // Make sure background has changed for fullscreen. - EXPECT_FALSE(ColorEquals(initial_background, scene_->GetBackgroundColor())); + EXPECT_NE(initial_background, scene_->GetBackgroundColor()); } // Exit fullscreen. @@ -196,7 +191,7 @@ } { SCOPED_TRACE("Exited Fullsceen"); - EXPECT_TRUE(ColorEquals(initial_background, scene_->GetBackgroundColor())); + EXPECT_EQ(initial_background, scene_->GetBackgroundColor()); } }
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index 5369bbf..9fffc43 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -1132,9 +1132,11 @@ glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); - const vr::Colorf& backgroundColor = scene_->GetBackgroundColor(); - glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, - backgroundColor.a); + const SkColor backgroundColor = scene_->GetBackgroundColor(); + glClearColor(SkColorGetR(backgroundColor) / 255.0, + SkColorGetG(backgroundColor) / 255.0, + SkColorGetB(backgroundColor) / 255.0, + SkColorGetA(backgroundColor) / 255.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } std::vector<const UiElement*> elements = scene_->GetWorldElements();
diff --git a/chrome/browser/android/vr_shell/vr_shell_renderer.cc b/chrome/browser/android/vr_shell/vr_shell_renderer.cc index b1ddae5..1390d68 100644 --- a/chrome/browser/android/vr_shell/vr_shell_renderer.cc +++ b/chrome/browser/android/vr_shell/vr_shell_renderer.cc
@@ -262,6 +262,11 @@ } } +void SetColorUniform(GLuint handle, SkColor c) { + glUniform4f(handle, SkColorGetR(c) / 255.0, SkColorGetG(c) / 255.0, + SkColorGetB(c) / 255.0, SkColorGetA(c) / 255.0); +} + } // namespace namespace vr_shell { @@ -692,8 +697,8 @@ } void GradientQuadRenderer::Draw(const vr::Mat4f& view_proj_matrix, - const vr::Colorf& edge_color, - const vr::Colorf& center_color, + SkColor edge_color, + SkColor center_color, float opacity) { PrepareToDraw(model_view_proj_matrix_handle_, view_proj_matrix); @@ -701,10 +706,8 @@ glUniform1f(scene_radius_handle_, kHalfSize); // Set the edge color to the fog color so that it seems to fade out. - glUniform4f(edge_color_handle_, edge_color.r, edge_color.g, edge_color.b, - edge_color.a); - glUniform4f(center_color_handle_, center_color.r, center_color.g, - center_color.b, center_color.a); + SetColorUniform(edge_color_handle_, edge_color); + SetColorUniform(center_color_handle_, center_color); glUniform1f(opacity_handle_, opacity); glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); @@ -726,8 +729,8 @@ } void GradientGridRenderer::Draw(const vr::Mat4f& view_proj_matrix, - const vr::Colorf& edge_color, - const vr::Colorf& center_color, + SkColor edge_color, + SkColor center_color, int gridline_count, float opacity) { // In case the tile number changed we have to regenerate the grid lines. @@ -745,10 +748,8 @@ glUniform1f(scene_radius_handle_, kHalfSize); // Set the edge color to the fog color so that it seems to fade out. - glUniform4f(edge_color_handle_, edge_color.r, edge_color.g, edge_color.b, - edge_color.a); - glUniform4f(center_color_handle_, center_color.r, center_color.g, - center_color.b, center_color.a); + SetColorUniform(edge_color_handle_, edge_color); + SetColorUniform(center_color_handle_, center_color); glUniform1f(opacity_handle_, opacity); // Draw the grid.
diff --git a/chrome/browser/android/vr_shell/vr_shell_renderer.h b/chrome/browser/android/vr_shell/vr_shell_renderer.h index 7a046ab..5759fea 100644 --- a/chrome/browser/android/vr_shell/vr_shell_renderer.h +++ b/chrome/browser/android/vr_shell/vr_shell_renderer.h
@@ -233,8 +233,8 @@ ~GradientQuadRenderer() override; void Draw(const vr::Mat4f& view_proj_matrix, - const vr::Colorf& edge_color, - const vr::Colorf& center_color, + SkColor edge_color, + SkColor center_color, float opacity); private: @@ -253,8 +253,8 @@ ~GradientGridRenderer() override; void Draw(const vr::Mat4f& view_proj_matrix, - const vr::Colorf& edge_color, - const vr::Colorf& center_color, + SkColor edge_color, + SkColor center_color, int gridline_count, float opacity);
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json index f03b03a8..887404b 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -50,6 +50,7 @@ "dom_distiller::mojom::DistillerJavaScriptService", "extensions::KeepAlive", "extensions::mime_handler::MimeHandlerService", + "extensions::mojom::InlineInstall", "media_router::mojom::MediaRouter", "page_load_metrics::mojom::PageLoadMetrics", "password_manager::mojom::CredentialManager",
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 6427015..f22e7aa 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -463,6 +463,8 @@ "events/system_key_event_listener.h", "events/xinput_hierarchy_changed_event_listener.cc", "events/xinput_hierarchy_changed_event_listener.h", + "extensions/active_tab_permission_granter_delegate_chromeos.cc", + "extensions/active_tab_permission_granter_delegate_chromeos.h", "extensions/default_app_order.cc", "extensions/default_app_order.h", "extensions/device_local_account_external_policy_loader.cc", @@ -1609,6 +1611,7 @@ "drive/write_on_cache_file_unittest.cc", "events/event_rewriter_unittest.cc", "events/keyboard_driven_event_rewriter_unittest.cc", + "extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc", "extensions/default_app_order_unittest.cc", "extensions/device_local_account_external_policy_loader_unittest.cc", "extensions/device_local_account_management_policy_provider_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc new file mode 100644 index 0000000..03377d5 --- /dev/null +++ b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h" + +#include "chrome/browser/chromeos/extensions/public_session_permission_helper.h" +#include "chrome/browser/profiles/profiles_state.h" +#include "extensions/common/extension.h" +#include "extensions/common/permissions/api_permission.h" + +namespace extensions { + +ActiveTabPermissionGranterDelegateChromeOS:: + ActiveTabPermissionGranterDelegateChromeOS() {} + +ActiveTabPermissionGranterDelegateChromeOS:: + ~ActiveTabPermissionGranterDelegateChromeOS() {} + +bool ActiveTabPermissionGranterDelegateChromeOS::ShouldGrantActiveTab( + const Extension* extension, + content::WebContents* web_contents) { + bool already_handled = permission_helper::HandlePermissionRequest( + *extension, {APIPermission::kActiveTab}, web_contents, + permission_helper::RequestResolvedCallback(), + permission_helper::PromptFactory()); + + return already_handled && permission_helper::PermissionAllowed( + extension, APIPermission::kActiveTab); +} + +} // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h new file mode 100644 index 0000000..83ecfce1e --- /dev/null +++ b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_ACTIVE_TAB_PERMISSION_GRANTER_DELEGATE_CHROMEOS_H_ +#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_ACTIVE_TAB_PERMISSION_GRANTER_DELEGATE_CHROMEOS_H_ + +#include "base/macros.h" +#include "chrome/browser/extensions/active_tab_permission_granter.h" + +namespace content { +class WebContents; +} + +namespace extensions { +class Extension; + +// In Public Sessions, apps and extensions are force-installed by admin policy +// so the user does not get a chance to review the permissions for these apps. +// This is not acceptable from a security standpoint, so we show a permission +// prompt the first time an extension tries to use activeTab permission (unless +// the extension is whitelisted). +class ActiveTabPermissionGranterDelegateChromeOS + : public ActiveTabPermissionGranter::Delegate { + public: + ActiveTabPermissionGranterDelegateChromeOS(); + ~ActiveTabPermissionGranterDelegateChromeOS() override; + + // ActiveTabPermissionGranter::Delegate + bool ShouldGrantActiveTab(const Extension* extension, + content::WebContents* web_contents) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ActiveTabPermissionGranterDelegateChromeOS); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_ACTIVE_TAB_PERMISSION_GRANTER_DELEGATE_CHROMEOS_H_
diff --git a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc new file mode 100644 index 0000000..9cca475 --- /dev/null +++ b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc
@@ -0,0 +1,85 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h" + +#include <string> + +#include "base/run_loop.h" +#include "chrome/browser/chromeos/extensions/public_session_permission_helper.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "chromeos/login/scoped_test_public_session_login_state.h" +#include "extensions/browser/extension_dialog_auto_confirm.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace extensions { + +namespace { + +const char kWhitelistedId[] = "cbkkbcmdlboombapidmoeolnmdacpkch"; +// Use an extension ID that will never be whitelisted. +const char kNonWhitelistedId[] = "bogus"; + +scoped_refptr<Extension> CreateExtension(const std::string& id) { + return ExtensionBuilder() + .SetManifest( + DictionaryBuilder().Set("name", "test").Set("version", "0.1").Build()) + .SetID(id) + .Build(); +} + +} // namespace + +class ActiveTabPermissionGranterDelegateChromeOSTest + : public ChromeRenderViewHostTestHarness { + protected: + void SetUp() override; + void TearDown() override; + + ActiveTabPermissionGranterDelegateChromeOS delegate_; + chromeos::ScopedTestPublicSessionLoginState login_state_; +}; + +void ActiveTabPermissionGranterDelegateChromeOSTest::SetUp() { + ChromeRenderViewHostTestHarness::SetUp(); +} + +void ActiveTabPermissionGranterDelegateChromeOSTest::TearDown() { + permission_helper::ResetPermissionsForTesting(); + ChromeRenderViewHostTestHarness::TearDown(); +} + +TEST_F(ActiveTabPermissionGranterDelegateChromeOSTest, GrantedForWhitelisted) { + auto extension = CreateExtension(kWhitelistedId); + EXPECT_TRUE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); +} + +TEST_F(ActiveTabPermissionGranterDelegateChromeOSTest, + RejectedForNonWhitelisted) { + auto extension = CreateExtension(kNonWhitelistedId); + // Deny the permission request. + ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::CANCEL); + // First request is always rejected (by design). + EXPECT_FALSE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + // Spin the loop, allowing the dialog to be resolved. + base::RunLoop().RunUntilIdle(); + // Dialog result is propagated here, permission request is rejected. + EXPECT_FALSE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); +} + +TEST_F(ActiveTabPermissionGranterDelegateChromeOSTest, + GrantedForNonWhitelisted) { + auto extension = CreateExtension(kNonWhitelistedId); + // Allow the permission request. + ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT); + EXPECT_FALSE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + base::RunLoop().RunUntilIdle(); + // The permission request is granted now. + EXPECT_TRUE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); +} + +} // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc index 92948d8..48ef2a1a 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc +++ b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc
@@ -389,7 +389,9 @@ // doesn't trigger a permission warning on install though, so blocking is // somewhat at odds with the spirit of the API - however I presume the API // design assumes user-installed extensions, which we don't have here. - // "activeTab", + // Whitelisted because it's restricted now (asks user for permission the + // first time an extension tries to use it). + "activeTab", // Schedule code to run at future times. "alarms",
diff --git a/chrome/browser/chromeos/extensions/public_session_permission_helper.cc b/chrome/browser/chromeos/extensions/public_session_permission_helper.cc index c54a197..33b072f8 100644 --- a/chrome/browser/chromeos/extensions/public_session_permission_helper.cc +++ b/chrome/browser/chromeos/extensions/public_session_permission_helper.cc
@@ -15,14 +15,20 @@ #include "base/lazy_instance.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.h" #include "chrome/browser/extensions/extension_install_prompt.h" +#include "chrome/browser/profiles/profiles_state.h" +#include "chrome/grit/generated_resources.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "extensions/common/extension.h" #include "extensions/common/extension_id.h" +#include "extensions/common/permissions/api_permission_set.h" #include "extensions/common/permissions/manifest_permission_set.h" +#include "extensions/common/permissions/permission_message.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/url_pattern_set.h" +#include "ui/base/l10n/l10n_util.h" namespace extensions { namespace permission_helper { @@ -34,6 +40,11 @@ return base::MakeUnique<ExtensionInstallPrompt>(web_contents); } +bool PermissionCheckNeeded(const Extension* extension) { + return !chromeos::DeviceLocalAccountManagementPolicyProvider::IsWhitelisted( + extension->id()); +} + // This class is the internal implementation of HandlePermissionRequest(). It // contains the actual prompt showing and resolving logic, and it caches the // user choices. @@ -43,12 +54,15 @@ PublicSessionPermissionHelper(PublicSessionPermissionHelper&& other); ~PublicSessionPermissionHelper(); - void HandlePermissionRequestImpl(const Extension& extension, + bool HandlePermissionRequestImpl(const Extension& extension, const PermissionIDSet& requested_permissions, content::WebContents* web_contents, const RequestResolvedCallback& callback, const PromptFactory& prompt_factory); + bool PermissionAllowedImpl(const Extension* extension, + APIPermission::ID permission); + private: void ResolvePermissionPrompt(const ExtensionInstallPrompt* prompt, const PermissionIDSet& unprompted_permissions, @@ -82,13 +96,18 @@ PublicSessionPermissionHelper::~PublicSessionPermissionHelper() {} -void PublicSessionPermissionHelper::HandlePermissionRequestImpl( +bool PublicSessionPermissionHelper::HandlePermissionRequestImpl( const Extension& extension, const PermissionIDSet& requested_permissions, content::WebContents* web_contents, const RequestResolvedCallback& callback, const PromptFactory& prompt_factory) { - CHECK(web_contents); + DCHECK(profiles::IsPublicSession()); + if (!PermissionCheckNeeded(&extension)) { + if (!callback.is_null()) + callback.Run(requested_permissions); + return true; + } PermissionIDSet unresolved_permissions = PermissionIDSet::Difference( requested_permissions, allowed_permission_set_); @@ -96,20 +115,22 @@ unresolved_permissions, denied_permission_set_); if (unresolved_permissions.empty()) { // All requested permissions are already resolved. - callback.Run(FilterAllowedPermissions(requested_permissions)); - return; + if (!callback.is_null()) + callback.Run(FilterAllowedPermissions(requested_permissions)); + return true; } // Since not all permissions are resolved yet, queue the callback to be called // when all of them are resolved. - callbacks_.push_back(RequestCallback(callback, requested_permissions)); + if (!callback.is_null()) + callbacks_.push_back(RequestCallback(callback, requested_permissions)); PermissionIDSet unprompted_permissions = PermissionIDSet::Difference( unresolved_permissions, prompted_permission_set_); if (unprompted_permissions.empty()) { // Some permissions aren't resolved yet, but they are currently being // prompted for, so no need to show a prompt. - return; + return false; } // Some permissions need prompting, setup the prompt and show it. @@ -121,6 +142,19 @@ auto permission_set = base::MakeUnique<PermissionSet>( new_apis, ManifestPermissionSet(), URLPatternSet(), URLPatternSet()); auto prompt = prompt_factory.Run(web_contents); + + auto permissions_prompt = base::MakeUnique<ExtensionInstallPrompt::Prompt>( + ExtensionInstallPrompt::PERMISSIONS_PROMPT); + // activeTab has no permission message by default, so one is added here. + if (unprompted_permissions.ContainsID(APIPermission::kActiveTab)) { + PermissionMessages messages; + messages.push_back(PermissionMessage( + l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_CURRENT_HOST), + extensions::PermissionIDSet())); + permissions_prompt->AddPermissions( + messages, ExtensionInstallPrompt::REGULAR_PERMISSIONS); + } + // This Unretained is safe because the lifetime of this object is until // process exit. prompt->ShowDialog( @@ -129,11 +163,20 @@ std::move(unprompted_permissions)), &extension, nullptr, // Use the extension icon. - base::MakeUnique<ExtensionInstallPrompt::Prompt>( - ExtensionInstallPrompt::PERMISSIONS_PROMPT), + std::move(permissions_prompt), std::move(permission_set), ExtensionInstallPrompt::GetDefaultShowDialogCallback()); prompts_.insert(std::move(prompt)); + + return false; +} + +bool PublicSessionPermissionHelper::PermissionAllowedImpl( + const Extension* extension, + APIPermission::ID permission) { + DCHECK(profiles::IsPublicSession()); + return !PermissionCheckNeeded(extension) || + allowed_permission_set_.ContainsID(permission); } void PublicSessionPermissionHelper::ResolvePermissionPrompt( @@ -203,7 +246,7 @@ } // namespace -void HandlePermissionRequest(const Extension& extension, +bool HandlePermissionRequest(const Extension& extension, const PermissionIDSet& requested_permissions, content::WebContents* web_contents, const RequestResolvedCallback& callback, @@ -216,6 +259,13 @@ extension, requested_permissions, web_contents, callback, factory); } +bool PermissionAllowed(const Extension* extension, + APIPermission::ID permission) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + return g_helpers.Get()[extension->id()].PermissionAllowedImpl(extension, + permission); +} + void ResetPermissionsForTesting() { // Clear out the std::map between tests. Just setting g_helpers to // LAZY_INSTANCE_INITIALIZER again causes a memory leak (because of the
diff --git a/chrome/browser/chromeos/extensions/public_session_permission_helper.h b/chrome/browser/chromeos/extensions/public_session_permission_helper.h index 445f879..251337f 100644 --- a/chrome/browser/chromeos/extensions/public_session_permission_helper.h +++ b/chrome/browser/chromeos/extensions/public_session_permission_helper.h
@@ -37,7 +37,8 @@ // // This function sets up the prompt asking the user for additional // permission(s), handles the result, caches it, and then runs the callback with -// the allowed permissions as the argument. +// the allowed permissions as the argument. It returns true if this +// permission(s) is already resolved, and false otherwise. // // The user will be prompted about a certain permission only once, and that // choice will be cached and used in any subsequent requests that use the same @@ -47,14 +48,21 @@ // // Caller must ensure that web_contents is valid. Must be called on UI thread. // +// Callback can be null (permission_helper::RequestResolvedCallback()), in which +// case it's not invoked but the permission prompt is still shown. +// // Passing in a null prompt_factory (permission_helper::PromptFactory()) // callback gets the default behaviour (ie. it is is used only for tests). -void HandlePermissionRequest(const Extension& extension, +bool HandlePermissionRequest(const Extension& extension, const PermissionIDSet& requested_permissions, content::WebContents* web_contents, const RequestResolvedCallback& callback, const PromptFactory& prompt_factory); +// Returns true if user granted this permission to the extension. +bool PermissionAllowed(const Extension* extension, + APIPermission::ID permission); + // Used to completely reset state in between tests. void ResetPermissionsForTesting();
diff --git a/chrome/browser/chromeos/extensions/public_session_permission_helper_unittest.cc b/chrome/browser/chromeos/extensions/public_session_permission_helper_unittest.cc index 0ca18d0..56b71b1 100644 --- a/chrome/browser/chromeos/extensions/public_session_permission_helper_unittest.cc +++ b/chrome/browser/chromeos/extensions/public_session_permission_helper_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/common/extensions/extension_test_util.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "chromeos/login/scoped_test_public_session_login_state.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_dialog_auto_confirm.h" #include "extensions/common/extension.h" @@ -30,12 +31,17 @@ using extensions::Manifest; using Result = ExtensionInstallPrompt::Result; +namespace extensions { +namespace permission_helper { namespace { auto permission_a = APIPermission::kAudio; auto permission_b = APIPermission::kBookmark; bool did_show_dialog; +const char kWhitelistedId[] = "cbkkbcmdlboombapidmoeolnmdacpkch"; +const char kNonWhitelistedId[] = "bogus"; + scoped_refptr<Extension> LoadManifestHelper(const std::string& id) { std::string error; scoped_refptr<Extension> extension = LoadManifestUnchecked( @@ -51,6 +57,11 @@ return tmp; } +base::Callback<void(const PermissionIDSet&)> BindQuitLoop(base::RunLoop* loop) { + return base::Bind( + [](base::RunLoop* loop, const PermissionIDSet&) { loop->Quit(); }, loop); +} + class ProgrammableInstallPrompt : public ExtensionInstallPrompt, public base::SupportsWeakPtr<ProgrammableInstallPrompt> { @@ -83,9 +94,6 @@ } // namespace -namespace extensions { -namespace permission_helper { - class PublicSessionPermissionHelperTest : public ChromeRenderViewHostTestHarness { public: @@ -111,6 +119,8 @@ std::vector<PermissionIDSet> allowed_permissions_; + chromeos::ScopedTestPublicSessionLoginState login_state_; + private: DISALLOW_COPY_AND_ASSIGN(PublicSessionPermissionHelperTest); }; @@ -251,5 +261,58 @@ EXPECT_TRUE(allowed_permissions_.at(1).Equals({permission_b})); } +TEST_F(PublicSessionPermissionHelperTest, WhitelistedExtension) { + auto extension = LoadManifestHelper(kWhitelistedId); + // Whitelisted extension can use any permission. + EXPECT_TRUE(PermissionAllowed(extension.get(), permission_a)); + EXPECT_TRUE(PermissionAllowed(extension.get(), permission_b)); + // Whitelisted extension is already handled (no permission prompt needed). + EXPECT_TRUE(HandlePermissionRequest(*extension, {permission_a}, + web_contents(), RequestResolvedCallback(), + PromptFactory())); + EXPECT_TRUE(PermissionAllowed(extension.get(), permission_a)); + EXPECT_TRUE(PermissionAllowed(extension.get(), permission_b)); +} + +TEST_F(PublicSessionPermissionHelperTest, NonWhitelistedExtension) { + auto extension = LoadManifestHelper(kNonWhitelistedId); + EXPECT_FALSE(PermissionAllowed(extension.get(), permission_a)); + EXPECT_FALSE(PermissionAllowed(extension.get(), permission_b)); + // Prompt for permission_a, grant it, verify. + { + ScopedTestDialogAutoConfirm auto_confirm( + ScopedTestDialogAutoConfirm::ACCEPT); + // Permission not handled yet, need to show a prompt. + base::RunLoop loop; + EXPECT_FALSE(HandlePermissionRequest(*extension, {permission_a}, + web_contents(), BindQuitLoop(&loop), + PromptFactory())); + loop.Run(); + EXPECT_TRUE(PermissionAllowed(extension.get(), permission_a)); + EXPECT_FALSE(PermissionAllowed(extension.get(), permission_b)); + } + // Already handled (allow), doesn't show a prompt. + EXPECT_TRUE(HandlePermissionRequest(*extension, {permission_a}, + web_contents(), RequestResolvedCallback(), + PromptFactory())); + // Prompt for permission_b, deny it, verify. + { + ScopedTestDialogAutoConfirm auto_confirm( + ScopedTestDialogAutoConfirm::CANCEL); + // Permission not handled yet, need to show a prompt. + base::RunLoop loop; + EXPECT_FALSE(HandlePermissionRequest(*extension, {permission_b}, + web_contents(), BindQuitLoop(&loop), + PromptFactory())); + loop.Run(); + EXPECT_TRUE(PermissionAllowed(extension.get(), permission_a)); + EXPECT_FALSE(PermissionAllowed(extension.get(), permission_b)); + } + // Already handled (deny), doesn't show a prompt. + EXPECT_TRUE(HandlePermissionRequest(*extension, {permission_b}, + web_contents(), RequestResolvedCallback(), + PromptFactory())); +} + } // namespace permission_helper } // namespace extensions
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index 660055c..495331f 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" +#include "chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h" #include "chrome/browser/chromeos/extensions/extension_tab_util_delegate_chromeos.h" #include "chrome/browser/chromeos/extensions/permissions_updater_delegate_chromeos.h" #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" @@ -154,6 +155,21 @@ return true; } +// Sets the neccessary delegates in Public Session. They will be active for the +// whole user-session and they will go away together with the browser process +// during logout (the browser process is destroyed during logout), ie. they are +// not freed and they leak but that is fine. +void SetPublicAccountDelegates() { + extensions::PermissionsUpdater::SetPlatformDelegate( + new extensions::PermissionsUpdaterDelegateChromeOS); + + extensions::ExtensionTabUtil::SetPlatformDelegate( + new extensions::ExtensionTabUtilDelegateChromeOS); + + extensions::ActiveTabPermissionGranter::SetPlatformDelegate( + new extensions::ActiveTabPermissionGranterDelegateChromeOS); +} + } // namespace // static @@ -837,19 +853,7 @@ GetUserImageManager(user->GetAccountId())->UserLoggedIn(false, true); WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); - // In Public Sessions set the PS delegate on PermissionsUpdater (used to - // remove clipboard read permission from extensions in PS). This delegate will - // be active for the whole user-session and it will go away together with the - // browser process during logout (the browser process is destroyed during - // logout), ie. it's not freed and it leaks but that is fine. - extensions::PermissionsUpdater::SetPlatformDelegate( - new extensions::PermissionsUpdaterDelegateChromeOS); - - // In Public Sessions set the PS delegate on ExtensionTabUtil (used to scrub - // URL down to origin for security reasons). See comment above about - // PermissionsUpdaterDelegateChromeOS for more info. - extensions::ExtensionTabUtil::SetPlatformDelegate( - new extensions::ExtensionTabUtilDelegateChromeOS); + SetPublicAccountDelegates(); } void ChromeUserManagerImpl::KioskAppLoggedIn(user_manager::User* user) {
diff --git a/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc b/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc index a8b1e8f..00168bb 100644 --- a/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc +++ b/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc
@@ -250,7 +250,7 @@ void SetUpPrinterDone(std::unique_ptr<SetUpPrinterData> data, PrinterSetupResult result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (result == PrinterSetupResult::SUCCESS) { + if (result == PrinterSetupResult::kSuccess) { if (data->is_new) { // We aren't done with data->printer yet, so we have to copy it instead // of moving it.
diff --git a/chrome/browser/chromeos/printing/printer_configurer.cc b/chrome/browser/chromeos/printing/printer_configurer.cc index a7c812b..c9e011e1a5 100644 --- a/chrome/browser/chromeos/printing/printer_configurer.cc +++ b/chrome/browser/chromeos/printing/printer_configurer.cc
@@ -72,25 +72,25 @@ PrinterSetupResult result; switch (result_code) { case debugd::CupsResult::CUPS_SUCCESS: - result = PrinterSetupResult::SUCCESS; + result = PrinterSetupResult::kSuccess; break; case debugd::CupsResult::CUPS_INVALID_PPD: - result = PrinterSetupResult::INVALID_PPD; + result = PrinterSetupResult::kInvalidPpd; break; case debugd::CupsResult::CUPS_AUTOCONF_FAILURE: // There are other reasons autoconf fails but this is the most likely. - result = PrinterSetupResult::PRINTER_UNREACHABLE; + result = PrinterSetupResult::kPrinterUnreachable; break; case debugd::CupsResult::CUPS_LPADMIN_FAILURE: // Printers should always be configurable by lpadmin. NOTREACHED() << "lpadmin could not add the printer"; - result = PrinterSetupResult::FATAL_ERROR; + result = PrinterSetupResult::kFatalError; break; case debugd::CupsResult::CUPS_FATAL: default: // We have no idea. It must be fatal. LOG(ERROR) << "Unrecognized printer setup error: " << result_code; - result = PrinterSetupResult::FATAL_ERROR; + result = PrinterSetupResult::kFatalError; break; } @@ -101,7 +101,7 @@ // The callback is expected to run on the UI thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); LOG(WARNING) << "Could not contact debugd"; - cb.Run(PrinterSetupResult::DBUS_ERROR); + cb.Run(PrinterSetupResult::kDbusError); } void AddPrinter(const Printer& printer, @@ -131,14 +131,14 @@ AddPrinter(printer, ppd_contents, cb); break; case printing::PpdProvider::CallbackResultCode::NOT_FOUND: - cb.Run(PPD_NOT_FOUND); + cb.Run(PrinterSetupResult::kPpdNotFound); break; case printing::PpdProvider::CallbackResultCode::SERVER_ERROR: - cb.Run(PPD_UNRETRIEVABLE); + cb.Run(PrinterSetupResult::kPpdUnretrievable); break; case printing::PpdProvider::CallbackResultCode::INTERNAL_ERROR: - // TODO(skau): Add PPD_TOO_LARGE when it's reported by the PpdProvider. - cb.Run(FATAL_ERROR); + // TODO(skau): Add kPpdTooLarge when it's reported by the PpdProvider. + cb.Run(PrinterSetupResult::kFatalError); break; } }
diff --git a/chrome/browser/chromeos/printing/printer_configurer.h b/chrome/browser/chromeos/printing/printer_configurer.h index 5aab7a3..bd97c26 100644 --- a/chrome/browser/chromeos/printing/printer_configurer.h +++ b/chrome/browser/chromeos/printing/printer_configurer.h
@@ -15,16 +15,18 @@ namespace chromeos { enum PrinterSetupResult { - FATAL_ERROR, - SUCCESS, // Printer set up successfully - PRINTER_UNREACHABLE, // Could not reach printer - DBUS_ERROR, // Could not contact debugd + kFatalError = 0, // Setup failed in an unrecognized way + kSuccess = 1, // Printer set up successfully + kPrinterUnreachable = 2, // Could not reach printer + kDbusError = 3, // Could not contact debugd + // Space left for additional errors // PPD errors - PPD_TOO_LARGE, // PPD exceeds size limit - INVALID_PPD, // PPD rejected by cupstestppd - PPD_NOT_FOUND, // Could not find PPD - PPD_UNRETRIEVABLE // Could not download PPD + kPpdTooLarge = 10, // PPD exceeds size limit + kInvalidPpd = 11, // PPD rejected by cupstestppd + kPpdNotFound = 12, // Could not find PPD + kPpdUnretrievable = 13, // Could not download PPD + kMaxValue // Maximum value for histograms }; using PrinterSetupCallback = base::Callback<void(PrinterSetupResult)>;
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc index 5ac3e8a1..fb8514f1 100644 --- a/chrome/browser/devtools/devtools_sanity_browsertest.cc +++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -87,7 +87,6 @@ #include "ui/gl/gl_switches.h" #include "url/gurl.h" -using app_modal::AppModalDialog; using app_modal::JavaScriptAppModalDialog; using app_modal::NativeAppModalDialog; using content::BrowserThread; @@ -452,11 +451,8 @@ } NativeAppModalDialog* GetDialog() { - AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); - EXPECT_TRUE(dialog->IsJavaScriptModalDialog()); - JavaScriptAppModalDialog* js_dialog = - static_cast<JavaScriptAppModalDialog*>(dialog); - NativeAppModalDialog* native_dialog = js_dialog->native_dialog(); + JavaScriptAppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); + NativeAppModalDialog* native_dialog = dialog->native_dialog(); EXPECT_TRUE(native_dialog); return native_dialog; }
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index e63a44b..1a59b4a 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -7,6 +7,7 @@ import("//chrome/common/features.gni") import("//extensions/features/features.gni") import("//media/media_options.gni") +import("//mojo/public/tools/bindings/mojom.gni") import("//rlz/features/features.gni") assert(enable_extensions) @@ -821,6 +822,7 @@ "//chrome/browser/media/router", "//chrome/browser/media/router/discovery", "//chrome/common", + "//chrome/common/extensions:mojo_bindings", "//chrome/common/extensions/api:api_registration", "//chrome/common/extensions/api:extensions_features", "//chrome/common/safe_browsing:proto",
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc index 1732c60..593628c 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.cc +++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -66,6 +66,8 @@ tab_process->Send(create_message.Run(false)); } +ActiveTabPermissionGranter::Delegate* g_delegate = nullptr; + } // namespace ActiveTabPermissionGranter::ActiveTabPermissionGranter( @@ -80,6 +82,17 @@ ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {} +// static +ActiveTabPermissionGranter::Delegate* +ActiveTabPermissionGranter::SetPlatformDelegate(Delegate* delegate) { + // Disallow setting it twice (but allow resetting - don't forget to free in + // that case). + CHECK(!g_delegate || !delegate); + Delegate* previous_delegate = g_delegate; + g_delegate = delegate; + return previous_delegate; +} + void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) { if (granted_extensions_.Contains(extension->id())) return; @@ -89,11 +102,15 @@ const PermissionsData* permissions_data = extension->permissions_data(); + bool should_grant_active_tab = + !g_delegate || + g_delegate->ShouldGrantActiveTab(extension, web_contents()); // If the extension requested all-hosts but has had it withheld, we grant it // active tab-style permissions, even if it doesn't have the activeTab // permission in the manifest. - if (permissions_data->HasAPIPermission(APIPermission::kActiveTab) || - permissions_data->HasWithheldImpliedAllHosts()) { + if (should_grant_active_tab && + (permissions_data->HasWithheldImpliedAllHosts() || + permissions_data->HasAPIPermission(APIPermission::kActiveTab))) { new_hosts.AddOrigin(UserScript::ValidUserScriptSchemes(), web_contents()->GetVisibleURL().GetOrigin()); new_apis.insert(APIPermission::kTab);
diff --git a/chrome/browser/extensions/active_tab_permission_granter.h b/chrome/browser/extensions/active_tab_permission_granter.h index a1245a2..48fcf9a1 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.h +++ b/chrome/browser/extensions/active_tab_permission_granter.h
@@ -32,11 +32,24 @@ : public content::WebContentsObserver, public extensions::ExtensionRegistryObserver { public: + // Platform specific delegate. + class Delegate { + public: + virtual ~Delegate() {} + // Platform specific check whether the activeTab permission is allowed. + virtual bool ShouldGrantActiveTab( + const Extension* extension, content::WebContents* web_contents) = 0; + }; + ActiveTabPermissionGranter(content::WebContents* web_contents, int tab_id, Profile* profile); ~ActiveTabPermissionGranter() override; + // Platform specific delegate should be set during startup. |delegate| is a + // singleton instance and is leaked. + static Delegate* SetPlatformDelegate(Delegate* delegate); + // If |extension| has the activeTab or tabCapture permission, grants // tab-specific permissions to it until the next page navigation or refresh. void GrantIfRequested(const Extension* extension);
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc index 908d366a..77b8e472 100644 --- a/chrome/browser/extensions/active_tab_unittest.cc +++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -7,6 +7,8 @@ #include <utility> #include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" @@ -32,6 +34,20 @@ #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/value_builder.h" +#if defined(OS_CHROMEOS) +#include "base/run_loop.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h" +#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/device_settings_service.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chromeos/login/scoped_test_public_session_login_state.h" +#include "components/signin/core/account_id/account_id.h" +#include "extensions/browser/extension_dialog_auto_confirm.h" +#endif + using base::DictionaryValue; using base::ListValue; using content::BrowserThread; @@ -67,6 +83,28 @@ PERMITTED_BOTH }; +class ActiveTabPermissionGranterTestDelegate + : public ActiveTabPermissionGranter::Delegate { + public: + ActiveTabPermissionGranterTestDelegate() {} + ~ActiveTabPermissionGranterTestDelegate() override {} + + // ActiveTabPermissionGranterTestDelegate::Delegate + bool ShouldGrantActiveTab(const Extension* extension, + content::WebContents* contents) override { + return should_grant_; + } + + void SetShouldGrant(bool should_grant) { + should_grant_ = should_grant; + } + + private: + bool should_grant_ = false; + + DISALLOW_COPY_AND_ASSIGN(ActiveTabPermissionGranterTestDelegate); +}; + class ActiveTabTest : public ChromeRenderViewHostTestHarness { protected: ActiveTabTest() @@ -380,5 +418,81 @@ tab_id() + 1, APIPermission::kTabCaptureForTab)); } +// Test that the custom platform delegate works as expected. +TEST_F(ActiveTabTest, Delegate) { + auto test_delegate = + base::MakeUnique<ActiveTabPermissionGranterTestDelegate>(); + ActiveTabPermissionGranter::SetPlatformDelegate(test_delegate.get()); + + GURL google("http://www.google.com"); + NavigateAndCommit(google); + + // Not granted because the delegate denies grant. + active_tab_permission_granter()->GrantIfRequested(extension.get()); + EXPECT_TRUE(IsBlocked(extension, google)); + + // This time it's granted because the delegate allows it. + test_delegate->SetShouldGrant(true); + active_tab_permission_granter()->GrantIfRequested(extension.get()); + EXPECT_TRUE(IsAllowed(extension, google)); + + // Cleanup :). + ActiveTabPermissionGranter::SetPlatformDelegate(nullptr); +} + +#if defined(OS_CHROMEOS) +// Test that the platform delegate is being set and the permission is prompted +// for. +TEST_F(ActiveTabTest, DelegateIsSet) { + // Setup, login a public account user. + chromeos::ScopedTestPublicSessionLoginState login_state; + std::string user_id = "public@account.user"; + std::string user_email = user_id; + AccountId account_id = AccountId::FromUserEmailGaiaId(user_email, user_id); + std::string user_id_hash = chromeos::ProfileHelper::Get()-> + GetUserIdHashByUserIdForTesting(user_id); + chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; + chromeos::ScopedTestCrosSettings test_cros_settings_; + ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal()); + chromeos::ScopedTestUserManager test_user_manager_; + chromeos::WallpaperManager::Initialize(); + g_browser_process->local_state()->SetString( + "PublicAccountPendingDataRemoval", user_email); + user_manager::UserManager::Get()->UserLoggedIn( + account_id, user_id_hash, true); + + GURL google("http://www.google.com"); + NavigateAndCommit(google); + + // Grant and verify. + { + ScopedTestDialogAutoConfirm auto_confirm( + ScopedTestDialogAutoConfirm::ACCEPT); + active_tab_permission_granter()->GrantIfRequested(extension.get()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(IsBlocked(extension, google)); + active_tab_permission_granter()->GrantIfRequested(extension.get()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(IsAllowed(extension, google)); + } + + // Deny and verify. Use a different extension so it doesn't trigger the cache. + { + ScopedTestDialogAutoConfirm auto_confirm( + ScopedTestDialogAutoConfirm::CANCEL); + active_tab_permission_granter()->GrantIfRequested(another_extension.get()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(IsBlocked(another_extension, google)); + active_tab_permission_granter()->GrantIfRequested(another_extension.get()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(IsBlocked(another_extension, google)); + } + + // Cleanup. + chromeos::WallpaperManager::Shutdown(); + free(ActiveTabPermissionGranter::SetPlatformDelegate(nullptr)); +} +#endif + } // namespace } // namespace extensions
diff --git a/chrome/browser/extensions/alert_apitest.cc b/chrome/browser/extensions/alert_apitest.cc index 9d638b9..f32e4159 100644 --- a/chrome/browser/extensions/alert_apitest.cc +++ b/chrome/browser/extensions/alert_apitest.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/app_modal/app_modal_dialog.h" #include "components/app_modal/app_modal_dialog_queue.h" #include "components/app_modal/javascript_app_modal_dialog.h" #include "components/app_modal/native_app_modal_dialog.h" @@ -25,11 +24,9 @@ void GetNextDialog(app_modal::NativeAppModalDialog** native_dialog) { DCHECK(native_dialog); *native_dialog = nullptr; - app_modal::AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); - ASSERT_TRUE(dialog->IsJavaScriptModalDialog()); - app_modal::JavaScriptAppModalDialog* js_dialog = - static_cast<app_modal::JavaScriptAppModalDialog*>(dialog); - *native_dialog = js_dialog->native_dialog(); + app_modal::JavaScriptAppModalDialog* dialog = + ui_test_utils::WaitForAppModalDialog(); + *native_dialog = dialog->native_dialog(); ASSERT_TRUE(*native_dialog); }
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc index d691a71..dcd7117 100644 --- a/chrome/browser/extensions/extension_install_prompt.cc +++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -161,16 +161,12 @@ ExtensionInstallPrompt::Prompt::~Prompt() { } -void ExtensionInstallPrompt::Prompt::SetPermissions( +void ExtensionInstallPrompt::Prompt::AddPermissions( const PermissionMessages& permissions, PermissionsType permissions_type) { InstallPromptPermissions& install_permissions = GetPermissionsForType(permissions_type); - install_permissions.permissions.clear(); - install_permissions.details.clear(); - install_permissions.is_showing_details.clear(); - for (const PermissionMessage& msg : permissions) { install_permissions.permissions.push_back(msg.message()); // Add a dash to the front of each permission detail. @@ -792,7 +788,7 @@ const extensions::PermissionMessageProvider* message_provider = extensions::PermissionMessageProvider::Get(); - prompt_->SetPermissions(message_provider->GetPermissionMessages( + prompt_->AddPermissions(message_provider->GetPermissionMessages( message_provider->GetAllPermissionIDs( *permissions_to_display, type)), REGULAR_PERMISSIONS); @@ -801,7 +797,7 @@ extension_ ? &extension_->permissions_data()->withheld_permissions() : nullptr; if (withheld && !withheld->IsEmpty()) { - prompt_->SetPermissions( + prompt_->AddPermissions( message_provider->GetPermissionMessages( message_provider->GetAllPermissionIDs(*withheld, type)), WITHHELD_PERMISSIONS);
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h index 3079697..635975d 100644 --- a/chrome/browser/extensions/extension_install_prompt.h +++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -98,7 +98,7 @@ explicit Prompt(PromptType type); ~Prompt(); - void SetPermissions(const extensions::PermissionMessages& permissions, + void AddPermissions(const extensions::PermissionMessages& permissions, PermissionsType permissions_type); void SetIsShowingDetails(DetailsType type, size_t index,
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index f4774c5..f6599d61 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -26,7 +26,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/app_modal/app_modal_dialog.h" +#include "components/app_modal/javascript_app_modal_dialog.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" #include "components/bookmarks/test/bookmark_test_helpers.h" @@ -239,7 +239,8 @@ ASSERT_TRUE(extension); // The test extension opens a dialog on installation. - app_modal::AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); + app_modal::JavaScriptAppModalDialog* dialog = + ui_test_utils::WaitForAppModalDialog(); ASSERT_TRUE(dialog); // With the dialog open the background page is still alive.
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 3ba0c93c..0f077ca 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -32,7 +32,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/api/webstore/webstore_api_constants.h" -#include "chrome/common/extensions/chrome_extension_messages.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/render_messages.h" @@ -63,6 +62,7 @@ #include "extensions/common/extension_urls.h" #include "extensions/common/feature_switch.h" #include "extensions/common/manifest_handlers/icons_handler.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "url/url_constants.h" #if defined(OS_WIN) @@ -83,12 +83,10 @@ public: InlineInstallObserver(TabHelper* tab_helper, content::BrowserContext* browser_context, - int routing_id, const ExtensionId& extension_id, bool observe_download_progress, bool observe_install_stage) : tab_helper_(tab_helper), - routing_id_(routing_id), extension_id_(extension_id), observe_download_progress_(observe_download_progress), observe_install_stage_(observe_install_stage), @@ -111,8 +109,10 @@ void OnDownloadProgress(const ExtensionId& extension_id, int percent_downloaded) override { if (observe_download_progress_ && extension_id == extension_id_) { - tab_helper_->Send(new ExtensionMsg_InlineInstallDownloadProgress( - routing_id_, percent_downloaded)); + auto iter = + tab_helper_->inline_install_progress_listeners_.find(extension_id); + DCHECK(iter != tab_helper_->inline_install_progress_listeners_.end()); + iter->second->InlineInstallDownloadProgress(percent_downloaded); } } void OnBeginCrxInstall(const ExtensionId& extension_id) override { @@ -124,17 +124,16 @@ void SendInstallStageChangedMessage(const ExtensionId& extension_id, api::webstore::InstallStage stage) { if (observe_install_stage_ && extension_id == extension_id_) { - tab_helper_->Send( - new ExtensionMsg_InlineInstallStageChanged(routing_id_, stage)); + auto iter = + tab_helper_->inline_install_progress_listeners_.find(extension_id); + DCHECK(iter != tab_helper_->inline_install_progress_listeners_.end()); + iter->second->InlineInstallStageChanged(stage); } } // The owning TabHelper (guaranteed to be valid). TabHelper* const tab_helper_; - // The routing id to use in sending IPC updates. - int routing_id_; - // The id of the extension to observe. ExtensionId extension_id_; @@ -147,6 +146,10 @@ DISALLOW_COPY_AND_ASSIGN(InlineInstallObserver); }; +TabHelper::~TabHelper() { + RemoveScriptExecutionObserver(ActivityLog::GetInstance(profile_)); +} + TabHelper::TabHelper(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())), @@ -159,6 +162,7 @@ extension_action_runner_(new ExtensionActionRunner(web_contents)), webstore_inline_installer_factory_(new WebstoreInlineInstallerFactory()), registry_observer_(this), + bindings_(web_contents, this), image_loader_ptr_factory_(this), weak_ptr_factory_(this) { // The ActiveTabPermissionManager requires a session ID; ensure this @@ -192,10 +196,6 @@ &web_contents->GetController())); } -TabHelper::~TabHelper() { - RemoveScriptExecutionObserver(ActivityLog::GetInstance(profile_)); -} - void TabHelper::CreateHostedAppFromWebContents() { DCHECK(CanCreateBookmarkApp()); if (pending_web_app_action_ != NONE) @@ -346,8 +346,6 @@ content::RenderFrameHost* render_frame_host) { bool handled = true; IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(TabHelper, message, render_frame_host) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_InlineWebstoreInstall, - OnInlineWebstoreInstall) IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppInstallState, OnGetAppInstallState) IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting, @@ -408,11 +406,17 @@ pending_web_app_action_ = NONE; } -void TabHelper::OnInlineWebstoreInstall(content::RenderFrameHost* host, - int install_id, - int return_route_id, - const std::string& webstore_item_id, - int listeners_mask) { +void TabHelper::DoInlineInstall( + const std::string& webstore_item_id, + int listeners_mask, + mojom::InlineInstallProgressListenerPtr install_progress_listener, + DoInlineInstallCallback callback) { + content::RenderFrameHost* host = web_contents()->GetMainFrame(); + if (bindings_.GetCurrentTargetFrame() != host) { + NOTREACHED(); + return; + } + GURL requestor_url(host->GetLastCommittedURL()); // Check that the listener is reasonable. We should never get anything other // than an install stage listener, a download listener, or both. @@ -420,39 +424,37 @@ // child frames from sending the IPC. if ((listeners_mask & ~(api::webstore::INSTALL_STAGE_LISTENER | api::webstore::DOWNLOAD_PROGRESS_LISTENER)) != 0 || - !requestor_url.is_valid() || requestor_url == url::kAboutBlankURL || - host->GetParent()) { + !requestor_url.is_valid() || requestor_url == url::kAboutBlankURL) { NOTREACHED(); return; } - if (pending_inline_installations_.count(webstore_item_id) != 0) { - Send(new ExtensionMsg_InlineWebstoreInstallResponse( - return_route_id, install_id, false, - webstore_install::kInstallInProgressError, - webstore_install::INSTALL_IN_PROGRESS)); + if (base::ContainsKey(install_callbacks_, webstore_item_id)) { + std::move(callback).Run(false, webstore_install::kInstallInProgressError, + webstore_install::INSTALL_IN_PROGRESS); return; } - pending_inline_installations_.insert(webstore_item_id); + install_callbacks_[webstore_item_id] = std::move(callback); + inline_install_progress_listeners_[webstore_item_id] = + std::move(install_progress_listener); // Inform the Webstore API that an inline install is happening, in case the // page requested status updates. ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); if (registry->disabled_extensions().Contains(webstore_item_id) && (ExtensionPrefs::Get(profile_)->GetDisableReasons(webstore_item_id) & - Extension::DISABLE_PERMISSIONS_INCREASE) != 0) { - // The extension was disabled due to permissions increase. Prompt for - // re-enable. - // TODO(devlin): We should also prompt for re-enable for other reasons, - // like user-disabled. - // For clarity, explicitly end any prior reenable process. - extension_reenabler_.reset(); - extension_reenabler_ = ExtensionReenabler::PromptForReenable( - registry->disabled_extensions().GetByID(webstore_item_id), profile_, - web_contents(), requestor_url, - base::Bind(&TabHelper::OnReenableComplete, - weak_ptr_factory_.GetWeakPtr(), install_id, - return_route_id, webstore_item_id)); + Extension::DISABLE_PERMISSIONS_INCREASE) != 0) { + // The extension was disabled due to permissions increase. Prompt for + // re-enable. + // TODO(devlin): We should also prompt for re-enable for other reasons, + // like user-disabled. + // For clarity, explicitly end any prior reenable process. + extension_reenabler_.reset(); + extension_reenabler_ = ExtensionReenabler::PromptForReenable( + registry->disabled_extensions().GetByID(webstore_item_id), profile_, + web_contents(), requestor_url, + base::Bind(&TabHelper::OnReenableComplete, + weak_ptr_factory_.GetWeakPtr(), webstore_item_id)); } else { // TODO(devlin): We should adddress the case of the extension already // being installed and enabled. @@ -464,14 +466,13 @@ DCHECK_EQ(0u, install_observers_.count(webstore_item_id)); install_observers_[webstore_item_id] = base::MakeUnique<InlineInstallObserver>( - this, web_contents()->GetBrowserContext(), return_route_id, - webstore_item_id, observe_download_progress, - observe_install_stage); + this, web_contents()->GetBrowserContext(), webstore_item_id, + observe_download_progress, observe_install_stage); } - WebstoreStandaloneInstaller::Callback callback = base::Bind( - &TabHelper::OnInlineInstallComplete, weak_ptr_factory_.GetWeakPtr(), - install_id, return_route_id, webstore_item_id); + WebstoreStandaloneInstaller::Callback callback = + base::Bind(&TabHelper::OnInlineInstallComplete, + weak_ptr_factory_.GetWeakPtr(), webstore_item_id); scoped_refptr<WebstoreInlineInstaller> installer( webstore_inline_installer_factory_->CreateInstaller( web_contents(), host, webstore_item_id, requestor_url, callback)); @@ -561,9 +562,7 @@ return ExtensionTabUtil::GetWindowControllerOfTab(web_contents()); } -void TabHelper::OnReenableComplete(int install_id, - int return_route_id, - const ExtensionId& extension_id, +void TabHelper::OnReenableComplete(const ExtensionId& extension_id, ExtensionReenabler::ReenableResult result) { // Map the re-enable results to webstore-install results. webstore_install::Result webstore_result = webstore_install::SUCCESS; @@ -585,7 +584,7 @@ break; } - OnInlineInstallComplete(install_id, return_route_id, extension_id, + OnInlineInstallComplete(extension_id, result == ExtensionReenabler::REENABLE_SUCCESS, error, webstore_result); // Note: ExtensionReenabler contained the callback with the curried-in @@ -593,21 +592,15 @@ extension_reenabler_.reset(); } -void TabHelper::OnInlineInstallComplete(int install_id, - int return_route_id, - const ExtensionId& extension_id, +void TabHelper::OnInlineInstallComplete(const ExtensionId& extension_id, bool success, const std::string& error, webstore_install::Result result) { - DCHECK_EQ(1u, pending_inline_installations_.count(extension_id)); - pending_inline_installations_.erase(extension_id); install_observers_.erase(extension_id); - Send(new ExtensionMsg_InlineWebstoreInstallResponse( - return_route_id, - install_id, - success, - success ? std::string() : error, - result)); + auto iter = install_callbacks_.find(extension_id); + DCHECK(iter != install_callbacks_.end()); + std::move(iter->second).Run(success, success ? std::string() : error, result); + install_callbacks_.erase(iter); } WebContents* TabHelper::GetAssociatedWebContents() const {
diff --git a/chrome/browser/extensions/tab_helper.h b/chrome/browser/extensions/tab_helper.h index 09b09f6..c0df70eb 100644 --- a/chrome/browser/extensions/tab_helper.h +++ b/chrome/browser/extensions/tab_helper.h
@@ -16,10 +16,12 @@ #include "base/scoped_observer.h" #include "chrome/browser/extensions/active_tab_permission_granter.h" #include "chrome/browser/extensions/extension_reenabler.h" +#include "chrome/common/extensions/mojom/inline_install.mojom.h" #include "chrome/common/extensions/webstore_install_result.h" #include "chrome/common/web_application_info.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "content/public/browser/web_contents_binding_set.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "extensions/browser/extension_function_dispatcher.h" @@ -45,7 +47,8 @@ public ExtensionFunctionDispatcher::Delegate, public ExtensionRegistryObserver, public content::NotificationObserver, - public content::WebContentsUserData<TabHelper> { + public content::WebContentsUserData<TabHelper>, + public mojom::InlineInstaller { public: ~TabHelper() override; @@ -128,10 +131,11 @@ }; explicit TabHelper(content::WebContents* web_contents); + friend class content::WebContentsUserData<TabHelper>; // Displays UI for completion of creating a bookmark hosted app. - void FinishCreateBookmarkApp(const extensions::Extension* extension, + void FinishCreateBookmarkApp(const Extension* extension, const WebApplicationInfo& web_app_info); // content::WebContentsObserver overrides. @@ -145,8 +149,8 @@ content::WebContents* old_web_contents, content::WebContents* new_web_contents) override; - // extensions::ExtensionFunctionDispatcher::Delegate overrides. - extensions::WindowController* GetExtensionWindowController() const override; + // ExtensionFunctionDispatcher::Delegate overrides. + WindowController* GetExtensionWindowController() const override; content::WebContents* GetAssociatedWebContents() const override; // ExtensionRegistryObserver: @@ -154,13 +158,15 @@ const Extension* extension, UnloadedExtensionReason reason) override; + // mojom::InlineInstall: + void DoInlineInstall( + const std::string& webstore_item_id, + int listeners_mask, + mojom::InlineInstallProgressListenerPtr install_progress_listener, + DoInlineInstallCallback callback) override; + // Message handlers. void OnDidGetWebApplicationInfo(const WebApplicationInfo& info); - void OnInlineWebstoreInstall(content::RenderFrameHost* host, - int install_id, - int return_route_id, - const std::string& webstore_item_id, - int listeners_mask); void OnGetAppInstallState(content::RenderFrameHost* host, const GURL& requestor_url, int return_route_id, @@ -181,17 +187,13 @@ void OnImageLoaded(const gfx::Image& image); // WebstoreStandaloneInstaller::Callback. - void OnInlineInstallComplete(int install_id, - int return_route_id, - const ExtensionId& extension_id, + void OnInlineInstallComplete(const ExtensionId& extension_id, bool success, const std::string& error, webstore_install::Result result); // ExtensionReenabler::Callback. - void OnReenableComplete(int install_id, - int return_route_id, - const ExtensionId& extension_id, + void OnReenableComplete(const ExtensionId& extension_id, ExtensionReenabler::ReenableResult result); // content::NotificationObserver. @@ -260,8 +262,14 @@ std::map<ExtensionId, std::unique_ptr<InlineInstallObserver>> install_observers_; - // The set of extension ids that are currently being installed. - std::set<ExtensionId> pending_inline_installations_; + // Map of function callbacks that are invoked when the inline installation for + // a particular extension (hence ExtensionId) completes. + std::map<ExtensionId, DoInlineInstallCallback> install_callbacks_; + + content::WebContentsFrameBindingSet<mojom::InlineInstaller> bindings_; + + std::map<ExtensionId, mojom::InlineInstallProgressListenerPtr> + inline_install_progress_listeners_; // Vend weak pointers that can be invalidated to stop in-progress loads. base::WeakPtrFactory<TabHelper> image_loader_ptr_factory_;
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client.cc b/chrome/browser/favicon/chrome_fallback_icon_client.cc deleted file mode 100644 index ee983aa..0000000 --- a/chrome/browser/favicon/chrome_fallback_icon_client.cc +++ /dev/null
@@ -1,25 +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/favicon/chrome_fallback_icon_client.h" - -#include "build/build_config.h" -#include "chrome/grit/platform_locale_settings.h" -#include "ui/base/l10n/l10n_util.h" - -ChromeFallbackIconClient::ChromeFallbackIconClient() { -#if defined(OS_CHROMEOS) - font_list_.push_back("Noto Sans"); -#else - font_list_.push_back(l10n_util::GetStringUTF8(IDS_SANS_SERIF_FONT_FAMILY)); -#endif -} - -ChromeFallbackIconClient::~ChromeFallbackIconClient() { -} - -const std::vector<std::string>& ChromeFallbackIconClient::GetFontNameList() - const { - return font_list_; -}
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client.h b/chrome/browser/favicon/chrome_fallback_icon_client.h deleted file mode 100644 index 85013a2..0000000 --- a/chrome/browser/favicon/chrome_fallback_icon_client.h +++ /dev/null
@@ -1,29 +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_FAVICON_CHROME_FALLBACK_ICON_CLIENT_H_ -#define CHROME_BROWSER_FAVICON_CHROME_FALLBACK_ICON_CLIENT_H_ - -#include <string> -#include <vector> - -#include "base/macros.h" -#include "components/favicon/core/fallback_icon_client.h" - -// ChromeFallbackIconClient implements the FallbackIconClient interface. -class ChromeFallbackIconClient : public favicon::FallbackIconClient { - public: - ChromeFallbackIconClient(); - ~ChromeFallbackIconClient() override; - - // FallbackIconClient implementation: - const std::vector<std::string>& GetFontNameList() const override; - - private: - std::vector<std::string> font_list_; - - DISALLOW_COPY_AND_ASSIGN(ChromeFallbackIconClient); -}; - -#endif // CHROME_BROWSER_FAVICON_CHROME_FALLBACK_ICON_CLIENT_H_
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client_factory.cc b/chrome/browser/favicon/chrome_fallback_icon_client_factory.cc deleted file mode 100644 index e2ace70..0000000 --- a/chrome/browser/favicon/chrome_fallback_icon_client_factory.cc +++ /dev/null
@@ -1,39 +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/favicon/chrome_fallback_icon_client_factory.h" - -#include "base/memory/singleton.h" -#include "chrome/browser/favicon/chrome_fallback_icon_client.h" -#include "chrome/browser/profiles/incognito_helpers.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "content/public/browser/browser_context.h" - -ChromeFallbackIconClientFactory::ChromeFallbackIconClientFactory() - : BrowserContextKeyedServiceFactory( - "ChromeFallbackIconClient", - BrowserContextDependencyManager::GetInstance()) { -} - -ChromeFallbackIconClientFactory::~ChromeFallbackIconClientFactory() { -} - -// static -favicon::FallbackIconClient* -ChromeFallbackIconClientFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<favicon::FallbackIconClient*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -ChromeFallbackIconClientFactory* -ChromeFallbackIconClientFactory::GetInstance() { - return base::Singleton<ChromeFallbackIconClientFactory>::get(); -} - -KeyedService* ChromeFallbackIconClientFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return new ChromeFallbackIconClient(); -}
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client_factory.h b/chrome/browser/favicon/chrome_fallback_icon_client_factory.h deleted file mode 100644 index 0f349a6..0000000 --- a/chrome/browser/favicon/chrome_fallback_icon_client_factory.h +++ /dev/null
@@ -1,46 +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_FAVICON_CHROME_FALLBACK_ICON_CLIENT_FACTORY_H_ -#define CHROME_BROWSER_FAVICON_CHROME_FALLBACK_ICON_CLIENT_FACTORY_H_ - -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace base { -template <typename T> struct DefaultSingletonTraits; -} - -namespace content { -class BrowserContext; -} - -namespace favicon { -class FallbackIconClient; -} - -// Singleton that owns all ChromeFallbackIconClients and associates them with -// Profiles. -class ChromeFallbackIconClientFactory - : public BrowserContextKeyedServiceFactory { - public: - // Returns the instance of FallbackIconClient associated with this profile - // (creating one if none exists). - static favicon::FallbackIconClient* GetForBrowserContext( - content::BrowserContext* context); - - // Returns an instance of the factory singleton. - static ChromeFallbackIconClientFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<ChromeFallbackIconClientFactory>; - - ChromeFallbackIconClientFactory(); - ~ChromeFallbackIconClientFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; -}; - -#endif // CHROME_BROWSER_FAVICON_CHROME_FALLBACK_ICON_CLIENT_FACTORY_H_
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client_unittest.cc b/chrome/browser/favicon/chrome_fallback_icon_client_unittest.cc deleted file mode 100644 index 41c1a68..0000000 --- a/chrome/browser/favicon/chrome_fallback_icon_client_unittest.cc +++ /dev/null
@@ -1,14 +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/favicon/chrome_fallback_icon_client.h" - -#include "base/macros.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(ChromeFallbackIconClientTest, GetFontNameList) { - ChromeFallbackIconClient client; - // Just ensure non-empty, otherwise not checking the actual font. - EXPECT_FALSE(client.GetFontNameList().empty()); -}
diff --git a/chrome/browser/favicon/fallback_icon_service_factory.cc b/chrome/browser/favicon/fallback_icon_service_factory.cc deleted file mode 100644 index a1871dd..0000000 --- a/chrome/browser/favicon/fallback_icon_service_factory.cc +++ /dev/null
@@ -1,49 +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/favicon/fallback_icon_service_factory.h" - -#include "base/memory/singleton.h" -#include "chrome/browser/favicon/chrome_fallback_icon_client_factory.h" -#include "chrome/browser/profiles/incognito_helpers.h" -#include "components/favicon/core/fallback_icon_service.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "content/public/browser/browser_context.h" - -// static -favicon::FallbackIconService* FallbackIconServiceFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<favicon::FallbackIconService*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -FallbackIconServiceFactory* FallbackIconServiceFactory::GetInstance() { - return base::Singleton<FallbackIconServiceFactory>::get(); -} - -FallbackIconServiceFactory::FallbackIconServiceFactory() - : BrowserContextKeyedServiceFactory( - "FallbackIconService", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(ChromeFallbackIconClientFactory::GetInstance()); -} - -FallbackIconServiceFactory::~FallbackIconServiceFactory() {} - -content::BrowserContext* FallbackIconServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return chrome::GetBrowserContextRedirectedInIncognito(context); -} - -KeyedService* FallbackIconServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - favicon::FallbackIconClient* fallback_icon_client = - ChromeFallbackIconClientFactory::GetForBrowserContext(context); - return new favicon::FallbackIconService(fallback_icon_client); -} - -bool FallbackIconServiceFactory::ServiceIsNULLWhileTesting() const { - return true; -}
diff --git a/chrome/browser/favicon/fallback_icon_service_factory.h b/chrome/browser/favicon/fallback_icon_service_factory.h deleted file mode 100644 index 82b30bc9..0000000 --- a/chrome/browser/favicon/fallback_icon_service_factory.h +++ /dev/null
@@ -1,48 +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_FAVICON_FALLBACK_ICON_SERVICE_FACTORY_H_ -#define CHROME_BROWSER_FAVICON_FALLBACK_ICON_SERVICE_FACTORY_H_ - -#include "base/macros.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace base { -template <typename T> struct DefaultSingletonTraits; -} - -namespace content { -class BrowserContext; -} - -namespace favicon { -class FallbackIconService; -} - -// Singleton that owns all FallbackIconService and associates them with -// BrowserContext instances. -class FallbackIconServiceFactory : public BrowserContextKeyedServiceFactory { - public: - static favicon::FallbackIconService* GetForBrowserContext( - content::BrowserContext* context); - - static FallbackIconServiceFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<FallbackIconServiceFactory>; - - FallbackIconServiceFactory(); - ~FallbackIconServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - bool ServiceIsNULLWhileTesting() const override; - - DISALLOW_COPY_AND_ASSIGN(FallbackIconServiceFactory); -}; - -#endif // CHROME_BROWSER_FAVICON_FALLBACK_ICON_SERVICE_FACTORY_H_
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 3fe7dc57..b3fd4593 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3115,6 +3115,11 @@ "Changes the maximum number af autocomplete matches displayed in the " "Omnibox UI."; +const char kOmniboxUIVerticalLayoutName[] = "Omnibox UI Vertical Layout"; + +const char kOmniboxUIVerticalLayoutDescription[] = + "Displays Omnibox sugestions in 2 lines - title over origin."; + const char kOmniboxUIVerticalMarginName[] = "Omnibox UI Vertical Margin"; const char kOmniboxUIVerticalMarginDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index a7b0869f7..9b73cfc 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -494,6 +494,9 @@ extern const char kOmniboxUIMaxAutocompleteMatchesName[]; extern const char kOmniboxUIMaxAutocompleteMatchesDescription[]; +extern const char kOmniboxUIVerticalLayoutName[]; +extern const char kOmniboxUIVerticalLayoutDescription[]; + extern const char kOmniboxUIVerticalMarginName[]; extern const char kOmniboxUIVerticalMarginDescription[];
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 935ebc38..12463d42 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -649,15 +649,15 @@ net::ProxyService::CreateDirectWithNetLog(net_log_); globals_->dns_probe_service.reset(new chrome_browser_net::DnsProbeService()); globals_->host_mapping_rules.reset(new net::HostMappingRules()); - params_.host_mapping_rules = globals_->host_mapping_rules.get(); - globals_->http_user_agent_settings.reset( - new net::StaticHttpUserAgentSettings(std::string(), GetUserAgent())); if (command_line.HasSwitch(switches::kHostRules)) { TRACE_EVENT_BEGIN0("startup", "IOThread::InitAsync:SetRulesFromString"); globals_->host_mapping_rules->SetRulesFromString( command_line.GetSwitchValueASCII(switches::kHostRules)); TRACE_EVENT_END0("startup", "IOThread::InitAsync:SetRulesFromString"); } + params_.host_mapping_rules = *globals_->host_mapping_rules.get(); + globals_->http_user_agent_settings.reset( + new net::StaticHttpUserAgentSettings(std::string(), GetUserAgent())); globals_->enable_brotli = base::FeatureList::IsEnabled(features::kBrotliEncoding); params_.enable_token_binding =
diff --git a/chrome/browser/lifetime/browser_close_manager_browsertest.cc b/chrome/browser/lifetime/browser_close_manager_browsertest.cc index 67f6bb69..d4e0baaa 100644 --- a/chrome/browser/lifetime/browser_close_manager_browsertest.cc +++ b/chrome/browser/lifetime/browser_close_manager_browsertest.cc
@@ -64,12 +64,10 @@ namespace { app_modal::NativeAppModalDialog* GetNextDialog() { - app_modal::AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); - EXPECT_TRUE(dialog->IsJavaScriptModalDialog()); - app_modal::JavaScriptAppModalDialog* js_dialog = - static_cast<app_modal::JavaScriptAppModalDialog*>(dialog); - CHECK(js_dialog->native_dialog()); - return js_dialog->native_dialog(); + app_modal::JavaScriptAppModalDialog* dialog = + ui_test_utils::WaitForAppModalDialog(); + CHECK(dialog->native_dialog()); + return dialog->native_dialog(); } // Note: call |PrepareForDialog| on the relevant WebContents or Browser before
diff --git a/chrome/browser/resources/device_log_ui/device_log_ui.html b/chrome/browser/resources/device_log_ui/device_log_ui.html index 17635af..30a1073 100644 --- a/chrome/browser/resources/device_log_ui/device_log_ui.html +++ b/chrome/browser/resources/device_log_ui/device_log_ui.html
@@ -1,69 +1,68 @@ <!DOCTYPE html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> - <title id="device-log-title" i18n-content="titleText"></title> + <title id="device-log-title">$i18n{titleText}</title> <link rel="stylesheet" href="chrome://device-log/device_log_ui.css"> <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/util.js"></script> <script src="chrome://device-log/strings.js"></script> <script src="chrome://device-log/device_log_ui.js"></script> </head> -<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> +<body style="fontFamily:$i18n{fontfamily};fontSize:$i18n{fontsize};"> <div id="header"> - <p i18n-content="autoRefreshText"></p> + <p>$i18n{autoRefreshText}</p> </div> <div id="log-checkbox-container"> - <button id="log-refresh" i18n-content="logRefreshText"></button> - <label id="log-checkbox-show" i18n-content="logLevelShowText"></label> - + <button id="log-refresh">$i18n{logRefreshText}</button> + <label id="log-checkbox-show">$i18n{logLevelShowText}</label> <label> <input id="log-level-error" type="checkbox"> - <span i18n-content="logLevelErrorText"></span> + <span>$i18n{logLevelErrorText}</span> </label> <label> <input id="log-level-user" type="checkbox"> - <span i18n-content="logLevelUserText"></span> + <span>$i18n{logLevelUserText}</span> </label> <label> <input id="log-level-event" type="checkbox"> - <span i18n-content="logLevelEventText"></span> + <span>$i18n{logLevelEventText}</span> </label> <label> <input id="log-level-debug" type="checkbox"> - <span i18n-content="logLevelDebugText"></span> + <span>$i18n{logLevelDebugText}</span> </label> <label> <input id="log-type-login" type="checkbox"> - <span i18n-content="logTypeLoginText"></span> + <span>$i18n{logTypeLoginText}</span> </label> <label> <input id="log-type-network" type="checkbox"> - <span i18n-content="logTypeNetworkText"></span> + <span>$i18n{logTypeNetworkText}</span> </label> <label> <input id="log-type-power" type="checkbox"> - <span i18n-content="logTypePowerText"></span> + <span>$i18n{logTypePowerText}</span> </label> <label> <input id="log-type-bluetooth" type="checkbox"> - <span i18n-content="logTypeBluetoothText"></span> + <span>$i18n{logTypeBluetoothText}</span> </label> <label> <input id="log-type-usb" type="checkbox"> - <span i18n-content="logTypeUsbText"></span> + <span>$i18n{logTypeUsbText}</span> </label> <label> <input id="log-type-hid" type="checkbox"> - <span i18n-content="logTypeHidText"></span> + <span>$i18n{logTypeHidText}</span> </label> <label> <input id="log-fileinfo" type="checkbox"> - <span i18n-content="logLevelFileinfoText"></span> + <span>$i18n{logLevelFileinfoText}</span> </label> <label> <input id="log-timedetail" type="checkbox"> - <span i18n-content="logLevelTimeDetailText"></span> + <span>$i18n{logLevelTimeDetailText}</span> </label> </div> <div id="log-container"></div>
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc index cfdd6ff..c265435 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" #include "chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h" +#include "chrome/browser/ssl/cert_report_helper.h" #include "chrome/browser/ssl/certificate_reporting_test_utils.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -65,7 +66,9 @@ class CertificateReportingServiceBrowserTest : public InProcessBrowserTest { public: CertificateReportingServiceBrowserTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { + CertReportHelper::SetFakeOfficialBuildForTesting(); + } void SetUpOnMainThread() override { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index 42d838d1..2218ddb2 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc
@@ -29,7 +29,6 @@ #include "chrome/browser/ui/webui/theme_source.h" #include "chrome/common/render_messages.h" #include "chrome/grit/theme_resources.h" -#include "components/favicon/core/fallback_icon_service.h" #include "components/history/core/browser/top_sites.h" #include "components/image_fetcher/core/image_fetcher_impl.h" #include "components/keyed_service/core/service_access_type.h"
diff --git a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc index 4b93c43..e7f3115 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc +++ b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc
@@ -95,7 +95,9 @@ class CaptivePortalBlockingPageTest : public InProcessBrowserTest { public: - CaptivePortalBlockingPageTest() {} + CaptivePortalBlockingPageTest() { + CertReportHelper::SetFakeOfficialBuildForTesting(); + } void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitchASCII(
diff --git a/chrome/browser/ssl/cert_report_helper.cc b/chrome/browser/ssl/cert_report_helper.cc index 053ce92..418750ad 100644 --- a/chrome/browser/ssl/cert_report_helper.cc +++ b/chrome/browser/ssl/cert_report_helper.cc
@@ -29,6 +29,10 @@ namespace { +// Certificate reports are only sent from official builds, but this flag can be +// set by tests. +static bool g_is_fake_official_build_for_testing = false; + // Returns a pointer to the Profile associated with |web_contents|. Profile* GetProfile(content::WebContents* web_contents) { return Profile::FromBrowserContext(web_contents->GetBrowserContext()); @@ -65,6 +69,11 @@ CertReportHelper::~CertReportHelper() { } +// static +void CertReportHelper::SetFakeOfficialBuildForTesting() { + g_is_fake_official_build_for_testing = true; +} + void CertReportHelper::PopulateExtendedReportingOption( base::DictionaryValue* load_time_data) { // Only show the checkbox if not off-the-record and if this client is @@ -149,6 +158,15 @@ bool CertReportHelper::ShouldReportCertificateError() { DCHECK(ShouldShowCertificateReporterCheckbox()); + + bool is_official_build = g_is_fake_official_build_for_testing; +#if defined(OFFICIAL_BUILD) && defined(GOOGLE_CHROME_BUILD) + is_official_build = true; +#endif + + if (!is_official_build) + return false; + // Even in case the checkbox was shown, we don't send error reports // for all of these users. Check the Finch configuration for a sending // threshold and only send reports in case the threshold isn't exceeded.
diff --git a/chrome/browser/ssl/cert_report_helper.h b/chrome/browser/ssl/cert_report_helper.h index 8982bcea..0222524 100644 --- a/chrome/browser/ssl/cert_report_helper.h +++ b/chrome/browser/ssl/cert_report_helper.h
@@ -48,6 +48,10 @@ virtual ~CertReportHelper(); + // This method can be called by tests to fake an official build (reports are + // only sent from official builds). + static void SetFakeOfficialBuildForTesting(); + // Populates data that JavaScript code on the interstitial uses to show // the checkbox. void PopulateExtendedReportingOption(base::DictionaryValue* load_time_data);
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index f943989..5992e360 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -768,7 +768,11 @@ class SSLUITestWithExtendedReporting : public SSLUITest { public: - SSLUITestWithExtendedReporting() : SSLUITest() {} + SSLUITestWithExtendedReporting() : SSLUITest() { + // Certificate reports are only sent from official builds, unless this has + // been called. + CertReportHelper::SetFakeOfficialBuildForTesting(); + } }; // Visits a regular page over http.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index a8db9d9b..9162e927 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -346,8 +346,6 @@ "webui/domain_reliability_internals_ui.h", "webui/engagement/site_engagement_ui.cc", "webui/engagement/site_engagement_ui.h", - "webui/fallback_icon_source.cc", - "webui/fallback_icon_source.h", "webui/favicon_source.cc", "webui/favicon_source.h", "webui/fileicon_source.cc", @@ -1574,8 +1572,6 @@ "views/payments/payment_request_views_util.h", "views/payments/payment_sheet_view_controller.cc", "views/payments/payment_sheet_view_controller.h", - "views/payments/preselected_combobox_model.cc", - "views/payments/preselected_combobox_model.h", "views/payments/profile_list_view_controller.cc", "views/payments/profile_list_view_controller.h", "views/payments/shipping_address_editor_view_controller.cc",
diff --git a/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc b/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc index fe7062ce..f3aeb72 100644 --- a/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc +++ b/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc
@@ -152,7 +152,7 @@ ScopedJavaLocalRef<jobject> GetCurrentModalDialog( JNIEnv* env, const JavaParamRef<jclass>& clazz) { - app_modal::AppModalDialog* dialog = + app_modal::JavaScriptAppModalDialog* dialog = app_modal::AppModalDialogQueue::GetInstance()->active_dialog(); if (!dialog || !dialog->native_dialog()) return ScopedJavaLocalRef<jobject>();
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index b418cee..dd8d124 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -432,9 +432,8 @@ return chrome::IsRunningInForcedAppMode(); } -bool ChromeShellDelegate::CanShowWindowForUser(ash::WmWindow* window) const { - return ::CanShowWindowForUser(ash::WmWindow::GetAuraWindow(window), - base::Bind(&GetActiveBrowserContext)); +bool ChromeShellDelegate::CanShowWindowForUser(aura::Window* window) const { + return ::CanShowWindowForUser(window, base::Bind(&GetActiveBrowserContext)); } bool ChromeShellDelegate::IsForceMaximizeOnFirstRun() const {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index cdfc843e..e2e1063 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -35,7 +35,7 @@ bool IsMultiProfilesEnabled() const override; bool IsIncognitoAllowed() const override; bool IsRunningInForcedAppMode() const override; - bool CanShowWindowForUser(ash::WmWindow* window) const override; + bool CanShowWindowForUser(aura::Window* window) const override; bool IsForceMaximizeOnFirstRun() const override; void PreInit() override; void PreShutdown() override;
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc index b838b68..d6f8cc9 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -116,9 +116,9 @@ return new ash::test::TestSessionStateDelegate; } - bool CanShowWindowForUser(ash::WmWindow* window) const override { + bool CanShowWindowForUser(aura::Window* window) const override { return ::CanShowWindowForUser( - ash::WmWindow::GetAuraWindow(window), + window, base::Bind(&ash::ShellContentState::GetActiveBrowserContext, base::Unretained(ash::ShellContentState::GetInstance()))); }
diff --git a/chrome/browser/ui/autofill/autofill_dialog_models.cc b/chrome/browser/ui/autofill/autofill_dialog_models.cc index 71f02b1..c0ad8ef 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_models.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_models.cc
@@ -1,21 +1,60 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/autofill/autofill_dialog_models.h" -#include "base/bind.h" +#include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "chrome/grit/generated_resources.h" -#include "components/autofill/core/browser/autofill_country.h" -#include "components/prefs/pref_service.h" +#include "components/autofill/core/common/autofill_clock.h" #include "ui/base/l10n/l10n_util.h" namespace autofill { +namespace { + +// Number of years to be shown in the year combobox, including the current year. +// YearComboboxModel has the option of passing an additional year if not +// contained within the initial range. +const int kNumberOfExpirationYears = 10; + +// Returns the items that are in the expiration year dropdown. If +// |additional_year| is not 0 and not within the normal range, it will be added +// accordingly. +std::vector<base::string16> GetExpirationYearItems(int additional_year) { + std::vector<base::string16> years; + // Add the "Year" placeholder item. + years.push_back( + l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR)); + + base::Time::Exploded now_exploded; + AutofillClock::Now().LocalExplode(&now_exploded); + + if (additional_year != 0 && additional_year < now_exploded.year) + years.push_back(base::UTF8ToUTF16(std::to_string(additional_year))); + + for (int i = 0; i < kNumberOfExpirationYears; i++) + years.push_back(base::UTF8ToUTF16(std::to_string(now_exploded.year + i))); + + if (additional_year != 0 && + additional_year >= now_exploded.year + kNumberOfExpirationYears) { + years.push_back(base::UTF8ToUTF16(std::to_string(additional_year))); + } + + return years; +} + +// Formats a month, zero-padded (e.g. "02"). +base::string16 FormatMonth(int month) { + return base::ASCIIToUTF16(base::StringPrintf("%.2d", month)); +} + +} // namespace + SuggestionsMenuModelDelegate::~SuggestionsMenuModelDelegate() {} // SuggestionsMenuModel ---------------------------------------------------- @@ -135,11 +174,6 @@ return 13; } -// static -base::string16 MonthComboboxModel::FormatMonth(int index) { - return base::ASCIIToUTF16(base::StringPrintf("%.2d", index)); -} - base::string16 MonthComboboxModel::GetItemAt(int index) { return index == 0 ? l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH) : @@ -148,27 +182,9 @@ // YearComboboxModel ----------------------------------------------------------- -YearComboboxModel::YearComboboxModel() : this_year_(0) { - base::Time time = base::Time::Now(); - base::Time::Exploded exploded; - time.LocalExplode(&exploded); - this_year_ = exploded.year; -} +YearComboboxModel::YearComboboxModel(int additional_year) + : ui::SimpleComboboxModel(GetExpirationYearItems(additional_year)) {} YearComboboxModel::~YearComboboxModel() {} -int YearComboboxModel::GetItemCount() const { - // 10 years plus the empty entry. - return 11; -} - -base::string16 YearComboboxModel::GetItemAt(int index) { - if (index == 0) { - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR); - } - - return base::IntToString16(this_year_ + index - 1); -} - } // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_dialog_models.h b/chrome/browser/ui/autofill/autofill_dialog_models.h index 0fec489..f2f00e7 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_models.h +++ b/chrome/browser/ui/autofill/autofill_dialog_models.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "ui/base/models/combobox_model.h" +#include "ui/base/models/simple_combobox_model.h" #include "ui/base/models/simple_menu_model.h" namespace autofill { @@ -114,8 +115,6 @@ MonthComboboxModel(); ~MonthComboboxModel() override; - static base::string16 FormatMonth(int index); - // ui::Combobox implementation: int GetItemCount() const override; base::string16 GetItemAt(int index) override; @@ -125,19 +124,15 @@ }; // A model for years between now and a decade hence. -class YearComboboxModel : public ui::ComboboxModel { +class YearComboboxModel : public ui::SimpleComboboxModel { public: - YearComboboxModel(); + // If |additional_year| is not in the year range initially in this model + // [current year, current year + 9], this will add |additional_year| to the + // model. Passing 0 has no effect. + explicit YearComboboxModel(int additional_year = 0); ~YearComboboxModel() override; - // ui::Combobox implementation: - int GetItemCount() const override; - base::string16 GetItemAt(int index) override; - private: - // The current year (e.g., 2012). - int this_year_; - DISALLOW_COPY_AND_ASSIGN(YearComboboxModel); };
diff --git a/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc index b9a90dea..921a71e 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc
@@ -3,9 +3,87 @@ // found in the LICENSE file. #include "chrome/browser/ui/autofill/autofill_dialog_models.h" -#include "testing/gmock/include/gmock/gmock.h" + +#include "base/strings/utf_string_conversions.h" +#include "chrome/grit/generated_resources.h" +#include "components/autofill/core/browser/test_autofill_clock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" namespace autofill { +namespace { + +const base::Time kJune2017 = base::Time::FromDoubleT(1497552271); + +} // namespace + +TEST(YearComboboxModelTest, ExpirationYear) { + autofill::TestAutofillClock test_clock; + test_clock.SetNow(kJune2017); + + YearComboboxModel model; + ASSERT_EQ(11, model.GetItemCount()); // Placeholder + 2017-2026. + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR), + model.GetItemAt(0)); + EXPECT_EQ(base::ASCIIToUTF16("2017"), model.GetItemAt(1)); + EXPECT_EQ(base::ASCIIToUTF16("2018"), model.GetItemAt(2)); + EXPECT_EQ(base::ASCIIToUTF16("2019"), model.GetItemAt(3)); + EXPECT_EQ(base::ASCIIToUTF16("2020"), model.GetItemAt(4)); + EXPECT_EQ(base::ASCIIToUTF16("2021"), model.GetItemAt(5)); + EXPECT_EQ(base::ASCIIToUTF16("2022"), model.GetItemAt(6)); + EXPECT_EQ(base::ASCIIToUTF16("2023"), model.GetItemAt(7)); + EXPECT_EQ(base::ASCIIToUTF16("2024"), model.GetItemAt(8)); + EXPECT_EQ(base::ASCIIToUTF16("2025"), model.GetItemAt(9)); + EXPECT_EQ(base::ASCIIToUTF16("2026"), model.GetItemAt(10)); +} + +// Tests that we show the correct years, including an additional year. +TEST(YearComboboxModelTest, ShowAdditionalYear) { + autofill::TestAutofillClock test_clock; + test_clock.SetNow(kJune2017); + + YearComboboxModel model(2016); + ASSERT_EQ(12, model.GetItemCount()); // Placeholder + 2016 + 2017-2026. + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR), + model.GetItemAt(0)); + EXPECT_EQ(base::ASCIIToUTF16("2016"), model.GetItemAt(1)); + EXPECT_EQ(base::ASCIIToUTF16("2017"), model.GetItemAt(2)); + EXPECT_EQ(base::ASCIIToUTF16("2018"), model.GetItemAt(3)); + EXPECT_EQ(base::ASCIIToUTF16("2019"), model.GetItemAt(4)); + EXPECT_EQ(base::ASCIIToUTF16("2020"), model.GetItemAt(5)); + EXPECT_EQ(base::ASCIIToUTF16("2021"), model.GetItemAt(6)); + EXPECT_EQ(base::ASCIIToUTF16("2022"), model.GetItemAt(7)); + EXPECT_EQ(base::ASCIIToUTF16("2023"), model.GetItemAt(8)); + EXPECT_EQ(base::ASCIIToUTF16("2024"), model.GetItemAt(9)); + EXPECT_EQ(base::ASCIIToUTF16("2025"), model.GetItemAt(10)); + EXPECT_EQ(base::ASCIIToUTF16("2026"), model.GetItemAt(11)); +} + +// Tests that we show the additional year, even if it is more than 10 years from +// now. +TEST(YearComboboxModelTest, ExpirationYear_ShowFarFutureYear) { + autofill::TestAutofillClock test_clock; + test_clock.SetNow(kJune2017); + + YearComboboxModel model(2042); + ASSERT_EQ(12, model.GetItemCount()); // Placeholder + 2017-2026 + 2042. + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR), + model.GetItemAt(0)); + EXPECT_EQ(base::ASCIIToUTF16("2017"), model.GetItemAt(1)); + EXPECT_EQ(base::ASCIIToUTF16("2018"), model.GetItemAt(2)); + EXPECT_EQ(base::ASCIIToUTF16("2019"), model.GetItemAt(3)); + EXPECT_EQ(base::ASCIIToUTF16("2020"), model.GetItemAt(4)); + EXPECT_EQ(base::ASCIIToUTF16("2021"), model.GetItemAt(5)); + EXPECT_EQ(base::ASCIIToUTF16("2022"), model.GetItemAt(6)); + EXPECT_EQ(base::ASCIIToUTF16("2023"), model.GetItemAt(7)); + EXPECT_EQ(base::ASCIIToUTF16("2024"), model.GetItemAt(8)); + EXPECT_EQ(base::ASCIIToUTF16("2025"), model.GetItemAt(9)); + EXPECT_EQ(base::ASCIIToUTF16("2026"), model.GetItemAt(10)); + EXPECT_EQ(base::ASCIIToUTF16("2042"), model.GetItemAt(11)); +} + } // namespace autofill
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc index ea174126..2a9fd4f 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -708,19 +708,16 @@ tab->GetMainFrame()->ExecuteJavaScriptForTests( base::UTF8ToUTF16("var o = document.createElement('object'); o.data = " "'/alert_dialog.pdf'; document.body.appendChild(o);")); - app_modal::AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); + app_modal::JavaScriptAppModalDialog* dialog = + ui_test_utils::WaitForAppModalDialog(); #if !defined(OS_MACOSX) if (chrome::FindLastActive() != browser()) alert_waiter.WaitForActivation(); #endif // Verify that after the dialog was closed, the popup is in front again. - ASSERT_TRUE(dialog->IsJavaScriptModalDialog()); - app_modal::JavaScriptAppModalDialog* js_dialog = - static_cast<app_modal::JavaScriptAppModalDialog*>(dialog); - ui_test_utils::BrowserActivationWaiter waiter(popup_browser); - js_dialog->native_dialog()->AcceptAppModalDialog(); + dialog->native_dialog()->AcceptAppModalDialog(); waiter.WaitForActivation(); ASSERT_EQ(popup_browser, chrome::FindLastActive()); }
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 3c05a8e..0610283d 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -71,7 +71,6 @@ #include "chrome/grit/generated_resources.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/app_modal/app_modal_dialog.h" #include "components/app_modal/app_modal_dialog_queue.h" #include "components/app_modal/javascript_app_modal_dialog.h" #include "components/app_modal/native_app_modal_dialog.h" @@ -127,7 +126,6 @@ #include "chrome/browser/browser_process.h" #endif -using app_modal::AppModalDialog; using app_modal::AppModalDialogQueue; using app_modal::JavaScriptAppModalDialog; using base::ASCIIToUTF16; @@ -617,7 +615,7 @@ // Start a navigation to trigger the beforeunload dialog. contents->GetMainFrame()->ExecuteJavaScriptForTests( ASCIIToUTF16("window.location.href = 'about:blank'")); - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); EXPECT_TRUE(alert->IsValid()); AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance(); EXPECT_TRUE(dialog_queue->HasActiveDialog()); @@ -708,7 +706,7 @@ // Navigate to another page, but click cancel in the dialog. Make sure that // the throbber stops spinning. chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); alert->CloseModalDialog(); EXPECT_FALSE(contents->IsLoading()); @@ -835,9 +833,8 @@ browser()->OpenURL(OpenURLParams(redirect_url, Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); - EXPECT_TRUE( - static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog()); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + EXPECT_TRUE(alert->is_before_unload_dialog()); alert->native_dialog()->AcceptAppModalDialog(); nav_observer.Wait(); @@ -866,7 +863,7 @@ content::NotificationService::AllSources()); // Cancel the dialog. - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); alert->CloseModalDialog(); EXPECT_FALSE(contents->IsLoading()); @@ -906,12 +903,11 @@ ->GetMainFrame() ->ExecuteJavaScriptWithUserGestureForTests( ASCIIToUTF16("w.close(); alert('bar');")); - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); alert->native_dialog()->AcceptAppModalDialog(); alert = ui_test_utils::WaitForAppModalDialog(); - EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)-> - is_before_unload_dialog()); + EXPECT_FALSE(alert->is_before_unload_dialog()); alert->native_dialog()->AcceptAppModalDialog(); } @@ -925,8 +921,8 @@ // Reload the page, and check that we get a "before reload" dialog. chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); - EXPECT_TRUE(static_cast<JavaScriptAppModalDialog*>(alert)->is_reload()); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + EXPECT_TRUE(alert->is_reload()); // Proceed with the reload. alert->native_dialog()->AcceptAppModalDialog(); @@ -941,7 +937,7 @@ ui::PAGE_TRANSITION_TYPED, false)); alert = ui_test_utils::WaitForAppModalDialog(); - EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)->is_reload()); + EXPECT_FALSE(alert->is_reload()); // Accept the navigation so we end up on a page without a beforeunload hook. alert->native_dialog()->AcceptAppModalDialog(); @@ -1013,10 +1009,9 @@ // The beforeunload handler will run at exit, ensure it does, and then accept // it to allow shutdown to proceed. - AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); ASSERT_TRUE(alert); - EXPECT_TRUE( - static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog()); + EXPECT_TRUE(alert->is_before_unload_dialog()); alert->native_dialog()->AcceptAppModalDialog(); // But wait there's more! If this test times out, it likely means that the
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm index a15c22a3..fc11f65b 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm
@@ -83,7 +83,7 @@ PermissionMessages permissions; permissions.push_back(PermissionMessage(base::UTF8ToUTF16("warning 1"), PermissionIDSet())); - prompt->SetPermissions(permissions, type); + prompt->AddPermissions(permissions, type); base::string16 permissionString = prompt->GetPermission(0, type); base::scoped_nsobject<ExtensionInstallViewController> controller( @@ -141,7 +141,7 @@ PermissionMessages permissions; permissions.push_back(PermissionMessage(base::UTF8ToUTF16("warning 1"), PermissionIDSet())); - prompt->SetPermissions(permissions, type); + prompt->AddPermissions(permissions, type); base::scoped_nsobject<ExtensionInstallViewController> controller( [[ExtensionInstallViewController alloc] @@ -171,13 +171,13 @@ PermissionMessages permissions; permissions.push_back(PermissionMessage(base::UTF8ToUTF16("warning 1"), PermissionIDSet())); - one_warning_prompt->SetPermissions(permissions, type); + one_warning_prompt->AddPermissions(permissions, type); std::unique_ptr<ExtensionInstallPrompt::Prompt> two_warnings_prompt( chrome::BuildExtensionInstallPrompt(extension_.get())); permissions.push_back(PermissionMessage(base::UTF8ToUTF16("warning 2"), PermissionIDSet())); - two_warnings_prompt->SetPermissions(permissions, type); + two_warnings_prompt->AddPermissions(permissions, type); base::scoped_nsobject<ExtensionInstallViewController> controller1( [[ExtensionInstallViewController alloc] @@ -322,7 +322,7 @@ PermissionMessages permissions; permissions.push_back(PermissionMessage(base::UTF8ToUTF16("warning 1"), PermissionIDSet())); - prompt->SetPermissions(permissions, type); + prompt->AddPermissions(permissions, type); base::scoped_nsobject<ExtensionInstallViewController> controller( [[ExtensionInstallViewController alloc] @@ -355,7 +355,7 @@ base::UTF8ToUTF16("warning 1"), PermissionIDSet(), std::vector<base::string16>(1, base::UTF8ToUTF16("Detail 1")))); - prompt->SetPermissions(permissions, type); + prompt->AddPermissions(permissions, type); prompt->SetIsShowingDetails( ExtensionInstallPrompt::PERMISSIONS_DETAILS, 0, true); base::string16 permissionString = prompt->GetPermissionsDetails(0, type);
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc index 3ac2aad7..7bece9ae 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
@@ -128,7 +128,7 @@ PermissionIDSet())); } std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt = CreatePrompt(); - prompt->SetPermissions(permissions, + prompt->AddPermissions(permissions, ExtensionInstallPrompt::REGULAR_PERMISSIONS); ASSERT_TRUE(IsScrollbarVisible(std::move(prompt))) << "Scrollbar is not visible"; @@ -143,7 +143,7 @@ permissions.push_back(PermissionMessage(permission_string, PermissionIDSet())); std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt = CreatePrompt(); - prompt->SetPermissions(permissions, + prompt->AddPermissions(permissions, ExtensionInstallPrompt::REGULAR_PERMISSIONS); ASSERT_FALSE(IsScrollbarVisible(std::move(prompt))) << "Scrollbar is visible"; }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 810c6f9..6120c4b 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -103,8 +103,8 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h" #include "chrome/grit/theme_resources.h" -#include "components/app_modal/app_modal_dialog.h" #include "components/app_modal/app_modal_dialog_queue.h" +#include "components/app_modal/javascript_app_modal_dialog.h" #include "components/app_modal/native_app_modal_dialog.h" #include "components/omnibox/browser/omnibox_popup_model.h" #include "components/omnibox/browser/omnibox_popup_view.h" @@ -2597,7 +2597,7 @@ void BrowserView::ActivateAppModalDialog() const { // If another browser is app modal, flash and activate the modal browser. - app_modal::AppModalDialog* active_dialog = + app_modal::JavaScriptAppModalDialog* active_dialog = app_modal::AppModalDialogQueue::GetInstance()->active_dialog(); if (!active_dialog) return;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index aff68fc..dab6daf3 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -17,6 +17,7 @@ #include <algorithm> // NOLINT +#include "base/feature_list.h" #include "base/i18n/bidi_line_iterator.h" #include "base/metrics/field_trial_params.h" #include "base/strings/string_number_conversions.h" @@ -303,6 +304,8 @@ int height = GetTextHeight() + (2 * GetVerticalMargin()); if (match_.answer) height += GetAnswerHeight() + kVerticalPadding; + else if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) + height += GetTextHeight() + kVerticalPadding; return gfx::Size(0, height); } @@ -351,42 +354,57 @@ if (description) description->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0))); int contents_max_width, description_max_width; + bool description_on_separate_line = + match.answer != nullptr || + base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout); OmniboxPopupModel::ComputeMatchMaxWidths( - contents->GetContentWidth(), - separator_width_, + contents->GetContentWidth(), separator_width_, description ? description->GetContentWidth() : 0, - mirroring_context_->remaining_width(x), - match.answer != nullptr, - !AutocompleteMatch::IsSearchType(match.type), - &contents_max_width, + mirroring_context_->remaining_width(x), description_on_separate_line, + !AutocompleteMatch::IsSearchType(match.type), &contents_max_width, &description_max_width); - int after_contents_x = DrawRenderText(match, contents, CONTENTS, canvas, - x, y, contents_max_width); - - if (description_max_width != 0) { - if (match.answer) { - y += GetTextHeight() + kVerticalPadding; - if (!answer_image_.isNull()) { - int answer_icon_size = GetAnswerHeight(); - canvas->DrawImageInt( - answer_image_, - 0, 0, answer_image_.width(), answer_image_.height(), - GetMirroredXInView(x), y, answer_icon_size, answer_icon_size, true); - // TODO(dschuyler): Perhaps this should be based on the font size - // instead of hardcoded to 2 dp (e.g. by adding a space in an - // appropriate font to the beginning of the description, then reducing - // the additional padding here to zero). - const int kAnswerIconToTextPadding = 2; - x += answer_icon_size + kAnswerIconToTextPadding; - } - } else { - x = DrawRenderText(match, separator_rendertext_.get(), SEPARATOR, canvas, - after_contents_x, y, separator_width_); + // Answers in Suggest results. + if (match.answer && description_max_width != 0) { + DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); + y += GetTextHeight() + kVerticalPadding; + if (!answer_image_.isNull()) { + int answer_icon_size = GetAnswerHeight(); + canvas->DrawImageInt(answer_image_, 0, 0, answer_image_.width(), + answer_image_.height(), GetMirroredXInView(x), y, + answer_icon_size, answer_icon_size, true); + // TODO(dschuyler): Perhaps this should be based on the font size + // instead of hardcoded to 2 dp (e.g. by adding a space in an + // appropriate font to the beginning of the description, then reducing + // the additional padding here to zero). + const int kAnswerIconToTextPadding = 2; + x += answer_icon_size + kAnswerIconToTextPadding; } + return; + } - DrawRenderText(match, description, DESCRIPTION, canvas, x, y, - description_max_width); + // Regular results. + if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) { + // For no description, shift down halfways to draw contents in middle. + if (description_max_width == 0) + y += (GetTextHeight() + kVerticalPadding) / 2; + + DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); + + if (description_max_width != 0) { + y += GetTextHeight() + kVerticalPadding; + DrawRenderText(match, description, DESCRIPTION, canvas, x, y, + description_max_width); + } + } else { + x = DrawRenderText(match, contents, CONTENTS, canvas, x, y, + contents_max_width); + if (description_max_width != 0) { + x = DrawRenderText(match, separator_rendertext_.get(), SEPARATOR, canvas, + x, y, separator_width_); + DrawRenderText(match, description, DESCRIPTION, canvas, x, y, + description_max_width); + } } } @@ -599,8 +617,15 @@ contents_rendertext_ = CreateAnswerText(match_.answer->first_line(), font_list_); } else { + bool swap_match_text = + base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout) && + !AutocompleteMatch::IsSearchType(match_.type) && + !match_.description.empty(); + contents_rendertext_ = CreateClassifiedRenderText( - match_.contents, match_.contents_class, false); + swap_match_text ? match_.description : match_.contents, + swap_match_text ? match_.description_class : match_.contents_class, + false); } } } @@ -617,8 +642,12 @@ const int end_x = width() - start_x; const gfx::ImageSkia icon = GetIcon(); - const int icon_y = - GetVerticalMargin() + (GetTextHeight() - icon.height()) / 2; + + int row_height = GetTextHeight(); + if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) + row_height += kVerticalPadding + GetTextHeight(); + + const int icon_y = GetVerticalMargin() + (row_height - icon.height()) / 2; icon_bounds_.SetRect(start_x, icon_y, icon.width(), icon.height()); const int text_x = start_x + LocationBarView::kIconWidth + horizontal_padding; @@ -660,8 +689,16 @@ description_rendertext_ = CreateAnswerText(match_.answer->second_line(), GetAnswerFont()); } else if (!match_.description.empty()) { + // If the description is empty, we wouldn't swap with the contents -- + // nor would we create the description RenderText object anyways. + bool swap_match_text = base::FeatureList::IsEnabled( + omnibox::kUIExperimentVerticalLayout) && + !AutocompleteMatch::IsSearchType(match_.type); + description_rendertext_ = CreateClassifiedRenderText( - match_.description, match_.description_class, true); + swap_match_text ? match_.contents : match_.description, + swap_match_text ? match_.contents_class : match_.description_class, + false); } } PaintMatch(match_, contents_rendertext_.get(),
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index 687d476..0068ad3 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -16,10 +16,10 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "chrome/browser/ui/autofill/autofill_dialog_models.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h" -#include "chrome/browser/ui/views/payments/preselected_combobox_model.h" #include "chrome/browser/ui/views/payments/validating_combobox.h" #include "chrome/browser/ui/views/payments/validating_textfield.h" #include "chrome/grit/generated_resources.h" @@ -50,12 +50,6 @@ namespace { -// Number of years to be shown in the expiration year dropdown. If the card's -// year is outside of the range of -// [currentYear, currentYear+kNumberOfExpirationYears], then the UI shows an -// additional entry for the card's expiration year. -const int kNumberOfExpirationYears = 10; - // Opacity of card network icons when they are not selected and are displayed // alongside a selected icon. const float kDimmedCardIconOpacity = 0.33f; @@ -64,49 +58,6 @@ // used. const auto kBillingAddressType = autofill::ADDRESS_BILLING_LINE1; -// Returns the items that are in the expiration month dropdown. Will return the -// months in order starting at "01" until "12". Uses a clock so that the -// |default_index| is set to the current month. -std::vector<base::string16> GetExpirationMonthItems(int* default_index) { - std::vector<base::string16> months; - months.reserve(12); - for (int i = 1; i <= 12; i++) - months.push_back(base::UTF8ToUTF16(base::StringPrintf("%02d", i))); - - base::Time::Exploded now_exploded; - autofill::AutofillClock::Now().LocalExplode(&now_exploded); - *default_index = now_exploded.month - 1; - - return months; -} - -// Returns the items that are in the expiration year dropdown. -std::vector<base::string16> GetExpirationYearItems( - const autofill::CreditCard* card_to_edit) { - std::vector<base::string16> years; - years.reserve(kNumberOfExpirationYears + 1); - - base::Time::Exploded now_exploded; - autofill::AutofillClock::Now().LocalExplode(&now_exploded); - - if (card_to_edit && card_to_edit->expiration_year() < now_exploded.year) { - years.push_back( - base::UTF8ToUTF16(std::to_string(card_to_edit->expiration_year()))); - } - - for (int i = 0; i < kNumberOfExpirationYears; i++) { - years.push_back(base::UTF8ToUTF16(std::to_string(now_exploded.year + i))); - } - - if (card_to_edit && card_to_edit->expiration_year() >= - now_exploded.year + kNumberOfExpirationYears) { - years.push_back( - base::UTF8ToUTF16(std::to_string(card_to_edit->expiration_year()))); - } - - return years; -} - bool IsCardExpired(const base::string16& month, const base::string16& year, const std::string& app_locale) { @@ -533,14 +484,11 @@ const autofill::ServerFieldType& type) { switch (type) { case autofill::CREDIT_CARD_EXP_MONTH: { - int default_index = 0; - std::vector<base::string16> months = - GetExpirationMonthItems(&default_index); - return base::MakeUnique<PreselectedComboboxModel>(months, default_index); + return base::MakeUnique<autofill::MonthComboboxModel>(); } case autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR: - return base::MakeUnique<ui::SimpleComboboxModel>( - GetExpirationYearItems(credit_card_to_edit_)); + return base::MakeUnique<autofill::YearComboboxModel>( + credit_card_to_edit_ ? credit_card_to_edit_->expiration_year() : 0); case kBillingAddressType: // The combobox filled with potential billing addresses. It's fine to pass // empty string as the default selected guid if there are no cards being
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc index c3813dfd..0047e43 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc
@@ -453,16 +453,25 @@ InvokePaymentRequestUI(); - // One instrument is available, but it's not selected. + // One instrument is available, and it's selected because being expired can + // still select the instrument. PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); EXPECT_EQ(1U, request->state()->available_instruments().size()); - EXPECT_EQ(nullptr, request->state()->selected_instrument()); + EXPECT_NE(nullptr, request->state()->selected_instrument()); OpenPaymentMethodScreen(); + // Opening the credit card editor by clicking the edit button. + views::View* list_view = dialog_view()->GetViewByID( + static_cast<int>(DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW)); + EXPECT_TRUE(list_view); + EXPECT_EQ(1, list_view->child_count()); + + views::View* edit_button = list_view->child_at(0)->GetViewByID( + static_cast<int>(DialogViewID::EDIT_ITEM_BUTTON)); + ResetEventObserver(DialogEvent::CREDIT_CARD_EDITOR_OPENED); - ClickOnChildInListViewAndWait(/*child_index=*/0, /*num_children=*/1, - DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW); + ClickOnDialogViewAndWait(edit_button); EXPECT_EQ(base::ASCIIToUTF16("Test User"), GetEditorTextfieldValue(autofill::CREDIT_CARD_NAME_FULL)); @@ -507,7 +516,7 @@ EXPECT_EQ(base::ASCIIToUTF16("Test User"), credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL)); - // Still have one instrument, but now it's selected. + // Still have one instrument, and it's still selected. EXPECT_EQ(1U, request->state()->available_instruments().size()); EXPECT_EQ(request->state()->available_instruments().back().get(), request->state()->selected_instrument());
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller_unittest.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_unittest.cc deleted file mode 100644 index a377bd8..0000000 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller_unittest.cc +++ /dev/null
@@ -1,168 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/payments/credit_card_editor_view_controller.h" - -#include "base/callback_forward.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/views/payments/editor_view_controller.h" -#include "components/autofill/core/browser/test_autofill_clock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/views/controls/combobox/combobox.h" - -namespace payments { - -namespace { - -const base::Time kJanuary2017 = base::Time::FromDoubleT(1484505871); -const base::Time kJune2017 = base::Time::FromDoubleT(1497552271); - -} // namespace - -// Test that if we are in January, the returned months are as expected, and the -// default selected month is January. -TEST(CreditCardEditorViewControllerTest, ExpirationMonth_FromJanuary) { - autofill::TestAutofillClock test_clock; - test_clock.SetNow(kJanuary2017); - - CreditCardEditorViewController view_controller( - nullptr, nullptr, nullptr, BackNavigationType::kPaymentSheet, 0, - base::OnceClosure(), - base::OnceCallback<void(const autofill::CreditCard&)>(), nullptr); - - auto model = - view_controller.GetComboboxModelForType(autofill::CREDIT_CARD_EXP_MONTH); - ASSERT_EQ(12, model->GetItemCount()); - EXPECT_EQ(base::ASCIIToUTF16("01"), model->GetItemAt(0)); - EXPECT_EQ(base::ASCIIToUTF16("02"), model->GetItemAt(1)); - EXPECT_EQ(base::ASCIIToUTF16("03"), model->GetItemAt(2)); - EXPECT_EQ(base::ASCIIToUTF16("04"), model->GetItemAt(3)); - EXPECT_EQ(base::ASCIIToUTF16("05"), model->GetItemAt(4)); - EXPECT_EQ(base::ASCIIToUTF16("06"), model->GetItemAt(5)); - EXPECT_EQ(base::ASCIIToUTF16("07"), model->GetItemAt(6)); - EXPECT_EQ(base::ASCIIToUTF16("08"), model->GetItemAt(7)); - EXPECT_EQ(base::ASCIIToUTF16("09"), model->GetItemAt(8)); - EXPECT_EQ(base::ASCIIToUTF16("10"), model->GetItemAt(9)); - EXPECT_EQ(base::ASCIIToUTF16("11"), model->GetItemAt(10)); - EXPECT_EQ(base::ASCIIToUTF16("12"), model->GetItemAt(11)); - - // Selected item is the current month. - EXPECT_EQ(0, model->GetDefaultIndex()); -} - -// Test that if we are in June, the returned months are as expected, and the -// default selected month is June. -TEST(CreditCardEditorViewControllerTest, ExpirationMonth_FromJune) { - autofill::TestAutofillClock test_clock; - test_clock.SetNow(kJune2017); - - CreditCardEditorViewController view_controller( - nullptr, nullptr, nullptr, BackNavigationType::kPaymentSheet, 0, - base::OnceClosure(), - base::OnceCallback<void(const autofill::CreditCard&)>(), nullptr); - - auto model = - view_controller.GetComboboxModelForType(autofill::CREDIT_CARD_EXP_MONTH); - ASSERT_EQ(12, model->GetItemCount()); - EXPECT_EQ(base::ASCIIToUTF16("01"), model->GetItemAt(0)); - EXPECT_EQ(base::ASCIIToUTF16("02"), model->GetItemAt(1)); - EXPECT_EQ(base::ASCIIToUTF16("03"), model->GetItemAt(2)); - EXPECT_EQ(base::ASCIIToUTF16("04"), model->GetItemAt(3)); - EXPECT_EQ(base::ASCIIToUTF16("05"), model->GetItemAt(4)); - EXPECT_EQ(base::ASCIIToUTF16("06"), model->GetItemAt(5)); - EXPECT_EQ(base::ASCIIToUTF16("07"), model->GetItemAt(6)); - EXPECT_EQ(base::ASCIIToUTF16("08"), model->GetItemAt(7)); - EXPECT_EQ(base::ASCIIToUTF16("09"), model->GetItemAt(8)); - EXPECT_EQ(base::ASCIIToUTF16("10"), model->GetItemAt(9)); - EXPECT_EQ(base::ASCIIToUTF16("11"), model->GetItemAt(10)); - EXPECT_EQ(base::ASCIIToUTF16("12"), model->GetItemAt(11)); - - EXPECT_EQ(5, model->GetDefaultIndex()); -} - -// Tests that we show the correct amount of years in the year dropdown, starting -// with the current one. -TEST(CreditCardEditorViewControllerTest, ExpirationYear_From2017) { - autofill::TestAutofillClock test_clock; - test_clock.SetNow(kJune2017); - - CreditCardEditorViewController view_controller( - nullptr, nullptr, nullptr, BackNavigationType::kPaymentSheet, 0, - base::OnceClosure(), - base::OnceCallback<void(const autofill::CreditCard&)>(), nullptr); - - auto model = view_controller.GetComboboxModelForType( - autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR); - ASSERT_EQ(10, model->GetItemCount()); - EXPECT_EQ(base::ASCIIToUTF16("2017"), model->GetItemAt(0)); - EXPECT_EQ(base::ASCIIToUTF16("2018"), model->GetItemAt(1)); - EXPECT_EQ(base::ASCIIToUTF16("2019"), model->GetItemAt(2)); - EXPECT_EQ(base::ASCIIToUTF16("2020"), model->GetItemAt(3)); - EXPECT_EQ(base::ASCIIToUTF16("2021"), model->GetItemAt(4)); - EXPECT_EQ(base::ASCIIToUTF16("2022"), model->GetItemAt(5)); - EXPECT_EQ(base::ASCIIToUTF16("2023"), model->GetItemAt(6)); - EXPECT_EQ(base::ASCIIToUTF16("2024"), model->GetItemAt(7)); - EXPECT_EQ(base::ASCIIToUTF16("2025"), model->GetItemAt(8)); - EXPECT_EQ(base::ASCIIToUTF16("2026"), model->GetItemAt(9)); -} - -// Tests that we show the expiration year of the card, even if the card is -// expired. -TEST(CreditCardEditorViewControllerTest, ExpirationYear_ShowExpiredYear) { - autofill::TestAutofillClock test_clock; - test_clock.SetNow(kJune2017); - - autofill::CreditCard card; - card.SetExpirationYear(2016); - CreditCardEditorViewController view_controller( - nullptr, nullptr, nullptr, BackNavigationType::kPaymentSheet, 0, - base::OnceClosure(), - base::OnceCallback<void(const autofill::CreditCard&)>(), &card); - - auto model = view_controller.GetComboboxModelForType( - autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR); - ASSERT_EQ(11, model->GetItemCount()); - EXPECT_EQ(base::ASCIIToUTF16("2016"), model->GetItemAt(0)); - EXPECT_EQ(base::ASCIIToUTF16("2017"), model->GetItemAt(1)); - EXPECT_EQ(base::ASCIIToUTF16("2018"), model->GetItemAt(2)); - EXPECT_EQ(base::ASCIIToUTF16("2019"), model->GetItemAt(3)); - EXPECT_EQ(base::ASCIIToUTF16("2020"), model->GetItemAt(4)); - EXPECT_EQ(base::ASCIIToUTF16("2021"), model->GetItemAt(5)); - EXPECT_EQ(base::ASCIIToUTF16("2022"), model->GetItemAt(6)); - EXPECT_EQ(base::ASCIIToUTF16("2023"), model->GetItemAt(7)); - EXPECT_EQ(base::ASCIIToUTF16("2024"), model->GetItemAt(8)); - EXPECT_EQ(base::ASCIIToUTF16("2025"), model->GetItemAt(9)); - EXPECT_EQ(base::ASCIIToUTF16("2026"), model->GetItemAt(10)); -} - -// Tests that we show the expiration year of the card, even if the card expires -// more than 10 years from now. -TEST(CreditCardEditorViewControllerTest, ExpirationYear_ShowFarFutureYear) { - autofill::TestAutofillClock test_clock; - test_clock.SetNow(kJune2017); - - autofill::CreditCard card; - card.SetExpirationYear(2027); - CreditCardEditorViewController view_controller( - nullptr, nullptr, nullptr, BackNavigationType::kPaymentSheet, 0, - base::OnceClosure(), - base::OnceCallback<void(const autofill::CreditCard&)>(), &card); - - auto model = view_controller.GetComboboxModelForType( - autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR); - ASSERT_EQ(11, model->GetItemCount()); - EXPECT_EQ(base::ASCIIToUTF16("2017"), model->GetItemAt(0)); - EXPECT_EQ(base::ASCIIToUTF16("2018"), model->GetItemAt(1)); - EXPECT_EQ(base::ASCIIToUTF16("2019"), model->GetItemAt(2)); - EXPECT_EQ(base::ASCIIToUTF16("2020"), model->GetItemAt(3)); - EXPECT_EQ(base::ASCIIToUTF16("2021"), model->GetItemAt(4)); - EXPECT_EQ(base::ASCIIToUTF16("2022"), model->GetItemAt(5)); - EXPECT_EQ(base::ASCIIToUTF16("2023"), model->GetItemAt(6)); - EXPECT_EQ(base::ASCIIToUTF16("2024"), model->GetItemAt(7)); - EXPECT_EQ(base::ASCIIToUTF16("2025"), model->GetItemAt(8)); - EXPECT_EQ(base::ASCIIToUTF16("2026"), model->GetItemAt(9)); - EXPECT_EQ(base::ASCIIToUTF16("2027"), model->GetItemAt(10)); -} - -} // namespace payments
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc index 9f005eb..39951a8a 100644 --- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc +++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc
@@ -53,6 +53,7 @@ result_delegate, content::WebContents* web_contents) : PaymentRequestSheetController(spec, state, dialog), + year_combobox_model_(credit_card.expiration_year()), credit_card_(credit_card), web_contents_(web_contents), payments_client_( @@ -205,11 +206,15 @@ auto month = base::MakeUnique<views::Combobox>(&month_combobox_model_); month->set_listener(this); month->set_id(static_cast<int>(DialogViewID::CVC_MONTH)); + month->SelectValue(credit_card_.ExpirationMonthAsString()); + month->SetInvalid(true); layout->AddView(month.release()); auto year = base::MakeUnique<views::Combobox>(&year_combobox_model_); year->set_listener(this); year->set_id(static_cast<int>(DialogViewID::CVC_YEAR)); + year->SelectValue(credit_card_.Expiration4DigitYearAsString()); + year->SetInvalid(true); layout->AddView(year.release()); } @@ -342,6 +347,9 @@ expiration_date_valid = autofill::IsValidCreditCardExpirationDate( year_value, month_value, autofill::AutofillClock::Now()); + + month->SetInvalid(!expiration_date_valid); + year->SetInvalid(!expiration_date_valid); } }
diff --git a/chrome/browser/ui/views/payments/preselected_combobox_model.cc b/chrome/browser/ui/views/payments/preselected_combobox_model.cc deleted file mode 100644 index 14339d9..0000000 --- a/chrome/browser/ui/views/payments/preselected_combobox_model.cc +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/payments/preselected_combobox_model.h" - -namespace payments { - -PreselectedComboboxModel::PreselectedComboboxModel( - const std::vector<base::string16>& items, - int default_index) - : SimpleComboboxModel(items), default_index_(default_index) {} - -PreselectedComboboxModel::~PreselectedComboboxModel() {} - -int PreselectedComboboxModel::GetDefaultIndex() const { - return default_index_; -} - -} // namespace payments
diff --git a/chrome/browser/ui/views/payments/preselected_combobox_model.h b/chrome/browser/ui/views/payments/preselected_combobox_model.h deleted file mode 100644 index 8a1bb75..0000000 --- a/chrome/browser/ui/views/payments/preselected_combobox_model.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_PRESELECTED_COMBOBOX_MODEL_H_ -#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PRESELECTED_COMBOBOX_MODEL_H_ - -#include <vector> - -#include "base/macros.h" -#include "base/strings/string16.h" -#include "ui/base/models/simple_combobox_model.h" - -namespace payments { - -// A simple data model for a combobox that takes a string16 vector as the items, -// as well as the default selected index. An empty string is a separator. -class PreselectedComboboxModel : public ui::SimpleComboboxModel { - public: - PreselectedComboboxModel(const std::vector<base::string16>& items, - int default_index); - ~PreselectedComboboxModel() override; - - // ui::ComboboxModel: - int GetDefaultIndex() const override; - - private: - const int default_index_; - - DISALLOW_COPY_AND_ASSIGN(PreselectedComboboxModel); -}; - -} // namespace payments - -#endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PRESELECTED_COMBOBOX_MODEL_H_
diff --git a/chrome/browser/ui/webui/fallback_icon_source.cc b/chrome/browser/ui/webui/fallback_icon_source.cc deleted file mode 100644 index 7fbe9f3..0000000 --- a/chrome/browser/ui/webui/fallback_icon_source.cc +++ /dev/null
@@ -1,99 +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/ui/webui/fallback_icon_source.h" - -#include <vector> - -#include "base/memory/ref_counted_memory.h" -#include "chrome/browser/search/instant_io_context.h" -#include "chrome/common/url_constants.h" -#include "components/favicon/core/fallback_icon_service.h" -#include "components/favicon_base/fallback_icon_url_parser.h" -#include "components/keyed_service/core/service_access_type.h" -#include "net/url_request/url_request.h" -#include "ui/gfx/favicon_size.h" -#include "url/gurl.h" - -FallbackIconSource::FallbackIconSource( - favicon::FallbackIconService* fallback_icon_service) - : fallback_icon_service_(fallback_icon_service) { -} - -FallbackIconSource::~FallbackIconSource() { -} - -std::string FallbackIconSource::GetSource() const { - return chrome::kChromeUIFallbackIconHost; -} - -void FallbackIconSource::StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) { - chrome::ParsedFallbackIconPath parsed; - bool success = parsed.Parse(path); - if (!success) { - SendDefaultResponse(callback); - return; - } - - GURL url(parsed.url_string()); - if (url.is_empty() || !url.is_valid()) { - SendDefaultResponse(callback); - return; - } - - SendFallbackIconHelper( - url, parsed.size_in_pixels(), parsed.style(), callback); -} - -std::string FallbackIconSource::GetMimeType(const std::string&) const { - // We need to explicitly return a mime type, otherwise if the user tries to - // drag the image they get no extension. - return "image/png"; -} - -bool FallbackIconSource::AllowCaching() const { - return false; -} - -bool FallbackIconSource::ShouldReplaceExistingSource() const { - // Leave the existing DataSource in place, otherwise we'll drop any pending - // requests on the floor. - return false; -} - -bool FallbackIconSource::ShouldServiceRequest( - const GURL& url, - content::ResourceContext* resource_context, - int render_process_id) const { - if (url.SchemeIs(chrome::kChromeSearchScheme)) { - return InstantIOContext::ShouldServiceRequest(url, resource_context, - render_process_id); - } - return URLDataSource::ShouldServiceRequest(url, resource_context, - render_process_id); -} - -void FallbackIconSource::SendFallbackIconHelper( - const GURL& url, - int size_in_pixels, - const favicon_base::FallbackIconStyle& style, - const content::URLDataSource::GotDataCallback& callback) { - if (!fallback_icon_service_) { // Can be null for tests. - callback.Run(nullptr); // Trigger "Not Found" response. - return; - } - std::vector<unsigned char> bitmap_data = - fallback_icon_service_->RenderFallbackIconBitmap( - url, size_in_pixels, style); - callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data)); -} - -void FallbackIconSource::SendDefaultResponse( - const content::URLDataSource::GotDataCallback& callback) { - favicon_base::FallbackIconStyle default_style; - SendFallbackIconHelper(GURL(), gfx::kFaviconSize, default_style, callback); -}
diff --git a/chrome/browser/ui/webui/fallback_icon_source.h b/chrome/browser/ui/webui/fallback_icon_source.h deleted file mode 100644 index 5526f77..0000000 --- a/chrome/browser/ui/webui/fallback_icon_source.h +++ /dev/null
@@ -1,91 +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_UI_WEBUI_FALLBACK_ICON_SOURCE_H_ -#define CHROME_BROWSER_UI_WEBUI_FALLBACK_ICON_SOURCE_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "content/public/browser/url_data_source.h" - -class GURL; - -namespace favicon_base { -struct FallbackIconStyle; -} - -namespace favicon { -class FallbackIconService; -} - -// FallbackIconSource services explicit chrome:// requests for fallback icons. -// -// Format: -// chrome://fallback-icon/size,bc,tc,fsr,r/url -// All of the parameters except for the url are optional. However, the order of -// the parameters is not interchangeable, and all "," must be in place. -// -// Parameter: -// 'size' -// Positive integer to specify the fallback icon's size in pixels. -// 'bc' -// Fallback icon's background color, as named CSS color, or RGB / ARGB / -// RRGGBB / AARRGGBB hex formats (no leading "#"). -// 'tc' -// Fallback icon text color, as named CSS color, or RGB / ARGB / RRGGBB / -// AARRGGBB hex formats (no leading "#"). -// 'fsr' -// Number in [0.0, 1.0] to specify the fallback icon's font size (pixels) -// as a ratio to the icon's size. -// 'r' -// Number in [0.0, 1.0] to specify the fallback icon's roundness. -// 0.0 specifies a square icon; 1.0 specifies a circle icon; intermediate -// values specify a rounded square icon. -// 'url' -// String to specify the page URL of the fallback icon. -// -// Example: chrome://fallback-icon/32,red,#000,0.5,1.0/http://www.google.com/ -// This requests a 32x32 fallback icon for http://www.google.com, using -// red as the background color, #000 as the text color, with font size of -// 32 * 0.5 = 16, and the icon's background shape is a circle. -class FallbackIconSource : public content::URLDataSource { - public: - // |fallback_icon_service| is owned by caller, and may be null. - explicit FallbackIconSource( - favicon::FallbackIconService* fallback_icon_service); - - ~FallbackIconSource() override; - - // content::URLDataSource implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) override; - std::string GetMimeType(const std::string&) const override; - bool AllowCaching() const override; - bool ShouldReplaceExistingSource() const override; - bool ShouldServiceRequest(const GURL& url, - content::ResourceContext* resource_context, - int render_process_id) const override; - - private: - void SendFallbackIconHelper( - const GURL& url, - int size_in_pixels, - const favicon_base::FallbackIconStyle& style, - const content::URLDataSource::GotDataCallback& callback); - - // Sends the default fallback icon. - void SendDefaultResponse( - const content::URLDataSource::GotDataCallback& callback); - - favicon::FallbackIconService* fallback_icon_service_; - - DISALLOW_COPY_AND_ASSIGN(FallbackIconSource); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_FALLBACK_ICON_SOURCE_H_
diff --git a/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc b/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc index 94cca8f5..22867769 100644 --- a/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc +++ b/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc
@@ -131,7 +131,7 @@ if (prefs_->IsConfigurationCurrent(*printer)) { // Skip setup if the printer is already installed. - HandlePrinterSetup(std::move(printer), cb, chromeos::SUCCESS); + HandlePrinterSetup(std::move(printer), cb, chromeos::kSuccess); return; } @@ -149,7 +149,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); switch (result) { - case chromeos::PrinterSetupResult::SUCCESS: + case chromeos::PrinterSetupResult::kSuccess: VLOG(1) << "Printer setup successful for " << printer->id() << " fetching properties"; prefs_->PrinterInstalled(*printer); @@ -157,23 +157,26 @@ // fetch settings on the blocking pool and invoke callback. FetchCapabilities(std::move(printer), cb); return; - case chromeos::PrinterSetupResult::PPD_NOT_FOUND: + case chromeos::PrinterSetupResult::kPpdNotFound: LOG(WARNING) << "Could not find PPD. Check printer configuration."; // Prompt user to update configuration. // TODO(skau): Fill me in break; - case chromeos::PrinterSetupResult::PPD_UNRETRIEVABLE: + case chromeos::PrinterSetupResult::kPpdUnretrievable: LOG(WARNING) << "Could not download PPD. Check Internet connection."; // Could not download PPD. Connect to Internet. // TODO(skau): Fill me in break; - case chromeos::PrinterSetupResult::PRINTER_UNREACHABLE: - case chromeos::PrinterSetupResult::DBUS_ERROR: - case chromeos::PrinterSetupResult::PPD_TOO_LARGE: - case chromeos::PrinterSetupResult::INVALID_PPD: - case chromeos::PrinterSetupResult::FATAL_ERROR: + case chromeos::PrinterSetupResult::kPrinterUnreachable: + case chromeos::PrinterSetupResult::kDbusError: + case chromeos::PrinterSetupResult::kPpdTooLarge: + case chromeos::PrinterSetupResult::kInvalidPpd: + case chromeos::PrinterSetupResult::kFatalError: LOG(ERROR) << "Unexpected error in printer setup." << result; break; + case chromeos::PrinterSetupResult::kMaxValue: + NOTREACHED() << "This value is not expected"; + break; } // TODO(skau): Open printer settings if this is resolvable.
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc index 28a1781f..0a07cfa 100644 --- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -256,35 +256,38 @@ chromeos::PrinterSetupResult result_code) { std::string printer_name = printer->display_name(); switch (result_code) { - case chromeos::PrinterSetupResult::SUCCESS: { + case chromeos::PrinterSetupResult::kSuccess: { auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_); manager->PrinterInstalled(*printer); manager->RegisterPrinter(std::move(printer)); break; } - case chromeos::PrinterSetupResult::PPD_NOT_FOUND: + case chromeos::PrinterSetupResult::kPpdNotFound: LOG(WARNING) << "Could not locate requested PPD"; break; - case chromeos::PrinterSetupResult::PPD_TOO_LARGE: + case chromeos::PrinterSetupResult::kPpdTooLarge: LOG(WARNING) << "PPD is too large"; break; - case chromeos::PrinterSetupResult::PPD_UNRETRIEVABLE: + case chromeos::PrinterSetupResult::kPpdUnretrievable: LOG(WARNING) << "Could not retrieve PPD from server"; break; - case chromeos::PrinterSetupResult::INVALID_PPD: + case chromeos::PrinterSetupResult::kInvalidPpd: LOG(WARNING) << "Provided PPD is invalid."; break; - case chromeos::PrinterSetupResult::PRINTER_UNREACHABLE: + case chromeos::PrinterSetupResult::kPrinterUnreachable: LOG(WARNING) << "Could not contact printer for configuration"; break; - case chromeos::PrinterSetupResult::DBUS_ERROR: - case chromeos::PrinterSetupResult::FATAL_ERROR: + case chromeos::PrinterSetupResult::kDbusError: + case chromeos::PrinterSetupResult::kFatalError: LOG(ERROR) << "Unrecoverable error. Reboot required."; break; + case chromeos::PrinterSetupResult::kMaxValue: + NOTREACHED() << "This is not an expected value"; + break; } CallJavascriptFunction( "cr.webUIListenerCallback", base::Value("on-add-cups-printer"), - base::Value(result_code == chromeos::PrinterSetupResult::SUCCESS), + base::Value(result_code == chromeos::PrinterSetupResult::kSuccess), base::Value(printer_name)); }
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc index 1051724..6b50fa4c 100644 --- a/chrome/browser/unload_browsertest.cc +++ b/chrome/browser/unload_browsertest.cc
@@ -195,14 +195,12 @@ // If |accept| is true, simulates user clicking OK, otherwise simulates // clicking Cancel. void ClickModalDialogButton(bool accept) { - app_modal::AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); - ASSERT_TRUE(dialog->IsJavaScriptModalDialog()); - app_modal::JavaScriptAppModalDialog* js_dialog = - static_cast<app_modal::JavaScriptAppModalDialog*>(dialog); + app_modal::JavaScriptAppModalDialog* dialog = + ui_test_utils::WaitForAppModalDialog(); if (accept) - js_dialog->native_dialog()->AcceptAppModalDialog(); + dialog->native_dialog()->AcceptAppModalDialog(); else - js_dialog->native_dialog()->CancelAppModalDialog(); + dialog->native_dialog()->CancelAppModalDialog(); } void PrepareForDialog(Browser* browser) {
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 958a29a..e0170a7 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -312,6 +312,7 @@ "extensions/manifest_handlers/theme_handler.h", "extensions/manifest_handlers/ui_overrides_handler.cc", "extensions/manifest_handlers/ui_overrides_handler.h", + "extensions/mojom/inline_install_traits.h", "extensions/permissions/chrome_api_permissions.cc", "extensions/permissions/chrome_api_permissions.h", "extensions/permissions/chrome_permission_message_provider.cc",
diff --git a/chrome/common/extensions/BUILD.gn b/chrome/common/extensions/BUILD.gn index fc461066..3d7c604 100644 --- a/chrome/common/extensions/BUILD.gn +++ b/chrome/common/extensions/BUILD.gn
@@ -26,6 +26,7 @@ mojom("mojo_bindings") { sources = [ "media_parser.mojom", + "mojom/inline_install.mojom", "removable_storage_writer.mojom", ]
diff --git a/chrome/common/extensions/chrome_extension_messages.h b/chrome/common/extensions/chrome_extension_messages.h index b21ab89c..14712e95 100644 --- a/chrome/common/extensions/chrome_extension_messages.h +++ b/chrome/common/extensions/chrome_extension_messages.h
@@ -29,6 +29,8 @@ #define IPC_MESSAGE_START ChromeExtensionMsgStart +// TODO(crbug.com/725275): Remove these ipc enums once all ipc messages here are +// converted to mojo. IPC_ENUM_TRAITS_MAX_VALUE(extensions::api::webstore::InstallStage, extensions::api::webstore::INSTALL_STAGE_INSTALLING) IPC_ENUM_TRAITS_MAX_VALUE(extensions::webstore_install::Result, @@ -36,24 +38,6 @@ // Messages sent from the browser to the renderer. -// Sent to the renderer if install stage updates were requested for an inline -// install. -IPC_MESSAGE_ROUTED1(ExtensionMsg_InlineInstallStageChanged, - extensions::api::webstore::InstallStage /* stage */) - -// Sent to the renderer if download progress updates were requested for an -// inline install. -IPC_MESSAGE_ROUTED1(ExtensionMsg_InlineInstallDownloadProgress, - int /* percent_downloaded */) - -// Send to renderer once the installation mentioned on -// ExtensionHostMsg_InlineWebstoreInstall is complete. -IPC_MESSAGE_ROUTED4(ExtensionMsg_InlineWebstoreInstallResponse, - int32_t /* install id */, - bool /* whether the install was successful */, - std::string /* error */, - extensions::webstore_install::Result /* result */) - IPC_STRUCT_TRAITS_BEGIN(ui::AXNodeData) IPC_STRUCT_TRAITS_MEMBER(id) IPC_STRUCT_TRAITS_MEMBER(role) @@ -141,12 +125,3 @@ IPC_MESSAGE_ROUTED1(ExtensionMsg_AccessibilityLocationChange, ExtensionMsg_AccessibilityLocationChangeParams) -// Messages sent from the renderer to the browser. - - -// Sent by the renderer to implement chrome.webstore.install(). -IPC_MESSAGE_ROUTED4(ExtensionHostMsg_InlineWebstoreInstall, - int32_t /* install id */, - int32_t /* return route id */, - std::string /* Web Store item ID */, - int /* listeners_mask */)
diff --git a/chrome/common/extensions/mojom/OWNERS b/chrome/common/extensions/mojom/OWNERS new file mode 100644 index 0000000..229dacdd --- /dev/null +++ b/chrome/common/extensions/mojom/OWNERS
@@ -0,0 +1,4 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chrome/common/extensions/mojom/inline_install.mojom b/chrome/common/extensions/mojom/inline_install.mojom new file mode 100644 index 0000000..e298424 --- /dev/null +++ b/chrome/common/extensions/mojom/inline_install.mojom
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module extensions.mojom; + +[Native] +enum WebstoreInstallResult; + +[Native] +enum WebstoreInstallStage; + +interface InlineInstallProgressListener { + // Notifies the renderer when install stage updates were requested for an + // inline install. + InlineInstallStageChanged(WebstoreInstallStage stage); + + // Notifies the renderer when download progress updates were requested for an + // inline install. + InlineInstallDownloadProgress(int32 percent_downloaded); +}; + +interface InlineInstaller { + // Sent by the renderer to implement chrome.webstore.install() and notifies + // the renderer once the installation is complete. + DoInlineInstall(string webstore_item_id, int32 listeners_mask, + InlineInstallProgressListener install_progress_listener) => + (bool success, string error, WebstoreInstallResult result); +}; + +
diff --git a/chrome/common/extensions/mojom/inline_install.typemap b/chrome/common/extensions/mojom/inline_install.typemap new file mode 100644 index 0000000..3a08ce5 --- /dev/null +++ b/chrome/common/extensions/mojom/inline_install.typemap
@@ -0,0 +1,14 @@ +# 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. + +mojom = "//chrome/common/extensions/mojom/inline_install.mojom" +public_headers = [ + "//chrome/common/extensions/api/webstore/webstore_api_constants.h", + "//chrome/common/extensions/webstore_install_result.h", +] +traits_headers = [ "//chrome/common/extensions/mojom/inline_install_traits.h" ] +type_mappings = [ + "extensions.mojom.WebstoreInstallStage=::extensions::api::webstore::InstallStage", + "extensions.mojom.WebstoreInstallResult=::extensions::webstore_install::Result", +]
diff --git a/chrome/common/extensions/mojom/inline_install_traits.h b/chrome/common/extensions/mojom/inline_install_traits.h new file mode 100644 index 0000000..4363634 --- /dev/null +++ b/chrome/common/extensions/mojom/inline_install_traits.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_EXTENSIONS_MOJOM_INLINE_INSTALL_TRAITS_H_ +#define CHROME_COMMON_EXTENSIONS_MOJOM_INLINE_INSTALL_TRAITS_H_ + +#include "chrome/common/extensions/api/webstore/webstore_api_constants.h" +#include "chrome/common/extensions/webstore_install_result.h" +#include "ipc/ipc_message_macros.h" + +IPC_ENUM_TRAITS_MAX_VALUE( + extensions::api::webstore::InstallStage, + extensions::api::webstore::InstallStage::INSTALL_STAGE_INSTALLING) +IPC_ENUM_TRAITS_MAX_VALUE(extensions::webstore_install::Result, + extensions::webstore_install::RESULT_LAST) + +#endif // CHROME_COMMON_EXTENSIONS_MOJOM_INLINE_INSTALL_TRAITS_H_
diff --git a/chrome/common/extensions/typemaps.gni b/chrome/common/extensions/typemaps.gni index 0194203..17f61e7 100644 --- a/chrome/common/extensions/typemaps.gni +++ b/chrome/common/extensions/typemaps.gni
@@ -2,4 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -typemaps = [ "//chrome/common/extensions/media_parser.typemap" ] +typemaps = [ + "//chrome/common/extensions/media_parser.typemap", + "//chrome/common/extensions/mojom/inline_install.typemap", +]
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index d21a5c8..ea8be8c 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -52,7 +52,6 @@ const char kChromeUIExtensionIconURL[] = "chrome://extension-icon/"; const char kChromeUIExtensionsFrameURL[] = "chrome://extensions-frame/"; const char kChromeUIExtensionsURL[] = "chrome://extensions/"; -const char kChromeUIFallbackIconURL[] = "chrome://fallback-icon/"; const char kChromeUIFaviconURL[] = "chrome://favicon/"; const char kChromeUIFeedbackURL[] = "chrome://feedback/"; const char kChromeUIFlagsURL[] = "chrome://flags/"; @@ -199,7 +198,6 @@ const char kChromeUIExtensionIconHost[] = "extension-icon"; const char kChromeUIExtensionsFrameHost[] = "extensions-frame"; const char kChromeUIExtensionsHost[] = "extensions"; -const char kChromeUIFallbackIconHost[] = "fallback-icon"; const char kChromeUIFaviconHost[] = "favicon"; const char kChromeUIFeedbackHost[] = "feedback"; const char kChromeUIFlagsHost[] = "flags";
diff --git a/chrome/renderer/extensions/webstore_bindings.cc b/chrome/renderer/extensions/webstore_bindings.cc index 2a3c2aa..290814e 100644 --- a/chrome/renderer/extensions/webstore_bindings.cc +++ b/chrome/renderer/extensions/webstore_bindings.cc
@@ -9,8 +9,8 @@ #include "base/macros.h" #include "base/strings/string_util.h" #include "chrome/common/extensions/api/webstore/webstore_api_constants.h" -#include "chrome/common/extensions/chrome_extension_messages.h" #include "components/crx_file/id_util.h" +#include "content/public/common/associated_interface_provider.h" #include "content/public/renderer/render_frame.h" #include "extensions/common/extension.h" #include "extensions/common/extension_urls.h" @@ -45,7 +45,7 @@ // chrome.webstore.install() calls generate an install ID so that the install's // callbacks may be fired when the browser notifies us of install completion -// (successful or not) via OnInlineWebstoreInstallResponse. +// (successful or not) via |InlineInstallResponse|. int g_next_install_id = 0; } // anonymous namespace @@ -54,6 +54,59 @@ : ObjectBackedNativeHandler(context) { RouteFunction("Install", "webstore", base::Bind(&WebstoreBindings::Install, base::Unretained(this))); + content::RenderFrame* render_frame = context->GetRenderFrame(); + if (render_frame) + render_frame->GetRemoteAssociatedInterfaces()->GetInterface( + &inline_installer_); +} + +WebstoreBindings::~WebstoreBindings() {} + +void WebstoreBindings::InlineInstallResponse(int install_id, + bool success, + const std::string& error, + webstore_install::Result result) { + v8::Isolate* isolate = context()->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Context::Scope context_scope(context()->v8_context()); + v8::Local<v8::Value> argv[] = { + v8::Integer::New(isolate, install_id), v8::Boolean::New(isolate, success), + v8::String::NewFromUtf8(isolate, error.c_str()), + v8::String::NewFromUtf8( + isolate, + api::webstore::kInstallResultCodes[static_cast<int>(result)])}; + context()->module_system()->CallModuleMethodSafe( + "webstore", "onInstallResponse", arraysize(argv), argv); +} + +void WebstoreBindings::InlineInstallStageChanged( + api::webstore::InstallStage stage) { + const char* stage_string = nullptr; + switch (stage) { + case api::webstore::INSTALL_STAGE_DOWNLOADING: + stage_string = api::webstore::kInstallStageDownloading; + break; + case api::webstore::INSTALL_STAGE_INSTALLING: + stage_string = api::webstore::kInstallStageInstalling; + break; + } + v8::Isolate* isolate = context()->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Context::Scope context_scope(context()->v8_context()); + v8::Local<v8::Value> argv[] = { + v8::String::NewFromUtf8(isolate, stage_string)}; + context()->module_system()->CallModuleMethodSafe( + "webstore", "onInstallStageChanged", arraysize(argv), argv); +} + +void WebstoreBindings::InlineInstallDownloadProgress(int percent_downloaded) { + v8::Isolate* isolate = context()->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Context::Scope context_scope(context()->v8_context()); + v8::Local<v8::Value> argv[] = { + v8::Number::New(isolate, percent_downloaded / 100.0)}; + context()->module_system()->CallModuleMethodSafe( + "webstore", "onDownloadProgress", arraysize(argv), argv); } void WebstoreBindings::Install( @@ -91,10 +144,13 @@ int install_id = g_next_install_id++; - Send(new ExtensionHostMsg_InlineWebstoreInstall( - render_frame->GetRoutingID(), install_id, GetRoutingID(), - webstore_item_id, listener_mask)); + mojom::InlineInstallProgressListenerPtr install_progress_listener = + install_progress_listener_bindings_.CreateInterfacePtrAndBind(this); + inline_installer_->DoInlineInstall( + webstore_item_id, listener_mask, std::move(install_progress_listener), + base::Bind(&WebstoreBindings::InlineInstallResponse, + base::Unretained(this), install_id)); args.GetReturnValue().Set(static_cast<int32_t>(install_id)); } @@ -186,67 +242,4 @@ return false; } -bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(WebstoreBindings, message) - IPC_MESSAGE_HANDLER(ExtensionMsg_InlineWebstoreInstallResponse, - OnInlineWebstoreInstallResponse) - IPC_MESSAGE_HANDLER(ExtensionMsg_InlineInstallStageChanged, - OnInlineInstallStageChanged) - IPC_MESSAGE_HANDLER(ExtensionMsg_InlineInstallDownloadProgress, - OnInlineInstallDownloadProgress) - IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") - IPC_END_MESSAGE_MAP() - return true; -} - -void WebstoreBindings::OnInlineWebstoreInstallResponse( - int install_id, - bool success, - const std::string& error, - webstore_install::Result result) { - v8::Isolate* isolate = context()->isolate(); - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(context()->v8_context()); - v8::Local<v8::Value> argv[] = { - v8::Integer::New(isolate, install_id), - v8::Boolean::New(isolate, success), - v8::String::NewFromUtf8(isolate, error.c_str()), - v8::String::NewFromUtf8( - isolate, api::webstore::kInstallResultCodes[static_cast<int>(result)]) - }; - context()->module_system()->CallModuleMethodSafe( - "webstore", "onInstallResponse", arraysize(argv), argv); -} - -void WebstoreBindings::OnInlineInstallStageChanged(int stage) { - const char* stage_string = NULL; - api::webstore::InstallStage install_stage = - static_cast<api::webstore::InstallStage>(stage); - switch (install_stage) { - case api::webstore::INSTALL_STAGE_DOWNLOADING: - stage_string = api::webstore::kInstallStageDownloading; - break; - case api::webstore::INSTALL_STAGE_INSTALLING: - stage_string = api::webstore::kInstallStageInstalling; - break; - } - v8::Isolate* isolate = context()->isolate(); - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(context()->v8_context()); - v8::Local<v8::Value> argv[] = { - v8::String::NewFromUtf8(isolate, stage_string)}; - context()->module_system()->CallModuleMethodSafe( - "webstore", "onInstallStageChanged", arraysize(argv), argv); -} - -void WebstoreBindings::OnInlineInstallDownloadProgress(int percent_downloaded) { - v8::Isolate* isolate = context()->isolate(); - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(context()->v8_context()); - v8::Local<v8::Value> argv[] = { - v8::Number::New(isolate, percent_downloaded / 100.0)}; - context()->module_system()->CallModuleMethodSafe( - "webstore", "onDownloadProgress", arraysize(argv), argv); -} - } // namespace extensions
diff --git a/chrome/renderer/extensions/webstore_bindings.h b/chrome/renderer/extensions/webstore_bindings.h index 641fddd..09c5dacb 100644 --- a/chrome/renderer/extensions/webstore_bindings.h +++ b/chrome/renderer/extensions/webstore_bindings.h
@@ -7,39 +7,39 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "chrome/common/extensions/mojom/inline_install.mojom.h" #include "chrome/common/extensions/webstore_install_result.h" -#include "chrome/renderer/extensions/chrome_v8_extension_handler.h" #include "extensions/renderer/object_backed_native_handler.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "v8/include/v8.h" namespace blink { class WebLocalFrame; } namespace extensions { +class ScriptContext; // A V8 extension that creates an object at window.chrome.webstore. This object // allows JavaScript to initiate inline installs of apps that are listed in the // Chrome Web Store (CWS). class WebstoreBindings : public ObjectBackedNativeHandler, - public ChromeV8ExtensionHandler { + public mojom::InlineInstallProgressListener { public: explicit WebstoreBindings(ScriptContext* context); + ~WebstoreBindings() override; - // IPC::Listener - bool OnMessageReceived(const IPC::Message& message) override; + // mojom::InlineInstallProgressListener: + void InlineInstallStageChanged(api::webstore::InstallStage stage) override; + void InlineInstallDownloadProgress(int percent_downloaded) override; private: + void InlineInstallResponse(int install_id, + bool success, + const std::string& error, + webstore_install::Result result); void Install(const v8::FunctionCallbackInfo<v8::Value>& args); - void OnInlineWebstoreInstallResponse(int install_id, - bool success, - const std::string& error, - webstore_install::Result result); - - void OnInlineInstallStageChanged(int stage); - - void OnInlineInstallDownloadProgress(int percent_downloaded); - // Extracts a Web Store item ID from a <link rel="chrome-webstore-item" // href="https://chrome.google.com/webstore/detail/id"> node found in the // frame. On success, true will be returned and the |webstore_item_id| @@ -51,6 +51,11 @@ std::string* webstore_item_id, std::string* error); + mojom::InlineInstallerAssociatedPtr inline_installer_; + + mojo::BindingSet<mojom::InlineInstallProgressListener> + install_progress_listener_bindings_; + DISALLOW_COPY_AND_ASSIGN(WebstoreBindings); };
diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc index 035d81a..b07e104 100644 --- a/chrome/renderer/searchbox/searchbox.cc +++ b/chrome/renderer/searchbox/searchbox.cc
@@ -20,10 +20,8 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "chrome/renderer/searchbox/searchbox_extension.h" -#include "components/favicon_base/fallback_icon_url_parser.h" #include "components/favicon_base/favicon_types.h" #include "components/favicon_base/favicon_url_parser.h" -#include "components/favicon_base/large_icon_url_parser.h" #include "components/omnibox/common/omnibox_focus_state.h" #include "content/public/common/associated_interface_provider.h" #include "content/public/common/associated_interface_registry.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7f2ceae..1c6e150 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3058,7 +3058,6 @@ "../browser/engagement/site_engagement_score_unittest.cc", "../browser/engagement/site_engagement_service_unittest.cc", "../browser/external_protocol/external_protocol_handler_unittest.cc", - "../browser/favicon/chrome_fallback_icon_client_unittest.cc", "../browser/file_select_helper_unittest.cc", "../browser/gcm/fake_gcm_profile_service.cc", "../browser/gcm/fake_gcm_profile_service.h", @@ -4745,7 +4744,6 @@ "../browser/ui/views/global_error_bubble_view_unittest.cc", "../browser/ui/views/harmony/layout_provider_unittest.cc", "../browser/ui/views/page_info/page_info_bubble_view_unittest.cc", - "../browser/ui/views/payments/credit_card_editor_view_controller_unittest.cc", "../browser/ui/views/payments/payment_request_item_list_unittest.cc", "../browser/ui/views/payments/validating_textfield_unittest.cc", "../browser/ui/views/payments/view_stack_unittest.cc",
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index b9962788..bbff5e9c 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -27,8 +27,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/favicon/chrome_fallback_icon_client_factory.h" -#include "chrome/browser/favicon/fallback_icon_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/history/chrome_history_client.h" #include "chrome/browser/history/history_service_factory.h" @@ -57,7 +55,6 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/common/bookmark_constants.h" #include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/favicon/core/fallback_icon_service.h" #include "components/favicon/core/favicon_service.h" #include "components/history/content/browser/content_visit_delegate.h" #include "components/history/content/browser/history_database_helper.h"
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index dbfc6b7f..3214d5bb 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc
@@ -40,7 +40,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/find_in_page_observer.h" -#include "components/app_modal/app_modal_dialog.h" #include "components/app_modal/app_modal_dialog_queue.h" #include "components/app_modal/javascript_app_modal_dialog.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -109,7 +108,7 @@ AppModalDialogWaiter() : dialog_(nullptr) {} ~AppModalDialogWaiter() override {} - app_modal::AppModalDialog* Wait() { + app_modal::JavaScriptAppModalDialog* Wait() { if (dialog_) return dialog_; message_loop_runner_ = new content::MessageLoopRunner; @@ -119,7 +118,7 @@ } // AppModalDialogObserver: - void Notify(app_modal::AppModalDialog* dialog) override { + void Notify(app_modal::JavaScriptAppModalDialog* dialog) override { DCHECK(!dialog_); dialog_ = dialog; CheckForHangMonitorDisabling(dialog); @@ -127,17 +126,14 @@ message_loop_runner_->Quit(); } - static void CheckForHangMonitorDisabling(app_modal::AppModalDialog* dialog) { + static void CheckForHangMonitorDisabling( + app_modal::JavaScriptAppModalDialog* dialog) { // If a test waits for a beforeunload dialog but hasn't disabled the // beforeunload hang timer before triggering it, there will be a race // between the dialog and the timer and the test will be flaky. We can't // disable the timer here, as it's too late, but we can tell when we've won // a race that we shouldn't have been in. - if (!dialog->IsJavaScriptModalDialog()) - return; - - auto* js_dialog = static_cast<app_modal::JavaScriptAppModalDialog*>(dialog); - if (!js_dialog->is_before_unload_dialog()) + if (!dialog->is_before_unload_dialog()) return; // Unfortunately we don't know which frame spawned this dialog and should @@ -155,7 +151,7 @@ } private: - app_modal::AppModalDialog* dialog_; + app_modal::JavaScriptAppModalDialog* dialog_; scoped_refptr<content::MessageLoopRunner> message_loop_runner_; DISALLOW_COPY_AND_ASSIGN(AppModalDialogWaiter); @@ -336,7 +332,7 @@ return true; } -app_modal::AppModalDialog* WaitForAppModalDialog() { +app_modal::JavaScriptAppModalDialog* WaitForAppModalDialog() { app_modal::AppModalDialogQueue* dialog_queue = app_modal::AppModalDialogQueue::GetInstance(); if (dialog_queue->HasActiveDialog()) {
diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h index 24bd2d97..fac5d03 100644 --- a/chrome/test/base/ui_test_utils.h +++ b/chrome/test/base/ui_test_utils.h
@@ -33,7 +33,7 @@ class Profile; namespace app_modal { -class AppModalDialog; +class JavaScriptAppModalDialog; } namespace base { @@ -130,8 +130,8 @@ // Generate the path of the build directory, relative to the source root. bool GetRelativeBuildDirectory(base::FilePath* build_dir); -// Blocks until an application modal dialog is showns and returns it. -app_modal::AppModalDialog* WaitForAppModalDialog(); +// Blocks until an application modal dialog is shown and returns it. +app_modal::JavaScriptAppModalDialog* WaitForAppModalDialog(); // Performs a find in the page of the specified tab. Returns the number of // matches found. |ordinal| is an optional parameter which is set to the index
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.cc b/chrome/test/chromedriver/chrome/stub_web_view.cc index 6df576da4..f833e8af 100644 --- a/chrome/test/chromedriver/chrome/stub_web_view.cc +++ b/chrome/test/chromedriver/chrome/stub_web_view.cc
@@ -119,6 +119,17 @@ return Status(kOk); } +Status StubWebView::AddCookie(const std::string& name, + const std::string& url, + const std::string& value, + const std::string& domain, + const std::string& path, + bool secure, + bool httpOnly, + double expiry) { + return Status(kOk); +} + Status StubWebView::WaitForPendingNavigations(const std::string& frame_id, const Timeout& timeout, bool stop_load_on_timeout) {
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.h b/chrome/test/chromedriver/chrome/stub_web_view.h index 34d596d..5e3db39 100644 --- a/chrome/test/chromedriver/chrome/stub_web_view.h +++ b/chrome/test/chromedriver/chrome/stub_web_view.h
@@ -59,6 +59,14 @@ Status DispatchKeyEvents(const std::list<KeyEvent>& events) override; Status GetCookies(std::unique_ptr<base::ListValue>* cookies) override; Status DeleteCookie(const std::string& name, const std::string& url) override; + Status AddCookie(const std::string& name, + const std::string& url, + const std::string& value, + const std::string& domain, + const std::string& path, + bool secure, + bool httpOnly, + double expiry) override; Status WaitForPendingNavigations(const std::string& frame_id, const Timeout& timeout, bool stop_load_on_timeout) override;
diff --git a/chrome/test/chromedriver/chrome/web_view.h b/chrome/test/chromedriver/chrome/web_view.h index 6bd3b7bb..b80ccb5 100644 --- a/chrome/test/chromedriver/chrome/web_view.h +++ b/chrome/test/chromedriver/chrome/web_view.h
@@ -138,6 +138,15 @@ virtual Status DeleteCookie(const std::string& name, const std::string& url) = 0; + virtual Status AddCookie(const std::string& name, + const std::string& url, + const std::string& value, + const std::string& domain, + const std::string& path, + bool secure, + bool httpOnly, + double expiry) = 0; + // Waits until all pending navigations have completed in the given frame. // If |frame_id| is "", waits for navigations on the main frame. // If a modal dialog appears while waiting, kUnexpectedAlertOpen will be
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index ef4aee9..5ea721f 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -459,6 +459,26 @@ return client_->SendCommand("Page.deleteCookie", params); } +Status WebViewImpl::AddCookie(const std::string& name, + const std::string& url, + const std::string& value, + const std::string& domain, + const std::string& path, + bool secure, + bool httpOnly, + double expiry) { + base::DictionaryValue params; + params.SetString("name", name); + params.SetString("url", url); + params.SetString("value", value); + params.SetString("domain", domain); + params.SetString("path", path); + params.SetBoolean("secure", secure); + params.SetBoolean("httpOnly", httpOnly); + params.SetDouble("expirationDate", expiry); + return client_->SendCommand("Network.setCookie", params); +} + Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id, const Timeout& timeout, bool stop_load_on_timeout) {
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.h b/chrome/test/chromedriver/chrome/web_view_impl.h index 7e80da1..21169aad 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.h +++ b/chrome/test/chromedriver/chrome/web_view_impl.h
@@ -86,6 +86,14 @@ Status DispatchKeyEvents(const std::list<KeyEvent>& events) override; Status GetCookies(std::unique_ptr<base::ListValue>* cookies) override; Status DeleteCookie(const std::string& name, const std::string& url) override; + Status AddCookie(const std::string& name, + const std::string& url, + const std::string& value, + const std::string& domain, + const std::string& path, + bool secure, + bool httpOnly, + double expiry) override; Status WaitForPendingNavigations(const std::string& frame_id, const Timeout& timeout, bool stop_load_on_timeout) override;
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index e54307f..e58d70f 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -38,6 +38,9 @@ const std::string kUnreachableWebDataURL = "data:text/html,chromewebdata"; +// Defaults to 20 years into the future when adding a cookie. +const double kDefaultCookieExpiryTime = 20*365*24*60*60; + Status GetMouseButton(const base::DictionaryValue& params, MouseButton* button) { int button_num; @@ -948,11 +951,30 @@ const base::DictionaryValue* cookie; if (!params.GetDictionary("cookie", &cookie)) return Status(kUnknownError, "missing 'cookie'"); - base::ListValue args; - args.Append(cookie->CreateDeepCopy()); - std::unique_ptr<base::Value> result; - return web_view->CallFunction( - session->GetCurrentFrameId(), kAddCookieScript, args, &result); + std::string name; + std::string cookie_value; + if (!cookie->GetString("name", &name)) + return Status(kUnknownError, "missing 'name'"); + if (!cookie->GetString("value", &cookie_value)) + return Status(kUnknownError, "missing 'value'"); + std::string url; + Status status = GetUrl(web_view, session->GetCurrentFrameId(), &url); + if (status.IsError()) + return status; + std::string domain; + cookie->GetString("domain", &domain); + std::string path; + cookie->GetString("path", &path); + bool secure = false; + cookie->GetBoolean("secure", &secure); + bool httpOnly = false; + cookie->GetBoolean("httpOnly", &httpOnly); + double expiry; + if (!cookie->GetDouble("expiry", &expiry)) + expiry = (base::Time::Now() - base::Time::UnixEpoch()).InSeconds() + + kDefaultCookieExpiryTime; + return web_view->AddCookie(name, url, cookie_value, domain, path, + secure, httpOnly, expiry); } Status ExecuteDeleteCookie(Session* session,
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 17ab3fde..43e9261 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -151,6 +151,7 @@ sources += [ "print_preview/print_preview.js", "print_preview/print_preview_destination_search_test.js", + "print_preview/print_preview_ui_browsertest.js", ] } deps = [
diff --git a/chrome/test/data/webui/md_user_manager/user_manager_browsertest.js b/chrome/test/data/webui/md_user_manager/user_manager_browsertest.js index 2ffff2c..e204d7c 100644 --- a/chrome/test/data/webui/md_user_manager/user_manager_browsertest.js +++ b/chrome/test/data/webui/md_user_manager/user_manager_browsertest.js
@@ -37,7 +37,12 @@ runAccessibilityChecks: false, }; -TEST_F('UserManagerBrowserTest', 'UserManagerTest', function() { +GEN('#if defined(OS_WIN)'); +GEN('#define MAYBE_UserManagerTest DISABLED_UserManagerTest'); +GEN('#else'); +GEN('#define MAYBE_UserManagerTest UserManagerTest'); +GEN('#endif'); +TEST_F('UserManagerBrowserTest', 'MAYBE_UserManagerTest', function() { user_manager.control_bar_tests.registerTests(); user_manager.create_profile_tests.registerTests(); user_manager.import_supervised_user_tests.registerTests();
diff --git a/chrome/test/data/webui/print_preview/print_preview.js b/chrome/test/data/webui/print_preview/print_preview.js index 55a52053..3986fba 100644 --- a/chrome/test/data/webui/print_preview/print_preview.js +++ b/chrome/test/data/webui/print_preview/print_preview.js
@@ -18,27 +18,6 @@ this.previewArea_ = null; } -/** - * Index of the "Save as PDF" printer. - * @type {number} - * @const - */ -PrintPreviewWebUITest.PDF_INDEX = 0; - -/** - * Index of the Foo printer. - * @type {number} - * @const - */ -PrintPreviewWebUITest.FOO_INDEX = 1; - -/** - * Index of the Bar printer. - * @type {number} - * @const - */ -PrintPreviewWebUITest.BAR_INDEX = 2; - PrintPreviewWebUITest.prototype = { __proto__: testing.Test.prototype, @@ -248,96 +227,6 @@ }, }; -// Test some basic assumptions about the print preview WebUI. -TEST_F('PrintPreviewWebUITest', 'TestPrinterList', function() { - this.setInitialSettings(); - this.nativeLayer_.whenCalled('getInitialSettings').then( - function() { - this.setLocalDestinations(); - var recentList = - $('destination-search').querySelector('.recent-list ul'); - var localList = - $('destination-search').querySelector('.local-list ul'); - assertNotEquals(null, recentList); - assertEquals(1, recentList.childNodes.length); - assertEquals('FooName', - recentList.childNodes.item(0).querySelector( - '.destination-list-item-name').textContent); - assertNotEquals(null, localList); - assertEquals(3, localList.childNodes.length); - assertEquals('Save as PDF', - localList.childNodes.item(PrintPreviewWebUITest.PDF_INDEX). - querySelector('.destination-list-item-name').textContent); - assertEquals('FooName', - localList.childNodes.item(PrintPreviewWebUITest.FOO_INDEX). - querySelector('.destination-list-item-name').textContent); - assertEquals('BarName', - localList.childNodes.item(PrintPreviewWebUITest.BAR_INDEX). - querySelector('.destination-list-item-name').textContent); - testDone(); - }.bind(this)); -}); - -// Test that the printer list is structured correctly after calling -// addCloudPrinters with an empty list. -TEST_F('PrintPreviewWebUITest', 'TestPrinterListCloudEmpty', function() { - this.setInitialSettings(); - - this.nativeLayer_.whenCalled('getInitialSettings').then( - function() { - this.setLocalDestinations(); - - var cloudPrintEnableEvent = - new Event(print_preview.NativeLayer.EventType.CLOUD_PRINT_ENABLE); - cloudPrintEnableEvent.baseCloudPrintUrl = 'cloudprint url'; - this.nativeLayer_.getEventTarget().dispatchEvent( - cloudPrintEnableEvent); - - var searchDoneEvent = - new Event(cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE); - searchDoneEvent.printers = []; - searchDoneEvent.isRecent = true; - searchDoneEvent.email = 'foo@chromium.org'; - this.printPreview_.cloudPrintInterface_.dispatchEvent(searchDoneEvent); - - var recentList = - $('destination-search').querySelector('.recent-list ul'); - var localList = - $('destination-search').querySelector('.local-list ul'); - var cloudList = - $('destination-search').querySelector('.cloud-list ul'); - - assertNotEquals(null, recentList); - assertEquals(1, recentList.childNodes.length); - assertEquals('FooName', - recentList.childNodes.item(0). - querySelector('.destination-list-item-name'). - textContent); - - assertNotEquals(null, localList); - assertEquals(3, localList.childNodes.length); - assertEquals('Save as PDF', - localList.childNodes.item( - PrintPreviewWebUITest.PDF_INDEX). - querySelector('.destination-list-item-name'). - textContent); - assertEquals('FooName', - localList.childNodes. - item(PrintPreviewWebUITest.FOO_INDEX). - querySelector('.destination-list-item-name'). - textContent); - assertEquals('BarName', - localList.childNodes. - item(PrintPreviewWebUITest.BAR_INDEX). - querySelector('.destination-list-item-name'). - textContent); - - assertNotEquals(null, cloudList); - assertEquals(0, cloudList.childNodes.length); - - testDone(); - }.bind(this)); -}); /** * Verify that |section| visibility matches |visible|. @@ -406,115 +295,6 @@ loadTimeData.getBoolean('printPdfAsImageEnabled')); } -// Test restore settings with one destination. -TEST_F('PrintPreviewWebUITest', 'TestPrintPreviewRestoreLocalDestination', - function() { - this.initialSettings_.serializedAppStateStr_ = - '{"version":2,"recentDestinations":[{"id":"ID", "origin":"local",' + - '"account":"", "capabilities":0, "name":"", "extensionId":"",' + - '"extensionName":""}]}'; - - this.setInitialSettings(); - this.nativeLayer_.whenCalled('getInitialSettings').then( - function() { - testDone(); - }); -}); - -// Test with multiple destinations -TEST_F('PrintPreviewWebUITest', 'TestPrintPreviewRestoreMultipleDestinations', - function() { - var origin = cr.isChromeOS ? "chrome_os" : "local"; - - var appState = { - 'version': 2, - 'recentDestinations': [ - { - 'id': 'ID1', - 'origin': origin, - 'account': '', - 'capabilities': 0, - 'name': '', - 'extensionId': '', - 'extensionName': '' - }, - { - 'id': 'ID2', - 'origin': origin, - 'account': '', - 'capabilities': 0, - 'name': '', - 'extensionId': '', - 'extensionName': '' - }, - { - 'id': 'ID3', - 'origin': origin, - 'account': '', - 'capabilities': 0, - 'name': '', - 'extensionId': '', - 'extensionName': '' - } - ] - }; - - this.initialSettings_.serializedAppStateStr_ = JSON.stringify(appState); - this.setInitialSettings(); - - this.nativeLayer_.whenCalled('getInitialSettings').then( - function() { - // Set capabilities for the three recently used destinations + 1 more - this.setCapabilities(getCddTemplate('ID1')); - this.setCapabilities(getCddTemplate('ID2')); - this.setCapabilities(getCddTemplate('ID3')); - this.setCapabilities(getCddTemplate('ID4')); - - // The most recently used destination should be the currently selected - // one. This is ID1. - assertEquals( - 'ID1', this.printPreview_.destinationStore_.selectedDestination.id); - - // Look through the destinations. ID1, ID2, and ID3 should all be - // recent. - var destinations = this.printPreview_.destinationStore_.destinations_; - var idsFound = []; - - for (var i = 0; i < destinations.length; i++) { - if (!destinations[i]) - continue; - if (destinations[i].isRecent) - idsFound.push(destinations[i].id); - } - - // Make sure there were 3 recent destinations and that they are the - // correct IDs. - assertEquals(3, idsFound.length); - assertNotEquals(-1, idsFound.indexOf("ID1")); - assertNotEquals(-1, idsFound.indexOf("ID2")); - assertNotEquals(-1, idsFound.indexOf("ID3")); - - testDone(); - }.bind(this)); -}); - -TEST_F('PrintPreviewWebUITest', - 'TestPrintPreviewDefaultDestinationSelectionRules', function() { - // It also makes sure these rules do override system default destination. - this.initialSettings_.serializedDefaultDestinationSelectionRulesStr_ = - '{"namePattern":".*Bar.*"}'; - this.setInitialSettings(); - this.nativeLayer_.whenCalled('getInitialSettings').then( - function() { - this.setLocalDestinations(); - - assertEquals( - 'BarDevice', - this.printPreview_.destinationStore_.selectedDestination.id); - - testDone(); - }.bind(this)); -}); TEST_F('PrintPreviewWebUITest', 'TestSystemDialogLinkIsHiddenInAppKioskMode', function() {
diff --git a/chrome/test/data/webui/print_preview/print_preview_tests.js b/chrome/test/data/webui/print_preview/print_preview_tests.js new file mode 100644 index 0000000..19acd3c --- /dev/null +++ b/chrome/test/data/webui/print_preview/print_preview_tests.js
@@ -0,0 +1,366 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('print_preview_test', function() { + /** + * Index of the "Save as PDF" printer. + * @type {number} + * @const + */ + var PDF_INDEX = 0; + + /** + * Index of the Foo printer. + * @type {number} + * @const + */ + var FOO_INDEX = 1; + + /** + * Index of the Bar printer. + * @type {number} + * @const + */ + var BAR_INDEX = 2; + + var printPreview = null; + var nativeLayer = null; + var initialSettings = null; + var localDestinationInfos = null; + var previewArea = null; + + /** + * Initialize print preview with the initial settings currently stored in + * |initialSettings|. Creates |printPreview| if it does not + * already exist. + */ + function setInitialSettings() { + nativeLayer.setInitialSettings(initialSettings); + printPreview.initialize(); + } + + /** + * Dispatch the LOCAL_DESTINATIONS_SET event. This call is NOT async and will + * happen in the same thread. + */ + function setLocalDestinations() { + var localDestsSetEvent = + new Event(print_preview.NativeLayer.EventType.LOCAL_DESTINATIONS_SET); + localDestsSetEvent.destinationInfos = localDestinationInfos; + nativeLayer.getEventTarget().dispatchEvent(localDestsSetEvent); + } + + /** + * Dispatch the CAPABILITIES_SET event. This call is NOT async and will + * happen in the same thread. + * @param {!Object} device The device whose capabilities should be dispatched. + */ + function setCapabilities(device) { + var capsSetEvent = + new Event(print_preview.NativeLayer.EventType.CAPABILITIES_SET); + capsSetEvent.settingsInfo = device; + nativeLayer.getEventTarget().dispatchEvent(capsSetEvent); + } + + /** + * Verify that |section| visibility matches |visible|. + * @param {HTMLDivElement} section The section to check. + * @param {boolean} visible The expected state of visibility. + */ + function checkSectionVisible(section, visible) { + assertNotEquals(null, section); + expectEquals( + visible, + section.classList.contains('visible'), 'section=' + section.id); + } + + /** + * @param {string} printerId + * @return {!Object} + */ + function getCddTemplate(printerId) { + return { + printerId: printerId, + capabilities: { + version: '1.0', + printer: { + supported_content_type: [{content_type: 'application/pdf'}], + collate: {}, + color: { + option: [ + {type: 'STANDARD_COLOR', is_default: true}, + {type: 'STANDARD_MONOCHROME'} + ] + }, + copies: {}, + duplex: { + option: [ + {type: 'NO_DUPLEX', is_default: true}, + {type: 'LONG_EDGE'}, + {type: 'SHORT_EDGE'} + ] + }, + page_orientation: { + option: [ + {type: 'PORTRAIT', is_default: true}, + {type: 'LANDSCAPE'}, + {type: 'AUTO'} + ] + }, + media_size: { + option: [ + { name: 'NA_LETTER', + width_microns: 215900, + height_microns: 279400, + is_default: true + } + ] + } + } + } + }; + } + + suite('PrintPreview', function() { + suiteSetup(function() { + function CloudPrintInterfaceStub() { + cr.EventTarget.call(this); + } + CloudPrintInterfaceStub.prototype = { + __proto__: cr.EventTarget.prototype, + search: function(isRecent) {} + }; + var oldCpInterfaceEventType = cloudprint.CloudPrintInterfaceEventType; + cloudprint.CloudPrintInterface = CloudPrintInterfaceStub; + cloudprint.CloudPrintInterfaceEventType = oldCpInterfaceEventType; + + print_preview.PreviewArea.prototype.checkPluginCompatibility_ = + function() { + return false; + }; + }); + + setup(function() { + initialSettings = new print_preview.NativeInitialSettings( + false /*isInKioskAutoPrintMode*/, + false /*isInAppKioskMode*/, + ',' /*thousandsDelimeter*/, + '.' /*decimalDelimeter*/, + 1 /*unitType*/, + true /*isDocumentModifiable*/, + 'title' /*documentTitle*/, + true /*documentHasSelection*/, + false /*selectionOnly*/, + 'FooDevice' /*systemDefaultDestinationId*/, + null /*serializedAppStateStr*/, + null /*serializedDefaultDestinationSelectionRulesStr*/); + + localDestinationInfos = [ + { printerName: 'FooName', deviceName: 'FooDevice' }, + { printerName: 'BarName', deviceName: 'BarDevice' }, + ]; + + nativeLayer = new print_preview.NativeLayerStub(); + print_preview.NativeLayer.setInstance(nativeLayer); + printPreview = new print_preview.PrintPreview(); + previewArea = printPreview.getPreviewArea(); + }); + + // Test some basic assumptions about the print preview WebUI. + test('PrinterList', function() { + setInitialSettings(); + return nativeLayer.whenCalled('getInitialSettings').then( + function() { + setLocalDestinations(); + var recentList = + $('destination-search').querySelector('.recent-list ul'); + var localList = + $('destination-search').querySelector('.local-list ul'); + assertNotEquals(null, recentList); + assertEquals(1, recentList.childNodes.length); + assertEquals('FooName', + recentList.childNodes.item(0).querySelector( + '.destination-list-item-name').textContent); + assertNotEquals(null, localList); + assertEquals(3, localList.childNodes.length); + assertEquals( + 'Save as PDF', + localList.childNodes.item(PDF_INDEX). + querySelector('.destination-list-item-name').textContent); + assertEquals( + 'FooName', + localList.childNodes.item(FOO_INDEX). + querySelector('.destination-list-item-name').textContent); + assertEquals( + 'BarName', + localList.childNodes.item(BAR_INDEX). + querySelector('.destination-list-item-name').textContent); + }); + }); + + // Test that the printer list is structured correctly after calling + // addCloudPrinters with an empty list. + test('PrinterListCloudEmpty', function() { + setInitialSettings(); + + return nativeLayer.whenCalled('getInitialSettings').then( + function() { + setLocalDestinations(); + + var cloudPrintEnableEvent = new Event( + print_preview.NativeLayer.EventType.CLOUD_PRINT_ENABLE); + cloudPrintEnableEvent.baseCloudPrintUrl = 'cloudprint url'; + nativeLayer.getEventTarget().dispatchEvent( + cloudPrintEnableEvent); + + var searchDoneEvent = + new Event(cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE); + searchDoneEvent.printers = []; + searchDoneEvent.isRecent = true; + searchDoneEvent.email = 'foo@chromium.org'; + printPreview.cloudPrintInterface_.dispatchEvent(searchDoneEvent); + + var recentList = + $('destination-search').querySelector('.recent-list ul'); + var localList = + $('destination-search').querySelector('.local-list ul'); + var cloudList = + $('destination-search').querySelector('.cloud-list ul'); + + assertNotEquals(null, recentList); + assertEquals(1, recentList.childNodes.length); + assertEquals('FooName', + recentList.childNodes.item(0). + querySelector('.destination-list-item-name'). + textContent); + + assertNotEquals(null, localList); + assertEquals(3, localList.childNodes.length); + assertEquals('Save as PDF', + localList.childNodes.item(PDF_INDEX). + querySelector('.destination-list-item-name'). + textContent); + assertEquals('FooName', + localList.childNodes. + item(FOO_INDEX). + querySelector('.destination-list-item-name'). + textContent); + assertEquals('BarName', + localList.childNodes. + item(BAR_INDEX). + querySelector('.destination-list-item-name'). + textContent); + + assertNotEquals(null, cloudList); + assertEquals(0, cloudList.childNodes.length); + }); + }); + + // Test restore settings with one destination. + test('RestoreLocalDestination', function() { + initialSettings.serializedAppStateStr_ = JSON.stringify({ + version: 2, + recentDestinations: [ + { + id: 'ID', + origin: cr.isChromeOS ? 'chrome_os' : 'local', + account: '', + capabilities: 0, + name: '', + extensionId: '', + extensionName: '', + }, + ], + }); + + setInitialSettings(); + return nativeLayer.whenCalled('getInitialSettings'); + }); + + test('RestoreMultipleDestinations', function() { + var origin = cr.isChromeOS ? 'chrome_os' : 'local'; + + initialSettings.serializedAppStateStr_ = JSON.stringify({ + version: 2, + recentDestinations: [ + { + id: 'ID1', + origin: origin, + account: '', + capabilities: 0, + name: '', + extensionId: '', + extensionName: '', + }, { + id: 'ID2', + origin: origin, + account: '', + capabilities: 0, + name: '', + extensionId: '', + extensionName: '', + }, { + id: 'ID3', + origin: origin, + account: '', + capabilities: 0, + name: '', + extensionId: '', + extensionName: '', + }, + ], + }); + + setInitialSettings(); + + return nativeLayer.whenCalled('getInitialSettings').then( + function() { + // Set capabilities for the three recently used destinations + 1 + // more. + setCapabilities(getCddTemplate('ID1')); + setCapabilities(getCddTemplate('ID2')); + setCapabilities(getCddTemplate('ID3')); + setCapabilities(getCddTemplate('ID4')); + + // The most recently used destination should be the currently + // selected one. This is ID1. + assertEquals( + 'ID1', printPreview.destinationStore_.selectedDestination.id); + + // Look through the destinations. ID1, ID2, and ID3 should all be + // recent. + var destinations = printPreview.destinationStore_.destinations_; + var idsFound = []; + + for (var i = 0; i < destinations.length; i++) { + if (!destinations[i]) + continue; + if (destinations[i].isRecent) + idsFound.push(destinations[i].id); + } + + // Make sure there were 3 recent destinations and that they are the + // correct IDs. + assertEquals(3, idsFound.length); + assertNotEquals(-1, idsFound.indexOf('ID1')); + assertNotEquals(-1, idsFound.indexOf('ID2')); + assertNotEquals(-1, idsFound.indexOf('ID3')); + }); + }); + + test('DefaultDestinationSelectionRules', function() { + // It also makes sure these rules do override system default destination. + initialSettings.serializedDefaultDestinationSelectionRulesStr_ = + JSON.stringify({namePattern: '.*Bar.*'}); + setInitialSettings(); + return nativeLayer.whenCalled('getInitialSettings').then( + function() { + setLocalDestinations(); + assertEquals( + 'BarDevice', + printPreview.destinationStore_.selectedDestination.id); + }); + }); + }); +});
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js new file mode 100644 index 0000000..3b678f60 --- /dev/null +++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -0,0 +1,83 @@ +// 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. + +/** @fileoverview Runs the Print Preview tests. */ + +var ROOT_PATH = '../../../../../'; + +/** + * @constructor + * @extends {testing.Test} + */ +function PrintPreviewUIBrowserTest() {} + +PrintPreviewUIBrowserTest.prototype = { + __proto__: testing.Test.prototype, + + /** + * Browse to the sample page, cause print preview & call preLoad(). + * @override + */ + browsePrintPreload: 'print_preview/print_preview_hello_world_test.html', + + /** @override */ + runAccessibilityChecks: true, + + /** @override */ + accessibilityIssuesAreErrors: false, + + /** @override */ + isAsync: true, + + /** @override */ + preLoad: function() { + window.isTest = true; + testing.Test.prototype.preLoad.call(this); + + }, + + /** @override */ + setUp: function() { + testing.Test.prototype.setUp.call(this); + + testing.Test.disableAnimationsAndTransitions(); + // Enable when failure is resolved. + // AX_TEXT_03: http://crbug.com/559209 + this.accessibilityAuditConfig.ignoreSelectors( + 'multipleLabelableElementsPerLabel', + '#page-settings > .right-column > *'); + }, + + extraLibraries: [ + ROOT_PATH + 'ui/webui/resources/js/cr.js', + ROOT_PATH + 'ui/webui/resources/js/promise_resolver.js', + ROOT_PATH + 'third_party/mocha/mocha.js', + ROOT_PATH + 'chrome/test/data/webui/mocha_adapter.js', + ROOT_PATH + 'ui/webui/resources/js/util.js', + ROOT_PATH + 'chrome/test/data/webui/settings/test_browser_proxy.js', + 'print_preview_tests.js', + 'native_layer_stub.js', + ], +}; + +TEST_F('PrintPreviewUIBrowserTest', 'PrinterList', function() { + mocha.grep(/PrinterList\b/).run(); +}); + +TEST_F('PrintPreviewUIBrowserTest', 'PrinterListCloudEmpty', function() { + mocha.grep(/PrinterListCloudEmpty\b/).run(); +}); + +TEST_F('PrintPreviewUIBrowserTest', 'RestoreLocalDestination', function() { + mocha.grep(/RestoreLocalDestination\b/).run(); +}); + +TEST_F('PrintPreviewUIBrowserTest', 'RestoreMultipleDestinations', function() { + mocha.grep(/RestoreMultipleDestinations\b/).run(); +}); + +TEST_F('PrintPreviewUIBrowserTest', 'DefaultDestinationSelectionRules', + function() { + mocha.grep(/DefaultDestinationSelectionRules\b/).run(); + });
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index a4de4ee..2931dbd 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -51,6 +51,7 @@ "error_codes.h", "file_utils.cc", "file_utils.h", + "observer.h", "path_utils.cc", "path_utils.h", "pref_names.cc", @@ -128,6 +129,7 @@ "bind_to_task_runner_unittest.cc", "device_capabilities_impl_unittest.cc", "error_codes_unittest.cc", + "observer_unittest.cc", "path_utils_unittest.cc", "process_utils_unittest.cc", "serializers_unittest.cc",
diff --git a/chromecast/base/chromecast_switches.cc b/chromecast/base/chromecast_switches.cc index 9a94435..ce23b09 100644 --- a/chromecast/base/chromecast_switches.cc +++ b/chromecast/base/chromecast_switches.cc
@@ -91,6 +91,11 @@ // Calibrated max output volume dBa for voice content at 1 meter, if known. const char kMaxOutputVolumeDba1m[] = "max-output-volume-dba1m"; +// Number of audio output channels. This will be used to send audio buffer with +// specific number of channels to ALSA and generate loopback audio. Default +// value is 2. +const char kAudioOutputChannels[] = "audio-output-channels"; + // Some platforms typically have very little 'free' memory, but plenty is // available in buffers+cached. For such platforms, configure this amount // as the portion of buffers+cached memory that should be treated as
diff --git a/chromecast/base/chromecast_switches.h b/chromecast/base/chromecast_switches.h index cee08a1..298452e 100644 --- a/chromecast/base/chromecast_switches.h +++ b/chromecast/base/chromecast_switches.h
@@ -50,6 +50,7 @@ extern const char kAlsaMuteDeviceName[]; extern const char kAlsaMuteElementName[]; extern const char kMaxOutputVolumeDba1m[]; +extern const char kAudioOutputChannels[]; // Memory pressure switches extern const char kMemPressureSystemReservedKb[];
diff --git a/chromecast/base/observer.h b/chromecast/base/observer.h new file mode 100644 index 0000000..a1b6d48 --- /dev/null +++ b/chromecast/base/observer.h
@@ -0,0 +1,429 @@ +// 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. + +// Safe Observer/Observable implementation. +// +// When using ObserverListThreadSafe, we were running into issues since there +// was no synchronization between getting the existing value, and registering +// as an observer. See go/cast-platform-design-synchronized-value for more +// details. +// +// To fix this issue, and to make observing values safer and simpler in general, +// use the Observable/Observer pattern in this file. When you have a value that +// other code wants to observe (ie, get the value of and receive any changes), +// wrap that value in an Observable<T>. The value type T must be copyable and +// copy-assignable. The Observable must be constructed with the initial observed +// value, and the value may be updated at any time from any thread by calling +// SetValue(). You can also get the value using GetValue(); but note that this +// is not threadsafe (the value is returned without locking), so the caller must +// ensure safety by other means. Calling GetValueThreadSafe() is threadsafe but +// involves a mutex lock. +// +// Code that wants to observe the value calls Observe() on it at any point when +// the value is alive. Note that Observe() may be called safely from any thread. +// Observe() returns an Observer<T> instance, which MUST be used and destroyed +// only on the thread that called Observe(). The Observer initially contains the +// value that the Observable had when Observe() was called, and that value will +// be updated asynchronously whenever the Observable's SetValue() method is +// is called. NOTE: the initial value of the Observer is the value known to the +// thread that created the Observer at the time; there may be an updated value +// from the Observable that hasn't been handled by the Observer's thread yet. +// +// The Observer's view of the observed value is returned by GetValue(); this is +// a low-cost call since there is no locking (the value is updated on the thread +// that constructed the Observer). Note that Observers are always updated +// asynchronously with PostTask(), even if they belong to the same thread that +// calls SetValue(). All Observers on the same thread have the same consistent +// view of the observed value. +// +// Observers may be copied freely; the copy also observes the original +// Observable, and belongs to the thread that created the copy. Copying is safe +// even when the original Observable has been destroyed. +// +// Code may register a callback that is called whenever an Observer's value is +// updated, by calling SetOnUpdateCallback(). If you get an Observer by calling +// Observe() and then immediately call SetOnUpdateCallback() to register a +// a callback, you are guaranteed to get every value of the Observable starting +// from when you called Observe() - you get the initial value by calling +// GetValue() on the returned Observer, and any subsequent updates will trigger +// the callback so you can call GetValue() to get the new value. You will not +// receive any extra callbacks (exactly one callback per value update). +// +// Note that Observers are not default-constructible, since there is no way to +// construct it in a default state. In cases where you need to instantiate an +// Observer after your constructor, you can use a std::unique_ptr<Observer> +// instead, and initialize it when needed. +// +// Example usage: +// +// class MediaManager { +// public: +// MediaManager() : volume_(0.0f) {} +// +// Observer<float> ObserveVolume() { return volume_.Observe(); } +// +// // ... other methods ... +// +// private: +// // Assume this is called from some other internal code when the volume is +// // updated. +// void OnUpdateVolume(float new_volume) { +// volume_.SetValue(new_volume); // All observers will get the new value. +// } +// +// Observable<float> volume_; +// } +// +// class VolumeFeedbackManager { +// public: +// VolumeFeedbackManager(MediaManager* media_manager) +// : volume_observer_(media_manager->ObserveVolume()) { +// volume_observer_.SetOnUpdateCallback( +// base::BindRepeating(&VolumeFeedbackManager::OnVolumeChanged, +// base::Unretained(this))); +// } +// +// private: +// void OnVolumeChanged() { +// ShowVolumeFeedback(volume_observer_.GetValue()); +// } +// +// void ShowVolumeFeedback(float volume) { +// // ... some implementation ... +// } +// }; +// + +#ifndef CHROMECAST_BASE_OBSERVER_H_ +#define CHROMECAST_BASE_OBSERVER_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <memory> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" +#include "base/synchronization/lock.h" +#include "base/threading/sequenced_task_runner_handle.h" + +namespace chromecast { + +namespace subtle { +template <typename T> +class ObservableInternals; +} // namespace subtle + +template <typename T> +class Observable; + +template <typename T> +class Observer { + public: + Observer(const Observer& other); + + ~Observer(); + + void SetOnUpdateCallback(base::RepeatingClosure callback) { + on_update_callback_ = std::move(callback); + } + + const T& GetValue() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return value_; + } + + private: + friend class subtle::ObservableInternals<T>; + friend class Observable<T>; + + explicit Observer(scoped_refptr<subtle::ObservableInternals<T>> internals); + + void OnUpdate(); + + const scoped_refptr<subtle::ObservableInternals<T>> internals_; + // Note: value_ is a const ref to the value copy for this sequence, stored in + // SequenceOwnedInfo. + const T& value_; + base::RepeatingClosure on_update_callback_; + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_ASSIGN(Observer); +}; + +template <typename T> +class Observable { + static_assert(std::is_copy_constructible<T>::value, + "Observable values must be copyable"); + static_assert(std::is_copy_assignable<T>::value, + "Observable values must be copy-assignable"); + + public: + explicit Observable(const T& initial_value); + Observer<T> Observe(); + + void SetValue(const T& new_value); + const T& GetValue() const; // NOT threadsafe! + T GetValueThreadSafe() const; + + private: + // By using a refcounted object to store the value and observer list, we can + // avoid tying the lifetime of Observable to its Observers or vice versa. + const scoped_refptr<subtle::ObservableInternals<T>> internals_; + + DISALLOW_COPY_AND_ASSIGN(Observable); +}; + +namespace subtle { + +template <typename T> +class ObservableInternals + : public base::RefCountedThreadSafe<ObservableInternals<T>> { + public: + explicit ObservableInternals(const T& initial_value) + : value_(initial_value) {} + + void SetValue(const T& new_value) { + base::AutoLock lock(lock_); + value_ = new_value; + + for (auto& item : per_sequence_) { + item.SetValue(new_value); + } + } + + const T& GetValue() const { return value_; } + + T GetValueThreadSafe() const { + base::AutoLock lock(lock_); + return value_; + } + + const T& AddObserver(Observer<T>* observer) { + DCHECK(observer); + DCHECK(base::SequencedTaskRunnerHandle::IsSet()); + auto task_runner = base::SequencedTaskRunnerHandle::Get(); + + base::AutoLock lock(lock_); + auto it = per_sequence_.begin(); + while (it != per_sequence_.end() && it->task_runner() != task_runner) { + ++it; + } + if (it == per_sequence_.end()) { + per_sequence_.emplace_back(std::move(task_runner), value_); + it = --per_sequence_.end(); + } + it->AddObserver(observer); + return it->value(); + } + + void RemoveObserver(Observer<T>* observer) { + DCHECK(observer); + DCHECK(base::SequencedTaskRunnerHandle::IsSet()); + auto task_runner = base::SequencedTaskRunnerHandle::Get(); + + base::AutoLock lock(lock_); + for (size_t i = 0; i < per_sequence_.size(); ++i) { + if (per_sequence_[i].task_runner() == task_runner) { + per_sequence_[i].RemoveObserver(observer); + + if (per_sequence_[i].Empty()) { + per_sequence_[i].Swap(per_sequence_.back()); + per_sequence_.pop_back(); + } + return; + } + } + + NOTREACHED() << "Tried to remove observer from unknown task runner"; + } + + private: + // Information owned by a particular sequence. Must be only accessed on that + // sequence, and must be deleted by posting a task to that sequence. + // This class MUST NOT contain a scoped_refptr to the task_runner, since if it + // did, there would be a reference cycle during cleanup, when the task to + // Destroy() is posted. + class SequenceOwnedInfo { + public: + SequenceOwnedInfo(const T& value) : value_(value) {} + + const T& value() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return value_; + } + + void AddObserver(Observer<T>* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(observer); + DCHECK(std::find(observers_.begin(), observers_.end(), observer) == + observers_.end()); + observers_.push_back(observer); + } + + void RemoveObserver(Observer<T>* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(observer); + DCHECK(std::find(observers_.begin(), observers_.end(), observer) != + observers_.end()); + observers_.erase( + std::remove(observers_.begin(), observers_.end(), observer), + observers_.end()); + } + + bool Empty() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return observers_.empty(); + } + + void SetValue(const T& value) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + value_ = value; + for (auto* obs : observers_) { + obs->OnUpdate(); + } + } + + static void Destroy(std::unique_ptr<SequenceOwnedInfo> self) { + // The unique_ptr deletes automatically. + } + + private: + std::vector<Observer<T>*> observers_; + T value_; + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(SequenceOwnedInfo); + }; + + class PerSequenceInfo { + public: + PerSequenceInfo(scoped_refptr<base::SequencedTaskRunner> task_runner, + const T& value) + : task_runner_(std::move(task_runner)), + owned_info_(base::MakeUnique<SequenceOwnedInfo>(value)) {} + + PerSequenceInfo(PerSequenceInfo&& other) = default; + + ~PerSequenceInfo() { + if (!owned_info_) { + // Members have been moved out via move constructor. + return; + } + + DCHECK(Empty()); + // Must post a task to delete the owned info, since there may still be a + // pending task to call SequenceOwnedInfo::SetValue(). + // Use manual PostNonNestableTask(), since DeleteSoon() does not + // guarantee deletion. + task_runner_->PostNonNestableTask( + FROM_HERE, + base::BindOnce(&SequenceOwnedInfo::Destroy, std::move(owned_info_))); + } + + const T& value() const { return owned_info_->value(); } + + const base::SequencedTaskRunner* task_runner() const { + return task_runner_.get(); + } + + void AddObserver(Observer<T>* observer) { + owned_info_->AddObserver(observer); + } + + void RemoveObserver(Observer<T>* observer) { + owned_info_->RemoveObserver(observer); + } + + bool Empty() const { return owned_info_->Empty(); } + + void Swap(PerSequenceInfo& other) { + std::swap(task_runner_, other.task_runner_); + std::swap(owned_info_, other.owned_info_); + } + + void SetValue(const T& value) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&SequenceOwnedInfo::SetValue, + base::Unretained(owned_info_.get()), value)); + } + + private: + // Operations on |owned_info| do not need to be synchronized with a lock, + // since all operations must occur on |task_runner|. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + std::unique_ptr<SequenceOwnedInfo> owned_info_; + }; + + friend class base::RefCountedThreadSafe<ObservableInternals>; + ~ObservableInternals() {} + + mutable base::Lock lock_; + T value_; + std::vector<PerSequenceInfo> per_sequence_; + + DISALLOW_COPY_AND_ASSIGN(ObservableInternals); +}; + +} // namespace subtle + +template <typename T> +Observer<T>::Observer(scoped_refptr<subtle::ObservableInternals<T>> internals) + : internals_(std::move(internals)), value_(internals_->AddObserver(this)) {} + +template <typename T> +Observer<T>::Observer(const Observer& other) : Observer(other.internals_) {} + +template <typename T> +Observer<T>::~Observer() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + internals_->RemoveObserver(this); +} + +template <typename T> +void Observer<T>::OnUpdate() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (on_update_callback_) { + on_update_callback_.Run(); + } +} + +template <typename T> +Observable<T>::Observable(const T& initial_value) + : internals_(make_scoped_refptr( + new subtle::ObservableInternals<T>(initial_value))) {} + +template <typename T> +Observer<T> Observable<T>::Observe() { + return Observer<T>(internals_); +} + +template <typename T> +void Observable<T>::SetValue(const T& new_value) { + internals_->SetValue(new_value); +} + +template <typename T> +const T& Observable<T>::GetValue() const { + return internals_->GetValue(); +} + +template <typename T> +T Observable<T>::GetValueThreadSafe() const { + return internals_->GetValueThreadSafe(); +} + +} // namespace chromecast + +#endif // CHROMECAST_BASE_OBSERVER_H_
diff --git a/chromecast/base/observer_unittest.cc b/chromecast/base/observer_unittest.cc new file mode 100644 index 0000000..87a6fafd --- /dev/null +++ b/chromecast/base/observer_unittest.cc
@@ -0,0 +1,354 @@ +// 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 <functional> +#include <memory> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" +#include "chromecast/base/observer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { + +class ObserverTest : public ::testing::Test { + protected: + ObserverTest() : message_loop_(base::MakeUnique<base::MessageLoop>()) {} + + const std::unique_ptr<base::MessageLoop> message_loop_; +}; + +struct NoDefaultConstructor { + NoDefaultConstructor(int v) : value(v) {} + + int value; +}; + +class ThreadedObservable { + public: + ThreadedObservable() : thread_("ThreadedObservable"), value_(0) { + thread_.Start(); + } + + Observer<int> Observe() { return value_.Observe(); } + + void SetValue(int value) { + thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&ThreadedObservable::SetValueOnThread, + base::Unretained(this), value)); + } + + private: + void SetValueOnThread(int value) { + DCHECK(thread_.task_runner()->BelongsToCurrentThread()); + value_.SetValue(value); + } + + base::Thread thread_; + Observable<int> value_; + + DISALLOW_COPY_AND_ASSIGN(ThreadedObservable); +}; + +class ThreadedObserver { + public: + ThreadedObserver() + : thread_("ThreadedObserver"), + observing_(base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED) { + thread_.Start(); + } + + ~ThreadedObserver() { + thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&ThreadedObserver::DestroyOnThread, + base::Unretained(this))); + thread_.Stop(); + } + + void Observe(Observable<int>* observable) { + thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&ThreadedObserver::ObserveOnThread, + base::Unretained(this), observable)); + observing_.Wait(); + } + + void CheckValue(int value) { + thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&ThreadedObserver::CheckValueOnThread, + base::Unretained(this), value)); + } + + private: + void ObserveOnThread(Observable<int>* observable) { + DCHECK(thread_.task_runner()->BelongsToCurrentThread()); + observer_ = base::MakeUnique<Observer<int>>(observable->Observe()); + observing_.Signal(); + } + + void CheckValueOnThread(int value) { + DCHECK(thread_.task_runner()->BelongsToCurrentThread()); + EXPECT_EQ(value, observer_->GetValue()); + } + + void DestroyOnThread() { + DCHECK(thread_.task_runner()->BelongsToCurrentThread()); + observer_.reset(); + } + + base::Thread thread_; + std::unique_ptr<Observer<int>> observer_; + base::WaitableEvent observing_; + + DISALLOW_COPY_AND_ASSIGN(ThreadedObserver); +}; + +void RunCallback(std::function<void()> callback) { + callback(); +} + +TEST_F(ObserverTest, SimpleValue) { + Observable<int> original(0); + Observer<int> observer = original.Observe(); + + EXPECT_EQ(0, observer.GetValue()); + + original.SetValue(1); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, observer.GetValue()); +} + +TEST_F(ObserverTest, MultipleObservers) { + Observable<int> original(0); + Observer<int> observer1 = original.Observe(); + Observer<int> observer2 = observer1; + + EXPECT_EQ(0, observer1.GetValue()); + EXPECT_EQ(0, observer2.GetValue()); + + original.SetValue(1); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, observer1.GetValue()); + EXPECT_EQ(1, observer2.GetValue()); +} + +TEST_F(ObserverTest, NoDefaultConstructor) { + Observable<NoDefaultConstructor> original(0); + Observer<NoDefaultConstructor> observer = original.Observe(); + + EXPECT_EQ(0, observer.GetValue().value); + + original.SetValue(1); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, observer.GetValue().value); +} + +TEST_F(ObserverTest, NoMissingEvents) { + Observable<int> original(0); + Observer<int> observer = original.Observe(); + original.SetValue(1); + + std::vector<int> event_values; + std::function<void()> callback = [&]() { + event_values.push_back(observer.GetValue()); + }; + observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback)); + + EXPECT_EQ(0, observer.GetValue()); + + original.SetValue(2); + base::RunLoop().RunUntilIdle(); + original.SetValue(3); + original.SetValue(4); + base::RunLoop().RunUntilIdle(); + + ASSERT_EQ(4u, event_values.size()); + EXPECT_EQ(1, event_values[0]); + EXPECT_EQ(2, event_values[1]); + EXPECT_EQ(3, event_values[2]); + EXPECT_EQ(4, event_values[3]); + + EXPECT_EQ(4, observer.GetValue()); +} + +TEST_F(ObserverTest, NoExtraEventsAfterChange) { + Observable<int> original(0); + original.SetValue(1); + + Observer<int> observer = original.Observe(); + EXPECT_EQ(1, observer.GetValue()); + + std::vector<int> event_values; + std::function<void()> callback = [&]() { + event_values.push_back(observer.GetValue()); + }; + observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback)); + + // Propagate the SetValue event; the observer shouldn't get it since it + // started observing after SetValue(). + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, observer.GetValue()); + EXPECT_EQ(0u, event_values.size()); +} + +TEST_F(ObserverTest, NoExtraEventsBetweenChanges) { + Observable<int> original(0); + original.SetValue(1); + + Observer<int> observer = original.Observe(); + EXPECT_EQ(1, observer.GetValue()); + + original.SetValue(2); + + std::vector<int> event_values; + std::function<void()> callback = [&]() { + event_values.push_back(observer.GetValue()); + }; + observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback)); + + // Propagate the SetValue events; the observer should only get the second + // event, corresponding to the SetValue after the observer was created. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2, observer.GetValue()); + ASSERT_EQ(1u, event_values.size()); + EXPECT_EQ(2, event_values[0]); +} + +TEST_F(ObserverTest, NoExtraEventsForCopy) { + Observable<int> original(0); + original.SetValue(1); + + Observer<int> observer1 = original.Observe(); + EXPECT_EQ(1, observer1.GetValue()); + + original.SetValue(2); + + Observer<int> observer2 = observer1; + // All observers on the same thread observe the same value. The update hasn't + // propagated yet. + EXPECT_EQ(1, observer2.GetValue()); + + std::vector<int> event_values1; + std::function<void()> callback1 = [&]() { + event_values1.push_back(observer1.GetValue()); + }; + observer1.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback1)); + + std::vector<int> event_values2; + std::function<void()> callback2 = [&]() { + event_values2.push_back(observer2.GetValue()); + }; + observer2.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback2)); + + // Propagate the SetValue events; each observer should get just one callback + // for the new value. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2, observer1.GetValue()); + EXPECT_EQ(2, observer2.GetValue()); + + ASSERT_EQ(1u, event_values1.size()); + EXPECT_EQ(2, event_values1[0]); + + ASSERT_EQ(1u, event_values2.size()); + EXPECT_EQ(2, event_values2[0]); +} + +TEST_F(ObserverTest, SetCallbackTwice) { + Observable<int> original(0); + original.SetValue(1); + + Observer<int> observer = original.Observe(); + EXPECT_EQ(1, observer.GetValue()); + + original.SetValue(2); + + std::vector<int> event_values1; + std::function<void()> callback1 = [&]() { + event_values1.push_back(observer.GetValue()); + }; + observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback1)); + + std::vector<int> event_values2; + std::function<void()> callback2 = [&]() { + event_values2.push_back(observer.GetValue()); + }; + observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback2)); + + // Propagate the SetValue events; only the second callback should be run. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2, observer.GetValue()); + EXPECT_EQ(0u, event_values1.size()); + ASSERT_EQ(1u, event_values2.size()); + EXPECT_EQ(2, event_values2[0]); +} + +TEST_F(ObserverTest, ObserverOutlivesObservable) { + auto original = base::MakeUnique<Observable<int>>(0); + Observer<int> observer1 = original->Observe(); + + EXPECT_EQ(0, observer1.GetValue()); + + original->SetValue(1); + original.reset(); + + Observer<int> observer2 = observer1; + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(1, observer1.GetValue()); + EXPECT_EQ(1, observer2.GetValue()); +} + +TEST_F(ObserverTest, ObserverOnDifferentThread) { + auto original = base::MakeUnique<ThreadedObservable>(); + Observer<int> observer = original->Observe(); + EXPECT_EQ(0, observer.GetValue()); + + std::vector<int> event_values; + std::function<void()> callback = [&]() { + event_values.push_back(observer.GetValue()); + }; + observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback)); + + original->SetValue(1); + original->SetValue(2); + original.reset(); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(2, observer.GetValue()); + ASSERT_EQ(2u, event_values.size()); + EXPECT_EQ(1, event_values[0]); + EXPECT_EQ(2, event_values[1]); +} + +TEST_F(ObserverTest, ObserveOnManyThreads) { + auto original = base::MakeUnique<Observable<int>>(0); + std::vector<std::unique_ptr<ThreadedObserver>> observers; + for (int i = 0; i < 20; ++i) { + observers.push_back(base::MakeUnique<ThreadedObserver>()); + observers.back()->Observe(original.get()); + } + + original->SetValue(1); + original.reset(); + + base::RunLoop().RunUntilIdle(); + for (auto& observer : observers) { + observer->CheckValue(1); + } + + // Deleting the observers should check the expectations, since all posted + // tasks on their internal threads will run. + observers.clear(); +} + +} // chromecast
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 3d7f353..f4700d5 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -312,12 +312,18 @@ command_line->AppendSwitch(switches::kEnableCrashReporter); } - // Renderer process command-line + // Command-line for different processes. if (process_type == switches::kRendererProcess) { // Any browser command-line switches that should be propagated to // the renderer go here. if (browser_command_line->HasSwitch(switches::kAllowHiddenMediaPlayback)) command_line->AppendSwitch(switches::kAllowHiddenMediaPlayback); + } else if (process_type == switches::kUtilityProcess) { + if (browser_command_line->HasSwitch(switches::kAudioOutputChannels)) { + command_line->AppendSwitchASCII(switches::kAudioOutputChannels, + browser_command_line->GetSwitchValueASCII( + switches::kAudioOutputChannels)); + } } #if defined(OS_LINUX)
diff --git a/chromecast/media/cma/backend/alsa/BUILD.gn b/chromecast/media/cma/backend/alsa/BUILD.gn index 63dfa36..4de9c9a 100644 --- a/chromecast/media/cma/backend/alsa/BUILD.gn +++ b/chromecast/media/cma/backend/alsa/BUILD.gn
@@ -100,6 +100,7 @@ test("cast_alsa_cma_backend_unittests") { sources = [ + "filter_group_unittest.cc", "stream_mixer_alsa_unittest.cc", ]
diff --git a/chromecast/media/cma/backend/alsa/cast_media_shlib.cc b/chromecast/media/cma/backend/alsa/cast_media_shlib.cc index cc29c7c..2dfe4c6 100644 --- a/chromecast/media/cma/backend/alsa/cast_media_shlib.cc +++ b/chromecast/media/cma/backend/alsa/cast_media_shlib.cc
@@ -88,6 +88,8 @@ } // namespace void CastMediaShlib::Initialize(const std::vector<std::string>& argv) { + // Sets logging to display process and thread ID. + logging::SetLogItems(true, true, false, false); chromecast::InitCommandLineShlib(argv); g_video_plane = new DefaultVideoPlane();
diff --git a/chromecast/media/cma/backend/alsa/filter_group.cc b/chromecast/media/cma/backend/alsa/filter_group.cc index 881a4cf28..6937c56 100644 --- a/chromecast/media/cma/backend/alsa/filter_group.cc +++ b/chromecast/media/cma/backend/alsa/filter_group.cc
@@ -17,17 +17,25 @@ namespace chromecast { namespace media { FilterGroup::FilterGroup(int num_channels, + bool mix_to_mono, const std::string& name, const base::ListValue* filter_list, const std::unordered_set<std::string>& device_ids, const std::vector<FilterGroup*>& mixed_inputs) : num_channels_(num_channels), + mix_to_mono_(mix_to_mono), name_(name), device_ids_(device_ids), mixed_inputs_(mixed_inputs), output_samples_per_second_(0), post_processing_pipeline_( - PostProcessingPipeline::Create(name_, filter_list, num_channels_)) {} + PostProcessingPipeline::Create(name_, filter_list, num_channels_)) { + for (auto* const m : mixed_inputs) + DCHECK_EQ(m->GetOutputChannelCount(), num_channels); + // Don't need mono mixer if input is single channel. + if (num_channels == 1) + mix_to_mono_ = false; +} FilterGroup::~FilterGroup() = default; @@ -108,6 +116,17 @@ delay_frames_ = post_processing_pipeline_->ProcessFrames( interleaved(), chunk_size, last_volume_, is_silence); + + // Mono mixing after all processing if needed. + if (mix_to_mono_) { + for (int frame = 0; frame < chunk_size; ++frame) { + float sum = 0; + for (int c = 0; c < num_channels_; ++c) + sum += interleaved()[frame * num_channels_ + c]; + interleaved()[frame] = sum / num_channels_; + } + } + return last_volume_; } @@ -120,6 +139,10 @@ active_inputs_.clear(); } +int FilterGroup::GetOutputChannelCount() const { + return mix_to_mono_ ? 1 : num_channels_; +} + void FilterGroup::ResizeBuffersIfNecessary(int chunk_size) { if (!mixed_ || mixed_->frames() < chunk_size) { mixed_ = ::media::AudioBus::Create(num_channels_, chunk_size);
diff --git a/chromecast/media/cma/backend/alsa/filter_group.h b/chromecast/media/cma/backend/alsa/filter_group.h index 6c9f2ae..b71a20e 100644 --- a/chromecast/media/cma/backend/alsa/filter_group.h +++ b/chromecast/media/cma/backend/alsa/filter_group.h
@@ -36,6 +36,10 @@ // MixAndFilter() is called (they must be added each time data is queried). class FilterGroup { public: + // |num_channels| indicates number of input audio channels. + // |mix_to_mono| enables mono mixing in the pipeline. The number of audio + // output channels will be 1 if it is set to true, otherwise it remains + // same as |num_channels|. // |name| is used for debug printing // |filter_list| is a list of {"processor": LIBRARY_NAME, "configs": CONFIG} // that is used to create PostProcessingPipeline. @@ -47,6 +51,7 @@ // FilterGroups currently use either InputQueues OR FilterGroups as inputs, // but there is no technical limitation preventing mixing input classes. FilterGroup(int num_channels, + bool mix_to_mono, const std::string& name, const base::ListValue* filter_list, const std::unordered_set<std::string>& device_ids, @@ -85,10 +90,14 @@ std::string name() const { return name_; } + // Returns number of audio output channels from the filter group. + int GetOutputChannelCount() const; + private: void ResizeBuffersIfNecessary(int chunk_size); const int num_channels_; + bool mix_to_mono_; const std::string name_; const std::unordered_set<std::string> device_ids_; std::vector<FilterGroup*> mixed_inputs_;
diff --git a/chromecast/media/cma/backend/alsa/filter_group_unittest.cc b/chromecast/media/cma/backend/alsa/filter_group_unittest.cc new file mode 100644 index 0000000..b3a920e3 --- /dev/null +++ b/chromecast/media/cma/backend/alsa/filter_group_unittest.cc
@@ -0,0 +1,172 @@ +// 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 "chromecast/media/cma/backend/alsa/filter_group.h" + +#include "base/memory/ptr_util.h" +#include "chromecast/media/cma/backend/alsa/stream_mixer_alsa.h" +#include "media/base/audio_bus.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { +namespace media { + +// Total of Test damples including left and right channels. +#define NUM_SAMPLES 64 + +constexpr size_t kBytesPerSample = sizeof(int32_t); +constexpr int kNumInputChannels = 2; +constexpr int kInputSampleRate = 48000; + +// Note: Test data should be represented as 32-bit integers and copied into +// ::media::AudioBus instances, rather than wrapping statically declared float +// arrays. +constexpr int32_t kTestData[NUM_SAMPLES] = { + 74343736, -1333200799, -1360871126, 1138806283, 1931811865, + 1856308487, 649203634, 564640023, 1676630678, 23416591, + -1293255456, 547928305, -976258952, 1840550252, 1714525174, + 358704931, 983646295, 1264863573, 442473973, 1222979052, + 317404525, 366912613, 1393280948, -1022004648, -2054669405, + -159762261, 1127018745, -1984491787, 1406988336, -693327981, + -1549544744, 1232236854, 970338338, -1750160519, -783213057, + 1231504562, 1155296810, -820018779, 1155689800, -1108462340, + -150535168, 1033717023, 2121241397, 1829995370, -1893006836, + -819097508, -495186107, 1001768909, -1441111852, 692174781, + 1916569026, -687787473, -910565280, 1695751872, 994166817, + 1775451433, 909418522, 492671403, -761744663, -2064315902, + 1357716471, -1580019684, 1872702377, -1524457840, +}; + +// Return a scoped pointer filled with the data above. +std::unique_ptr<::media::AudioBus> GetTestData() { + int samples = NUM_SAMPLES / kNumInputChannels; + auto data = ::media::AudioBus::Create(kNumInputChannels, samples); + data->FromInterleaved(kTestData, samples, kBytesPerSample); + return data; +} + +// TODO(erickung): Consolidate this mock class with the one used in +// StreamMixerAlsaTest. +// Class to provide a fake 64 audio samples. +class MockInputQueue : public StreamMixerAlsa::InputQueue { + public: + MockInputQueue() : data_(GetTestData()) {} + ~MockInputQueue() override = default; + + // StreamMixerAlsa::InputQueue implementations. Most of them are dummy except + // for + int input_samples_per_second() const override { return kInputSampleRate; } + bool primary() const override { return true; } + std::string device_id() const override { return "test"; } + AudioContentType content_type() const override { + return AudioContentType::kMedia; + } + bool IsDeleting() const override { return false; } + void Initialize(const MediaPipelineBackendAlsa::RenderingDelay& + mixer_rendering_delay) override {} + void set_filter_group(FilterGroup* filter_group) override { + filter_group_ = filter_group; + } + FilterGroup* filter_group() override { return filter_group_; } + int MaxReadSize() override { return NUM_SAMPLES; } + void GetResampledData(::media::AudioBus* dest, int frames) override { + DCHECK(data_); + data_->CopyPartialFramesTo(0, frames, 0, dest); + } + void VolumeScaleAccumulate(bool repeat_transition, + const float* src, + int frames, + float* dest) override { + DCHECK(dest); + DCHECK(src); + // Bypass the original audio data. + std::memcpy(dest, src, frames * sizeof(float)); + } + void OnSkipped() override {} + void AfterWriteFrames(const MediaPipelineBackendAlsa::RenderingDelay& + mixer_rendering_delay) override {} + void SignalError(StreamMixerAlsaInput::MixerError error) override {} + void PrepareToDelete(const OnReadyToDeleteCb& delete_cb) override {} + void SetContentTypeVolume(float volume, int fade_ms) override {} + void SetMuted(bool muted) override {} + float EffectiveVolume() override { return 1.0; } + + const ::media::AudioBus* data() const { return data_.get(); } + + private: + FilterGroup* filter_group_ = nullptr; + std::unique_ptr<::media::AudioBus> data_; + + DISALLOW_COPY_AND_ASSIGN(MockInputQueue); +}; + +class FilterGroupTest : public testing::Test { + protected: + FilterGroupTest() : message_loop_(new base::MessageLoop()) {} + ~FilterGroupTest() override {} + + private: + const std::unique_ptr<base::MessageLoop> message_loop_; + + DISALLOW_COPY_AND_ASSIGN(FilterGroupTest); +}; + +TEST_F(FilterGroupTest, Passthrough) { + const int num_output_channel = 2; + std::unique_ptr<MockInputQueue> input(new MockInputQueue()); + base::ListValue empty_filter_list; + std::unordered_set<std::string> empty_device_ids; + std::unique_ptr<FilterGroup> filter_group(new FilterGroup( + kNumInputChannels, false /* mix to mono */, "pass_through_filter", + &empty_filter_list, empty_device_ids, std::vector<FilterGroup*>())); + input->set_filter_group(filter_group.get()); + const int input_samples = NUM_SAMPLES / kNumInputChannels; + filter_group->Initialize(kInputSampleRate); + + // Adds input queue into filter group. + filter_group->AddActiveInput(input.get()); + + // Mixing input in the filter group + filter_group->MixAndFilter(input_samples); + + // Verify if the fiter group output matches the source. + float* interleaved_data = filter_group->interleaved(); + const int output_sample_size = input_samples * num_output_channel; + for (int i = 0; i < output_sample_size; ++i) { + int channel = (i % 2 == 0) ? 0 : 1; + float sample = input->data()->channel(channel)[i >> 1]; + ASSERT_EQ(sample, interleaved_data[i]); + } +} + +TEST_F(FilterGroupTest, MonoMixer) { + const int num_output_channel = 1; + const int input_samples = NUM_SAMPLES / kNumInputChannels; + std::unique_ptr<MockInputQueue> input(new MockInputQueue()); + base::ListValue empty_filter_list; + std::unordered_set<std::string> empty_device_ids; + std::unique_ptr<FilterGroup> filter_group(new FilterGroup( + kNumInputChannels, true /* mix to mono */, "mono_mix_filter", + &empty_filter_list, empty_device_ids, std::vector<FilterGroup*>())); + input->set_filter_group(filter_group.get()); + filter_group->Initialize(kInputSampleRate); + + // Adds input queue into filter group. + filter_group->AddActiveInput(input.get()); + + // Mixing input in the filter group + filter_group->MixAndFilter(input_samples); + + // Verify if the fiter group output matches the source after down mixing. + float* interleaved_data = filter_group->interleaved(); + const int output_chunk_size = input_samples * num_output_channel; + for (int i = 0; i < output_chunk_size; ++i) { + const float* left_input = input->data()->channel(0); + const float* right_input = input->data()->channel(1); + ASSERT_EQ((left_input[i] + right_input[i]) / 2, interleaved_data[i]); + } +} + +} // namespace media +} // namespace chromecast
diff --git a/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc b/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc index b75ceae..3779dcd 100644 --- a/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc +++ b/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc
@@ -72,7 +72,7 @@ namespace { const char kOutputDeviceDefaultName[] = "default"; -const int kNumOutputChannels = 2; +const int kNumInputChannels = 2; const int kDefaultOutputBufferSizeFrames = 4096; const bool kPcmRecoverIsSilent = false; @@ -245,6 +245,11 @@ fixed_output_samples_per_second_ = fixed_samples_per_second; + num_output_channels_ = GetSwitchValueNonNegativeInt( + switches::kAudioOutputChannels, kNumInputChannels); + DCHECK(num_output_channels_ == kNumInputChannels || + num_output_channels_ == 1); + low_sample_rate_cutoff_ = chromecast::GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false) ? kLowSampleRateCutoff @@ -274,8 +279,8 @@ << pipeline_parser->GetFilePath() << "."; } filter_groups_.push_back(base::MakeUnique<FilterGroup>( - kNumOutputChannels, *device_ids.begin() /* name */, - stream_pipeline.pipeline, device_ids, + kNumInputChannels, false /* mono_mixer */, + *device_ids.begin() /* name */, stream_pipeline.pipeline, device_ids, std::vector<FilterGroup*>() /* mixed_inputs */)); if (device_ids.find(::media::AudioDeviceDescription::kDefaultDeviceId) != device_ids.end()) { @@ -288,8 +293,8 @@ std::string kDefaultDeviceId = ::media::AudioDeviceDescription::kDefaultDeviceId; filter_groups_.push_back(base::MakeUnique<FilterGroup>( - kNumOutputChannels, kDefaultDeviceId /* name */, nullptr, - std::unordered_set<std::string>({kDefaultDeviceId}), + kNumInputChannels, false /* mono_mixer */, kDefaultDeviceId /* name */, + nullptr, std::unordered_set<std::string>({kDefaultDeviceId}), std::vector<FilterGroup*>() /* mixed_inputs */)); default_filter_ = filter_groups_.back().get(); } @@ -299,13 +304,17 @@ filter_groups_.begin(), filter_groups_.end(), filter_group_ptrs.begin(), [](const std::unique_ptr<FilterGroup>& group) { return group.get(); }); + // Enable Mono mixer in |mix_filter_| if necessary. + bool enabled_mono_mixer = (num_output_channels_ == 1); filter_groups_.push_back(base::MakeUnique<FilterGroup>( - kNumOutputChannels, "mix", pipeline_parser->GetMixPipeline(), + kNumInputChannels, enabled_mono_mixer, "mix", + pipeline_parser->GetMixPipeline(), std::unordered_set<std::string>() /* device_ids */, filter_group_ptrs)); mix_filter_ = filter_groups_.back().get(); filter_groups_.push_back(base::MakeUnique<FilterGroup>( - kNumOutputChannels, "linearize", pipeline_parser->GetLinearizePipeline(), + num_output_channels_, false /* mono_mixer */, "linearize", + pipeline_parser->GetLinearizePipeline(), std::unordered_set<std::string>() /* device_ids */, std::vector<FilterGroup*>({mix_filter_}))); linearize_filter_ = filter_groups_.back().get(); @@ -443,7 +452,7 @@ RETURN_ERROR_CODE(PcmHwParamsSetFormat, pcm_, pcm_hw_params_, pcm_format_); RETURN_ERROR_CODE(PcmHwParamsSetChannels, pcm_, pcm_hw_params_, - kNumOutputChannels); + num_output_channels_); // Set output rate, allow resampling with a warning if the device doesn't // support the rate natively. @@ -894,7 +903,7 @@ size_t StreamMixerAlsa::InterleavedSize(int frames) { return BytesPerOutputFormatSample() * - static_cast<size_t>(frames * kNumOutputChannels); + static_cast<size_t>(frames * num_output_channels_); } ssize_t StreamMixerAlsa::BytesPerOutputFormatSample() { @@ -906,7 +915,7 @@ CHECK_PCM_INITIALIZED(); // Resize interleaved if necessary. - size_t interleaved_size = static_cast<size_t>(frames) * kNumOutputChannels * + size_t interleaved_size = static_cast<size_t>(frames) * num_output_channels_ * BytesPerOutputFormatSample(); int64_t expected_playback_time; @@ -919,7 +928,7 @@ } // Hard limit to [1.0, -1.0] - for (int i = 0; i < frames * kNumOutputChannels; ++i) { + for (int i = 0; i < frames * num_output_channels_; ++i) { mix_filter_->interleaved()[i] = std::min(1.0f, std::max(-1.0f, mix_filter_->interleaved()[i])); } @@ -927,7 +936,7 @@ for (CastMediaShlib::LoopbackAudioObserver* observer : loopback_observers_) { observer->OnLoopbackAudio( expected_playback_time, kSampleFormatF32, output_samples_per_second_, - kNumOutputChannels, + num_output_channels_, reinterpret_cast<uint8_t*>(mix_filter_->interleaved()), InterleavedSize(frames)); } @@ -935,7 +944,7 @@ uint8_t* data; if (pcm_format_ == SND_PCM_FORMAT_FLOAT) { // Hard limit to [1.0, -1.0]. ToFixedPoint handles this for other cases. - for (int i = 0; i < frames * kNumOutputChannels; ++i) { + for (int i = 0; i < frames * num_output_channels_; ++i) { linearize_filter_->interleaved()[i] = std::min(1.0f, std::max(-1.0f, linearize_filter_->interleaved()[i])); } @@ -944,8 +953,9 @@ if (interleaved_.size() < interleaved_size) { interleaved_.resize(interleaved_size); } - ToFixedPoint(linearize_filter_->interleaved(), frames * kNumOutputChannels, - BytesPerOutputFormatSample(), interleaved_.data()); + ToFixedPoint(linearize_filter_->interleaved(), + frames * num_output_channels_, BytesPerOutputFormatSample(), + interleaved_.data()); data = interleaved_.data(); } @@ -967,7 +977,8 @@ } frames_left -= frames_or_error; DCHECK_GE(frames_left, 0); - data += frames_or_error * kNumOutputChannels * BytesPerOutputFormatSample(); + data += + frames_or_error * num_output_channels_ * BytesPerOutputFormatSample(); } UpdateRenderingDelay(frames); MediaPipelineBackendAlsa::RenderingDelay common_rendering_delay =
diff --git a/chromecast/media/cma/backend/alsa/stream_mixer_alsa.h b/chromecast/media/cma/backend/alsa/stream_mixer_alsa.h index 3b8f181..4b54751e 100644 --- a/chromecast/media/cma/backend/alsa/stream_mixer_alsa.h +++ b/chromecast/media/cma/backend/alsa/stream_mixer_alsa.h
@@ -257,6 +257,7 @@ scoped_refptr<base::SingleThreadTaskRunner> mixer_task_runner_; unsigned int fixed_output_samples_per_second_; + int num_output_channels_; unsigned int low_sample_rate_cutoff_; int requested_output_samples_per_second_; int output_samples_per_second_;
diff --git a/components/app_modal/BUILD.gn b/components/app_modal/BUILD.gn index 23b1b84..dfb72d1c 100644 --- a/components/app_modal/BUILD.gn +++ b/components/app_modal/BUILD.gn
@@ -6,8 +6,6 @@ static_library("app_modal") { sources = [ - "app_modal_dialog.cc", - "app_modal_dialog.h", "app_modal_dialog_queue.cc", "app_modal_dialog_queue.h", "javascript_app_modal_dialog.cc",
diff --git a/components/app_modal/app_modal_dialog.cc b/components/app_modal/app_modal_dialog.cc deleted file mode 100644 index 8689b7f..0000000 --- a/components/app_modal/app_modal_dialog.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/app_modal/app_modal_dialog.h" - -#include "base/logging.h" -#include "base/run_loop.h" -#include "components/app_modal/app_modal_dialog_queue.h" -#include "components/app_modal/native_app_modal_dialog.h" - -using content::WebContents; - -namespace app_modal { -namespace { - -AppModalDialogObserver* app_modal_dialog_observer = NULL; - -} // namespace - -AppModalDialogObserver::AppModalDialogObserver() { - DCHECK(!app_modal_dialog_observer); - app_modal_dialog_observer = this; -} - -AppModalDialogObserver::~AppModalDialogObserver() { - DCHECK(app_modal_dialog_observer); - app_modal_dialog_observer = NULL; -} - -AppModalDialog::AppModalDialog(WebContents* web_contents, - const base::string16& title) - : title_(title), - completed_(false), - valid_(true), - native_dialog_(NULL), - web_contents_(web_contents) { -} - -AppModalDialog::~AppModalDialog() { - CompleteDialog(); -} - -void AppModalDialog::ShowModalDialog() { - native_dialog_ = CreateNativeDialog(); - native_dialog_->ShowAppModalDialog(); - if (app_modal_dialog_observer) - app_modal_dialog_observer->Notify(this); -} - -bool AppModalDialog::IsValid() { - return valid_; -} - -void AppModalDialog::Invalidate() { - valid_ = false; -} - -bool AppModalDialog::IsJavaScriptModalDialog() { - return false; -} - -void AppModalDialog::ActivateModalDialog() { - DCHECK(native_dialog_); - native_dialog_->ActivateAppModalDialog(); -} - -void AppModalDialog::CloseModalDialog() { - DCHECK(native_dialog_); - native_dialog_->CloseAppModalDialog(); -} - -void AppModalDialog::CompleteDialog() { - if (!completed_) { - completed_ = true; - AppModalDialogQueue::GetInstance()->ShowNextDialog(); - } -} - -} // namespace app_modal
diff --git a/components/app_modal/app_modal_dialog.h b/components/app_modal/app_modal_dialog.h deleted file mode 100644 index c4923ea..0000000 --- a/components/app_modal/app_modal_dialog.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_APP_MODAL_APP_MODAL_DIALOG_H_ -#define COMPONENTS_APP_MODAL_APP_MODAL_DIALOG_H_ - -#include <string> - -#include "base/macros.h" -#include "base/strings/string16.h" -#include "build/build_config.h" - -namespace content { -class WebContents; -} - -namespace app_modal { - -class NativeAppModalDialog; - -// A controller+model base class for modal dialogs. -class AppModalDialog { - public: - // A union of data necessary to determine the type of message box to - // show. - AppModalDialog(content::WebContents* web_contents, - const base::string16& title); - virtual ~AppModalDialog(); - - // Called by the AppModalDialogQueue to show this dialog. - void ShowModalDialog(); - - // Called by the AppModalDialogQueue to activate the dialog. - void ActivateModalDialog(); - - // Closes the dialog if it is showing. - void CloseModalDialog(); - - // Completes dialog handling, shows next modal dialog from the queue. - // TODO(beng): Get rid of this method. - void CompleteDialog(); - - base::string16 title() const { return title_; } - NativeAppModalDialog* native_dialog() const { return native_dialog_; } - content::WebContents* web_contents() const { return web_contents_; } - - // Returns true if the dialog is still valid. As dialogs are created they are - // added to the AppModalDialogQueue. When the current modal dialog finishes - // and it's time to show the next dialog in the queue IsValid is invoked. - // If IsValid returns false the dialog is deleted and not shown. - bool IsValid(); - - // Methods overridable by AppModalDialog subclasses: - - // Invalidates the dialog, therefore causing it to not be shown when its turn - // to be shown comes around. - virtual void Invalidate(); - - // Used only for testing. Returns whether the dialog is a JavaScript modal - // dialog. - virtual bool IsJavaScriptModalDialog(); - - protected: - // Overridden by subclasses to create the feature-specific native dialog box. - virtual NativeAppModalDialog* CreateNativeDialog() = 0; - - private: - // Information about the message box is held in the following variables. - base::string16 title_; - - // True if CompleteDialog was called. - bool completed_; - - // False if the dialog should no longer be shown, e.g. because the underlying - // tab navigated away while the dialog was queued. - bool valid_; - - // The toolkit-specific implementation of the app modal dialog box. - NativeAppModalDialog* native_dialog_; - - content::WebContents* web_contents_; - - DISALLOW_COPY_AND_ASSIGN(AppModalDialog); -}; - -// An interface to observe that a modal dialog is shown. -class AppModalDialogObserver { - public: - AppModalDialogObserver(); - virtual ~AppModalDialogObserver(); - - // Called when the modal dialog is shown. - virtual void Notify(AppModalDialog* dialog) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver); -}; - -} // namespace app_modal - -#endif // COMPONENTS_APP_MODAL_APP_MODAL_DIALOG_H_
diff --git a/components/app_modal/app_modal_dialog_queue.cc b/components/app_modal/app_modal_dialog_queue.cc index ab041eb..ce1fc2b 100644 --- a/components/app_modal/app_modal_dialog_queue.cc +++ b/components/app_modal/app_modal_dialog_queue.cc
@@ -5,7 +5,7 @@ #include "components/app_modal/app_modal_dialog_queue.h" #include "base/memory/singleton.h" -#include "components/app_modal/app_modal_dialog.h" +#include "components/app_modal/javascript_app_modal_dialog.h" namespace app_modal { @@ -14,7 +14,7 @@ return base::Singleton<AppModalDialogQueue>::get(); } -void AppModalDialogQueue::AddDialog(AppModalDialog* dialog) { +void AppModalDialogQueue::AddDialog(JavaScriptAppModalDialog* dialog) { if (!active_dialog_) { ShowModalDialog(dialog); return; @@ -23,11 +23,11 @@ } void AppModalDialogQueue::ShowNextDialog() { - AppModalDialog* dialog = GetNextDialog(); + JavaScriptAppModalDialog* dialog = GetNextDialog(); if (dialog) ShowModalDialog(dialog); else - active_dialog_ = NULL; + active_dialog_ = nullptr; } void AppModalDialogQueue::ActivateModalDialog() { @@ -43,7 +43,7 @@ } bool AppModalDialogQueue::HasActiveDialog() const { - return active_dialog_ != NULL; + return active_dialog_ != nullptr; } AppModalDialogQueue::AppModalDialogQueue() @@ -54,11 +54,11 @@ AppModalDialogQueue::~AppModalDialogQueue() { } -void AppModalDialogQueue::ShowModalDialog(AppModalDialog* dialog) { +void AppModalDialogQueue::ShowModalDialog(JavaScriptAppModalDialog* dialog) { // Be sure and set the active_dialog_ field first, otherwise if // ShowModalDialog triggers a call back to the queue they'll get the old // dialog. Also, if the dialog calls |ShowNextDialog()| before returning, that - // would write NULL into |active_dialog_| and this function would then undo + // would write nullptr into |active_dialog_| and this function would then undo // that. active_dialog_ = dialog; showing_modal_dialog_ = true; @@ -66,15 +66,15 @@ showing_modal_dialog_ = false; } -AppModalDialog* AppModalDialogQueue::GetNextDialog() { +JavaScriptAppModalDialog* AppModalDialogQueue::GetNextDialog() { while (!app_modal_dialog_queue_.empty()) { - AppModalDialog* dialog = app_modal_dialog_queue_.front(); + JavaScriptAppModalDialog* dialog = app_modal_dialog_queue_.front(); app_modal_dialog_queue_.pop_front(); if (dialog->IsValid()) return dialog; delete dialog; } - return NULL; + return nullptr; } } // namespace app_modal
diff --git a/components/app_modal/app_modal_dialog_queue.h b/components/app_modal/app_modal_dialog_queue.h index 96a582e..3b945b6b 100644 --- a/components/app_modal/app_modal_dialog_queue.h +++ b/components/app_modal/app_modal_dialog_queue.h
@@ -15,14 +15,14 @@ namespace app_modal { -class AppModalDialog; +class JavaScriptAppModalDialog; -// Keeps a queue of AppModalDialogs, making sure only one app modal +// Keeps a queue of JavaScriptAppModalDialogs, making sure only one app modal // dialog is shown at a time. // This class is a singleton. class AppModalDialogQueue { public: - typedef std::deque<AppModalDialog*>::iterator iterator; + typedef std::deque<JavaScriptAppModalDialog*>::iterator iterator; // Returns the singleton instance. static AppModalDialogQueue* GetInstance(); @@ -32,9 +32,9 @@ // most recently active browser window (or whichever is currently active) // will be app modal, meaning it will be activated if the user tries to // activate any other browser windows. - // Note: The AppModalDialog |dialog| must be window modal before it + // Note: The JavaScriptAppModalDialog |dialog| must be window modal before it // can be added as app modal. - void AddDialog(AppModalDialog* dialog); + void AddDialog(JavaScriptAppModalDialog* dialog); // Removes the current dialog in the queue (the one that is being shown). // Shows the next dialog in the queue, if any is present. This does not @@ -53,7 +53,7 @@ // Returns true if there is currently an active app modal dialog box. bool HasActiveDialog() const; - AppModalDialog* active_dialog() { return active_dialog_; } + JavaScriptAppModalDialog* active_dialog() { return active_dialog_; } // Iterators to walk the queue. The queue does not include the currently // active app modal dialog box. @@ -67,21 +67,21 @@ ~AppModalDialogQueue(); // Shows |dialog| and notifies the BrowserList that a modal dialog is showing. - void ShowModalDialog(AppModalDialog* dialog); + void ShowModalDialog(JavaScriptAppModalDialog* dialog); // Returns the next dialog to show. This removes entries from // app_modal_dialog_queue_ until one is valid or the queue is empty. This - // returns NULL if there are no more dialogs, or all the dialogs in the queue - // are not valid. - AppModalDialog* GetNextDialog(); + // returns nullptr if there are no more dialogs, or all the dialogs in the + // queue are not valid. + JavaScriptAppModalDialog* GetNextDialog(); // Contains all app modal dialogs which are waiting to be shown. The currently // active modal dialog is not included. - std::deque<AppModalDialog*> app_modal_dialog_queue_; + std::deque<JavaScriptAppModalDialog*> app_modal_dialog_queue_; - // The currently active app-modal dialog box's delegate. NULL if there is no - // active app-modal dialog box. - AppModalDialog* active_dialog_; + // The currently active app-modal dialog box. nullptr if there is no active + // app-modal dialog box. + JavaScriptAppModalDialog* active_dialog_; // Stores if |ShowModalDialog()| is currently being called on an app-modal // dialog.
diff --git a/components/app_modal/javascript_app_modal_dialog.cc b/components/app_modal/javascript_app_modal_dialog.cc index dd58080..2e2ec520 100644 --- a/components/app_modal/javascript_app_modal_dialog.cc +++ b/components/app_modal/javascript_app_modal_dialog.cc
@@ -7,13 +7,17 @@ #include "base/metrics/histogram_macros.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/app_modal/app_modal_dialog_queue.h" #include "components/app_modal/javascript_dialog_manager.h" #include "components/app_modal/javascript_native_dialog_factory.h" +#include "components/app_modal/native_app_modal_dialog.h" #include "ui/gfx/text_elider.h" namespace app_modal { namespace { +AppModalDialogObserver* app_modal_dialog_observer = nullptr; + // Control maximum sizes of various texts passed to us from javascript. #if defined(OS_POSIX) && !defined(OS_MACOSX) // Two-dimensional eliding. Reformat the text of the message dialog @@ -66,7 +70,11 @@ bool is_before_unload_dialog, bool is_reload, const content::JavaScriptDialogManager::DialogClosedCallback& callback) - : AppModalDialog(web_contents, title), + : title_(title), + completed_(false), + valid_(true), + native_dialog_(nullptr), + web_contents_(web_contents), extra_data_map_(extra_data_map), javascript_dialog_type_(javascript_dialog_type), display_suppress_checkbox_(display_suppress_checkbox), @@ -80,25 +88,46 @@ } JavaScriptAppModalDialog::~JavaScriptAppModalDialog() { + CompleteDialog(); } -NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() { - return JavaScriptDialogManager::GetInstance() - ->native_dialog_factory() - ->CreateNativeJavaScriptDialog(this); +void JavaScriptAppModalDialog::ShowModalDialog() { + native_dialog_ = JavaScriptDialogManager::GetInstance() + ->native_dialog_factory() + ->CreateNativeJavaScriptDialog(this); + native_dialog_->ShowAppModalDialog(); + if (app_modal_dialog_observer) + app_modal_dialog_observer->Notify(this); } -bool JavaScriptAppModalDialog::IsJavaScriptModalDialog() { - return true; +void JavaScriptAppModalDialog::ActivateModalDialog() { + DCHECK(native_dialog_); + native_dialog_->ActivateAppModalDialog(); +} + +void JavaScriptAppModalDialog::CloseModalDialog() { + DCHECK(native_dialog_); + native_dialog_->CloseAppModalDialog(); +} + +void JavaScriptAppModalDialog::CompleteDialog() { + if (!completed_) { + completed_ = true; + AppModalDialogQueue::GetInstance()->ShowNextDialog(); + } +} + +bool JavaScriptAppModalDialog::IsValid() { + return valid_; } void JavaScriptAppModalDialog::Invalidate() { - if (!IsValid()) + if (!valid_) return; - AppModalDialog::Invalidate(); + valid_ = false; CallDialogClosedCallback(false, base::string16()); - if (native_dialog()) + if (native_dialog_) CloseModalDialog(); } @@ -138,7 +167,7 @@ void JavaScriptAppModalDialog::NotifyDelegate(bool success, const base::string16& user_input, bool suppress_js_messages) { - if (!IsValid()) + if (!valid_) return; CallDialogClosedCallback(success, user_input); @@ -146,7 +175,7 @@ // The close callback above may delete web_contents_, thus removing the extra // data from the map owned by ::JavaScriptDialogManager. Make sure // to only use the data if still present. http://crbug.com/236476 - ExtraDataMap::iterator extra_data = extra_data_map_->find(web_contents()); + ExtraDataMap::iterator extra_data = extra_data_map_->find(web_contents_); if (extra_data != extra_data_map_->end()) { extra_data->second.has_already_shown_a_dialog_ = true; extra_data->second.suppress_javascript_messages_ = suppress_js_messages; @@ -154,14 +183,14 @@ // On Views, we can end up coming through this code path twice :(. // See crbug.com/63732. - AppModalDialog::Invalidate(); + valid_ = false; } void JavaScriptAppModalDialog::CallDialogClosedCallback(bool success, const base::string16& user_input) { // TODO(joenotcharles): Both the callers of this function also check IsValid - // and call AppModalDialog::Invalidate, but in different orders. If the - // difference is not significant, more common code could be moved here. + // and call Invalidate, but in different orders. If the difference is not + // significant, more common code could be moved here. UMA_HISTOGRAM_MEDIUM_TIMES( "JSDialogs.FineTiming.TimeBetweenDialogCreatedAndSameDialogClosed", base::TimeTicks::Now() - creation_time_); @@ -171,4 +200,14 @@ } } +AppModalDialogObserver::AppModalDialogObserver() { + DCHECK(!app_modal_dialog_observer); + app_modal_dialog_observer = this; +} + +AppModalDialogObserver::~AppModalDialogObserver() { + DCHECK(app_modal_dialog_observer); + app_modal_dialog_observer = nullptr; +} + } // namespace app_modal
diff --git a/components/app_modal/javascript_app_modal_dialog.h b/components/app_modal/javascript_app_modal_dialog.h index a87febde9f..06269e1 100644 --- a/components/app_modal/javascript_app_modal_dialog.h +++ b/components/app_modal/javascript_app_modal_dialog.h
@@ -10,11 +10,12 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/time/time.h" -#include "components/app_modal/app_modal_dialog.h" #include "content/public/browser/javascript_dialog_manager.h" namespace app_modal { +class NativeAppModalDialog; + // Extra data for JavaScript dialogs to add Chrome-only features. class ChromeJavaScriptDialogExtraData { public: @@ -32,7 +33,7 @@ // A controller + model class for JavaScript alert, confirm, prompt, and // onbeforeunload dialog boxes. -class JavaScriptAppModalDialog : public AppModalDialog { +class JavaScriptAppModalDialog { public: typedef std::map<void*, ChromeJavaScriptDialogExtraData> ExtraDataMap; @@ -47,12 +48,26 @@ bool is_before_unload_dialog, bool is_reload, const content::JavaScriptDialogManager::DialogClosedCallback& callback); - ~JavaScriptAppModalDialog() override; + ~JavaScriptAppModalDialog(); - // Overridden from AppModalDialog: - NativeAppModalDialog* CreateNativeDialog() override; - bool IsJavaScriptModalDialog() override; - void Invalidate() override; + // Called by the AppModalDialogQueue to show this dialog. + void ShowModalDialog(); + + // Called by the AppModalDialogQueue to activate the dialog. + void ActivateModalDialog(); + + // Closes the dialog if it is showing. + void CloseModalDialog(); + + // Returns true if the dialog is still valid. As dialogs are created they are + // added to the AppModalDialogQueue. When the current modal dialog finishes + // and it's time to show the next dialog in the queue IsValid is invoked. + // If IsValid returns false the dialog is deleted and not shown. + bool IsValid(); + + // Invalidates the dialog, therefore causing it to not be shown when its turn + // to be shown comes around. + void Invalidate(); // Callbacks from NativeDialog when the user accepts or cancels the dialog. void OnCancel(bool suppress_js_messages); @@ -66,7 +81,10 @@ // its delegate instead of whatever the UI reports. void SetOverridePromptText(const base::string16& prompt_text); - // Accessors + // Accessors. + base::string16 title() const { return title_; } + NativeAppModalDialog* native_dialog() const { return native_dialog_; } + content::WebContents* web_contents() const { return web_contents_; } content::JavaScriptDialogType javascript_dialog_type() const { return javascript_dialog_type_; } @@ -84,6 +102,26 @@ void CallDialogClosedCallback(bool success, const base::string16& prompt_text); + // Completes dialog handling, shows next modal dialog from the queue. + // TODO(beng): Get rid of this method. + void CompleteDialog(); + + // The title of the dialog. + base::string16 title_; + + // // True if CompleteDialog was called. + bool completed_; + + // False if the dialog should no longer be shown, e.g. because the underlying + // tab navigated away while the dialog was queued. + bool valid_; + + // // The toolkit-specific implementation of the app modal dialog box. + NativeAppModalDialog* native_dialog_; + + // The WebContents that opened this dialog. + content::WebContents* web_contents_; + // A map of extra Chrome-only data associated with the delegate_. Can be // inspected via |extra_data_map_[web_contents_]|. ExtraDataMap* extra_data_map_; @@ -108,6 +146,19 @@ DISALLOW_COPY_AND_ASSIGN(JavaScriptAppModalDialog); }; +// An interface to observe that a modal dialog is shown. +class AppModalDialogObserver { + public: + AppModalDialogObserver(); + virtual ~AppModalDialogObserver(); + + // Called when the modal dialog is shown. + virtual void Notify(JavaScriptAppModalDialog* dialog) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver); +}; + } // namespace app_modal #endif // COMPONENTS_APP_MODAL_JAVASCRIPT_APP_MODAL_DIALOG_H_
diff --git a/components/app_modal/javascript_dialog_manager.cc b/components/app_modal/javascript_dialog_manager.cc index c5a3683..de3674c 100644 --- a/components/app_modal/javascript_dialog_manager.cc +++ b/components/app_modal/javascript_dialog_manager.cc
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" -#include "components/app_modal/app_modal_dialog.h" #include "components/app_modal/app_modal_dialog_queue.h" #include "components/app_modal/javascript_dialog_extensions_client.h" #include "components/app_modal/javascript_native_dialog_factory.h" @@ -244,7 +243,6 @@ const base::string16* prompt_override) { AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance(); if (!dialog_queue->HasActiveDialog() || - !dialog_queue->active_dialog()->IsJavaScriptModalDialog() || dialog_queue->active_dialog()->web_contents() != web_contents) { return false; } @@ -272,15 +270,14 @@ void JavaScriptDialogManager::CancelDialogs(content::WebContents* web_contents, bool reset_state) { AppModalDialogQueue* queue = AppModalDialogQueue::GetInstance(); - AppModalDialog* active_dialog = queue->active_dialog(); - for (AppModalDialogQueue::iterator i = queue->begin(); - i != queue->end(); ++i) { + JavaScriptAppModalDialog* active_dialog = queue->active_dialog(); + for (auto* dialog : *queue) { // Invalidating the active dialog might trigger showing a not-yet // invalidated dialog, so invalidate the active dialog last. - if ((*i) == active_dialog) + if (dialog == active_dialog) continue; - if ((*i)->web_contents() == web_contents) - (*i)->Invalidate(); + if (dialog->web_contents() == web_contents) + dialog->Invalidate(); } if (active_dialog && active_dialog->web_contents() == web_contents) active_dialog->Invalidate();
diff --git a/components/autofill/core/browser/credit_card.h b/components/autofill/core/browser/credit_card.h index 6dd2b3e..5b1ba15 100644 --- a/components/autofill/core/browser/credit_card.h +++ b/components/autofill/core/browser/credit_card.h
@@ -215,14 +215,14 @@ base::string16 GetLastUsedDateForDisplay(const std::string& app_locale) const; // Formatted expiration date (e.g., 05/2020). base::string16 ExpirationDateForDisplay() const; + // Expiration functions. + base::string16 ExpirationMonthAsString() const; + base::string16 Expiration4DigitYearAsString() const; private: FRIEND_TEST_ALL_PREFIXES(CreditCardTest, SetExpirationDateFromString); FRIEND_TEST_ALL_PREFIXES(CreditCardTest, SetExpirationYearFromString); - // Private display functions. - base::string16 ExpirationMonthAsString() const; - base::string16 Expiration4DigitYearAsString() const; base::string16 Expiration2DigitYearAsString() const; // FormGroup:
diff --git a/components/autofill/core/browser/validation.cc b/components/autofill/core/browser/validation.cc index a2d3e25f..4588a13b 100644 --- a/components/autofill/core/browser/validation.cc +++ b/components/autofill/core/browser/validation.cc
@@ -154,11 +154,11 @@ base::string16 GetCompletionMessageForCard(CreditCardCompletionStatus status) { switch (status) { + // No message is shown for complete or expired card (which will be fixable) + // in the CVC screen. case CREDIT_CARD_COMPLETE: - return base::string16(); case CREDIT_CARD_EXPIRED: - return l10n_util::GetStringUTF16( - IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED); + return base::string16(); case CREDIT_CARD_NO_CARDHOLDER: return l10n_util::GetStringUTF16(IDS_PAYMENTS_NAME_ON_CARD_REQUIRED); case CREDIT_CARD_NO_NUMBER:
diff --git a/components/component_updater/default_component_installer.cc b/components/component_updater/default_component_installer.cc index 6cdca7ed..62842079 100644 --- a/components/component_updater/default_component_installer.cc +++ b/components/component_updater/default_component_installer.cc
@@ -11,7 +11,9 @@ #include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "base/location.h" +#include "base/macros.h" #include "base/path_service.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" @@ -116,6 +118,11 @@ VLOG(1) << "Install: version=" << version.GetString() << " current version=" << current_version_.GetString(); + // Take the ownership of the |unpack_path| to enforce its deletion. + DCHECK(DirectoryExists(unpack_path)); + base::ScopedTempDir unpack_path_owner; + ignore_result(unpack_path_owner.Set(unpack_path)); + if (!version.IsValid()) return Result(InstallError::INVALID_VERSION); if (current_version_.CompareTo(version) > 0) @@ -134,6 +141,10 @@ base::DeleteFile(install_path, true); return result; } + + // If install has been successful, the installer has deleted the unpack path. + DCHECK(!base::PathExists(unpack_path)); + current_version_ = version; current_install_dir_ = install_path; // TODO(ddorwin): Change parameter to std::unique_ptr<base::DictionaryValue>
diff --git a/components/component_updater/default_component_installer_unittest.cc b/components/component_updater/default_component_installer_unittest.cc index 278e3aa..d012be1 100644 --- a/components/component_updater/default_component_installer_unittest.cc +++ b/components/component_updater/default_component_installer_unittest.cc
@@ -8,16 +8,23 @@ #include <vector> #include "base/callback.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" +#include "base/path_service.h" #include "base/run_loop.h" #include "base/task_scheduler/post_task.h" +#include "base/test/scoped_path_override.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/version.h" +#include "components/component_updater/component_updater_paths.h" #include "components/component_updater/component_updater_service.h" #include "components/component_updater/component_updater_service_internal.h" #include "components/component_updater/default_component_installer.h" +#include "components/update_client/component_unpacker.h" #include "components/update_client/crx_update_item.h" #include "components/update_client/test_configurator.h" #include "components/update_client/update_client.h" @@ -25,6 +32,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ComponentUnpacker = update_client::ComponentUnpacker; using Configurator = update_client::Configurator; using CrxUpdateItem = update_client::CrxUpdateItem; using TestConfigurator = update_client::TestConfigurator; @@ -43,6 +51,19 @@ 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, 0xf6, 0xc4, 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; +constexpr base::FilePath::CharType relative_install_dir[] = + FILE_PATH_LITERAL("fake"); + +base::FilePath test_file(const char* file) { + base::FilePath path; + PathService::Get(base::DIR_SOURCE_ROOT, &path); + return path.AppendASCII("components") + .AppendASCII("test") + .AppendASCII("data") + .AppendASCII("update_client") + .AppendASCII(file); +} + class MockUpdateClient : public UpdateClient { public: MockUpdateClient() {} @@ -72,6 +93,7 @@ class FakeInstallerTraits : public ComponentInstallerTraits { public: + FakeInstallerTraits() {} ~FakeInstallerTraits() override {} bool VerifyInstallation(const base::DictionaryValue& manifest, @@ -97,7 +119,7 @@ std::unique_ptr<base::DictionaryValue> manifest) override {} base::FilePath GetRelativeInstallDir() const override { - return base::FilePath(FILE_PATH_LITERAL("fake")); + return base::FilePath(relative_install_dir); } void GetHash(std::vector<uint8_t>* hash) const override { GetPkHash(hash); } @@ -135,15 +157,22 @@ protected: void RunThreads(); + void Unpack(const base::FilePath& crx_path); + ComponentUnpacker::Result result() const { return result_; } private: + void UnpackComplete(const ComponentUnpacker::Result& result); + base::test::ScopedTaskEnvironment scoped_task_environment_; + const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_ = + base::ThreadTaskRunnerHandle::Get(); base::RunLoop runloop_; base::Closure quit_closure_; scoped_refptr<TestConfigurator> config_; scoped_refptr<MockUpdateClient> update_client_; std::unique_ptr<ComponentUpdateService> component_updater_; + ComponentUnpacker::Result result_; }; DefaultComponentInstallerTest::DefaultComponentInstallerTest() @@ -151,13 +180,14 @@ base::test::ScopedTaskEnvironment::MainThreadType::UI) { quit_closure_ = runloop_.QuitClosure(); - config_ = new TestConfigurator( + config_ = base::MakeRefCounted<TestConfigurator>( base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}), base::ThreadTaskRunnerHandle::Get()); - update_client_ = new MockUpdateClient(); + update_client_ = base::MakeRefCounted<MockUpdateClient>(); EXPECT_CALL(update_client(), AddObserver(_)).Times(1); - component_updater_.reset(new CrxUpdateService(config_, update_client_)); + component_updater_ = + base::MakeUnique<CrxUpdateService>(config_, update_client_); } DefaultComponentInstallerTest::~DefaultComponentInstallerTest() { @@ -169,6 +199,25 @@ runloop_.Run(); } +void DefaultComponentInstallerTest::Unpack(const base::FilePath& crx_path) { + auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>( + std::vector<uint8_t>(std::begin(kSha256Hash), std::end(kSha256Hash)), + crx_path, nullptr, nullptr, config_->GetSequencedTaskRunner()); + component_unpacker->Unpack(base::Bind( + &DefaultComponentInstallerTest::UnpackComplete, base::Unretained(this))); + RunThreads(); +} + +void DefaultComponentInstallerTest::UnpackComplete( + const ComponentUnpacker::Result& result) { + result_ = result; + + EXPECT_EQ(update_client::UnpackerError::kNone, result_.error); + EXPECT_EQ(0, result_.extended_error); + + main_thread_task_runner_->PostTask(FROM_HERE, quit_closure_); +} + } // namespace // Tests that the component metadata is propagated from the default @@ -205,10 +254,8 @@ EXPECT_CALL(update_client(), GetCrxUpdateState(id, _)).Times(1); EXPECT_CALL(update_client(), Stop()).Times(1); - std::unique_ptr<ComponentInstallerTraits> traits(new FakeInstallerTraits()); - - DefaultComponentInstaller* installer = - new DefaultComponentInstaller(std::move(traits)); + auto installer = base::MakeRefCounted<DefaultComponentInstaller>( + base::MakeUnique<FakeInstallerTraits>()); installer->Register(component_updater(), base::Closure()); RunThreads(); @@ -232,4 +279,55 @@ EXPECT_TRUE(component.supports_group_policy_enable_component_updates); } +// Tests that the unpack path is removed when the install succeeded. +TEST_F(DefaultComponentInstallerTest, UnpackPathInstallSuccess) { + auto installer = base::MakeRefCounted<DefaultComponentInstaller>( + base::MakeUnique<FakeInstallerTraits>()); + + Unpack(test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); + + const auto unpack_path = result().unpack_path; + EXPECT_TRUE(base::DirectoryExists(unpack_path)); + + const auto manifest = update_client::ReadManifest(unpack_path); + + base::ScopedPathOverride scoped_path_override(DIR_COMPONENT_USER); + base::FilePath base_dir; + EXPECT_TRUE(PathService::Get(DIR_COMPONENT_USER, &base_dir)); + base_dir = base_dir.Append(relative_install_dir); + EXPECT_TRUE(base::CreateDirectory(base_dir)); + const auto result = installer->Install(*manifest, unpack_path); + EXPECT_EQ(0, result.error); + EXPECT_FALSE(base::PathExists(unpack_path)); + + EXPECT_CALL(update_client(), Stop()).Times(1); +} + +// Tests that the unpack path is removed when the install failed. +TEST_F(DefaultComponentInstallerTest, UnpackPathInstallError) { + auto installer = base::MakeRefCounted<DefaultComponentInstaller>( + base::MakeUnique<FakeInstallerTraits>()); + + Unpack(test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); + + const auto unpack_path = result().unpack_path; + EXPECT_TRUE(base::DirectoryExists(unpack_path)); + + const auto manifest = update_client::ReadManifest(unpack_path); + + // Test the precondition that DIR_COMPONENT_USER is not registered with + // the path service. + base::FilePath base_dir; + EXPECT_FALSE(PathService::Get(DIR_COMPONENT_USER, &base_dir)); + + // Calling |Install| fails since DIR_COMPONENT_USER does not exist. + const auto result = installer->Install(*manifest, unpack_path); + EXPECT_EQ( + static_cast<int>(update_client::InstallError::NO_DIR_COMPONENT_USER), + result.error); + EXPECT_FALSE(base::PathExists(unpack_path)); + + EXPECT_CALL(update_client(), Stop()).Times(1); +} + } // namespace component_updater
diff --git a/components/favicon/core/BUILD.gn b/components/favicon/core/BUILD.gn index b4d4a79e..ecccff0c 100644 --- a/components/favicon/core/BUILD.gn +++ b/components/favicon/core/BUILD.gn
@@ -43,14 +43,6 @@ "//ui/gfx", "//url", ] - if (!is_ios) { - deps += [ "//cc/paint" ] - sources += [ - "fallback_icon_client.h", - "fallback_icon_service.cc", - "fallback_icon_service.h", - ] - } } source_set("unit_tests") {
diff --git a/components/favicon/core/fallback_icon_client.h b/components/favicon/core/fallback_icon_client.h deleted file mode 100644 index 8efa28c2..0000000 --- a/components/favicon/core/fallback_icon_client.h +++ /dev/null
@@ -1,28 +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 COMPONENTS_FAVICON_CORE_FALLBACK_ICON_CLIENT_H_ -#define COMPONENTS_FAVICON_CORE_FALLBACK_ICON_CLIENT_H_ - -#include <string> -#include <vector> - -#include "components/keyed_service/core/keyed_service.h" - -namespace favicon { - -// This class abstracts operations that depend on the embedder's environment, -// e.g. Chrome. -class FallbackIconClient : public KeyedService { - public: - // Returns a list of font names for fallback icon rendering. - virtual const std::vector<std::string>& GetFontNameList() const = 0; - - protected: - ~FallbackIconClient() override {} -}; - -} // namespace favicon - -#endif // COMPONENTS_FAVICON_CORE_FALLBACK_ICON_CLIENT_H_
diff --git a/components/favicon/core/fallback_icon_service.cc b/components/favicon/core/fallback_icon_service.cc deleted file mode 100644 index 291e1fa..0000000 --- a/components/favicon/core/fallback_icon_service.cc +++ /dev/null
@@ -1,90 +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 "components/favicon/core/fallback_icon_service.h" - -#include <stddef.h> - -#include <algorithm> - -#include "cc/paint/skia_paint_canvas.h" -#include "components/favicon/core/fallback_icon_client.h" -#include "components/favicon/core/fallback_url_util.h" -#include "components/favicon_base/fallback_icon_style.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size.h" -#include "url/gurl.h" - -namespace favicon { -namespace { - -// Arbitrary maximum icon size, can be reasonably increased if needed. -const int kMaxFallbackFaviconSize = 288; - -} // namespace - -FallbackIconService::FallbackIconService( - FallbackIconClient* fallback_icon_client) - : fallback_icon_client_(fallback_icon_client) { -} - -FallbackIconService::~FallbackIconService() { -} - -std::vector<unsigned char> FallbackIconService::RenderFallbackIconBitmap( - const GURL& icon_url, - int size, - const favicon_base::FallbackIconStyle& style) { - int size_to_use = std::min(kMaxFallbackFaviconSize, size); - SkBitmap bitmap; - bitmap.allocN32Pixels(size_to_use, size_to_use, false); - cc::SkiaPaintCanvas paint_canvas(bitmap); - gfx::Canvas canvas(&paint_canvas, 1.f); - - DrawFallbackIcon(icon_url, size_to_use, style, &canvas); - - std::vector<unsigned char> bitmap_data; - if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data)) - bitmap_data.clear(); - return bitmap_data; -} - -void FallbackIconService::DrawFallbackIcon( - const GURL& icon_url, - int size, - const favicon_base::FallbackIconStyle& style, - gfx::Canvas* canvas) { - const int kOffsetX = 0; - const int kOffsetY = 0; - cc::PaintFlags flags; - flags.setStyle(cc::PaintFlags::kFill_Style); - flags.setAntiAlias(true); - - // Draw a filled, colored rounded square. - flags.setColor(style.background_color); - int corner_radius = static_cast<int>(size * style.roundness * 0.5 + 0.5); - canvas->DrawRoundRect(gfx::Rect(kOffsetX, kOffsetY, size, size), - corner_radius, flags); - - // Draw text. - base::string16 icon_text = GetFallbackIconText(icon_url); - if (icon_text.empty()) - return; - int font_size = static_cast<int>(size * style.font_size_ratio); - if (font_size <= 0) - return; - - canvas->DrawStringRectWithFlags( - icon_text, - gfx::FontList(fallback_icon_client_->GetFontNameList(), gfx::Font::NORMAL, - font_size, gfx::Font::Weight::NORMAL), - style.text_color, gfx::Rect(kOffsetX, kOffsetY, size, size), - gfx::Canvas::TEXT_ALIGN_CENTER); -} - -} // namespace favicon
diff --git a/components/favicon/core/fallback_icon_service.h b/components/favicon/core/fallback_icon_service.h deleted file mode 100644 index 56b155e..0000000 --- a/components/favicon/core/fallback_icon_service.h +++ /dev/null
@@ -1,55 +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 COMPONENTS_FAVICON_CORE_FALLBACK_ICON_SERVICE_H_ -#define COMPONENTS_FAVICON_CORE_FALLBACK_ICON_SERVICE_H_ - -#include <vector> - -#include "base/macros.h" -#include "components/keyed_service/core/keyed_service.h" - -class GURL; - -namespace gfx { -class Canvas; -} - -namespace favicon_base { -struct FallbackIconStyle; -} - -namespace favicon { - -class FallbackIconClient; - -// A service to provide methods to render fallback favicons. -class FallbackIconService : public KeyedService { - public: - explicit FallbackIconService(FallbackIconClient* fallback_icon_client); - ~FallbackIconService() override; - - // Renders a fallback icon synchronously and returns the bitmap. Returns an - // empty std::vector on failure. |size| is icon width and height in pixels. - std::vector<unsigned char> RenderFallbackIconBitmap( - const GURL& icon_url, - int size, - const favicon_base::FallbackIconStyle& style); - - private: - // Renders a fallback icon on |canvas| at position (|x|, |y|). |size| is icon - // width and height in pixels. - void DrawFallbackIcon(const GURL& icon_url, - int size, - const favicon_base::FallbackIconStyle& style, - gfx::Canvas* canvas); - - FallbackIconClient* fallback_icon_client_; - - DISALLOW_COPY_AND_ASSIGN(FallbackIconService); -}; - -} // namespace favicon - -#endif // COMPONENTS_FAVICON_CORE_FALLBACK_ICON_SERVICE_H_
diff --git a/components/favicon_base/BUILD.gn b/components/favicon_base/BUILD.gn index 3050e5ca..57e743e 100644 --- a/components/favicon_base/BUILD.gn +++ b/components/favicon_base/BUILD.gn
@@ -6,8 +6,6 @@ sources = [ "fallback_icon_style.cc", "fallback_icon_style.h", - "fallback_icon_url_parser.cc", - "fallback_icon_url_parser.h", "favicon_callback.h", "favicon_types.cc", "favicon_types.h", @@ -40,7 +38,6 @@ source_set("unit_tests") { testonly = true sources = [ - "fallback_icon_url_parser_unittest.cc", "favicon_url_parser_unittest.cc", "large_icon_url_parser_unittest.cc", "select_favicon_frames_unittest.cc",
diff --git a/components/favicon_base/fallback_icon_style.cc b/components/favicon_base/fallback_icon_style.cc index cbb478b1..c85d768 100644 --- a/components/favicon_base/fallback_icon_style.cc +++ b/components/favicon_base/fallback_icon_style.cc
@@ -13,10 +13,6 @@ namespace { -// Luma threshold for background color determine whether to use dark or light -// text color. -const uint8_t kDarkTextLumaThreshold = 190; - // The maximum lightness of the background color to ensure light text is // readable. const double kMaxBackgroundColorLightness = 0.67; @@ -24,20 +20,14 @@ // Default values for FallbackIconStyle. const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78); -const SkColor kDefaultTextColorDark = SK_ColorBLACK; -const SkColor kDefaultTextColorLight = SK_ColorWHITE; -const double kDefaultFontSizeRatio = 0.44; -const double kDefaultRoundness = 0; // Square. Round corners are applied - // externally (Javascript or Java). +const SkColor kDefaultTextColor = SK_ColorWHITE; } // namespace FallbackIconStyle::FallbackIconStyle() : background_color(kDefaultBackgroundColor), is_default_background_color(true), - text_color(kDefaultTextColorLight), - font_size_ratio(kDefaultFontSizeRatio), - roundness(kDefaultRoundness) {} + text_color(kDefaultTextColor) {} FallbackIconStyle::~FallbackIconStyle() { } @@ -45,21 +35,7 @@ bool FallbackIconStyle::operator==(const FallbackIconStyle& other) const { return background_color == other.background_color && is_default_background_color == other.is_default_background_color && - text_color == other.text_color && - font_size_ratio == other.font_size_ratio && - roundness == other.roundness; -} - -void MatchFallbackIconTextColorAgainstBackgroundColor( - FallbackIconStyle* style) { - const uint8_t luma = color_utils::GetLuma(style->background_color); - style->text_color = (luma >= kDarkTextLumaThreshold) ? - kDefaultTextColorDark : kDefaultTextColorLight; -} - -bool ValidateFallbackIconStyle(const FallbackIconStyle& style) { - return style.font_size_ratio >= 0.0 && style.font_size_ratio <= 1.0 && - style.roundness >= 0.0 && style.roundness <= 1.0; + text_color == other.text_color; } void SetDominantColorAsBackground(
diff --git a/components/favicon_base/fallback_icon_style.h b/components/favicon_base/fallback_icon_style.h index 9257730..0680d54 100644 --- a/components/favicon_base/fallback_icon_style.h +++ b/components/favicon_base/fallback_icon_style.h
@@ -17,8 +17,6 @@ FallbackIconStyle(); ~FallbackIconStyle(); - // If any member changes, also update FallbackIconStyleBuilder. - // Icon background fill color. SkColor background_color; bool is_default_background_color; @@ -26,21 +24,9 @@ // Icon text color. SkColor text_color; - // Ratio in [0.0, 1.0] of the text font size (pixels) to the icon size. - double font_size_ratio; - - // The roundness of the icon's corners. 0 => square icon, 1 => circle icon. - double roundness; - bool operator==(const FallbackIconStyle& other) const; }; -// Reassigns |style|'s |text_color| to matches well against |background_color|. -void MatchFallbackIconTextColorAgainstBackgroundColor(FallbackIconStyle* style); - -// Returns whether |style| values are within bounds. -bool ValidateFallbackIconStyle(const FallbackIconStyle& style); - // Set |style|'s background color to the dominant color of |bitmap_data|, // clamping luminance down to a reasonable maximum value so that light text is // readable.
diff --git a/components/favicon_base/fallback_icon_url_parser.cc b/components/favicon_base/fallback_icon_url_parser.cc deleted file mode 100644 index 214c88ff9..0000000 --- a/components/favicon_base/fallback_icon_url_parser.cc +++ /dev/null
@@ -1,142 +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 "components/favicon_base/fallback_icon_url_parser.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "third_party/skia/include/utils/SkParse.h" -#include "ui/gfx/favicon_size.h" - -namespace { - -// List of sizes corresponding to RGB, ARGB, RRGGBB, AARRGGBB. -const size_t kValidHexColorSizes[] = {3, 4, 6, 8}; - -// Returns whether |color_str| is a valid CSS color in hex format if we prepend -// '#', i.e., whether |color_str| matches /^[0-9A-Fa-f]{3,4,6,8}$/. -bool IsHexColorString(const std::string& color_str) { - size_t len = color_str.length(); - const size_t* end = kValidHexColorSizes + arraysize(kValidHexColorSizes); - if (std::find(kValidHexColorSizes, end, len) == end) - return false; - for (auto ch : color_str) { - if (!base::IsHexDigit(ch)) - return false; - } - return true; -} - -} // namespace - -namespace chrome { - -ParsedFallbackIconPath::ParsedFallbackIconPath() - : size_in_pixels_(gfx::kFaviconSize) { -} - -ParsedFallbackIconPath::~ParsedFallbackIconPath() { -} - -bool ParsedFallbackIconPath::Parse(const std::string& path) { - if (path.empty()) - return false; - - size_t slash = path.find("/", 0); - if (slash == std::string::npos) - return false; - std::string spec_str = path.substr(0, slash); - if (!ParseSpecs(spec_str, &size_in_pixels_, &style_)) - return false; // Parse failed. - - // Need to store the index of the URL field, so Instant Extended can translate - // fallback icon URLs using advanced parameters. - // Example: - // "chrome-search://fallback-icon/48/<renderer-id>/<most-visited-id>" - // would be translated to: - // "chrome-search://fallback-icon/48/<most-visited-item-with-given-id>". - path_index_ = slash + 1; - url_string_ = path.substr(path_index_); - return true; -} - -// static -bool ParsedFallbackIconPath::ParseSpecs( - const std::string& specs_str, - int *size, - favicon_base::FallbackIconStyle* style) { - DCHECK(size); - DCHECK(style); - - std::vector<std::string> tokens = base::SplitString( - specs_str, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); - if (tokens.size() != 5) // Force "," for empty fields. - return false; - - *size = gfx::kFaviconSize; - if (!tokens[0].empty() && !base::StringToInt(tokens[0], size)) - return false; - if (*size <= 0) - return false; - - *style = favicon_base::FallbackIconStyle(); - - if (!tokens[1].empty()) { - style->is_default_background_color = false; - if (!ParseColor(tokens[1], &style->background_color)) - return false; - } - - if (tokens[2].empty()) - favicon_base::MatchFallbackIconTextColorAgainstBackgroundColor(style); - else if (!ParseColor(tokens[2], &style->text_color)) - return false; - - if (!tokens[3].empty() && - !base::StringToDouble(tokens[3], &style->font_size_ratio)) - return false; - - if (!tokens[4].empty() && !base::StringToDouble(tokens[4], &style->roundness)) - return false; - - return favicon_base::ValidateFallbackIconStyle(*style); -} - -// static -bool ParsedFallbackIconPath::ParseColor(const std::string& color_str, - SkColor* color) { - DCHECK(color); - // Exclude the empty case. Also disallow the '#' prefix, since we want color - // to be part of an URL, but in URL '#' is used for ref fragment. - if (color_str.empty() || color_str[0] == '#') - return false; - - // If a valid color hex string is given, prepend '#' and parse (always works). - // This is unambiguous since named color never only use leters 'a' to 'f'. - if (IsHexColorString(color_str)) { - // Default alpha to 0xFF since FindColor() preserves unspecified alpha. - *color = SK_ColorWHITE; - // Need temp variable to avoid use-after-free of returned pointer. - std::string color_str_with_hash = "#" + color_str; - const char* end = SkParse::FindColor(color_str_with_hash.c_str(), color); - DCHECK(end && !*end); // Call should succeed and consume string. - return true; - } - - // Default alpha to 0xFF. - SkColor temp_color = SK_ColorWHITE; - const char* end = SkParse::FindColor(color_str.c_str(), &temp_color); - if (end && !*end) { // Successful if call succeeds and string is consumed. - *color = temp_color; - return true; - } - return false; -} - -} // namespace chrome
diff --git a/components/favicon_base/fallback_icon_url_parser.h b/components/favicon_base/fallback_icon_url_parser.h deleted file mode 100644 index 39a79fc3..0000000 --- a/components/favicon_base/fallback_icon_url_parser.h +++ /dev/null
@@ -1,74 +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 COMPONENTS_FAVICON_BASE_FALLBACK_ICON_URL_PARSER_H_ -#define COMPONENTS_FAVICON_BASE_FALLBACK_ICON_URL_PARSER_H_ - -#include <stddef.h> - -#include <string> - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "components/favicon_base/fallback_icon_style.h" -#include "third_party/skia/include/core/SkColor.h" - -namespace chrome { - -class ParsedFallbackIconPath { - public: - ParsedFallbackIconPath(); - ~ParsedFallbackIconPath(); - - const std::string& url_string() const { return url_string_; } - - int size_in_pixels() const { return size_in_pixels_; } - - const favicon_base::FallbackIconStyle& style() const { return style_; } - - size_t path_index() const { return path_index_; } - - // Parses |path|, which should be in the format described at the top of the - // file "chrome/browser/ui/webui/fallback_icon_source.h". - bool Parse(const std::string& path); - - private: - // Parses |specs_str|, which should be the comma-separated value portion - // in the format described at the top of the file - // "chrome/browser/ui/webui/fallback_icon_source.h". - static bool ParseSpecs(const std::string& specs_str, - int *size, - favicon_base::FallbackIconStyle* style); - - // Helper to parse color string (e.g., "red", "#f00", "#aB0137"). On success, - // returns true and writes te result to |*color|. - static bool ParseColor(const std::string& color_str, SkColor* color); - - friend class FallbackIconUrlParserTest; - FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseColorSuccess); - FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseColorFailure); - FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsEmpty); - FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsPartial); - FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsFull); - FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsFailure); - - // The page URL string the fallback icon is requested for. - std::string url_string_; - - // The size of the requested fallback icon in pixels. - int size_in_pixels_; - - // Styling specifications of fallback icon. - favicon_base::FallbackIconStyle style_; - - // The index of the first character (relative to the path) where the the URL - // from which the fallback icon is being requested is located. - size_t path_index_; - - DISALLOW_COPY_AND_ASSIGN(ParsedFallbackIconPath); -}; - -} // namespace chrome - -#endif // COMPONENTS_FAVICON_BASE_FALLBACK_ICON_URL_PARSER_H_
diff --git a/components/favicon_base/fallback_icon_url_parser_unittest.cc b/components/favicon_base/fallback_icon_url_parser_unittest.cc deleted file mode 100644 index 4dcb236a..0000000 --- a/components/favicon_base/fallback_icon_url_parser_unittest.cc +++ /dev/null
@@ -1,294 +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 "components/favicon_base/fallback_icon_url_parser.h" - -#include <stddef.h> - -#include "base/macros.h" -#include "components/favicon_base/fallback_icon_style.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/favicon_size.h" -#include "url/gurl.h" - -using chrome::ParsedFallbackIconPath; -using favicon_base::FallbackIconStyle; - -namespace chrome { - -namespace { - -// Default values for FallbackIconStyle, from -// /components/favicon_base/fallback_icon_style.h -const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78); -const SkColor kDefaultTextColorDark = SK_ColorBLACK; -const SkColor kDefaultTextColorLight = SK_ColorWHITE; -const double kDefaultFontSizeRatio = 0.44; -const double kDefaultRoundness = 0; - -const char kTestUrlStr[] = "https://www.google.ca/imghp?hl=en&tab=wi"; - -} // namespace - -class FallbackIconUrlParserTest : public testing::Test { - public: - FallbackIconUrlParserTest() { - } - - bool ParseSpecs(const std::string& specs_str, - int *size, - favicon_base::FallbackIconStyle* style) { - return ParsedFallbackIconPath::ParseSpecs(specs_str, size, style); - } - - bool ParseColor(const std::string& color_str, SkColor* color) { - return ParsedFallbackIconPath::ParseColor(color_str, color); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FallbackIconUrlParserTest); -}; - -TEST_F(FallbackIconUrlParserTest, ParseColorSuccess) { - SkColor c; - EXPECT_TRUE(ParseColor("31aBf0f4", &c)); - EXPECT_EQ(SkColorSetARGB(0x31, 0xAB, 0xF0, 0xF4), c); - EXPECT_TRUE(ParseColor("01aBf0", &c)); - EXPECT_EQ(SkColorSetRGB(0x01, 0xAB, 0xF0), c); - EXPECT_TRUE(ParseColor("501a", &c)); - EXPECT_EQ(SkColorSetARGB(0x55, 0x00, 0x11, 0xAA), c); - EXPECT_TRUE(ParseColor("01a", &c)); - EXPECT_EQ(SkColorSetRGB(0x00, 0x11, 0xAA), c); - EXPECT_TRUE(ParseColor("000000", &c)); - EXPECT_EQ(SkColorSetARGB(0xFF, 0x00, 0x00, 0x00), c); - EXPECT_TRUE(ParseColor("red", &c)); - EXPECT_EQ(SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00), c); -} - -TEST_F(FallbackIconUrlParserTest, ParseColorFailure) { - const char* test_cases[] = { - "", - "00000", - "000000000", - " 000000", - "ABCDEFG", - "#000", - "#000000", - "000000 ", - "ABCDEFH", - "#ABCDEF", - }; - for (size_t i = 0; i < arraysize(test_cases); ++i) { - SkColor c; - EXPECT_FALSE(ParseColor(test_cases[i], &c)) - << "test_cases[" << i << "]"; - } -} - -TEST_F(FallbackIconUrlParserTest, ParseSpecsEmpty) { - int size; - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs(",,,,", &size, &style)); - EXPECT_EQ(16, size); - EXPECT_EQ(kDefaultBackgroundColor, style.background_color); - EXPECT_TRUE(style.is_default_background_color); - EXPECT_EQ(kDefaultTextColorLight, style.text_color); - EXPECT_EQ(kDefaultFontSizeRatio, style.font_size_ratio); - EXPECT_EQ(kDefaultRoundness, style.roundness); -} - -TEST_F(FallbackIconUrlParserTest, ParseSpecsPartial) { - int size; - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs(",,aCE,,0.1", &size, &style)); - EXPECT_EQ(16, size); - EXPECT_EQ(kDefaultBackgroundColor, style.background_color); - EXPECT_TRUE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0xAA, 0xCC, 0xEE), style.text_color); - EXPECT_EQ(kDefaultFontSizeRatio, style.font_size_ratio); - EXPECT_EQ(0.1, style.roundness); -} - -TEST_F(FallbackIconUrlParserTest, ParseSpecsFull) { - int size; - - { - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs("16,000,f01,0.75,0.25", &size, &style)); - EXPECT_EQ(16, size); - EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); - EXPECT_FALSE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0xff, 0x00, 0x11), style.text_color); - EXPECT_EQ(0.75, style.font_size_ratio); - EXPECT_EQ(0.25, style.roundness); - } - - { - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs("48,black,123456,0.5,0.3", &size, &style)); - EXPECT_EQ(48, size); - EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); - EXPECT_FALSE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0x12, 0x34, 0x56), style.text_color); - EXPECT_EQ(0.5, style.font_size_ratio); - EXPECT_EQ(0.3, style.roundness); - } - - { - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs("1,000,red,0,0", &size, &style)); - EXPECT_EQ(1, size); - EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); - EXPECT_FALSE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0xFF, 0x00, 0x00), style.text_color); - EXPECT_EQ(0, style.font_size_ratio); - EXPECT_EQ(0, style.roundness); - } -} - -TEST_F(FallbackIconUrlParserTest, ParseSpecsDefaultTextColor) { - int size; - - { - // Dark background -> Light text. - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs(",000,,,", &size, &style)); - EXPECT_EQ(kDefaultTextColorLight, style.text_color); - } - - { - // Light background -> Dark text. - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs(",fff,,,", &size, &style)); - EXPECT_EQ(kDefaultTextColorDark, style.text_color); - } - - { - // Light background -> Dark text, more params don't matter. - FallbackIconStyle style; - EXPECT_TRUE(ParseSpecs("107,fff,,0.3,0.5", &size, &style)); - EXPECT_EQ(kDefaultTextColorDark, style.text_color); - } -} - -TEST_F(FallbackIconUrlParserTest, ParseSpecsFailure) { - const char* test_cases[] = { - // Need exactly 5 params. - "", - "16", - "16,black", - "16,black,fff", - "16,black,fff,0.75", - ",,," - ",,,,,", - "16,black,fff,0.75,0.25,junk", - // Don't allow any space. - "16,black,fff, 0.75,0.25", - "16,black ,fff,0.75,0.25", - "16,black,fff,0.75,0.25 ", - // Adding junk text. - "16,black,fff,0.75,0.25junk", - "junk,black,fff,0.75,0.25", - "16,#junk,fff,0.75,0.25", - "16,black,junk,0.75,0.25", - "16,black,fff,junk,0.25", - "16,black,fff,0.75,junk", - // Out of bound. - "0,black,fff,0.75,0.25", // size. - "4294967296,black,fff,0.75,0.25", // size. - "-1,black,fff,0.75,0.25", // size. - "16,black,fff,-0.1,0.25", // font_size_ratio. - "16,black,fff,1.1,0.25", // font_size_ratio. - "16,black,fff,0.75,-0.1", // roundness. - "16,black,fff,0.75,1.1", // roundness. - }; - for (size_t i = 0; i < arraysize(test_cases); ++i) { - int size; - FallbackIconStyle style; - EXPECT_FALSE(ParseSpecs(test_cases[i], &size, &style)) - << "test_cases[" << i << "]"; - - } -} - -TEST_F(FallbackIconUrlParserTest, ParseFallbackIconPathSuccess) { - const std::string specs = "31,black,fff,0.75,0.25"; - - // Everything populated. - { - chrome::ParsedFallbackIconPath parsed; - EXPECT_TRUE(parsed.Parse(specs + "/" + kTestUrlStr)); - EXPECT_EQ(31, parsed.size_in_pixels()); - const favicon_base::FallbackIconStyle& style = parsed.style(); - EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); - EXPECT_FALSE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0xFF, 0xFF, 0xFF), style.text_color); - EXPECT_EQ(0.75, style.font_size_ratio); - EXPECT_EQ(0.25, style.roundness); - EXPECT_EQ(GURL(kTestUrlStr), GURL(parsed.url_string())); - EXPECT_EQ(specs.length() + 1, parsed.path_index()); - } - - // Empty URL. - { - chrome::ParsedFallbackIconPath parsed; - EXPECT_TRUE(parsed.Parse(specs + "/")); - EXPECT_EQ(31, parsed.size_in_pixels()); - const favicon_base::FallbackIconStyle& style = parsed.style(); - EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); - EXPECT_FALSE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0xFF, 0xFF, 0xFF), style.text_color); - EXPECT_EQ(0.75, style.font_size_ratio); - EXPECT_EQ(0.25, style.roundness); - EXPECT_EQ(GURL(), GURL(parsed.url_string())); - EXPECT_EQ(specs.length() + 1, parsed.path_index()); - } - - // Tolerate invalid URL. - { - chrome::ParsedFallbackIconPath parsed; - EXPECT_TRUE(parsed.Parse(specs + "/NOT A VALID URL")); - EXPECT_EQ(31, parsed.size_in_pixels()); - const favicon_base::FallbackIconStyle& style = parsed.style(); - EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); - EXPECT_FALSE(style.is_default_background_color); - EXPECT_EQ(SkColorSetRGB(0xFF, 0xFF, 0xFF), style.text_color); - EXPECT_EQ(0.75, style.font_size_ratio); - EXPECT_EQ(0.25, style.roundness); - EXPECT_EQ("NOT A VALID URL", parsed.url_string()); - EXPECT_EQ(specs.length() + 1, parsed.path_index()); - } - - // Size and style are default. - { - std::string specs2 = ",,,,"; - chrome::ParsedFallbackIconPath parsed; - EXPECT_TRUE(parsed.Parse(specs2 + "/" + kTestUrlStr)); - EXPECT_EQ(gfx::kFaviconSize, parsed.size_in_pixels()); - const favicon_base::FallbackIconStyle& style = parsed.style(); - EXPECT_EQ(kDefaultBackgroundColor, style.background_color); - EXPECT_TRUE(style.is_default_background_color); - EXPECT_EQ(kDefaultTextColorLight, style.text_color); - EXPECT_EQ(kDefaultFontSizeRatio, style.font_size_ratio); - EXPECT_EQ(kDefaultRoundness, style.roundness); - EXPECT_EQ(GURL(kTestUrlStr), GURL(parsed.url_string())); - EXPECT_EQ(specs2.length() + 1, parsed.path_index()); - } -} - -TEST_F(FallbackIconUrlParserTest, ParseFallbackIconPathFailure) { - const char* test_cases[] = { - // Bad size. - "-1,000,fff,0.75,0.25/http://www.google.com/", - // Bad specs. - "32,#junk,fff,0.75,0.25/http://www.google.com/", - }; - for (size_t i = 0; i < arraysize(test_cases); ++i) { - chrome::ParsedFallbackIconPath parsed; - EXPECT_FALSE(parsed.Parse(test_cases[i])) << "test_cases[" << i << "]"; - } -} - -} // namespace chrome
diff --git a/components/nacl/loader/BUILD.gn b/components/nacl/loader/BUILD.gn index 74edc91..1eea0cea 100644 --- a/components/nacl/loader/BUILD.gn +++ b/components/nacl/loader/BUILD.gn
@@ -120,7 +120,7 @@ deps = [ ":loader", "//base", - "//build/config/sanitizers:deps_no_options", + "//build/config:exe_and_shlib_deps", "//components/nacl/common:switches", "//components/nacl/loader/sandbox_linux", "//content/public/common",
diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc index df24f6d..fbce5f9 100644 --- a/components/nacl/loader/nacl_helper_linux.cc +++ b/components/nacl/loader/nacl_helper_linux.cc
@@ -411,21 +411,8 @@ // Do not install the SIGSEGV handler in ASan. This should make the NaCl // platform qualification test pass. // detect_odr_violation=0: http://crbug.com/376306 -static const char kAsanDefaultOptionsNaCl[] = - "handle_segv=0:detect_odr_violation=0"; - -// Override the default ASan options for the NaCl helper. -// __asan_default_options should not be instrumented, because it is called -// before ASan is initialized. -extern "C" -__attribute__((no_sanitize_address)) -// The function isn't referenced from the executable itself. Make sure it isn't -// stripped by the linker. -__attribute__((used)) -__attribute__((visibility("default"))) -const char* __asan_default_options() { - return kAsanDefaultOptionsNaCl; -} +extern const char* kAsanDefaultOptionsNaCl; +const char* kAsanDefaultOptionsNaCl = "handle_segv=0:detect_odr_violation=0"; #endif int main(int argc, char* argv[]) {
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index f736254..1e40681 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -87,6 +87,10 @@ base::FEATURE_DISABLED_BY_DEFAULT}; // Feature used for the vertical margin UI experiment. +const base::Feature kUIExperimentVerticalLayout{ + "OmniboxUIExperimentVerticalLayout", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Feature used for the vertical margin UI experiment. const base::Feature kUIExperimentVerticalMargin{ "OmniboxUIExperimentVerticalMargin", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index 5bee37a..2033183 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -33,6 +33,7 @@ extern const base::Feature kZeroSuggestSwapTitleAndUrl; extern const base::Feature kDisplayTitleForCurrentUrl; extern const base::Feature kUIExperimentMaxAutocompleteMatches; +extern const base::Feature kUIExperimentVerticalLayout; extern const base::Feature kUIExperimentVerticalMargin; }
diff --git a/components/payments/core/autofill_payment_instrument.cc b/components/payments/core/autofill_payment_instrument.cc index 75c4484..82ff24d 100644 --- a/components/payments/core/autofill_payment_instrument.cc +++ b/components/payments/core/autofill_payment_instrument.cc
@@ -78,9 +78,11 @@ } bool AutofillPaymentInstrument::IsCompleteForPayment() { + // COMPLETE or EXPIRED cards are considered valid for payment. The user will + // be prompted to enter the new expiration at the CVC step. return autofill::GetCompletionStatusForCard(credit_card_, app_locale_, - billing_profiles_) == - autofill::CREDIT_CARD_COMPLETE; + billing_profiles_) <= + autofill::CREDIT_CARD_EXPIRED; } base::string16 AutofillPaymentInstrument::GetMissingInfoLabel() {
diff --git a/components/payments/core/autofill_payment_instrument_unittest.cc b/components/payments/core/autofill_payment_instrument_unittest.cc index 6b09937..7f84726 100644 --- a/components/payments/core/autofill_payment_instrument_unittest.cc +++ b/components/payments/core/autofill_payment_instrument_unittest.cc
@@ -170,16 +170,14 @@ EXPECT_TRUE(instrument.GetMissingInfoLabel().empty()); } -// An expired local card is not a valid instrument for payment. +// An expired local card is still a valid instrument for payment. TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_Expired) { autofill::CreditCard& card = local_credit_card(); card.SetExpirationYear(2016); // Expired. AutofillPaymentInstrument instrument("visa", card, billing_profiles(), "en-US", nullptr); - EXPECT_FALSE(instrument.IsCompleteForPayment()); - EXPECT_EQ(l10n_util::GetStringUTF16( - IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED), - instrument.GetMissingInfoLabel()); + EXPECT_TRUE(instrument.IsCompleteForPayment()); + EXPECT_EQ(base::string16(), instrument.GetMissingInfoLabel()); } // A local card with no name is not a valid instrument for payment. @@ -263,7 +261,7 @@ EXPECT_TRUE(instrument.GetMissingInfoLabel().empty()); } -// An expired masked (server) card is not a valid instrument for payment. +// An expired masked (server) card is still a valid instrument for payment. TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_ExpiredMaskedCard) { autofill::CreditCard card = autofill::test::GetMaskedServerCard(); ASSERT_GT(billing_profiles().size(), 0UL); @@ -271,10 +269,8 @@ card.SetExpirationYear(2016); // Expired. AutofillPaymentInstrument instrument("visa", card, billing_profiles(), "en-US", nullptr); - EXPECT_FALSE(instrument.IsCompleteForPayment()); - EXPECT_EQ(l10n_util::GetStringUTF16( - IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED), - instrument.GetMissingInfoLabel()); + EXPECT_TRUE(instrument.IsCompleteForPayment()); + EXPECT_EQ(base::string16(), instrument.GetMissingInfoLabel()); } // An expired card is a valid instrument for canMakePayment.
diff --git a/components/user_manager/user.h b/components/user_manager/user.h index fecc33be..032e9841 100644 --- a/components/user_manager/user.h +++ b/components/user_manager/user.h
@@ -190,6 +190,10 @@ // True if the user Profile is created. bool is_profile_created() const { return profile_is_created_; } + static User* CreatePublicAccountUserForTesting(const AccountId& account_id) { + return CreatePublicAccountUser(account_id); + } + protected: friend class UserManagerBase; friend class chromeos::ChromeUserManagerImpl;
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h index 70776a72..2e44e71 100644 --- a/components/user_manager/user_manager_base.h +++ b/components/user_manager/user_manager_base.h
@@ -132,6 +132,10 @@ // and ephemeral users are enabled. virtual bool AreEphemeralUsersEnabled() const = 0; + void AddUserRecordForTesting(User* user) { + return AddUserRecord(user); + } + protected: // Adds |user| to users list, and adds it to front of LRU list. It is assumed // that there is no user with same id.
diff --git a/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc index 393f53f..9156032b 100644 --- a/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc +++ b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
@@ -43,7 +43,6 @@ base::Bind(&GpuRootCompositorFrameSink::OnPrivateConnectionLost, base::Unretained(this))); display_->Initialize(this, surface_manager); - display_->SetVisible(true); } GpuRootCompositorFrameSink::~GpuRootCompositorFrameSink() = default;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index eb28c584..501316c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -692,6 +692,8 @@ "frame_host/frame_tree_node.h", "frame_host/frame_tree_node_blame_context.cc", "frame_host/frame_tree_node_blame_context.h", + "frame_host/input/legacy_ipc_frame_input_handler.cc", + "frame_host/input/legacy_ipc_frame_input_handler.h", "frame_host/interstitial_page_impl.cc", "frame_host/interstitial_page_impl.h", "frame_host/interstitial_page_navigator_impl.cc",
diff --git a/content/browser/android/ime_adapter_android.cc b/content/browser/android/ime_adapter_android.cc index bbb0ec9..2b5904cf 100644 --- a/content/browser/android/ime_adapter_android.cc +++ b/content/browser/android/ime_adapter_android.cc
@@ -293,8 +293,7 @@ if (!rfh) return; - rfh->Send(new InputMsg_SetEditableSelectionOffsets(rfh->GetRoutingID(), start, - end)); + rfh->GetFrameInputHandler()->SetEditableSelectionOffsets(start, end); } void ImeAdapterAndroid::SetCharacterBounds( @@ -328,12 +327,12 @@ if (!rfh) return; - std::vector<blink::WebCompositionUnderline> underlines; - underlines.push_back(blink::WebCompositionUnderline( - 0, end - start, SK_ColorBLACK, false, SK_ColorTRANSPARENT)); + std::vector<ui::CompositionUnderline> underlines; + underlines.push_back(ui::CompositionUnderline(0, end - start, SK_ColorBLACK, + false, SK_ColorTRANSPARENT)); - rfh->Send(new InputMsg_SetCompositionFromExistingText( - rfh->GetRoutingID(), start, end, underlines)); + rfh->GetFrameInputHandler()->SetCompositionFromExistingText(start, end, + underlines); } void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*, @@ -343,7 +342,7 @@ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetFocusedFrame()); if (rfh) - rfh->DeleteSurroundingText(before, after); + rfh->GetFrameInputHandler()->DeleteSurroundingText(before, after); } void ImeAdapterAndroid::DeleteSurroundingTextInCodePoints( @@ -353,8 +352,10 @@ int after) { RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetFocusedFrame()); - if (rfh) - rfh->DeleteSurroundingTextInCodePoints(before, after); + if (rfh) { + rfh->GetFrameInputHandler()->DeleteSurroundingTextInCodePoints(before, + after); + } } bool ImeAdapterAndroid::RequestTextInputStateUpdate(
diff --git a/content/browser/android/render_widget_host_connector_browsertest.cc b/content/browser/android/render_widget_host_connector_browsertest.cc index e1840ff7..fc9f24b 100644 --- a/content/browser/android/render_widget_host_connector_browsertest.cc +++ b/content/browser/android/render_widget_host_connector_browsertest.cc
@@ -119,18 +119,4 @@ EXPECT_EQ(nullptr, connector->GetRWHVAForTesting()); } -IN_PROC_BROWSER_TEST_F(RenderWidgetHostConnectorTest, - CleanUpConnectorReferenceAtWebContentsDestroyed) { - GURL http_url(embedded_test_server()->GetURL("/title1.html")); - - EXPECT_TRUE(NavigateToURL(shell(), http_url)); - RenderWidgetHostViewAndroid* rwhva = render_widget_host_view_android(); - RenderWidgetHostConnector* connector = render_widget_host_connector(); - EXPECT_EQ(connector, connector_in_rwhva(rwhva)); - - // Generate WebContentsObserver::WebContentsDestroyed by closing the contents. - web_contents()->Close(); - EXPECT_EQ(nullptr, connector_in_rwhva(rwhva)); -} - } // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 1f985ec5..d2ba7285 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -898,8 +898,8 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_ExecuteNoValueEditCommand( - focused_frame->GetRoutingID(), name)); + focused_frame->GetFrameInputHandler()->ExecuteEditCommand(name, + base::nullopt); } void BrowserPluginGuest::OnImeSetComposition( @@ -934,7 +934,7 @@ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>( web_contents()->GetFocusedFrame()); if (rfh) - rfh->ExtendSelectionAndDelete(before, after); + rfh->GetFrameInputHandler()->ExtendSelectionAndDelete(before, after); } void BrowserPluginGuest::OnLockMouse(bool user_gesture,
diff --git a/content/browser/frame_host/input/OWNERS b/content/browser/frame_host/input/OWNERS new file mode 100644 index 0000000..cf2b318 --- /dev/null +++ b/content/browser/frame_host/input/OWNERS
@@ -0,0 +1,7 @@ +aelias@chromium.org +dtapuska@chromium.org +tdresser@chromium.org + + +# TEAM: input-dev@chromium.org +# COMPONENT: Blink>Input
diff --git a/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc b/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc new file mode 100644 index 0000000..0cfd482 --- /dev/null +++ b/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc
@@ -0,0 +1,146 @@ +// 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 "content/browser/frame_host/input/legacy_ipc_frame_input_handler.h" + +#include "base/strings/utf_string_conversions.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/common/input_messages.h" + +namespace content { + +LegacyIPCFrameInputHandler::LegacyIPCFrameInputHandler( + RenderFrameHostImpl* frame_host, + int routing_id) + : frame_host_(frame_host), routing_id_(routing_id) { + DCHECK(frame_host); +} + +LegacyIPCFrameInputHandler::~LegacyIPCFrameInputHandler() {} + +void LegacyIPCFrameInputHandler::SetCompositionFromExistingText( + int32_t start, + int32_t end, + const std::vector<ui::CompositionUnderline>& ui_underlines) { + std::vector<blink::WebCompositionUnderline> underlines; + for (const auto& underline : ui_underlines) { + blink::WebCompositionUnderline blink_underline( + underline.start_offset, underline.end_offset, underline.color, + underline.thick, underline.background_color); + underlines.push_back(blink_underline); + } + + SendInput(base::MakeUnique<InputMsg_SetCompositionFromExistingText>( + routing_id_, start, end, underlines)); +} + +void LegacyIPCFrameInputHandler::ExtendSelectionAndDelete(int32_t before, + int32_t after) { + SendInput(base::MakeUnique<InputMsg_ExtendSelectionAndDelete>(routing_id_, + before, after)); +} + +void LegacyIPCFrameInputHandler::DeleteSurroundingText(int32_t before, + int32_t after) { + SendInput(base::MakeUnique<InputMsg_DeleteSurroundingText>(routing_id_, + before, after)); +} + +void LegacyIPCFrameInputHandler::DeleteSurroundingTextInCodePoints( + int32_t before, + int32_t after) { + SendInput(base::MakeUnique<InputMsg_DeleteSurroundingTextInCodePoints>( + routing_id_, before, after)); +} + +void LegacyIPCFrameInputHandler::SetEditableSelectionOffsets(int32_t start, + int32_t end) { + SendInput(base::MakeUnique<InputMsg_SetEditableSelectionOffsets>(routing_id_, + start, end)); +} + +void LegacyIPCFrameInputHandler::ExecuteEditCommand( + const std::string& command, + const base::Optional<base::string16>& value) { + if (!value) { + SendInput(base::MakeUnique<InputMsg_ExecuteNoValueEditCommand>(routing_id_, + command)); + } +} + +void LegacyIPCFrameInputHandler::Undo() { + SendInput(base::MakeUnique<InputMsg_Undo>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::Redo() { + SendInput(base::MakeUnique<InputMsg_Redo>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::Cut() { + SendInput(base::MakeUnique<InputMsg_Cut>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::Copy() { + SendInput(base::MakeUnique<InputMsg_Copy>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::CopyToFindPboard() { +#if defined(OS_MACOSX) + SendInput(base::MakeUnique<InputMsg_CopyToFindPboard>(routing_id_)); +#endif +} + +void LegacyIPCFrameInputHandler::Paste() { + SendInput(base::MakeUnique<InputMsg_Paste>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::PasteAndMatchStyle() { + SendInput(base::MakeUnique<InputMsg_PasteAndMatchStyle>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::Replace(const base::string16& word) { + SendInput(base::MakeUnique<InputMsg_Replace>(routing_id_, word)); +} + +void LegacyIPCFrameInputHandler::ReplaceMisspelling( + const base::string16& word) { + SendInput(base::MakeUnique<InputMsg_ReplaceMisspelling>(routing_id_, word)); +} + +void LegacyIPCFrameInputHandler::Delete() { + SendInput(base::MakeUnique<InputMsg_Delete>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::SelectAll() { + SendInput(base::MakeUnique<InputMsg_SelectAll>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::CollapseSelection() { + SendInput(base::MakeUnique<InputMsg_CollapseSelection>(routing_id_)); +} + +void LegacyIPCFrameInputHandler::SelectRange(const gfx::Point& point, + const gfx::Point& extent) { + SendInput(base::MakeUnique<InputMsg_SelectRange>(routing_id_, point, extent)); +} + +void LegacyIPCFrameInputHandler::AdjustSelectionByCharacterOffset(int32_t start, + int32_t end) { + SendInput(base::MakeUnique<InputMsg_AdjustSelectionByCharacterOffset>( + routing_id_, start, end)); +} + +void LegacyIPCFrameInputHandler::MoveRangeSelectionExtent( + const gfx::Point& extent) { + SendInput( + base::MakeUnique<InputMsg_MoveRangeSelectionExtent>(routing_id_, extent)); +} + +void LegacyIPCFrameInputHandler::SendInput( + std::unique_ptr<IPC::Message> message) { + frame_host_->GetRenderWidgetHost()->input_router()->SendInput( + std::move(message)); +} + +} // namespace content
diff --git a/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h b/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h new file mode 100644 index 0000000..46436e0 --- /dev/null +++ b/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h
@@ -0,0 +1,62 @@ +// 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 CONTENT_BROWSER_FRAME_HOST_INPUT_LEGACY_IPC_FRAME_INPUT_HANDLER_H_ +#define CONTENT_BROWSER_FRAME_HOST_INPUT_LEGACY_IPC_FRAME_INPUT_HANDLER_H_ + +#include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/input/input_router_impl.h" +#include "content/common/input/input_handler.mojom.h" + +namespace content { + +// An instance of a mojom::FrameInputHandler based on chrome IPC. +// This class is a temporary class to allow the input messages to +// remain as Chrome IPC messages but progressively work at moving +// them to mojo. +class CONTENT_EXPORT LegacyIPCFrameInputHandler + : public mojom::FrameInputHandler { + public: + LegacyIPCFrameInputHandler(RenderFrameHostImpl* frame_host, int routing_id); + ~LegacyIPCFrameInputHandler() override; + + void SetCompositionFromExistingText( + int32_t start, + int32_t end, + const std::vector<ui::CompositionUnderline>& underlines) override; + void ExtendSelectionAndDelete(int32_t before, int32_t after) override; + void DeleteSurroundingText(int32_t before, int32_t after) override; + void DeleteSurroundingTextInCodePoints(int32_t before, + int32_t after) override; + void SetEditableSelectionOffsets(int32_t start, int32_t end) override; + void ExecuteEditCommand(const std::string& command, + const base::Optional<base::string16>& value) override; + void Undo() override; + void Redo() override; + void Cut() override; + void Copy() override; + void CopyToFindPboard() override; + void Paste() override; + void PasteAndMatchStyle() override; + void Replace(const base::string16& word) override; + void ReplaceMisspelling(const base::string16& word) override; + void Delete() override; + void SelectAll() override; + void CollapseSelection() override; + void SelectRange(const gfx::Point& base, const gfx::Point& extent) override; + void AdjustSelectionByCharacterOffset(int32_t start, int32_t end) override; + void MoveRangeSelectionExtent(const gfx::Point& extent) override; + + private: + void SendInput(std::unique_ptr<IPC::Message> message); + + RenderFrameHostImpl* frame_host_; + int routing_id_; + + DISALLOW_COPY_AND_ASSIGN(LegacyIPCFrameInputHandler); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_FRAME_HOST_INPUT_LEGACY_IPC_FRAME_INPUT_HANDLER_H_
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc index d890e64..465086c 100644 --- a/content/browser/frame_host/interstitial_page_impl.cc +++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -438,8 +438,7 @@ if (!focused_node) return; - focused_node->current_frame_host()->Send( - new InputMsg_Cut(focused_node->current_frame_host()->GetRoutingID())); + focused_node->current_frame_host()->GetFrameInputHandler()->Cut(); RecordAction(base::UserMetricsAction("Cut")); } @@ -448,8 +447,7 @@ if (!focused_node) return; - focused_node->current_frame_host()->Send( - new InputMsg_Copy(focused_node->current_frame_host()->GetRoutingID())); + focused_node->current_frame_host()->GetFrameInputHandler()->Copy(); RecordAction(base::UserMetricsAction("Copy")); } @@ -458,8 +456,7 @@ if (!focused_node) return; - focused_node->current_frame_host()->Send( - new InputMsg_Paste(focused_node->current_frame_host()->GetRoutingID())); + focused_node->current_frame_host()->GetFrameInputHandler()->Paste(); RecordAction(base::UserMetricsAction("Paste")); } @@ -468,8 +465,7 @@ if (!focused_node) return; - focused_node->current_frame_host()->Send(new InputMsg_SelectAll( - focused_node->current_frame_host()->GetRoutingID())); + focused_node->current_frame_host()->GetFrameInputHandler()->SelectAll(); RecordAction(base::UserMetricsAction("SelectAll")); }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 55f8a8b..92a8c11 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -30,6 +30,7 @@ #include "content/browser/frame_host/debug_urls.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" +#include "content/browser/frame_host/input/legacy_ipc_frame_input_handler.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/frame_host/navigation_request.h" @@ -69,6 +70,7 @@ #include "content/common/content_security_policy/content_security_policy.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/input/input_handler.mojom.h" #include "content/common/input_messages.h" #include "content/common/inter_process_time_ticks_converter.h" #include "content/common/navigation_params.h" @@ -1035,6 +1037,12 @@ scheme) != bypassing_schemes.end(); } +mojom::FrameInputHandler* RenderFrameHostImpl::GetFrameInputHandler() { + if (legacy_frame_input_handler_) + return legacy_frame_input_handler_.get(); + return frame_input_handler_.get(); +} + bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id, int opener_routing_id, int parent_routing_id, @@ -3065,21 +3073,6 @@ new FrameMsg_AdvanceFocus(GetRoutingID(), type, source_proxy_routing_id)); } -void RenderFrameHostImpl::ExtendSelectionAndDelete(size_t before, - size_t after) { - Send(new InputMsg_ExtendSelectionAndDelete(routing_id_, before, after)); -} - -void RenderFrameHostImpl::DeleteSurroundingText(size_t before, size_t after) { - Send(new InputMsg_DeleteSurroundingText(routing_id_, before, after)); -} - -void RenderFrameHostImpl::DeleteSurroundingTextInCodePoints(int before, - int after) { - Send(new InputMsg_DeleteSurroundingTextInCodePoints(routing_id_, before, - after)); -} - void RenderFrameHostImpl::JavaScriptDialogClosed( IPC::Message* reply_msg, bool success, @@ -3235,6 +3228,14 @@ frame_->GetInterfaceProvider(mojo::MakeRequest(&remote_interfaces)); remote_interfaces_.reset(new service_manager::InterfaceProvider); remote_interfaces_->Bind(std::move(remote_interfaces)); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMojoInputMessages)) { + GetRemoteInterfaces()->GetInterface(&frame_input_handler_); + } else { + legacy_frame_input_handler_.reset( + new LegacyIPCFrameInputHandler(this, routing_id_)); + } } void RenderFrameHostImpl::InvalidateMojoConnection() {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 1d1de6e..7e7ca69f 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -85,6 +85,7 @@ namespace content { class AssociatedInterfaceProviderImpl; class AssociatedInterfaceRegistryImpl; +class LegacyIPCFrameInputHandler; class FeaturePolicy; class FrameTree; class FrameTreeNode; @@ -229,6 +230,8 @@ GURL* blocked_url, SourceLocation* source_location) const override; + mojom::FrameInputHandler* GetFrameInputHandler() override; + // Creates a RenderFrame in the renderer process. bool CreateRenderFrame(int proxy_routing_id, int opener_routing_id, @@ -446,21 +449,6 @@ void AdvanceFocus(blink::WebFocusType type, RenderFrameProxyHost* source_proxy); - // Deletes the current selection plus the specified number of characters - // before and after the selection or caret. - void ExtendSelectionAndDelete(size_t before, size_t after); - - // Deletes text before and after the current cursor position, excluding the - // selection. The lengths are supplied in Java chars (UTF-16 Code Unit), not - // in code points or in glyphs. - void DeleteSurroundingText(size_t before, size_t after); - - // Deletes text before and after the current cursor position, excluding the - // selection. The lengths are supplied in code points, not in Java chars - // (UTF-16 Code Unit) or in glyphs. Do nothing if there are one or more - // invalid surrogate pairs in the requested range. - void DeleteSurroundingTextInCodePoints(int before, int after); - // Notifies the RenderFrame that the JavaScript message that was shown was // closed by the user. void JavaScriptDialogClosed(IPC::Message* reply_msg, @@ -1245,6 +1233,9 @@ // crbug.com/715541 std::string untrusted_devtools_frame_id_; + mojom::FrameInputHandlerPtr frame_input_handler_; + std::unique_ptr<LegacyIPCFrameInputHandler> legacy_frame_input_handler_; + // NOTE: This must be the last member. base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index e9178424..a4b99cd 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1155,31 +1155,35 @@ request_id, std::move(url_loader_client)); return; } - // Check if we have a registered interceptor for the headers passed in. If - // yes then we need to mark the current request as pending and wait for the - // interceptor to invoke the callback with a status code indicating whether - // the request needs to be aborted or continued. - for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) { - HeaderInterceptorMap::iterator index = - http_header_interceptor_map_.find(it.name()); - if (index != http_header_interceptor_map_.end()) { - HeaderInterceptorInfo& interceptor_info = index->second; - bool call_interceptor = true; - if (!interceptor_info.starts_with.empty()) { - call_interceptor = - base::StartsWith(it.value(), interceptor_info.starts_with, - base::CompareCase::INSENSITIVE_ASCII); - } - if (call_interceptor) { - interceptor_info.interceptor.Run( - it.name(), it.value(), child_id, resource_context, - base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest, - base::Unretained(this), requester_info, request_id, - request_data, sync_result_handler, route_id, headers, - base::Passed(std::move(mojo_request)), - base::Passed(std::move(url_loader_client)))); - return; + if (!is_navigation_stream_request) { + // Check if we have a registered interceptor for the headers passed in. If + // yes then we need to mark the current request as pending and wait for the + // interceptor to invoke the callback with a status code indicating whether + // the request needs to be aborted or continued. + for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) { + HeaderInterceptorMap::iterator index = + http_header_interceptor_map_.find(it.name()); + if (index != http_header_interceptor_map_.end()) { + HeaderInterceptorInfo& interceptor_info = index->second; + + bool call_interceptor = true; + if (!interceptor_info.starts_with.empty()) { + call_interceptor = + base::StartsWith(it.value(), interceptor_info.starts_with, + base::CompareCase::INSENSITIVE_ASCII); + } + if (call_interceptor) { + interceptor_info.interceptor.Run( + it.name(), it.value(), child_id, resource_context, + base::Bind( + &ResourceDispatcherHostImpl::ContinuePendingBeginRequest, + base::Unretained(this), requester_info, request_id, + request_data, sync_result_handler, route_id, headers, + base::Passed(std::move(mojo_request)), + base::Passed(std::move(url_loader_client)))); + return; + } } } } @@ -1214,7 +1218,12 @@ return; } int child_id = requester_info->child_id(); - + storage::BlobStorageContext* blob_context = nullptr; + bool allow_download = false; + bool do_not_prompt_for_login = false; + bool report_raw_headers = false; + bool is_sync_load = !!sync_result_handler; + int load_flags = BuildLoadFlagsForRequest(request_data, is_sync_load); bool is_navigation_stream_request = IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(request_data.resource_type); @@ -1240,128 +1249,128 @@ : request_data.url, request_data.priority, nullptr, kTrafficAnnotation); - // Log that this request is a service worker navigation preload request here, - // since navigation preload machinery has no access to netlog. - // TODO(falken): Figure out how mojom::URLLoaderClient can - // access the request's netlog. - if (requester_info->IsNavigationPreload()) { - new_request->net_log().AddEvent( - net::NetLogEventType::SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST); - } - - // PlzNavigate: Always set the method to GET when gaining access to the - // stream that contains the response body of a navigation. Otherwise the data - // that was already fetched by the browser will not be transmitted to the - // renderer. - if (is_navigation_stream_request) + if (is_navigation_stream_request) { + // PlzNavigate: Always set the method to GET when gaining access to the + // stream that contains the response body of a navigation. Otherwise the + // data that was already fetched by the browser will not be transmitted to + // the renderer. new_request->set_method("GET"); - else + } else { + // Log that this request is a service worker navigation preload request + // here, since navigation preload machinery has no access to netlog. + // TODO(falken): Figure out how mojom::URLLoaderClient can + // access the request's netlog. + if (requester_info->IsNavigationPreload()) { + new_request->net_log().AddEvent( + net::NetLogEventType::SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST); + } + new_request->set_method(request_data.method); - new_request->set_first_party_for_cookies( - request_data.first_party_for_cookies); + new_request->set_first_party_for_cookies( + request_data.first_party_for_cookies); - // The initiator should normally be present, unless this is a navigation in a - // top-level frame. It may be null for some top-level navigations (eg: - // browser-initiated ones). - DCHECK(request_data.request_initiator.has_value() || - request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME); - new_request->set_initiator(request_data.request_initiator); + // The initiator should normally be present, unless this is a navigation in + // a top-level frame. It may be null for some top-level navigations (eg: + // browser-initiated ones). + DCHECK(request_data.request_initiator.has_value() || + request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME); + new_request->set_initiator(request_data.request_initiator); - if (request_data.originated_from_service_worker) { - new_request->SetUserData(URLRequestServiceWorkerData::kUserDataKey, - base::MakeUnique<URLRequestServiceWorkerData>()); - } + if (request_data.originated_from_service_worker) { + new_request->SetUserData(URLRequestServiceWorkerData::kUserDataKey, + base::MakeUnique<URLRequestServiceWorkerData>()); + } - // If the request is a MAIN_FRAME request, the first-party URL gets updated on - // redirects. - if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME) { - new_request->set_first_party_url_policy( - net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); - } + // If the request is a MAIN_FRAME request, the first-party URL gets updated + // on redirects. + if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME) { + new_request->set_first_party_url_policy( + net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); + } - // For PlzNavigate, this request has already been made and the referrer was - // checked previously. So don't set the referrer for this stream request, or - // else it will fail for SSL redirects since net/ will think the blob:https - // for the stream is not a secure scheme (specifically, in the call to - // ComputeReferrerForRedirect). - if (!is_navigation_stream_request) { + // For PlzNavigate, this request has already been made and the referrer was + // checked previously. So don't set the referrer for this stream request, or + // else it will fail for SSL redirects since net/ will think the blob:https + // for the stream is not a secure scheme (specifically, in the call to + // ComputeReferrerForRedirect). const Referrer referrer( request_data.referrer, request_data.referrer_policy); Referrer::SetReferrerForRequest(new_request.get(), referrer); - } - new_request->SetExtraRequestHeaders(headers); + new_request->SetExtraRequestHeaders(headers); - storage::BlobStorageContext* blob_context = - GetBlobStorageContext(requester_info->blob_storage_context()); - // Resolve elements from request_body and prepare upload data. - if (request_data.request_body.get()) { - // |blob_context| could be null when the request is from the plugins because - // ResourceMessageFilters created in PluginProcessHost don't have the blob - // context. - if (blob_context) { - // Attaches the BlobDataHandles to request_body not to free the blobs and - // any attached shareable files until upload completion. These data will - // be used in UploadDataStream and ServiceWorkerURLRequestJob. - AttachRequestBodyBlobDataHandles(request_data.request_body.get(), - resource_context); + blob_context = + GetBlobStorageContext(requester_info->blob_storage_context()); + // Resolve elements from request_body and prepare upload data. + if (request_data.request_body.get()) { + // |blob_context| could be null when the request is from the plugins + // because ResourceMessageFilters created in PluginProcessHost don't have + // the blob context. + if (blob_context) { + // Attaches the BlobDataHandles to request_body not to free the blobs + // and any attached shareable files until upload completion. These data + // will be used in UploadDataStream and ServiceWorkerURLRequestJob. + AttachRequestBodyBlobDataHandles(request_data.request_body.get(), + resource_context); + } + new_request->set_upload(UploadDataStreamBuilder::Build( + request_data.request_body.get(), blob_context, + requester_info->file_system_context(), + BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get())); } - new_request->set_upload(UploadDataStreamBuilder::Build( - request_data.request_body.get(), blob_context, - requester_info->file_system_context(), - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get())); + + allow_download = request_data.allow_download && + IsResourceTypeFrame(request_data.resource_type); + do_not_prompt_for_login = request_data.do_not_prompt_for_login; + + // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only + // allow requesting them if requester has ReadRawCookies permission. + ChildProcessSecurityPolicyImpl* policy = + ChildProcessSecurityPolicyImpl::GetInstance(); + report_raw_headers = request_data.report_raw_headers; + if (report_raw_headers && !policy->CanReadRawCookies(child_id) && + !requester_info->IsNavigationPreload()) { + // For navigation preload, the child_id is -1 so CanReadRawCookies would + // return false. But |report_raw_headers| of the navigation preload + // request was copied from the original request, so this check has already + // been carried out. + // TODO: crbug.com/523063 can we call bad_message::ReceivedBadMessage + // here? + VLOG(1) << "Denied unauthorized request for raw headers"; + report_raw_headers = false; + } + + if (request_data.resource_type == RESOURCE_TYPE_PREFETCH || + request_data.resource_type == RESOURCE_TYPE_FAVICON) { + do_not_prompt_for_login = true; + } + if (request_data.resource_type == RESOURCE_TYPE_IMAGE && + HTTP_AUTH_RELATION_BLOCKED_CROSS == + HttpAuthRelationTypeOf(request_data.url, + request_data.first_party_for_cookies)) { + // Prevent third-party image content from prompting for login, as this + // is often a scam to extract credentials for another domain from the + // user. Only block image loads, as the attack applies largely to the + // "src" property of the <img> tag. It is common for web properties to + // allow untrusted values for <img src>; this is considered a fair thing + // for an HTML sanitizer to do. Conversely, any HTML sanitizer that didn't + // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags + // would be considered vulnerable in and of itself. + do_not_prompt_for_login = true; + load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; + } + + // Sync loads should have maximum priority and should be the only + // requets that have the ignore limits flag set. + if (is_sync_load) { + DCHECK_EQ(request_data.priority, net::MAXIMUM_PRIORITY); + DCHECK_NE(load_flags & net::LOAD_IGNORE_LIMITS, 0); + } else { + DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0); + } } - bool allow_download = request_data.allow_download && - IsResourceTypeFrame(request_data.resource_type); - bool do_not_prompt_for_login = request_data.do_not_prompt_for_login; - bool is_sync_load = !!sync_result_handler; - - // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only - // allow requesting them if requester has ReadRawCookies permission. - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - bool report_raw_headers = request_data.report_raw_headers; - if (report_raw_headers && !policy->CanReadRawCookies(child_id) && - !requester_info->IsNavigationPreload()) { - // For navigation preload, the child_id is -1 so CanReadRawCookies would - // return false. But |report_raw_headers| of the navigation preload request - // was copied from the original request, so this check has already been - // carried out. - // TODO: crbug.com/523063 can we call bad_message::ReceivedBadMessage here? - VLOG(1) << "Denied unauthorized request for raw headers"; - report_raw_headers = false; - } - int load_flags = BuildLoadFlagsForRequest(request_data, is_sync_load); - if (request_data.resource_type == RESOURCE_TYPE_PREFETCH || - request_data.resource_type == RESOURCE_TYPE_FAVICON) { - do_not_prompt_for_login = true; - } - if (request_data.resource_type == RESOURCE_TYPE_IMAGE && - HTTP_AUTH_RELATION_BLOCKED_CROSS == - HttpAuthRelationTypeOf(request_data.url, - request_data.first_party_for_cookies)) { - // Prevent third-party image content from prompting for login, as this - // is often a scam to extract credentials for another domain from the user. - // Only block image loads, as the attack applies largely to the "src" - // property of the <img> tag. It is common for web properties to allow - // untrusted values for <img src>; this is considered a fair thing for an - // HTML sanitizer to do. Conversely, any HTML sanitizer that didn't - // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags - // would be considered vulnerable in and of itself. - do_not_prompt_for_login = true; - load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; - } - - // Sync loads should have maximum priority and should be the only - // requets that have the ignore limits flag set. - if (is_sync_load) { - DCHECK_EQ(request_data.priority, net::MAXIMUM_PRIORITY); - DCHECK_NE(load_flags & net::LOAD_IGNORE_LIMITS, 0); - } else { - DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0); - } new_request->SetLoadFlags(load_flags); // Make extra info and read footer (contains request ID). @@ -1395,38 +1404,48 @@ ->GetBlobDataFromPublicURL(new_request->url())); } - // Initialize the service worker handler for the request. We don't use - // ServiceWorker for synchronous loads to avoid renderer deadlocks. - const ServiceWorkerMode service_worker_mode = - is_sync_load ? ServiceWorkerMode::NONE : request_data.service_worker_mode; - ServiceWorkerRequestHandler::InitializeHandler( - new_request.get(), requester_info->service_worker_context(), blob_context, - child_id, request_data.service_worker_provider_id, - service_worker_mode != ServiceWorkerMode::ALL, - request_data.fetch_request_mode, request_data.fetch_credentials_mode, - request_data.fetch_redirect_mode, request_data.resource_type, - request_data.fetch_request_context_type, request_data.fetch_frame_type, - request_data.request_body); + std::unique_ptr<ResourceHandler> handler; + if (is_navigation_stream_request) { + // PlzNavigate: do not add ResourceThrottles for main resource requests from + // the renderer. Decisions about the navigation should have been done in + // the initial request. + handler = CreateBaseResourceHandler( + new_request.get(), std::move(mojo_request), + std::move(url_loader_client), request_data.resource_type); + } else { + // Initialize the service worker handler for the request. We don't use + // ServiceWorker for synchronous loads to avoid renderer deadlocks. + const ServiceWorkerMode service_worker_mode = + is_sync_load ? ServiceWorkerMode::NONE + : request_data.service_worker_mode; + ServiceWorkerRequestHandler::InitializeHandler( + new_request.get(), requester_info->service_worker_context(), + blob_context, child_id, request_data.service_worker_provider_id, + service_worker_mode != ServiceWorkerMode::ALL, + request_data.fetch_request_mode, request_data.fetch_credentials_mode, + request_data.fetch_redirect_mode, request_data.resource_type, + request_data.fetch_request_context_type, request_data.fetch_frame_type, + request_data.request_body); - ForeignFetchRequestHandler::InitializeHandler( - new_request.get(), requester_info->service_worker_context(), blob_context, - child_id, request_data.service_worker_provider_id, service_worker_mode, - request_data.fetch_request_mode, request_data.fetch_credentials_mode, - request_data.fetch_redirect_mode, request_data.resource_type, - request_data.fetch_request_context_type, request_data.fetch_frame_type, - request_data.request_body, request_data.initiated_in_secure_context); + ForeignFetchRequestHandler::InitializeHandler( + new_request.get(), requester_info->service_worker_context(), + blob_context, child_id, request_data.service_worker_provider_id, + service_worker_mode, request_data.fetch_request_mode, + request_data.fetch_credentials_mode, request_data.fetch_redirect_mode, + request_data.resource_type, request_data.fetch_request_context_type, + request_data.fetch_frame_type, request_data.request_body, + request_data.initiated_in_secure_context); - // Have the appcache associate its extra info with the request. - AppCacheInterceptor::SetExtraRequestInfo( - new_request.get(), requester_info->appcache_service(), child_id, - request_data.appcache_host_id, request_data.resource_type, - request_data.should_reset_appcache); - - std::unique_ptr<ResourceHandler> handler(CreateResourceHandler( - requester_info.get(), new_request.get(), request_data, - sync_result_handler, route_id, child_id, resource_context, - std::move(mojo_request), std::move(url_loader_client))); - + // Have the appcache associate its extra info with the request. + AppCacheInterceptor::SetExtraRequestInfo( + new_request.get(), requester_info->appcache_service(), child_id, + request_data.appcache_host_id, request_data.resource_type, + request_data.should_reset_appcache); + handler = CreateResourceHandler( + requester_info.get(), new_request.get(), request_data, + sync_result_handler, route_id, child_id, resource_context, + std::move(mojo_request), std::move(url_loader_client)); + } if (handler) BeginRequestInternal(std::move(new_request), std::move(handler)); } @@ -1462,14 +1481,9 @@ DCHECK(!url_loader_client); handler.reset(new SyncResourceHandler(request, sync_result_handler, this)); } else { - if (mojo_request.is_pending()) { - handler.reset(new MojoAsyncResourceHandler(request, this, - std::move(mojo_request), - std::move(url_loader_client), - request_data.resource_type)); - } else { - handler.reset(new AsyncResourceHandler(request, this)); - } + handler = CreateBaseResourceHandler(request, std::move(mojo_request), + std::move(url_loader_client), + request_data.resource_type); // The RedirectToFileResourceHandler depends on being next in the chain. if (request_data.download_to_file) { @@ -1502,15 +1516,6 @@ handler = std::move(detachable_handler); } - // PlzNavigate: do not add ResourceThrottles for main resource requests from - // the renderer. Decisions about the navigation should have been done in the - // initial request. - if (IsBrowserSideNavigationEnabled() && - IsResourceTypeFrame(request_data.resource_type)) { - DCHECK(request->url().SchemeIs(url::kBlobScheme)); - return handler; - } - return AddStandardHandlers(request, request_data.resource_type, resource_context, request_data.fetch_request_context_type, @@ -1520,6 +1525,23 @@ } std::unique_ptr<ResourceHandler> +ResourceDispatcherHostImpl::CreateBaseResourceHandler( + net::URLRequest* request, + mojom::URLLoaderAssociatedRequest mojo_request, + mojom::URLLoaderClientPtr url_loader_client, + ResourceType resource_type) { + std::unique_ptr<ResourceHandler> handler; + if (mojo_request.is_pending()) { + handler.reset(new MojoAsyncResourceHandler( + request, this, std::move(mojo_request), std::move(url_loader_client), + resource_type)); + } else { + handler.reset(new AsyncResourceHandler(request, this)); + } + return handler; +} + +std::unique_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers( net::URLRequest* request, ResourceType resource_type, @@ -2610,9 +2632,17 @@ ResourceContext* resource_context) { ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - + bool is_navigation_stream_request = + IsBrowserSideNavigationEnabled() && + IsResourceTypeFrame(request_data.resource_type); // Check if the renderer is permitted to request the requested URL. - if (!policy->CanRequestURL(child_id, request_data.url)) { + // PlzNavigate: no need to check the URL here. The browser already picked the + // right renderer to send the request to. The original URL isn't used, as the + // renderer is fetching the stream URL. Checking the original URL doesn't work + // in case of redirects across schemes, since the original URL might not be + // granted to the final URL's renderer. + if (!is_navigation_stream_request && + !policy->CanRequestURL(child_id, request_data.url)) { VLOG(1) << "Denied unauthorized request for " << request_data.url.possibly_invalid_spec(); return false;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index 826cc37..9ac1b25 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -597,6 +597,13 @@ mojom::URLLoaderAssociatedRequest mojo_request, mojom::URLLoaderClientPtr url_loader_client); + // Creates either MojoAsyncResourceHandler or AsyncResourceHandler. + std::unique_ptr<ResourceHandler> CreateBaseResourceHandler( + net::URLRequest* request, + mojom::URLLoaderAssociatedRequest mojo_request, + mojom::URLLoaderClientPtr url_loader_client, + ResourceType resource_type); + // Wraps |handler| in the standard resource handlers for normal resource // loading and navigation requests. This adds MimeTypeResourceHandler and // ResourceThrottles.
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc index 140b6347..5a40845a 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
@@ -187,9 +187,6 @@ anchor_point.Offset(-origin.x(), -origin.y()); RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(rwhv_->GetRenderWidgetHost()); - // TODO(wjmaclean): Probably this ViewMsg should be converted to a FrameMsg - // since it will need to go to a RenderFrame once the Blink-side plumbing for - // this is hooked up. host->Send(new ViewMsg_ShowContextMenu(host->GetRoutingID(), ui::MENU_SOURCE_TOUCH_EDIT_MENU, gfx::ToRoundedPoint(anchor_point)));
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 167bf42..80a0d1d 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1429,7 +1429,7 @@ size_t before, size_t after) { RenderFrameHostImpl* rfh = GetFocusedFrame(); if (rfh) - rfh->ExtendSelectionAndDelete(before, after); + rfh->GetFrameInputHandler()->ExtendSelectionAndDelete(before, after); } void RenderWidgetHostViewAura::EnsureCaretNotInRect(
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 1e75835a..0812caa 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -7851,8 +7851,7 @@ // "Select all" in the subframe. The bug only happens if there's a selection // change, which triggers the path through didChangeSelection. - root->child_at(0)->current_frame_host()->Send(new InputMsg_SelectAll( - root->child_at(0)->current_frame_host()->GetRoutingID())); + root->child_at(0)->current_frame_host()->GetFrameInputHandler()->SelectAll(); // Prevent b.com process from terminating right away once the subframe // navigates away from b.com below. This is necessary so that the renderer
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 627a0e5..ed882eff 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2752,8 +2752,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_MoveRangeSelectionExtent( - focused_frame->GetRoutingID(), extent)); + focused_frame->GetFrameInputHandler()->MoveRangeSelectionExtent(extent); } void WebContentsImpl::SelectRange(const gfx::Point& base, @@ -2762,8 +2761,7 @@ if (!focused_frame) return; - focused_frame->Send( - new InputMsg_SelectRange(focused_frame->GetRoutingID(), base, extent)); + focused_frame->GetFrameInputHandler()->SelectRange(base, extent); } void WebContentsImpl::AdjustSelectionByCharacterOffset(int start_adjust, @@ -2772,8 +2770,8 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_AdjustSelectionByCharacterOffset( - focused_frame->GetRoutingID(), start_adjust, end_adjust)); + focused_frame->GetFrameInputHandler()->AdjustSelectionByCharacterOffset( + start_adjust, end_adjust); } void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) { @@ -2933,7 +2931,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_Undo(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->Undo(); RecordAction(base::UserMetricsAction("Undo")); } @@ -2941,7 +2939,7 @@ RenderFrameHost* focused_frame = GetFocusedFrame(); if (!focused_frame) return; - focused_frame->Send(new InputMsg_Redo(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->Redo(); RecordAction(base::UserMetricsAction("Redo")); } @@ -2950,7 +2948,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_Cut(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->Cut(); RecordAction(base::UserMetricsAction("Cut")); } @@ -2959,7 +2957,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_Copy(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->Copy(); RecordAction(base::UserMetricsAction("Copy")); } @@ -2970,8 +2968,7 @@ return; // Windows/Linux don't have the concept of a find pasteboard. - focused_frame->Send( - new InputMsg_CopyToFindPboard(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->CopyToFindPboard(); RecordAction(base::UserMetricsAction("CopyToFindPboard")); #endif } @@ -2981,7 +2978,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_Paste(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->Paste(); RecordAction(base::UserMetricsAction("Paste")); } @@ -2990,8 +2987,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_PasteAndMatchStyle( - focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->PasteAndMatchStyle(); RecordAction(base::UserMetricsAction("PasteAndMatchStyle")); } @@ -3000,7 +2996,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_Delete(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->Delete(); RecordAction(base::UserMetricsAction("DeleteSelection")); } @@ -3009,7 +3005,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_SelectAll(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->SelectAll(); RecordAction(base::UserMetricsAction("SelectAll")); } @@ -3018,8 +3014,7 @@ if (!focused_frame) return; - focused_frame->Send( - new InputMsg_CollapseSelection(focused_frame->GetRoutingID())); + focused_frame->GetFrameInputHandler()->CollapseSelection(); } void WebContentsImpl::Replace(const base::string16& word) { @@ -3027,8 +3022,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_Replace( - focused_frame->GetRoutingID(), word)); + focused_frame->GetFrameInputHandler()->Replace(word); } void WebContentsImpl::ReplaceMisspelling(const base::string16& word) { @@ -3036,8 +3030,7 @@ if (!focused_frame) return; - focused_frame->Send(new InputMsg_ReplaceMisspelling( - focused_frame->GetRoutingID(), word)); + focused_frame->GetFrameInputHandler()->ReplaceMisspelling(word); } void WebContentsImpl::NotifyContextMenuClosed(
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 139a7dec..e5e245e 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -601,6 +601,7 @@ "host_zoom.mojom", "image_downloader/image_downloader.mojom", "indexed_db/indexed_db.mojom", + "input/input_handler.mojom", "leveldb_wrapper.mojom", "manifest_observer.mojom", "media/media_devices.mojom",
diff --git a/content/common/input/OWNERS b/content/common/input/OWNERS index d1c97c5..d74c0a7 100644 --- a/content/common/input/OWNERS +++ b/content/common/input/OWNERS
@@ -2,6 +2,8 @@ dtapuska@chromium.org tdresser@chromium.org +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS per-file *_param_traits*.*=set noparent per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom new file mode 100644 index 0000000..fae10f96 --- /dev/null +++ b/content/common/input/input_handler.mojom
@@ -0,0 +1,84 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module content.mojom; + +import "mojo/common/string16.mojom"; +import "services/ui/public/interfaces/ime/ime.mojom"; +import "ui/gfx/geometry/mojo/geometry.mojom"; + +interface WidgetInputHandler { + // TODO(dtapuska): Implement me. +}; + +// This interface provides the input actions associated with the RenderFrame. +// Other input actions may also be dispatched via the WidgetInputHandler +// interface. If frame input actions are dispatched the WidgetInputHandler +// should be fetched via the associated interface request so that input calls +// remain in order. See https://goo.gl/x4ee8A for more details. +interface FrameInputHandler { + // Sets the text composition to be between the given start and end offsets in + // the currently focused editable field. + SetCompositionFromExistingText( + int32 start, int32 end, array<ui.mojom.CompositionUnderline> underlines); + + // Deletes the current selection plus the specified number of characters + // before and after the selection or caret. + ExtendSelectionAndDelete(int32 before, int32 after); + + // Deletes text before and after the current cursor position, excluding the + // selection. The lengths are supplied in Java chars (UTF-16 Code Unit), + // not in code points or in glyphs. + DeleteSurroundingText(int32 before, int32 after); + + // Deletes text before and after the current cursor position, excluding the + // selection. The lengths are supplied in code points, not in Java chars + // (UTF-16 Code Unit) or in glyphs. Does nothing if there are one or more + // invalid surrogate pairs in the requested range + DeleteSurroundingTextInCodePoints(int32 before, int32 after); + + // Selects between the given start and end offsets in the currently focused + // editable field. + SetEditableSelectionOffsets(int32 start, int32 end); + + // Message payload is the name/value of a WebCore edit command to execute. + ExecuteEditCommand(string command, mojo.common.mojom.String16? value); + + // These messages are typically generated from context menus and request the + // renderer to apply the specified operation to the current selection. + Undo(); + Redo(); + Cut(); + Copy(); + CopyToFindPboard(); + Paste(); + PasteAndMatchStyle(); + Delete(); + SelectAll(); + CollapseSelection(); + + // Replaces the selected region or a word around the cursor with the + // specified string. + Replace(mojo.common.mojom.String16 word); + + // Replaces the misspelling in the selected region with the specified string. + ReplaceMisspelling(mojo.common.mojom.String16 word); + + // Requests the renderer to select the region between two points. + // Expects a SelectRange_ACK message when finished. + SelectRange(gfx.mojom.Point base, gfx.mojom.Point extent); + + // Sent by the browser to ask the renderer to adjust the selection start and + // end points by the given amounts. A negative amount moves the selection + // towards the beginning of the document, a positive amount moves the + // selection towards the end of the document. + AdjustSelectionByCharacterOffset(int32 start, int32 end); + + // Requests the renderer to move the selection extent point to a new position. + // Expects a MoveRangeSelectionExtent_ACK message when finished. + MoveRangeSelectionExtent(gfx.mojom.Point extent); + + // TODO(dtapuska): Implement WidgetInputHandler. + // GetWidgetInputHandler(associated WidgetInputHandler& interface_request); +};
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java index b332afa..4b7f15f 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java +++ b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
@@ -633,7 +633,7 @@ int id = item.getItemId(); int groupId = item.getGroupId(); - if (id == mAssistMenuItemId) { + if (BuildInfo.isAtLeastO() && id == mAssistMenuItemId) { doAssistAction(); mode.finish(); } else if (id == R.id.select_action_menu_select_all) {
diff --git a/content/public/app/mojo/content_renderer_manifest.json b/content/public/app/mojo/content_renderer_manifest.json index 9abc705..ddd80d4 100644 --- a/content/public/app/mojo/content_renderer_manifest.json +++ b/content/public/app/mojo/content_renderer_manifest.json
@@ -42,6 +42,7 @@ "blink::mojom::EngagementClient", "blink::mojom::InstallationService", "content::mojom::ImageDownloader", + "content::mojom::FrameInputHandler", "mojom::MediaDevicesListener" ] },
diff --git a/content/public/browser/DEPS b/content/public/browser/DEPS index f2291a9..ca1ff35 100644 --- a/content/public/browser/DEPS +++ b/content/public/browser/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+components/payments/mojom/payment_app.mojom.h", + "+content/common/input/input_handler.mojom.h", "+device/screen_orientation/public/interfaces", "+device/wake_lock/public/interfaces", ]
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index 5b23cbaf..e4dfc1f 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -10,6 +10,7 @@ #include "base/callback_forward.h" #include "build/build_config.h" #include "content/common/content_export.h" +#include "content/common/input/input_handler.mojom.h" #include "content/public/common/console_message_level.h" #include "content/public/common/file_chooser_params.h" #include "ipc/ipc_listener.h" @@ -274,6 +275,8 @@ // process to determine whether access to a feature is allowed. virtual bool IsFeatureEnabled(blink::WebFeaturePolicyFeature feature) = 0; + virtual mojom::FrameInputHandler* GetFrameInputHandler() = 0; + private: // This interface should only be implemented inside content. friend class RenderFrameHostImpl;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 7e5f3f3f..3a01702 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -632,6 +632,9 @@ const char kMHTMLSkipNostoreMain[] = "skip-nostore-main"; const char kMHTMLSkipNostoreAll[] = "skip-nostore-all"; +// Use Mojo-based Input Event routing. +const char kMojoInputMessages[] = "mojo-input-messages"; + // Use a Mojo-based LocalStorage implementation. const char kMojoLocalStorage[] = "mojo-local-storage";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 3a5c975..2638248 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -193,6 +193,7 @@ CONTENT_EXPORT extern const char kMHTMLGeneratorOption[]; CONTENT_EXPORT extern const char kMHTMLSkipNostoreMain[]; CONTENT_EXPORT extern const char kMHTMLSkipNostoreAll[]; +CONTENT_EXPORT extern const char kMojoInputMessages[]; CONTENT_EXPORT extern const char kMojoLocalStorage[]; CONTENT_EXPORT extern const char kMuteAudio[]; CONTENT_EXPORT extern const char kNoReferrers[];
diff --git a/content/public/test/test_browser_thread_bundle.cc b/content/public/test/test_browser_thread_bundle.cc index fa85212..6d0d4df2 100644 --- a/content/public/test/test_browser_thread_bundle.cc +++ b/content/public/test/test_browser_thread_bundle.cc
@@ -10,6 +10,7 @@ #include "base/run_loop.h" #include "base/task_scheduler/task_scheduler.h" #include "base/test/scoped_async_task_scheduler.h" +#include "base/threading/sequenced_worker_pool.h" #include "content/browser/browser_thread_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread.h" @@ -78,6 +79,12 @@ // for DestructionObservers hooked to |message_loop_| to be able to invoke // BrowserThread::CurrentlyOn() -- ref. ~TestBrowserThread(). message_loop_.reset(); + + // Disable redirection of SequencedWorkerPools to TaskScheduler. This is + // required in order to reset global state so that tests following this one in + // this process can still manage their own SequencedWorkerPool without using + // TestBrowserThreadBundle. + base::SequencedWorkerPool::EnableForProcess(); } void TestBrowserThreadBundle::Init() { @@ -123,6 +130,9 @@ base::MakeUnique<base::test::ScopedAsyncTaskScheduler>(); } + // Enable redirection of SequencedWorkerPools to TaskScheduler. + base::SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess(); + if (options_ & REAL_DB_THREAD) { db_thread_ = base::MakeUnique<TestBrowserThread>(BrowserThread::DB); db_thread_->Start();
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index a71ae45e..4fa3a91c 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -157,6 +157,8 @@ "ime_event_guard.h", "in_process_renderer_thread.cc", "in_process_renderer_thread.h", + "input/frame_input_handler_impl.cc", + "input/frame_input_handler_impl.h", "input/input_event_filter.cc", "input/input_event_filter.h", "input/input_handler_manager.cc",
diff --git a/content/renderer/input/frame_input_handler_impl.cc b/content/renderer/input/frame_input_handler_impl.cc new file mode 100644 index 0000000..79be471 --- /dev/null +++ b/content/renderer/input/frame_input_handler_impl.cc
@@ -0,0 +1,391 @@ +// 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 "content/renderer/input/frame_input_handler_impl.h" + +#include <utility> + +#include "base/bind.h" +#include "base/debug/stack_trace.h" +#include "base/logging.h" +#include "content/renderer/ime_event_guard.h" +#include "content/renderer/render_thread_impl.h" +#include "content/renderer/render_view_impl.h" +#include "content/renderer/render_widget.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" + +namespace content { + +FrameInputHandlerImpl::FrameInputHandlerImpl( + base::WeakPtr<RenderFrameImpl> render_frame, + mojom::FrameInputHandlerRequest request) + : binding_(this), + render_frame_(render_frame), + input_event_queue_(render_frame->GetRenderWidget()->GetInputEventQueue()), + main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), + weak_ptr_factory_(this) + +{ + weak_this_ = weak_ptr_factory_.GetWeakPtr(); + // If we have created an input event queue move the mojo request over to the + // compositor thread. + if (input_event_queue_) { + // Mojo channel bound on compositor thread. + RenderThreadImpl::current()->compositor_task_runner()->PostTask( + FROM_HERE, base::BindOnce(&FrameInputHandlerImpl::BindNow, + base::Unretained(this), std::move(request))); + } else { + // Mojo channel bound on main thread. + BindNow(std::move(request)); + } +} + +FrameInputHandlerImpl::~FrameInputHandlerImpl() {} + +// static +void FrameInputHandlerImpl::CreateMojoService( + base::WeakPtr<RenderFrameImpl> render_frame, + const service_manager::BindSourceInfo& source_info, + mojom::FrameInputHandlerRequest request) { + DCHECK(render_frame); + + // Owns itself. Will be deleted when message pipe is destroyed. + new FrameInputHandlerImpl(render_frame, std::move(request)); +} + +void FrameInputHandlerImpl::RunOnMainThread(const base::Closure& closure) { + if (input_event_queue_) { + input_event_queue_->QueueClosure(closure); + } else { + closure.Run(); + } +} + +void FrameInputHandlerImpl::SetCompositionFromExistingText( + int32_t start, + int32_t end, + const std::vector<ui::CompositionUnderline>& ui_underlines) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::SetCompositionFromExistingText, + weak_this_, start, end, ui_underlines)); + return; + } + + if (!render_frame_) + return; + + ImeEventGuard guard(render_frame_->GetRenderWidget()); + std::vector<blink::WebCompositionUnderline> underlines; + for (const auto& underline : ui_underlines) { + blink::WebCompositionUnderline blink_underline( + underline.start_offset, underline.end_offset, underline.color, + underline.thick, underline.background_color); + underlines.push_back(blink_underline); + } + + render_frame_->GetWebFrame()->SetCompositionFromExistingText(start, end, + underlines); +} + +void FrameInputHandlerImpl::ExtendSelectionAndDelete(int32_t before, + int32_t after) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExtendSelectionAndDelete, + weak_this_, before, after)); + return; + } + if (!render_frame_) + return; + render_frame_->GetWebFrame()->ExtendSelectionAndDelete(before, after); +} + +void FrameInputHandlerImpl::DeleteSurroundingText(int32_t before, + int32_t after) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::DeleteSurroundingText, + weak_this_, before, after)); + return; + } + if (!render_frame_) + return; + render_frame_->GetWebFrame()->DeleteSurroundingText(before, after); +} + +void FrameInputHandlerImpl::DeleteSurroundingTextInCodePoints(int32_t before, + int32_t after) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::DeleteSurroundingTextInCodePoints, + weak_this_, before, after)); + return; + } + if (!render_frame_) + return; + render_frame_->GetWebFrame()->DeleteSurroundingTextInCodePoints(before, + after); +} + +void FrameInputHandlerImpl::SetEditableSelectionOffsets(int32_t start, + int32_t end) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::SetEditableSelectionOffsets, + weak_this_, start, end)); + return; + } + if (!render_frame_) + return; + render_frame_->GetWebFrame()->SetEditableSelectionOffsets(start, end); +} + +void FrameInputHandlerImpl::ExecuteEditCommand( + const std::string& command, + const base::Optional<base::string16>& value) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteEditCommand, + weak_this_, command, value)); + return; + } + if (!render_frame_) + return; + if (value) { + render_frame_->GetWebFrame()->ExecuteCommand( + blink::WebString::FromUTF8(command), + blink::WebString::FromUTF16(value.value())); + return; + } + + render_frame_->GetWebFrame()->ExecuteCommand( + blink::WebString::FromUTF8(command)); +} + +void FrameInputHandlerImpl::Undo() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "Undo", UpdateState::kNone)); +} + +void FrameInputHandlerImpl::Redo() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "Redo", UpdateState::kNone)); +} + +void FrameInputHandlerImpl::Cut() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "Cut", + UpdateState::kIsSelectingRange)); +} + +void FrameInputHandlerImpl::Copy() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "Copy", + UpdateState::kIsSelectingRange)); +} + +void FrameInputHandlerImpl::CopyToFindPboard() { +#if defined(OS_MACOSX) + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::CopyToFindPboard, weak_this_)); + return; + } + if (!render_frame_) + return; + render_frame_->OnCopyToFindPboard(); +#endif +} + +void FrameInputHandlerImpl::Paste() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "Paste", UpdateState::kIsPasting)); +} + +void FrameInputHandlerImpl::PasteAndMatchStyle() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "PasteAndMatchStyle", + UpdateState::kIsPasting)); +} + +void FrameInputHandlerImpl::Replace(const base::string16& word) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::Replace, weak_this_, word)); + return; + } + if (!render_frame_) + return; + blink::WebLocalFrame* frame = render_frame_->GetWebFrame(); + if (frame->HasSelection()) + frame->SelectWordAroundCaret(); + frame->ReplaceSelection(blink::WebString::FromUTF16(word)); + render_frame_->SyncSelectionIfRequired(); +} + +void FrameInputHandlerImpl::ReplaceMisspelling(const base::string16& word) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ReplaceMisspelling, + weak_this_, word)); + return; + } + if (!render_frame_) + return; + blink::WebLocalFrame* frame = render_frame_->GetWebFrame(); + if (!frame->HasSelection()) + return; + frame->ReplaceMisspelledRange(blink::WebString::FromUTF16(word)); +} + +void FrameInputHandlerImpl::Delete() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "Delete", UpdateState::kNone)); +} + +void FrameInputHandlerImpl::SelectAll() { + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread, + weak_this_, "SelectAll", + UpdateState::kIsSelectingRange)); +} + +void FrameInputHandlerImpl::CollapseSelection() { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::CollapseSelection, weak_this_)); + return; + } + + if (!render_frame_) + return; + const blink::WebRange& range = + render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + if (range.IsNull()) + return; + + HandlingState handling_state(render_frame_.get(), + UpdateState::kIsSelectingRange); + render_frame_->GetWebFrame()->SelectRange( + blink::WebRange(range.EndOffset(), 0)); +} + +void FrameInputHandlerImpl::SelectRange(const gfx::Point& base, + const gfx::Point& extent) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + // TODO(dtapuska): This event should be coalesced. Chrome IPC uses + // one outstanding event and an ACK to handle coalescing on the browser + // side. We should be able to clobber them in the main thread event queue. + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::SelectRange, weak_this_, + base, extent)); + return; + } + + if (!render_frame_) + return; + RenderViewImpl* render_view = render_frame_->render_view(); + HandlingState handling_state(render_frame_.get(), + UpdateState::kIsSelectingRange); + render_frame_->GetWebFrame()->SelectRange( + render_view->ConvertWindowPointToViewport(base), + render_view->ConvertWindowPointToViewport(extent)); +} + +void FrameInputHandlerImpl::AdjustSelectionByCharacterOffset(int32_t start, + int32_t end) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + RunOnMainThread( + base::Bind(&FrameInputHandlerImpl::AdjustSelectionByCharacterOffset, + weak_this_, start, end)); + return; + } + + if (!render_frame_) + return; + blink::WebRange range = + render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + if (range.IsNull()) + return; + + // Sanity checks to disallow empty and out of range selections. + if (start - end > range.length() || range.StartOffset() + start < 0) + return; + + HandlingState handling_state(render_frame_.get(), + UpdateState::kIsSelectingRange); + // A negative adjust amount moves the selection towards the beginning of + // the document, a positive amount moves the selection towards the end of + // the document. + render_frame_->GetWebFrame()->SelectRange( + blink::WebRange(range.StartOffset() + start, + range.length() + end - start), + blink::WebLocalFrame::kPreserveHandleVisibility); +} + +void FrameInputHandlerImpl::MoveRangeSelectionExtent(const gfx::Point& extent) { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + // TODO(dtapuska): This event should be coalesced. Chrome IPC uses + // one outstanding event and an ACK to handle coalescing on the browser + // side. We should be able to clobber them in the main thread event queue. + RunOnMainThread(base::Bind(&FrameInputHandlerImpl::MoveRangeSelectionExtent, + weak_this_, extent)); + return; + } + + if (!render_frame_) + return; + HandlingState handling_state(render_frame_.get(), + UpdateState::kIsSelectingRange); + render_frame_->GetWebFrame()->MoveRangeSelectionExtent( + render_frame_->render_view()->ConvertWindowPointToViewport(extent)); +} + +void FrameInputHandlerImpl::ExecuteCommandOnMainThread( + const std::string& command, + UpdateState update_state) { + if (!render_frame_) + return; + + HandlingState handling_state(render_frame_.get(), update_state); + render_frame_->GetWebFrame()->ExecuteCommand( + blink::WebString::FromUTF8(command)); +} + +void FrameInputHandlerImpl::Release() { + if (!main_thread_task_runner_->BelongsToCurrentThread()) { + // Close the binding on the compositor thread first before telling the main + // thread to delete this object. + binding_.Close(); + main_thread_task_runner_->PostTask( + FROM_HERE, base::Bind(&FrameInputHandlerImpl::Release, weak_this_)); + return; + } + delete this; +} + +void FrameInputHandlerImpl::BindNow(mojom::FrameInputHandlerRequest request) { + binding_.Bind(std::move(request)); + binding_.set_connection_error_handler( + base::Bind(&FrameInputHandlerImpl::Release, base::Unretained(this))); +} + +FrameInputHandlerImpl::HandlingState::HandlingState( + RenderFrameImpl* render_frame, + UpdateState state) + : render_frame_(render_frame), + original_select_range_value_(render_frame->handling_select_range()), + original_pasting_value_(render_frame->IsPasting()) { + switch (state) { + case UpdateState::kIsPasting: + render_frame->set_is_pasting(true); + case UpdateState::kIsSelectingRange: + render_frame->set_handling_select_range(true); + break; + case UpdateState::kNone: + break; + } +} + +FrameInputHandlerImpl::HandlingState::~HandlingState() { + render_frame_->set_handling_select_range(original_select_range_value_); + render_frame_->set_is_pasting(original_pasting_value_); +} + +} // namespace content
diff --git a/content/renderer/input/frame_input_handler_impl.h b/content/renderer/input/frame_input_handler_impl.h new file mode 100644 index 0000000..9c756029 --- /dev/null +++ b/content/renderer/input/frame_input_handler_impl.h
@@ -0,0 +1,113 @@ +// 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 CONTENT_RENDERER_INPUT_FRAME_INPUT_HANDLER_IMPL_H_ +#define CONTENT_RENDERER_INPUT_FRAME_INPUT_HANDLER_IMPL_H_ + +#include "base/memory/ref_counted.h" +#include "content/common/input/input_handler.mojom.h" +#include "content/renderer/render_frame_impl.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace content { +class MainThreadEventQueue; + +// This class provides an implementation of FrameInputHandler mojo interface. +// When a compositor thread is being used in the renderer the mojo channel +// is bound on the compositor thread. Method calls, and events received on the +// compositor thread are then placed in the MainThreadEventQueue for +// the associated RenderWidget. This is done as to ensure that input related +// messages and events that are handled on the compositor thread aren't +// executed before other input events that need to be processed on the +// main thread. ie. Since some messages flow to the compositor thread +// all input needs to flow there so the ordering of events is kept in sequence. +// +// eg. (B = Browser, CT = Compositor Thread, MT = Main Thread) +// B sends MouseEvent +// B sends Copy message +// CT receives MouseEvent (CT might do something with the MouseEvent) +// CT places MouseEvent in MainThreadEventQueue +// CT receives Copy message (CT has no use for the Copy message) +// CT places Copy message in MainThreadEventQueue +// MT receives MouseEvent +// MT receives Copy message +// +// When a compositor thread isn't used the mojo channel is just bound +// on the main thread and messages are handled right away. +class FrameInputHandlerImpl : public mojom::FrameInputHandler { + public: + static void CreateMojoService( + base::WeakPtr<RenderFrameImpl> render_frame, + const service_manager::BindSourceInfo& source_info, + mojom::FrameInputHandlerRequest request); + + void SetCompositionFromExistingText( + int32_t start, + int32_t end, + const std::vector<ui::CompositionUnderline>& underlines) override; + void ExtendSelectionAndDelete(int32_t before, int32_t after) override; + void DeleteSurroundingText(int32_t before, int32_t after) override; + void DeleteSurroundingTextInCodePoints(int32_t before, + int32_t after) override; + void SetEditableSelectionOffsets(int32_t start, int32_t end) override; + void ExecuteEditCommand(const std::string& command, + const base::Optional<base::string16>& value) override; + void Undo() override; + void Redo() override; + void Cut() override; + void Copy() override; + void CopyToFindPboard() override; + void Paste() override; + void PasteAndMatchStyle() override; + void Replace(const base::string16& word) override; + void ReplaceMisspelling(const base::string16& word) override; + void Delete() override; + void SelectAll() override; + void CollapseSelection() override; + void SelectRange(const gfx::Point& base, const gfx::Point& extent) override; + void AdjustSelectionByCharacterOffset(int32_t start, int32_t end) override; + void MoveRangeSelectionExtent(const gfx::Point& extent) override; + + private: + ~FrameInputHandlerImpl() override; + enum class UpdateState { kNone, kIsPasting, kIsSelectingRange }; + + class HandlingState { + public: + HandlingState(RenderFrameImpl* render_frame, UpdateState state); + ~HandlingState(); + + private: + RenderFrameImpl* render_frame_; + bool original_select_range_value_; + bool original_pasting_value_; + }; + + FrameInputHandlerImpl(base::WeakPtr<RenderFrameImpl> render_frame, + mojom::FrameInputHandlerRequest request); + + void RunOnMainThread(const base::Closure& closure); + void BindNow(mojom::FrameInputHandlerRequest request); + void ExecuteCommandOnMainThread(const std::string& command, + UpdateState state); + void Release(); + + mojo::Binding<mojom::FrameInputHandler> binding_; + + // |render_frame_| should only be accessed on the main thread. Use + // GetRenderFrame so that it will DCHECK this for you. + base::WeakPtr<RenderFrameImpl> render_frame_; + + scoped_refptr<MainThreadEventQueue> input_event_queue_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + + base::WeakPtr<FrameInputHandlerImpl> weak_this_; + base::WeakPtrFactory<FrameInputHandlerImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(FrameInputHandlerImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_INPUT_FRAME_INPUT_HANDLER_IMPL_H_
diff --git a/content/renderer/pepper/pepper_video_decoder_host.cc b/content/renderer/pepper/pepper_video_decoder_host.cc index 3aea65f..d3fb411d 100644 --- a/content/renderer/pepper/pepper_video_decoder_host.cc +++ b/content/renderer/pepper/pepper_video_decoder_host.cc
@@ -502,8 +502,10 @@ min_picture_count_); std::unique_ptr<VideoDecoderShim> new_decoder( new VideoDecoderShim(this, shim_texture_pool_size)); - if (!new_decoder->Initialize(profile_, this)) + if (!new_decoder->Initialize(media::VideoDecodeAccelerator::Config(profile_), + this)) { return false; + } software_fallback_used_ = true; decoder_.reset(new_decoder.release());
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index d1e9d50..1959c8e 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -111,6 +111,7 @@ #include "content/renderer/history_serialization.h" #include "content/renderer/image_downloader/image_downloader_impl.h" #include "content/renderer/ime_event_guard.h" +#include "content/renderer/input/frame_input_handler_impl.h" #include "content/renderer/input/input_handler_manager.h" #include "content/renderer/installedapp/related_apps_fetcher.h" #include "content/renderer/internal_document_state_data.h" @@ -6957,6 +6958,9 @@ GetAssociatedInterfaceRegistry()->AddInterface(base::Bind( &RenderFrameImpl::BindFrameBindingsControl, weak_factory_.GetWeakPtr())); + GetInterfaceRegistry()->AddInterface(base::Bind( + &FrameInputHandlerImpl::CreateMojoService, weak_factory_.GetWeakPtr())); + if (!frame_->Parent()) { // Only main frame have ImageDownloader service. GetInterfaceRegistry()->AddInterface(base::Bind(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index f2449e2..169b4ba 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -734,6 +734,12 @@ bool ScheduleFileChooser(const FileChooserParams& params, blink::WebFileChooserCompletion* completion); + bool handling_select_range() const { return handling_select_range_; } + + void set_is_pasting(bool value) { is_pasting_ = value; } + + void set_handling_select_range(bool value) { handling_select_range_ = value; } + // Plugin-related functions -------------------------------------------------- #if BUILDFLAG(ENABLE_PLUGINS) @@ -763,6 +769,16 @@ void OnSetPepperVolume(int32_t pp_instance, double volume); #endif // ENABLE_PLUGINS +#if defined(OS_MACOSX) + void OnCopyToFindPboard(); +#endif + + // Dispatches the current state of selection on the webpage to the browser if + // it has changed. + // TODO(varunjain): delete this method once we figure out how to keep + // selection handles in sync with the webpage. + void SyncSelectionIfRequired(); + protected: explicit RenderFrameImpl(const CreateParams& params); @@ -959,10 +975,6 @@ #endif #endif -#if defined(OS_MACOSX) - void OnCopyToFindPboard(); -#endif - // Callback scheduled from OnSerializeAsMHTML for when writing serialized // MHTML to file has been completed in the file thread. void OnWriteMHTMLToDiskComplete( @@ -1015,12 +1027,6 @@ void UpdateEncoding(blink::WebFrame* frame, const std::string& encoding_name); - // Dispatches the current state of selection on the webpage to the browser if - // it has changed. - // TODO(varunjain): delete this method once we figure out how to keep - // selection handles in sync with the webpage. - void SyncSelectionIfRequired(); - bool RunJavaScriptDialog(JavaScriptDialogType type, const base::string16& message, const base::string16& default_value,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 034304b..301fc74 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1230,7 +1230,6 @@ IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt) IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt) IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive) - IPC_MESSAGE_HANDLER(ViewMsg_ShowContextMenu, OnShowContextMenu) IPC_MESSAGE_HANDLER(ViewMsg_ReleaseDisambiguationPopupBitmap, OnReleaseDisambiguationPopupBitmap) IPC_MESSAGE_HANDLER(ViewMsg_ResolveTapDisambiguation, @@ -1279,7 +1278,8 @@ if (focused_frame) { input_handler_->set_handling_input_event(true); blink::WebRange initial_range = focused_frame->SelectionRange(); - did_select = focused_frame->SelectWordAroundCaret(); + if (!initial_range.IsNull()) + did_select = focused_frame->SelectWordAroundCaret(); if (did_select) { blink::WebRange adjusted_range = focused_frame->SelectionRange(); start_adjust = @@ -2411,20 +2411,6 @@ date_time_picker_client_.reset(NULL); } -#endif // defined(OS_ANDROID) - -void RenderViewImpl::OnShowContextMenu( - ui::MenuSourceType source_type, const gfx::Point& location) { - input_handler_->set_context_menu_source_type(source_type); - has_host_context_menu_location_ = true; - host_context_menu_location_ = location; - if (webview()) - webview()->ShowContextMenu( - static_cast<blink::WebMenuSourceType>(source_type)); - has_host_context_menu_location_ = false; -} - -#if defined(OS_ANDROID) bool RenderViewImpl::DidTapMultipleTargets( const WebSize& inner_viewport_offset, const WebRect& touch_rect,
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 9c7c1a14..3e0a8e7 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -518,8 +518,6 @@ void OnClosePage(); void OnClose(); - void OnShowContextMenu(ui::MenuSourceType source_type, - const gfx::Point& location); void OnDeterminePageLanguage(); void OnDisableScrollbarsForSmallWindows( const gfx::Size& disable_scrollbars_size_limit);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 6c5e6d5..40f6f5a 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -615,6 +615,7 @@ IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetFocus) IPC_MESSAGE_HANDLER(InputMsg_SyntheticGestureCompleted, OnSyntheticGestureCompleted) + IPC_MESSAGE_HANDLER(ViewMsg_ShowContextMenu, OnShowContextMenu) IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose) IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) IPC_MESSAGE_HANDLER(ViewMsg_EnableDeviceEmulation, @@ -839,6 +840,10 @@ Send(new InputHostMsg_HandleInputEvent_ACK(routing_id_, ack)); } +scoped_refptr<MainThreadEventQueue> RenderWidget::GetInputEventQueue() { + return input_event_queue_; +} + void RenderWidget::OnCursorVisibilityChange(bool is_visible) { if (GetWebWidget()) GetWebWidget()->SetCursorVisibilityState(is_visible); @@ -1586,6 +1591,18 @@ } } +void RenderWidget::OnShowContextMenu(ui::MenuSourceType source_type, + const gfx::Point& location) { + input_handler_->set_context_menu_source_type(source_type); + has_host_context_menu_location_ = true; + host_context_menu_location_ = location; + if (GetWebWidget()) { + GetWebWidget()->ShowContextMenu( + static_cast<blink::WebMenuSourceType>(source_type)); + } + has_host_context_menu_location_ = false; +} + void RenderWidget::OnImeSetComposition( const base::string16& text, const std::vector<WebCompositionUnderline>& underlines,
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index de53c102..06552149 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -428,6 +428,8 @@ InputEventAckState ack_result, uint32_t touch_event_id) override; + scoped_refptr<MainThreadEventQueue> GetInputEventQueue(); + protected: // Friend RefCounted so that the dtor can be non-public. Using this class // without ref-counting is an error. @@ -505,6 +507,9 @@ void OnCreateVideoAck(int32_t video_id); void OnUpdateVideoAck(int32_t video_id); void OnRequestMoveAck(); + // Request from browser to show context menu. + virtual void OnShowContextMenu(ui::MenuSourceType source_type, + const gfx::Point& location); virtual void OnImeSetComposition( const base::string16& text, const std::vector<blink::WebCompositionUnderline>& underlines,
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index f181da5..3db1cf81 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -1067,6 +1067,7 @@ payments::mojom::PaymentAppResponsePtr response = payments::mojom::PaymentAppResponse::New(); response->method_name = web_response.method_name.Utf8(); + response->stringified_details = web_response.stringified_details.Utf8(); response_callback->OnPaymentAppResponse( std::move(response), base::Time::FromDoubleT(dispatch_event_time)); context_->payment_response_callbacks.erase(payment_request_id);
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm index ad78163..64dbb03 100644 --- a/device/bluetooth/bluetooth_adapter_mac.mm +++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -100,12 +100,12 @@ initWithDiscoveryManager:low_energy_discovery_manager_.get() andAdapter:this]); low_energy_central_manager_.reset([[CBCentralManager alloc] - initWithDelegate:low_energy_central_manager_delegate_.get() + initWithDelegate:low_energy_central_manager_delegate_ queue:dispatch_get_main_queue()]); low_energy_discovery_manager_->SetCentralManager( - low_energy_central_manager_.get()); + low_energy_central_manager_); } - DCHECK(classic_discovery_manager_.get()); + DCHECK(classic_discovery_manager_); } BluetoothAdapterMac::~BluetoothAdapterMac() { @@ -293,8 +293,7 @@ central_manager.delegate = low_energy_central_manager_delegate_; low_energy_central_manager_.reset(central_manager, base::scoped_policy::RETAIN); - low_energy_discovery_manager_->SetCentralManager( - low_energy_central_manager_.get()); + low_energy_discovery_manager_->SetCentralManager(low_energy_central_manager_); } CBCentralManager* BluetoothAdapterMac::GetCentralManager() {
diff --git a/device/bluetooth/bluetooth_adapter_mac_unittest.mm b/device/bluetooth/bluetooth_adapter_mac_unittest.mm index b330b3fa..8dc4c00 100644 --- a/device/bluetooth/bluetooth_adapter_mac_unittest.mm +++ b/device/bluetooth/bluetooth_adapter_mac_unittest.mm
@@ -69,7 +69,7 @@ } base::scoped_nsobject<MockCBPeripheral> mock_peripheral( [[MockCBPeripheral alloc] initWithUTF8StringIdentifier:identifier]); - return [mock_peripheral.get().peripheral retain]; + return [[mock_peripheral peripheral] retain]; } NSDictionary* AdvertisementData() { @@ -100,7 +100,7 @@ mock_central_manager_.reset([[MockCentralManager alloc] init]); [mock_central_manager_ setState:desired_state]; CBCentralManager* centralManager = - (CBCentralManager*)mock_central_manager_.get(); + static_cast<CBCentralManager*>(mock_central_manager_.get()); adapter_mac_->SetCentralManagerForTesting(centralManager); return true; } @@ -234,7 +234,7 @@ return; base::scoped_nsobject<CBPeripheral> mock_peripheral( CreateMockPeripheral(kTestNSUUID)); - if (mock_peripheral.get() == nil) + if (!mock_peripheral) return; EXPECT_EQ(kTestHashAddress, GetHashAddress(mock_peripheral)); } @@ -244,7 +244,7 @@ return; base::scoped_nsobject<CBPeripheral> mock_peripheral( CreateMockPeripheral(kTestNSUUID)); - if (mock_peripheral.get() == nil) + if (!mock_peripheral) return; base::scoped_nsobject<NSDictionary> advertisement_data(AdvertisementData());
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm index 80de028..2f2cfa9b 100644 --- a/device/bluetooth/bluetooth_low_energy_device_mac.mm +++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -31,7 +31,7 @@ connected_(false), discovery_pending_count_(0) { DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); - DCHECK(peripheral_.get()); + DCHECK(peripheral_); peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] initWithBluetoothLowEnergyDeviceMac:this]); [peripheral_ setDelegate:peripheral_delegate_];
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm index 4c9d99f8..900f3f66 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm
@@ -74,11 +74,11 @@ gatt_service_(gatt_service), cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN), weak_ptr_factory_(this) { - uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( - [cb_characteristic_.get() UUID]); + uuid_ = + BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_characteristic_ UUID]); identifier_ = base::SysNSStringToUTF8( [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), - (void*)cb_characteristic_]); + cb_characteristic_.get()]); } BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { @@ -104,7 +104,7 @@ BluetoothGattCharacteristic::Properties BluetoothRemoteGattCharacteristicMac::GetProperties() const { - return ConvertProperties(cb_characteristic_.get().properties); + return ConvertProperties([cb_characteristic_ properties]); } BluetoothGattCharacteristic::Permissions @@ -125,7 +125,7 @@ } bool BluetoothRemoteGattCharacteristicMac::IsNotifying() const { - return cb_characteristic_.get().isNotifying == YES; + return [cb_characteristic_ isNotifying] == YES; } std::vector<BluetoothRemoteGattDescriptor*> @@ -223,8 +223,7 @@ DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); subscribe_to_notification_callbacks_ = std::make_pair(callback, error_callback); - [GetCBPeripheral() setNotifyValue:YES - forCharacteristic:cb_characteristic_.get()]; + [GetCBPeripheral() setNotifyValue:YES forCharacteristic:cb_characteristic_]; } void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( @@ -238,16 +237,14 @@ DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); unsubscribe_from_notification_callbacks_ = std::make_pair(callback, error_callback); - [GetCBPeripheral() setNotifyValue:NO - forCharacteristic:cb_characteristic_.get()]; + [GetCBPeripheral() setNotifyValue:NO forCharacteristic:cb_characteristic_]; } void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { VLOG(1) << *this << ": Discover descriptors."; is_discovery_complete_ = false; ++discovery_pending_count_; - [GetCBPeripheral() - discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; + [GetCBPeripheral() discoverDescriptorsForCharacteristic:cb_characteristic_]; } void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { @@ -286,7 +283,7 @@ } void BluetoothRemoteGattCharacteristicMac::UpdateValue() { - NSData* nsdata_value = cb_characteristic_.get().value; + NSData* nsdata_value = [cb_characteristic_ value]; const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); value_.assign(buffer, buffer + nsdata_value.length); } @@ -372,7 +369,7 @@ descriptor_identifier_to_remove.insert(iter.first); } - for (CBDescriptor* cb_descriptor in cb_characteristic_.get().descriptors) { + for (CBDescriptor* cb_descriptor in [cb_characteristic_ descriptors]) { BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = GetBluetoothRemoteGattDescriptorMac(cb_descriptor); if (gatt_descriptor_mac) { @@ -427,7 +424,7 @@ CBCharacteristic* BluetoothRemoteGattCharacteristicMac::GetCBCharacteristic() const { - return cb_characteristic_.get(); + return cb_characteristic_; } BluetoothAdapterMac* BluetoothRemoteGattCharacteristicMac::GetMacAdapter()
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm index a8ede9c..173adcdf 100644 --- a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm +++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
@@ -51,7 +51,7 @@ uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_ UUID]); identifier_ = base::SysNSStringToUTF8( [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), - (void*)cb_descriptor_]); + cb_descriptor_.get()]); } std::string BluetoothRemoteGattDescriptorMac::GetIdentifier() const {
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_mac.mm b/device/bluetooth/bluetooth_remote_gatt_service_mac.mm index 15ec871..06ed4199 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_mac.mm +++ b/device/bluetooth/bluetooth_remote_gatt_service_mac.mm
@@ -26,10 +26,10 @@ is_primary_(is_primary), is_discovery_complete_(false), discovery_pending_count_(0) { - uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([service_.get() UUID]); + uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([service_ UUID]); identifier_ = base::SysNSStringToUTF8( [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), - (void*)service_]); + service_.get()]); } BluetoothRemoteGattServiceMac::~BluetoothRemoteGattServiceMac() {} @@ -214,7 +214,7 @@ } CBService* BluetoothRemoteGattServiceMac::GetService() const { - return service_.get(); + return service_; } BluetoothRemoteGattCharacteristicMac*
diff --git a/device/bluetooth/test/bluetooth_test_mac.mm b/device/bluetooth/test/bluetooth_test_mac.mm index 3c5e8000..5f16078 100644 --- a/device/bluetooth/test/bluetooth_test_mac.mm +++ b/device/bluetooth/test/bluetooth_test_mac.mm
@@ -38,7 +38,7 @@ } // Returns MockCentralManager instance. - MockCentralManager* get() { return mock_central_manager_.get(); }; + MockCentralManager* get() { return mock_central_manager_; }; private: scoped_nsobject<MockCentralManager> mock_central_manager_; @@ -235,10 +235,10 @@ scoped_nsobject<MockCBPeripheral> mock_peripheral([[MockCBPeripheral alloc] initWithUTF8StringIdentifier:identifier name:name]); - mock_peripheral.get().bluetoothTestMac = this; + [mock_peripheral setBluetoothTestMac:this]; [central_manager_delegate centralManager:central_manager - didDiscoverPeripheral:mock_peripheral.get().peripheral + didDiscoverPeripheral:[mock_peripheral peripheral] advertisementData:CreateAdvertisementData(name, uuids, service_data, tx_power) RSSI:rssi]; @@ -276,14 +276,14 @@ } DCHECK(name); DCHECK(identifier); - DCHECK([cbUUIDs.get() count] > 0); + DCHECK([cbUUIDs count] > 0); scoped_nsobject<MockCBPeripheral> mock_peripheral([[MockCBPeripheral alloc] initWithUTF8StringIdentifier:identifier name:name]); - mock_peripheral.get().bluetoothTestMac = this; + [mock_peripheral setBluetoothTestMac:this]; [mock_central_manager_->get() - setConnectedMockPeripheral:mock_peripheral.get().peripheral - withServiceUUIDs:cbUUIDs.get()]; + setConnectedMockPeripheral:[mock_peripheral peripheral] + withServiceUUIDs:cbUUIDs]; } void BluetoothTestMac::SimulateGattConnectionError(
diff --git a/device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.mm b/device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.mm index 0a27de2..2fc9060 100644 --- a/device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.mm +++ b/device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.mm
@@ -192,11 +192,11 @@ scoped_nsobject<MockCBDescriptor> descriptor_mock([[MockCBDescriptor alloc] initWithCharacteristic:self.characteristic CBUUID:uuid]); - [_descriptors.get() addObject:descriptor_mock]; + [_descriptors addObject:descriptor_mock]; } - (CBUUID*)UUID { - return _UUID.get(); + return _UUID; } - (CBCharacteristic*)characteristic { @@ -216,7 +216,7 @@ } - (id)value { - return _value.get(); + return _value; } - (BOOL)isNotifying {
diff --git a/device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.mm b/device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.mm index 3a2f6152..1e0d82b 100644 --- a/device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.mm +++ b/device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.mm
@@ -48,11 +48,11 @@ } - (CBUUID*)UUID { - return _UUID.get(); + return _UUID; } - (NSData*)value { - return _value.get(); + return _value; } - (CBDescriptor*)descriptor {
diff --git a/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm b/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm index ef7667b..9a2bbb8 100644 --- a/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm +++ b/device/bluetooth/test/mock_bluetooth_cbperipheral_mac.mm
@@ -123,11 +123,11 @@ } - (void)removeAllServices { - [_services.get() removeAllObjects]; + [_services removeAllObjects]; } - (void)addServices:(NSArray*)services { - if (!_services.get()) { + if (!_services) { _services.reset([[NSMutableArray alloc] init]); } for (CBUUID* uuid in services) { @@ -135,7 +135,7 @@ initWithPeripheral:self.peripheral CBUUID:uuid primary:YES]); - [_services.get() addObject:service.get().service]; + [_services addObject:[service service]]; } } @@ -147,7 +147,7 @@ base::scoped_nsobject<CBService> serviceToRemove(service, base::scoped_policy::RETAIN); DCHECK(serviceToRemove); - [_services.get() removeObject:serviceToRemove]; + [_services removeObject:serviceToRemove]; [self didModifyServices:@[ serviceToRemove ]]; } @@ -200,15 +200,15 @@ } - (NSUUID*)identifier { - return _identifier.get(); + return _identifier; } - (NSString*)name { - return _name.get(); + return _name; } - (NSArray*)services { - return _services.get(); + return _services; } - (CBPeripheral*)peripheral {
diff --git a/device/bluetooth/test/mock_bluetooth_cbservice_mac.mm b/device/bluetooth/test/mock_bluetooth_cbservice_mac.mm index e82527d..cdd1516 100644 --- a/device/bluetooth/test/mock_bluetooth_cbservice_mac.mm +++ b/device/bluetooth/test/mock_bluetooth_cbservice_mac.mm
@@ -60,7 +60,7 @@ } - (CBUUID*)UUID { - return _UUID.get(); + return _UUID; } - (void)addCharacteristicWithUUID:(CBUUID*)cb_uuid properties:(int)properties { @@ -68,11 +68,11 @@ [[MockCBCharacteristic alloc] initWithService:self.service CBUUID:cb_uuid properties:properties]); - [_characteristics.get() addObject:characteristic_mock]; + [_characteristics addObject:characteristic_mock]; } - (void)removeCharacteristicMock:(MockCBCharacteristic*)characteristic_mock { - [_characteristics.get() removeObject:characteristic_mock]; + [_characteristics removeObject:characteristic_mock]; } - (CBService*)service { @@ -80,7 +80,7 @@ } - (NSArray*)characteristics { - return _characteristics.get(); + return _characteristics; } @end
diff --git a/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm b/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm index fa0bd848..2a571246 100644 --- a/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm +++ b/device/bluetooth/test/mock_bluetooth_central_manager_mac.mm
@@ -78,16 +78,16 @@ } - (NSArray*)retrieveConnectedPeripheralServiceUUIDs { - return [[_retrieveConnectedPeripheralServiceUUIDs.get() copy] autorelease]; + return [[_retrieveConnectedPeripheralServiceUUIDs copy] autorelease]; } - (NSArray*)retrieveConnectedPeripheralsWithServices:(NSArray*)services { - [_retrieveConnectedPeripheralServiceUUIDs.get() + [_retrieveConnectedPeripheralServiceUUIDs addObjectsFromArray:[services copy]]; NSMutableArray* connectedPeripherals = [[NSMutableArray alloc] init]; for (CBUUID* uuid in services) { NSSet* peripheralSet = - [_connectedMockPeripheralPerServiceUUID.get() objectForKey:uuid]; + [_connectedMockPeripheralPerServiceUUID objectForKey:uuid]; [connectedPeripherals addObjectsFromArray:peripheralSet.allObjects]; } return connectedPeripherals; @@ -97,11 +97,11 @@ withServiceUUIDs:(NSSet*)serviceUUIDs { for (CBUUID* uuid in serviceUUIDs) { NSMutableSet* peripheralSet = - [_connectedMockPeripheralPerServiceUUID.get() objectForKey:uuid]; + [_connectedMockPeripheralPerServiceUUID objectForKey:uuid]; if (!peripheralSet) { peripheralSet = [NSMutableSet set]; - [_connectedMockPeripheralPerServiceUUID.get() setObject:peripheralSet - forKey:uuid]; + [_connectedMockPeripheralPerServiceUUID setObject:peripheralSet + forKey:uuid]; } [peripheralSet addObject:peripheral]; }
diff --git a/device/vr/vr_types.h b/device/vr/vr_types.h index a030bd9..a6980413 100644 --- a/device/vr/vr_types.h +++ b/device/vr/vr_types.h
@@ -25,13 +25,6 @@ float angle; } RotationAxisAngle; -typedef struct Colorf { - float r; - float g; - float b; - float a; -} Colorf; - // A floating point quaternion, in JPL format. typedef struct Quatf { /// qx, qy, qz are the vector component.
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 286ca631..04aafe1 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -5,6 +5,8 @@ import("//build/config/features.gni") import("//extensions/features/features.gni") +assert(enable_extensions) + group("browser") { public_deps = [ "//extensions/browser:browser_context_keyed_service_factories", @@ -12,14 +14,10 @@ "//extensions/browser/api:api_registration", ] - if (enable_extensions) { - # Includes all API implementations and the ExtensionsApiClient - # interface. Moving an API from src/chrome to src/extensions implies - # it can be cleanly disabled with enable_extensions=false. - # TODO: Eventually the entire extensions module should not be built - # when enable_extensions=false. - public_deps += [ "//extensions/browser/api" ] - } + # Includes all API implementations and the ExtensionsApiClient + # interface. Moving an API from src/chrome to src/extensions implies + # it can be cleanly disabled with enable_extensions=false. + public_deps += [ "//extensions/browser/api" ] } # Isolate the instantiation of BrowserContextKeyedServiceFactories. @@ -40,17 +38,231 @@ source_set("browser_sources") { visibility = [ "./*" ] - sources = [] + sources = [ + "api_activity_monitor.cc", + "api_activity_monitor.h", + "app_sorting.h", + "bad_message.cc", + "bad_message.h", + "blacklist_state.h", + "blob_holder.cc", + "blob_holder.h", + "blocked_action_type.h", + "browser_context_keyed_api_factory.h", + "component_extension_resource_manager.h", + "computed_hashes.cc", + "computed_hashes.h", + "content_hash_fetcher.cc", + "content_hash_fetcher.h", + "content_hash_reader.cc", + "content_hash_reader.h", + "content_hash_tree.cc", + "content_hash_tree.h", + "content_verifier.cc", + "content_verifier.h", + "content_verifier_delegate.h", + "content_verifier_io_data.cc", + "content_verifier_io_data.h", + "content_verify_job.cc", + "content_verify_job.h", + "crx_file_info.cc", + "crx_file_info.h", + "declarative_user_script_manager.cc", + "declarative_user_script_manager.h", + "declarative_user_script_manager_factory.cc", + "declarative_user_script_manager_factory.h", + "declarative_user_script_master.cc", + "declarative_user_script_master.h", + "deferred_start_render_host.h", + "deferred_start_render_host_observer.h", + "error_map.cc", + "error_map.h", + "event_listener_map.cc", + "event_listener_map.h", + "event_page_tracker.h", + "event_router.cc", + "event_router.h", + "event_router_factory.cc", + "event_router_factory.h", + "extension_api_frame_id_map.cc", + "extension_api_frame_id_map.h", + "extension_dialog_auto_confirm.cc", + "extension_dialog_auto_confirm.h", + "extension_error.cc", + "extension_error.h", + "extension_function.cc", + "extension_function.h", + "extension_function_dispatcher.cc", + "extension_function_dispatcher.h", + "extension_function_registry.cc", + "extension_function_registry.h", + "extension_host.cc", + "extension_host.h", + "extension_host_delegate.h", + "extension_host_observer.h", + "extension_host_queue.h", + "extension_icon_image.cc", + "extension_icon_image.h", + "extension_icon_placeholder.cc", + "extension_icon_placeholder.h", + "extension_message_filter.cc", + "extension_message_filter.h", + "extension_navigation_throttle.cc", + "extension_navigation_throttle.h", + "extension_navigation_ui_data.cc", + "extension_navigation_ui_data.h", + "extension_pref_store.cc", + "extension_pref_store.h", + "extension_pref_value_map.cc", + "extension_pref_value_map.h", + "extension_pref_value_map_factory.cc", + "extension_pref_value_map_factory.h", + "extension_prefs.cc", + "extension_prefs.h", + "extension_prefs_factory.cc", + "extension_prefs_factory.h", + "extension_prefs_observer.h", + "extension_prefs_scope.h", + "extension_protocols.cc", + "extension_protocols.h", + "extension_registry.cc", + "extension_registry.h", + "extension_registry_factory.cc", + "extension_registry_factory.h", + "extension_registry_observer.h", + "extension_request_limiting_throttle.cc", + "extension_request_limiting_throttle.h", + "extension_scoped_prefs.h", + "extension_service_worker_message_filter.cc", + "extension_service_worker_message_filter.h", + "extension_system.cc", + "extension_system.h", + "extension_system_provider.cc", + "extension_system_provider.h", + "extension_throttle_entry.cc", + "extension_throttle_entry.h", + "extension_throttle_entry_interface.h", + "extension_throttle_manager.cc", + "extension_throttle_manager.h", + "extension_user_script_loader.cc", + "extension_user_script_loader.h", + "extension_util.cc", + "extension_util.h", + "extension_web_contents_observer.cc", + "extension_web_contents_observer.h", + "extension_zoom_request_client.cc", + "extension_zoom_request_client.h", + "extensions_browser_client.cc", + "extensions_browser_client.h", + "external_install_info.cc", + "external_install_info.h", + "external_provider_interface.h", + "file_highlighter.cc", + "file_highlighter.h", + "file_reader.cc", + "file_reader.h", + "granted_file_entry.cc", + "granted_file_entry.h", + "image_loader.cc", + "image_loader.h", + "image_loader_factory.cc", + "image_loader_factory.h", + "info_map.cc", + "info_map.h", + "install_flag.h", + "io_thread_extension_message_filter.cc", + "io_thread_extension_message_filter.h", + "lazy_background_task_queue.cc", + "lazy_background_task_queue.h", + "lazy_background_task_queue_factory.cc", + "lazy_background_task_queue_factory.h", + "load_monitoring_extension_host_queue.cc", + "load_monitoring_extension_host_queue.h", + "management_policy.cc", + "management_policy.h", + "mojo/keep_alive_impl.cc", + "mojo/keep_alive_impl.h", + "mojo/service_registration.cc", + "mojo/service_registration.h", + "notification_types.cc", + "notification_types.h", + "null_app_sorting.cc", + "null_app_sorting.h", + "policy_check.cc", + "policy_check.h", + "pref_names.cc", + "pref_names.h", + "preload_check.cc", + "preload_check.h", + "preload_check_group.cc", + "preload_check_group.h", + "process_manager.cc", + "process_manager.h", + "process_manager_delegate.h", + "process_manager_factory.cc", + "process_manager_factory.h", + "process_manager_observer.h", + "process_map.cc", + "process_map.h", + "process_map_factory.cc", + "process_map_factory.h", + "quota_service.cc", + "quota_service.h", + "renderer_startup_helper.cc", + "renderer_startup_helper.h", + "requirements_checker.cc", + "requirements_checker.h", + "runtime_data.cc", + "runtime_data.h", + "sandboxed_unpacker.cc", + "sandboxed_unpacker.h", + "script_execution_observer.h", + "script_executor.cc", + "script_executor.h", + "serial_extension_host_queue.cc", + "serial_extension_host_queue.h", + "service_worker_manager.cc", + "service_worker_manager.h", + "state_store.cc", + "state_store.h", + "suggest_permission_util.cc", + "suggest_permission_util.h", + "uninstall_ping_sender.cc", + "uninstall_ping_sender.h", + "uninstall_reason.h", + "update_observer.h", + "url_request_util.cc", + "url_request_util.h", + "user_script_loader.cc", + "user_script_loader.h", + "verified_contents.cc", + "verified_contents.h", + "view_type_utils.cc", + "view_type_utils.h", + "warning_service.cc", + "warning_service.h", + "warning_service_factory.cc", + "warning_service_factory.h", + "warning_set.cc", + "warning_set.h", + "web_ui_user_script_loader.cc", + "web_ui_user_script_loader.h", + ] deps = [ "//base:i18n", "//components/cast_certificate", + "//components/crx_file", "//components/guest_view/browser", "//components/keyed_service/content", "//components/keyed_service/core", "//components/pref_registry", + "//components/prefs", "//components/sessions", + "//components/sync", "//components/update_client", + "//components/update_client", + "//components/variations", "//components/version_info", "//components/web_cache/browser", "//components/web_modal", @@ -58,256 +270,35 @@ "//content/public/browser", "//content/public/common", "//crypto:platform", + "//crypto:platform", + "//extensions:extensions_browser_resources", + "//extensions/common", "//extensions/common", "//extensions/common/api", "//extensions/features", "//extensions/strings", "//google_apis", + "//services/preferences/public/cpp", + "//services/service_manager/public/cpp", "//ui/display", ] + public_deps = [ + "//extensions/browser/app_window", + "//extensions/browser/guest_view", + "//extensions/browser/install", + "//extensions/browser/kiosk", + "//extensions/browser/updater", + "//extensions/browser/value_store", + "//ipc", + ] + configs += [ "//build/config:precompiled_headers", # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. "//build/config/compiler:no_size_t_to_int_warning", ] - - if (enable_extensions) { - sources = [ - "api_activity_monitor.cc", - "api_activity_monitor.h", - "app_sorting.h", - "bad_message.cc", - "bad_message.h", - "blacklist_state.h", - "blob_holder.cc", - "blob_holder.h", - "blocked_action_type.h", - "browser_context_keyed_api_factory.h", - "component_extension_resource_manager.h", - "computed_hashes.cc", - "computed_hashes.h", - "content_hash_fetcher.cc", - "content_hash_fetcher.h", - "content_hash_reader.cc", - "content_hash_reader.h", - "content_hash_tree.cc", - "content_hash_tree.h", - "content_verifier.cc", - "content_verifier.h", - "content_verifier_delegate.h", - "content_verifier_io_data.cc", - "content_verifier_io_data.h", - "content_verify_job.cc", - "content_verify_job.h", - "crx_file_info.cc", - "crx_file_info.h", - "declarative_user_script_manager.cc", - "declarative_user_script_manager.h", - "declarative_user_script_manager_factory.cc", - "declarative_user_script_manager_factory.h", - "declarative_user_script_master.cc", - "declarative_user_script_master.h", - "deferred_start_render_host.h", - "deferred_start_render_host_observer.h", - "error_map.cc", - "error_map.h", - "event_listener_map.cc", - "event_listener_map.h", - "event_page_tracker.h", - "event_router.cc", - "event_router.h", - "event_router_factory.cc", - "event_router_factory.h", - "extension_api_frame_id_map.cc", - "extension_api_frame_id_map.h", - "extension_dialog_auto_confirm.cc", - "extension_dialog_auto_confirm.h", - "extension_error.cc", - "extension_error.h", - "extension_function.cc", - "extension_function.h", - "extension_function_dispatcher.cc", - "extension_function_dispatcher.h", - "extension_function_registry.cc", - "extension_function_registry.h", - "extension_host.cc", - "extension_host.h", - "extension_host_delegate.h", - "extension_host_observer.h", - "extension_host_queue.h", - "extension_icon_image.cc", - "extension_icon_image.h", - "extension_icon_placeholder.cc", - "extension_icon_placeholder.h", - "extension_message_filter.cc", - "extension_message_filter.h", - "extension_navigation_throttle.cc", - "extension_navigation_throttle.h", - "extension_navigation_ui_data.cc", - "extension_navigation_ui_data.h", - "extension_pref_store.cc", - "extension_pref_store.h", - "extension_pref_value_map.cc", - "extension_pref_value_map.h", - "extension_pref_value_map_factory.cc", - "extension_pref_value_map_factory.h", - "extension_prefs.cc", - "extension_prefs.h", - "extension_prefs_factory.cc", - "extension_prefs_factory.h", - "extension_prefs_observer.h", - "extension_prefs_scope.h", - "extension_protocols.cc", - "extension_protocols.h", - "extension_registry.cc", - "extension_registry.h", - "extension_registry_factory.cc", - "extension_registry_factory.h", - "extension_registry_observer.h", - "extension_request_limiting_throttle.cc", - "extension_request_limiting_throttle.h", - "extension_scoped_prefs.h", - "extension_service_worker_message_filter.cc", - "extension_service_worker_message_filter.h", - "extension_system.cc", - "extension_system.h", - "extension_system_provider.cc", - "extension_system_provider.h", - "extension_throttle_entry.cc", - "extension_throttle_entry.h", - "extension_throttle_entry_interface.h", - "extension_throttle_manager.cc", - "extension_throttle_manager.h", - "extension_user_script_loader.cc", - "extension_user_script_loader.h", - "extension_util.cc", - "extension_util.h", - "extension_web_contents_observer.cc", - "extension_web_contents_observer.h", - "extension_zoom_request_client.cc", - "extension_zoom_request_client.h", - "extensions_browser_client.cc", - "extensions_browser_client.h", - "external_install_info.cc", - "external_install_info.h", - "external_provider_interface.h", - "file_highlighter.cc", - "file_highlighter.h", - "file_reader.cc", - "file_reader.h", - "granted_file_entry.cc", - "granted_file_entry.h", - "image_loader.cc", - "image_loader.h", - "image_loader_factory.cc", - "image_loader_factory.h", - "info_map.cc", - "info_map.h", - "install_flag.h", - "io_thread_extension_message_filter.cc", - "io_thread_extension_message_filter.h", - "lazy_background_task_queue.cc", - "lazy_background_task_queue.h", - "lazy_background_task_queue_factory.cc", - "lazy_background_task_queue_factory.h", - "load_monitoring_extension_host_queue.cc", - "load_monitoring_extension_host_queue.h", - "management_policy.cc", - "management_policy.h", - "mojo/keep_alive_impl.cc", - "mojo/keep_alive_impl.h", - "mojo/service_registration.cc", - "mojo/service_registration.h", - "notification_types.cc", - "notification_types.h", - "null_app_sorting.cc", - "null_app_sorting.h", - "policy_check.cc", - "policy_check.h", - "pref_names.cc", - "pref_names.h", - "preload_check.cc", - "preload_check.h", - "preload_check_group.cc", - "preload_check_group.h", - "process_manager.cc", - "process_manager.h", - "process_manager_delegate.h", - "process_manager_factory.cc", - "process_manager_factory.h", - "process_manager_observer.h", - "process_map.cc", - "process_map.h", - "process_map_factory.cc", - "process_map_factory.h", - "quota_service.cc", - "quota_service.h", - "renderer_startup_helper.cc", - "renderer_startup_helper.h", - "requirements_checker.cc", - "requirements_checker.h", - "runtime_data.cc", - "runtime_data.h", - "sandboxed_unpacker.cc", - "sandboxed_unpacker.h", - "script_execution_observer.h", - "script_executor.cc", - "script_executor.h", - "serial_extension_host_queue.cc", - "serial_extension_host_queue.h", - "service_worker_manager.cc", - "service_worker_manager.h", - "state_store.cc", - "state_store.h", - "suggest_permission_util.cc", - "suggest_permission_util.h", - "uninstall_ping_sender.cc", - "uninstall_ping_sender.h", - "uninstall_reason.h", - "update_observer.h", - "url_request_util.cc", - "url_request_util.h", - "user_script_loader.cc", - "user_script_loader.h", - "verified_contents.cc", - "verified_contents.h", - "view_type_utils.cc", - "view_type_utils.h", - "warning_service.cc", - "warning_service.h", - "warning_service_factory.cc", - "warning_service_factory.h", - "warning_set.cc", - "warning_set.h", - "web_ui_user_script_loader.cc", - "web_ui_user_script_loader.h", - ] - - public_deps = [ - "//extensions/browser/app_window", - "//extensions/browser/guest_view", - "//extensions/browser/install", - "//extensions/browser/kiosk", - "//extensions/browser/updater", - "//extensions/browser/value_store", - "//ipc", - ] - - deps += [ - "//components/crx_file", - "//components/prefs", - "//components/sync", - "//components/update_client", - "//components/variations", - "//crypto:platform", - "//extensions:extensions_browser_resources", - "//extensions/common", - "//services/preferences/public/cpp", - "//services/service_manager/public/cpp", - ] - } } source_set("browser_tests") {
diff --git a/extensions/test/BUILD.gn b/extensions/test/BUILD.gn index e04c482..96322ea 100644 --- a/extensions/test/BUILD.gn +++ b/extensions/test/BUILD.gn
@@ -2,8 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//extensions/features/features.gni") import("//tools/json_schema_compiler/json_features.gni") +assert(enable_extensions) + json_features("test_api_features") { feature_type = "APIFeature" provider_class = "TestAPIFeatureProvider"
diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc index 2777b46b..798c5029 100644 --- a/google_apis/gcm/tools/mcs_probe.cc +++ b/google_apis/gcm/tools/mcs_probe.cc
@@ -38,7 +38,6 @@ #include "google_apis/gcm/engine/gservices_settings.h" #include "google_apis/gcm/engine/mcs_client.h" #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h" -#include "net/base/host_mapping_rules.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_policy_enforcer.h" #include "net/cert/multi_log_ct_verifier.h" @@ -257,7 +256,6 @@ MCSProbeAuthPreferences http_auth_preferences_; std::unique_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory_; std::unique_ptr<net::HttpServerPropertiesImpl> http_server_properties_; - std::unique_ptr<net::HostMappingRules> host_mapping_rules_; std::unique_ptr<net::HttpNetworkSession> network_session_; std::unique_ptr<net::ProxyService> proxy_service_; @@ -406,7 +404,6 @@ http_auth_handler_factory_ = net::HttpAuthHandlerRegistryFactory::Create( &http_auth_preferences_, host_resolver_.get()); http_server_properties_.reset(new net::HttpServerPropertiesImpl()); - host_mapping_rules_.reset(new net::HostMappingRules()); proxy_service_ = net::ProxyService::CreateDirectWithNetLog(&net_log_); } @@ -421,7 +418,6 @@ session_params.ssl_config_service = new net::SSLConfigServiceDefaults(); session_params.http_auth_handler_factory = http_auth_handler_factory_.get(); session_params.http_server_properties = http_server_properties_.get(); - session_params.host_mapping_rules = host_mapping_rules_.get(); session_params.ignore_certificate_errors = true; session_params.testing_fixed_http_port = 0; session_params.testing_fixed_https_port = 0;
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.mm b/ios/chrome/browser/snapshots/snapshot_cache.mm index 7fb720d..612dc57e 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache.mm +++ b/ios/chrome/browser/snapshots/snapshot_cache.mm
@@ -10,6 +10,7 @@ #include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/lazy_instance.h" #include "base/location.h" #include "base/logging.h" #include "base/mac/bind_objc_block.h" @@ -18,6 +19,7 @@ #include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" #include "base/task_runner_util.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_restrictions.h" #include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/snapshots/lru_cache.h" @@ -52,12 +54,20 @@ const NSUInteger kCacheInitialCapacity = 100; const NSUInteger kGreyInitialCapacity = 8; const CGFloat kJPEGImageQuality = 1.0; // Highest quality. No compression. -// Sequence token to make sure creation/deletion of snapshots don't overlap. -const char kSequenceToken[] = "SnapshotCacheSequenceToken"; // Maximum size in number of elements that the LRU cache can hold before // starting to evict elements. const NSUInteger kLRUCacheMaxCapacity = 6; +struct SnapshotTaskRunner { + const scoped_refptr<base::SequencedTaskRunner> task_runner = + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); +}; + +// Sequence token to make sure creation/deletion of snapshots don't overlap. +base::LazyInstance<SnapshotTaskRunner>::Leaky g_snapshot_task_runner = + LAZY_INSTANCE_INITIALIZER; + // The paths of the images saved to disk, given a cache directory. base::FilePath FilePathForSessionID(NSString* sessionID, const base::FilePath& directory) { @@ -275,9 +285,8 @@ [imageDictionary_ setObject:img forKey:sessionID]; // Save the image to disk. - web::WebThread::PostBlockingPoolSequencedTask( - kSequenceToken, FROM_HERE, - base::BindBlock(^{ + g_snapshot_task_runner.Get().task_runner->PostTask( + FROM_HERE, base::BindBlock(^{ base::scoped_nsobject<UIImage> image([img retain]); WriteImageToDisk(image, [SnapshotCache imagePathForSessionID:sessionID]); @@ -291,9 +300,8 @@ else [imageDictionary_ removeObjectForKey:sessionID]; - web::WebThread::PostBlockingPoolSequencedTask( - kSequenceToken, FROM_HERE, - base::BindBlock(^{ + g_snapshot_task_runner.Get().task_runner->PostTask( + FROM_HERE, base::BindBlock(^{ base::FilePath imagePath = [SnapshotCache imagePathForSessionID:sessionID]; base::DeleteFile(imagePath, false); @@ -357,9 +365,8 @@ DCHECK_CURRENTLY_ON(web::WebThread::UI); // Copying the date, as the block must copy the value, not the reference. const base::Time dateCopy = date; - web::WebThread::PostBlockingPoolSequencedTask( - kSequenceToken, FROM_HERE, - base::BindBlock(^{ + g_snapshot_task_runner.Get().task_runner->PostTask( + FROM_HERE, base::BindBlock(^{ std::set<base::FilePath> filesToKeep; for (NSString* sessionID : liveSessionIds) { base::FilePath curImagePath = @@ -574,9 +581,10 @@ } } - web::WebThread::PostBlockingPoolTask( - FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath, - greyImagePath, backgroundingColorImage_)); + base::PostTaskWithTraits( + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, + base::BindOnce(&ConvertAndSaveGreyImage, colorImagePath, greyImagePath, + backgroundingColorImage_)); } @end
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm index 51fa1c8e..500f9422 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm +++ b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
@@ -16,11 +16,10 @@ #include "base/mac/scoped_nsobject.h" #include "base/run_loop.h" #include "base/strings/sys_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/task_scheduler.h" #include "base/time/time.h" #import "ios/chrome/browser/snapshots/snapshot_cache_internal.h" #include "ios/web/public/test/test_web_thread_bundle.h" -#include "ios/web/public/web_thread.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -84,7 +83,7 @@ // Flushes all the runloops internally used by the snapshot cache. void FlushRunLoops() { base::RunLoop().RunUntilIdle(); - web::WebThread::GetBlockingPool()->FlushForTesting(); + base::TaskScheduler::GetInstance()->FlushForTesting(); base::RunLoop().RunUntilIdle(); }
diff --git a/ios/web/public/web_thread.h b/ios/web/public/web_thread.h index be41b30..0ab786c 100644 --- a/ios/web/public/web_thread.h +++ b/ios/web/public/web_thread.h
@@ -139,38 +139,6 @@ return GetTaskRunnerForThread(identifier)->DeleteSoon(from_here, object); } - // Simplified wrappers for posting to the blocking thread pool. Use this - // for doing things like blocking I/O. - // - // The first variant will run the task in the pool with no sequencing - // semantics, so may get run in parallel with other posted tasks. The second - // variant will all post a task with no sequencing semantics, and will post a - // reply task to the origin TaskRunner upon completion. The third variant - // provides sequencing between tasks with the same sequence token name. - // - // These tasks are guaranteed to run before shutdown. - // - // If you need to provide different shutdown semantics (like you have - // something slow and noncritical that doesn't need to block shutdown), - // or you want to manually provide a sequence token (which saves a map - // lookup and is guaranteed unique without you having to come up with a - // unique string), you can access the sequenced worker pool directly via - // GetBlockingPool(). - // - // If you need to PostTaskAndReplyWithResult, use - // base::PostTaskAndReplyWithResult() with GetBlockingPool() as the task - // runner. - static bool PostBlockingPoolTask(const tracked_objects::Location& from_here, - base::OnceClosure task); - static bool PostBlockingPoolTaskAndReply( - const tracked_objects::Location& from_here, - base::OnceClosure task, - base::OnceClosure reply); - static bool PostBlockingPoolSequencedTask( - const std::string& sequence_token_name, - const tracked_objects::Location& from_here, - base::OnceClosure task); - // Returns the thread pool used for blocking file I/O. Use this object to // perform random blocking operations such as file writes. static base::SequencedWorkerPool* GetBlockingPool() WARN_UNUSED_RESULT;
diff --git a/ios/web/web_state/navigation_callbacks_inttest.mm b/ios/web/web_state/navigation_callbacks_inttest.mm index cedf3bb..56e2e82 100644 --- a/ios/web/web_state/navigation_callbacks_inttest.mm +++ b/ios/web/web_state/navigation_callbacks_inttest.mm
@@ -172,7 +172,7 @@ // Verifies correctness of |NavigationContext| (|arg0|) for reload navigation // passed to |DidFinishNavigation|. Asserts that |NavigationContext| the same as // |context|. -ACTION_P3(VerifyReloadFinishedContext, web_state, url, context) { +ACTION_P4(VerifyReloadFinishedContext, web_state, url, context, is_web_page) { ASSERT_EQ(*context, arg0); ASSERT_TRUE(*context); EXPECT_EQ(web_state, (*context)->GetWebState()); @@ -182,7 +182,14 @@ (*context)->GetPageTransition())); EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); - EXPECT_FALSE((*context)->GetResponseHeaders()); + if (is_web_page) { + ASSERT_TRUE((*context)->GetResponseHeaders()); + std::string mime_type; + (*context)->GetResponseHeaders()->GetMimeType(&mime_type); + EXPECT_EQ(kExpectedMimeType, mime_type); + } else { + EXPECT_FALSE((*context)->GetResponseHeaders()); + } NavigationManager* navigation_manager = web_state->GetNavigationManager(); NavigationItem* item = navigation_manager->GetLastCommittedItem(); EXPECT_GT(item->GetTimestamp().ToInternalValue(), 0); @@ -230,6 +237,36 @@ LoadUrl(url); } +// Tests web page reload navigation. +TEST_F(StartAndFinishNavigationTest, WebPageReloadNavigation) { + const GURL url = HttpServer::MakeUrl("http://chromium.test"); + std::map<GURL, std::string> responses; + responses[url] = "Chromium Test"; + web::test::SetUpSimpleHttpServer(responses); + + // Perform new page navigation. + NavigationContext* context = nullptr; + EXPECT_CALL(*observer_, DidStartNavigation(_)); + EXPECT_CALL(*observer_, DidFinishNavigation(_)); + LoadUrl(url); + + // Reload web page. + EXPECT_CALL(*observer_, DidStartNavigation(_)) + .WillOnce(VerifyReloadStartedContext(web_state(), url, &context)); + EXPECT_CALL(*observer_, DidFinishNavigation(_)) + .WillOnce(VerifyReloadFinishedContext(web_state(), url, &context, + true /* is_web_page */)); + // TODO(crbug.com/700958): ios/web ignores |check_for_repost| flag and current + // delegate does not run callback for ShowRepostFormWarningDialog. Clearing + // the delegate will allow form resubmission. Remove this workaround (clearing + // the delegate, once |check_for_repost| is supported). + web_state()->SetDelegate(nullptr); + ExecuteBlockAndWaitForLoad(url, ^{ + navigation_manager()->Reload(ReloadType::NORMAL, + false /*check_for_repost*/); + }); +} + // Tests user-initiated hash change. TEST_F(StartAndFinishNavigationTest, UserInitiatedHashChangeNavigation) { const GURL url = HttpServer::MakeUrl("http://chromium.test"); @@ -362,7 +399,8 @@ EXPECT_CALL(*observer_, DidStartNavigation(_)) .WillOnce(VerifyReloadStartedContext(web_state(), url, &context)); EXPECT_CALL(*observer_, DidFinishNavigation(_)) - .WillOnce(VerifyReloadFinishedContext(web_state(), url, &context)); + .WillOnce(VerifyReloadFinishedContext(web_state(), url, &context, + false /* is_web_page */)); navigation_manager()->Reload(ReloadType::NORMAL, false /*check_for_repost*/); }
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index ec226cd..7e7dfc3 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -2053,10 +2053,8 @@ [transientItem->GetHttpRequestHeaders() copy]); [self loadWithParams:reloadParams]; } else { - // As with back and forward navigation, load the URL manually instead of - // using the web view's reload. This ensures state processing and delegate - // calls are consistent. - // TODO(eugenebut): revisit this for WKWebView. + self.currentNavItem->SetTransitionType( + ui::PageTransition::PAGE_TRANSITION_RELOAD); [self loadCurrentURL]; } }
diff --git a/ios/web/web_thread_impl.cc b/ios/web/web_thread_impl.cc index b6d082e..d1d6f415 100644 --- a/ios/web/web_thread_impl.cc +++ b/ios/web/web_thread_impl.cc
@@ -330,31 +330,6 @@ } // static -bool WebThread::PostBlockingPoolTask(const tracked_objects::Location& from_here, - base::OnceClosure task) { - return g_globals.Get().blocking_pool->PostWorkerTask(from_here, - std::move(task)); -} - -// static -bool WebThread::PostBlockingPoolTaskAndReply( - const tracked_objects::Location& from_here, - base::OnceClosure task, - base::OnceClosure reply) { - return g_globals.Get().blocking_pool->PostTaskAndReply( - from_here, std::move(task), std::move(reply)); -} - -// static -bool WebThread::PostBlockingPoolSequencedTask( - const std::string& sequence_token_name, - const tracked_objects::Location& from_here, - base::OnceClosure task) { - return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( - sequence_token_name, from_here, std::move(task)); -} - -// static base::SequencedWorkerPool* WebThread::GetBlockingPool() { return g_globals.Get().blocking_pool.get(); }
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java index 9baeee13..8f67ebba 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
@@ -87,7 +87,13 @@ @SuppressWarnings("deprecation") private int getCodecCount() { if (hasNewMediaCodecList()) return mCodecList.length; - return MediaCodecList.getCodecCount(); + try { + return MediaCodecList.getCodecCount(); + } catch (RuntimeException e) { + // Swallow the exception due to bad Android implementation and pretend + // MediaCodecList is not supported. + return 0; + } } @SuppressWarnings("deprecation")
diff --git a/media/blink/multibuffer_data_source.cc b/media/blink/multibuffer_data_source.cc index 4d8d045a..c0e7c1dd 100644 --- a/media/blink/multibuffer_data_source.cc +++ b/media/blink/multibuffer_data_source.cc
@@ -505,6 +505,8 @@ render_task_runner_->PostTask( FROM_HERE, base::Bind(base::ResetAndReturn(&init_cb_), success)); + UpdateBufferSizes(); + // Even if data is cached, say that we're loading at this point for // compatibility. UpdateLoadingState_Locked(true); @@ -610,6 +612,17 @@ std::min((kTargetSecondsBufferedAhead + kTargetSecondsBufferedBehind) * bytes_per_second, preload_high + pin_backward); + + if (url_data_->FullyCached() || + (url_data_->length() != kPositionNotSpecified && + url_data_->length() < kDefaultPinSize)) { + // We just make pin_forwards/backwards big enough to encompass the + // whole file regardless of where we are, with some extra margins. + pin_forward = std::max(pin_forward, url_data_->length() * 2); + pin_backward = std::max(pin_backward, url_data_->length() * 2); + buffer_size = url_data_->length(); + } + reader_->SetMaxBuffer(buffer_size); reader_->SetPinRange(pin_backward, pin_forward);
diff --git a/media/blink/multibuffer_data_source_unittest.cc b/media/blink/multibuffer_data_source_unittest.cc index 90a6cea..1ade7293 100644 --- a/media/blink/multibuffer_data_source_unittest.cc +++ b/media/blink/multibuffer_data_source_unittest.cc
@@ -239,14 +239,15 @@ void InitializeWithCORS(const char* url, bool expected, - UrlData::CORSMode cors_mode) { + UrlData::CORSMode cors_mode, + size_t file_size = kFileSize) { GURL gurl(url); data_source_.reset(new MockMultibufferDataSource( gurl, cors_mode, message_loop_.task_runner(), url_index_, view_->MainFrame()->ToWebLocalFrame(), &host_)); data_source_->SetPreload(preload_); - response_generator_.reset(new TestResponseGenerator(gurl, kFileSize)); + response_generator_.reset(new TestResponseGenerator(gurl, file_size)); EXPECT_CALL(*this, OnInitialize(expected)); data_source_->Initialize(base::Bind( &MultibufferDataSourceTest::OnInitialize, base::Unretained(this))); @@ -256,8 +257,10 @@ EXPECT_EQ(data_source_->downloading(), false); } - void Initialize(const char* url, bool expected) { - InitializeWithCORS(url, expected, UrlData::CORS_UNSPECIFIED); + void Initialize(const char* url, + bool expected, + size_t file_size = kFileSize) { + InitializeWithCORS(url, expected, UrlData::CORS_UNSPECIFIED, file_size); } // Helper to initialize tests with a valid 200 response. @@ -272,8 +275,8 @@ } // Helper to initialize tests with a valid 206 response. - void InitializeWith206Response() { - Initialize(kHttpUrl, true); + void InitializeWith206Response(size_t file_size = kFileSize) { + Initialize(kHttpUrl, true, file_size); EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length())); Respond(response_generator_->Generate206(0)); @@ -1515,7 +1518,7 @@ } TEST_F(MultibufferDataSourceTest, CheckBufferSizes) { - InitializeWith206Response(); + InitializeWith206Response(1 << 30); // 1 gb data_source_->SetBitrate(1 << 20); // 1 mbit / s base::RunLoop().RunUntilIdle(); @@ -1563,6 +1566,28 @@ EXPECT_EQ(71 << 20, buffer_size()); } +TEST_F(MultibufferDataSourceTest, CheckBufferSizeForSmallFiles) { + InitializeWith206Response(); + + data_source_->SetBitrate(1 << 20); // 1 mbit / s + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1 << 20, data_source_bitrate()); + EXPECT_EQ(2 << 20, preload_low()); + EXPECT_EQ(3 << 20, preload_high()); + EXPECT_EQ(25 << 20, max_buffer_forward()); + EXPECT_EQ(kFileSize * 2, max_buffer_backward()); + EXPECT_EQ(5013504 /* file size rounted up to blocks size */, buffer_size()); + + data_source_->SetBitrate(80 << 20); // 80 mbit / s + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(80 << 20, data_source_bitrate()); + EXPECT_EQ(50 << 20, preload_low()); + EXPECT_EQ(51 << 20, preload_high()); + EXPECT_EQ(51 << 20, max_buffer_forward()); + EXPECT_EQ(20 << 20, max_buffer_backward()); + EXPECT_EQ(5013504 /* file size rounted up to blocks size */, buffer_size()); +} + // Provoke an edge case where the loading state may not end up transitioning // back to "idle" when we're done loading. TEST_F(MultibufferDataSourceTest, Http_CheckLoadingTransition) {
diff --git a/media/blink/resource_multibuffer_data_provider.cc b/media/blink/resource_multibuffer_data_provider.cc index 18a8847f..54f0d73 100644 --- a/media/blink/resource_multibuffer_data_provider.cc +++ b/media/blink/resource_multibuffer_data_provider.cc
@@ -452,6 +452,10 @@ url_data_->set_length(size); fifo_.push_back(DataBuffer::CreateEOSBuffer()); + if (url_data_->url_index()) { + url_data_->url_index()->TryInsert(url_data_); + } + DCHECK(Available()); url_data_->multibuffer()->OnDataProviderEvent(this);
diff --git a/media/blink/url_index.cc b/media/blink/url_index.cc index f255cb19..21babb7f 100644 --- a/media/blink/url_index.cc +++ b/media/blink/url_index.cc
@@ -149,10 +149,19 @@ scoped_refptr<UrlData>(this))); } -bool UrlData::Valid() const { +bool UrlData::FullyCached() { + DCHECK(thread_checker_.CalledOnValidThread()); + if (length_ == kPositionNotSpecified) + return false; + // Check that the first unavailable block in the cache is after the + // end of the file. + return (multibuffer()->FindNextUnavailable(0) << kBlockSizeShift) >= length_; +} + +bool UrlData::Valid() { DCHECK(thread_checker_.CalledOnValidThread()); base::Time now = base::Time::Now(); - if (!range_supported_) + if (!range_supported_ && !FullyCached()) return false; // When ranges are not supported, we cannot re-use cached data. if (valid_until_ > now)
diff --git a/media/blink/url_index.h b/media/blink/url_index.h index f18d358..d8c2a6cf 100644 --- a/media/blink/url_index.h +++ b/media/blink/url_index.h
@@ -91,6 +91,9 @@ // Returns the number of blocks cached for this resource. size_t CachedSize(); + // Returns true if this resource is fully cached in memory. + bool FullyCached(); + // Returns our url_index, or nullptr if it's been destroyed. UrlIndex* url_index() const { return url_index_.get(); } @@ -131,7 +134,7 @@ // Returns true it is valid to keep using this to access cached data. // A single media player instance may choose to ignore this for resources // that have already been opened. - bool Valid() const; + bool Valid(); // Virtual so we can override it for testing. virtual ResourceMultiBuffer* multibuffer();
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index 522e61cd..991394b3 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -647,10 +647,12 @@ LOG_ASSERT(decoder_deleted()); LOG_ASSERT(!decoder_.get()); + VideoDecodeAccelerator::Config config(profile_); + if (fake_decoder_) { decoder_.reset(new FakeVideoDecodeAccelerator( frame_size_, base::Bind(&DoNothingReturnTrue))); - LOG_ASSERT(decoder_->Initialize(profile_, this)); + LOG_ASSERT(decoder_->Initialize(config, this)); } else { if (!vda_factory_) { vda_factory_ = GpuVideoDecodeAcceleratorFactory::Create( @@ -660,7 +662,6 @@ LOG_ASSERT(vda_factory_); } - VideoDecodeAccelerator::Config config(profile_); if (g_test_import) { config.output_mode = VideoDecodeAccelerator::Config::OutputMode::IMPORT; }
diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index 6fe0573f..e61f6e2 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h
@@ -130,9 +130,7 @@ Config(); Config(const Config& config); - // Intentional converting constructor. - // TODO(watk): Make this explicit. - Config(VideoCodecProfile profile); + explicit Config(VideoCodecProfile profile); ~Config();
diff --git a/net/BUILD.gn b/net/BUILD.gn index ed29540..6b6dbf8 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -4331,6 +4331,7 @@ "cert/internal/certificate_policies_unittest.cc", "cert/internal/extended_key_usage_unittest.cc", "cert/internal/name_constraints_unittest.cc", + "cert/internal/nist_pkits_unittest.cc", "cert/internal/nist_pkits_unittest.h", "cert/internal/parse_certificate_unittest.cc", "cert/internal/parse_name_unittest.cc",
diff --git a/net/base/host_mapping_rules.cc b/net/base/host_mapping_rules.cc index 3c24b24..b8fef17 100644 --- a/net/base/host_mapping_rules.cc +++ b/net/base/host_mapping_rules.cc
@@ -28,22 +28,17 @@ HostMappingRules::HostMappingRules() {} +HostMappingRules::HostMappingRules(const HostMappingRules& host_mapping_rules) = + default; + HostMappingRules::~HostMappingRules() {} +HostMappingRules& HostMappingRules::operator=( + const HostMappingRules& host_mapping_rules) = default; + bool HostMappingRules::RewriteHost(HostPortPair* host_port) const { - // Check if the hostname was excluded. - for (ExclusionRuleList::const_iterator it = exclusion_rules_.begin(); - it != exclusion_rules_.end(); ++it) { - const ExclusionRule& rule = *it; - if (base::MatchPattern(host_port->host(), rule.hostname_pattern)) - return false; - } - // Check if the hostname was remapped. - for (MapRuleList::const_iterator it = map_rules_.begin(); - it != map_rules_.end(); ++it) { - const MapRule& rule = *it; - + for (const auto& rule : map_rules_) { // The rule's hostname_pattern will be something like: // www.foo.com // *.foo.com @@ -57,6 +52,12 @@ continue; // This rule doesn't apply. } + // Check if the hostname was excluded. + for (const auto& rule : exclusion_rules_) { + if (base::MatchPattern(host_port->host(), rule.hostname_pattern)) + return false; + } + host_port->set_host(rule.replacement_hostname); if (rule.replacement_port != -1) host_port->set_port(static_cast<uint16_t>(rule.replacement_port));
diff --git a/net/base/host_mapping_rules.h b/net/base/host_mapping_rules.h index 8c7bc0b..02aef43 100644 --- a/net/base/host_mapping_rules.h +++ b/net/base/host_mapping_rules.h
@@ -18,8 +18,11 @@ class NET_EXPORT_PRIVATE HostMappingRules { public: HostMappingRules(); + HostMappingRules(const HostMappingRules& host_mapping_rules); ~HostMappingRules(); + HostMappingRules& operator=(const HostMappingRules& host_mapping_rules); + // Modifies |*host_port| based on the current rules. Returns true if // |*host_port| was modified, false otherwise. bool RewriteHost(HostPortPair* host_port) const; @@ -46,8 +49,6 @@ MapRuleList map_rules_; ExclusionRuleList exclusion_rules_; - - DISALLOW_COPY_AND_ASSIGN(HostMappingRules); }; } // namespace net
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc index 9b2b35e..1dc2038 100644 --- a/net/base/network_change_notifier_win.cc +++ b/net/base/network_change_notifier_win.cc
@@ -14,6 +14,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" +#include "base/task_runner_util.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" @@ -136,8 +137,6 @@ // NetworkChangeNotifier::ConnectionType NetworkChangeNotifierWin::RecomputeCurrentConnectionType() const { - DCHECK(CalledOnValidThread()); - EnsureWinsockInit(); // The following code was adapted from: @@ -205,6 +204,18 @@ : NetworkChangeNotifier::CONNECTION_NONE; } +void NetworkChangeNotifierWin::RecomputeCurrentConnectionTypeOnDnsThread( + base::Callback<void(ConnectionType)> reply_callback) const { + // Unretained is safe in this call because this object owns the thread and the + // thread is stopped in this object's destructor. + base::PostTaskAndReplyWithResult( + dns_config_service_thread_->message_loop()->task_runner().get(), + FROM_HERE, + base::Bind(&NetworkChangeNotifierWin::RecomputeCurrentConnectionType, + base::Unretained(this)), + reply_callback); +} + NetworkChangeNotifier::ConnectionType NetworkChangeNotifierWin::GetCurrentConnectionType() const { base::AutoLock auto_lock(last_computed_connection_type_lock_); @@ -225,12 +236,13 @@ // Start watching for the next address change. WatchForAddressChange(); - NotifyObservers(); + RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + &NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); } -void NetworkChangeNotifierWin::NotifyObservers() { +void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { DCHECK(CalledOnValidThread()); - SetCurrentConnectionType(RecomputeCurrentConnectionType()); + SetCurrentConnectionType(connection_type); NotifyObserversOfIPAddressChange(); // Calling GetConnectionType() at this very moment is likely to give @@ -274,8 +286,11 @@ // Treat the transition from NotifyAddrChange failing to succeeding as a // network change event, since network changes were not being observed in // that interval. - if (sequential_failures_ > 0) - NotifyObservers(); + if (sequential_failures_ > 0) { + RecomputeCurrentConnectionTypeOnDnsThread( + base::Bind(&NetworkChangeNotifierWin::NotifyObservers, + weak_factory_.GetWeakPtr())); + } if (sequential_failures_ < 2000) { UMA_HISTOGRAM_COUNTS_10000("Net.NotifyAddrChangeFailures", @@ -305,7 +320,14 @@ } void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { - SetCurrentConnectionType(RecomputeCurrentConnectionType()); + RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChangeImpl, + weak_factory_.GetWeakPtr())); +} + +void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChangeImpl( + ConnectionType connection_type) { + SetCurrentConnectionType(connection_type); bool current_offline = IsOffline(); offline_polls_++; // If we continue to appear offline, delay sending out the notification in @@ -323,10 +345,10 @@ NotifyObserversOfConnectionTypeChange(); double max_bandwidth_mbps = 0.0; - ConnectionType connection_type = CONNECTION_NONE; + ConnectionType max_connection_type = CONNECTION_NONE; GetCurrentMaxBandwidthAndConnectionType(&max_bandwidth_mbps, - &connection_type); - NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps, connection_type); + &max_connection_type); + NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps, max_connection_type); } } // namespace net
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h index 94bab7f8..6871499 100644 --- a/net/base/network_change_notifier_win.h +++ b/net/base/network_change_notifier_win.h
@@ -9,6 +9,7 @@ #include <memory> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -62,15 +63,21 @@ // It is not thread safe, see crbug.com/324913. virtual ConnectionType RecomputeCurrentConnectionType() const; + // Calls RecomputeCurrentConnectionTypeImpl on the DNS thread and runs + // |reply_callback| with the type on the calling thread. + virtual void RecomputeCurrentConnectionTypeOnDnsThread( + base::Callback<void(ConnectionType)> reply_callback) const; + void SetCurrentConnectionType(ConnectionType connection_type); // Notifies IP address change observers of a change immediately, and notifies // network state change observers on a delay. Must only be called on the // thread |this| was created on. - void NotifyObservers(); + void NotifyObservers(ConnectionType connection_type); // Forwards connection type notifications to parent class. void NotifyParentOfConnectionTypeChange(); + void NotifyParentOfConnectionTypeChangeImpl(ConnectionType connection_type); // Tries to start listening for a single subsequent address change. Returns // false on failure. The caller is responsible for updating |is_watching_|.
diff --git a/net/base/network_change_notifier_win_unittest.cc b/net/base/network_change_notifier_win_unittest.cc index 40dc42d..96cf416b 100644 --- a/net/base/network_change_notifier_win_unittest.cc +++ b/net/base/network_change_notifier_win_unittest.cc
@@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "net/base/network_change_notifier_win.h" + #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/single_thread_task_runner.h" #include "net/base/network_change_notifier.h" #include "net/base/network_change_notifier_factory.h" -#include "net/base/network_change_notifier_win.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -39,6 +41,14 @@ } // From NetworkChangeNotifierWin. + void RecomputeCurrentConnectionTypeOnDnsThread( + base::Callback<void(ConnectionType)> reply_callback) const override { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(reply_callback, NetworkChangeNotifier::CONNECTION_UNKNOWN)); + } + + // From NetworkChangeNotifierWin. MOCK_METHOD0(WatchForAddressChangeInternal, bool()); private:
diff --git a/net/cert/internal/nist_pkits_unittest.cc b/net/cert/internal/nist_pkits_unittest.cc new file mode 100644 index 0000000..6e65dff --- /dev/null +++ b/net/cert/internal/nist_pkits_unittest.cc
@@ -0,0 +1,59 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/cert/internal/nist_pkits_unittest.h" + +#include "base/strings/string_split.h" +#include "net/cert/internal/certificate_policies.h" + +namespace net { + +namespace { + +// 2.16.840.1.101.3.2.1.48.1 +const uint8_t kTestPolicy1[] = {0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x02, 0x01, 0x30, 0x01}; + +// 2.16.840.1.101.3.2.1.48.2 +const uint8_t kTestPolicy2[] = {0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x02, 0x01, 0x30, 0x02}; + +// 2.16.840.1.101.3.2.1.48.3 +const uint8_t kTestPolicy3[] = {0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x02, 0x01, 0x30, 0x03}; + +// 2.16.840.1.101.3.2.1.48.6 +const uint8_t kTestPolicy6[] = {0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x02, 0x01, 0x30, 0x06}; + +} // namespace + +PkitsTestSettings::PkitsTestSettings() { + SetInitialPolicySet("anyPolicy"); +} + +PkitsTestSettings::~PkitsTestSettings() = default; + +void PkitsTestSettings::SetInitialPolicySet(const char* const policy_names) { + initial_policy_set.clear(); + std::vector<std::string> names = base::SplitString( + policy_names, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + for (const std::string& policy_name : names) { + if (policy_name == "anyPolicy") { + initial_policy_set.insert(AnyPolicy()); + } else if (policy_name == "NIST-test-policy-1") { + initial_policy_set.insert(der::Input(kTestPolicy1)); + } else if (policy_name == "NIST-test-policy-2") { + initial_policy_set.insert(der::Input(kTestPolicy2)); + } else if (policy_name == "NIST-test-policy-3") { + initial_policy_set.insert(der::Input(kTestPolicy3)); + } else if (policy_name == "NIST-test-policy-6") { + initial_policy_set.insert(der::Input(kTestPolicy6)); + } else { + ADD_FAILURE() << "Unknown policy name: " << policy_name; + } + } +} + +} // namespace net
diff --git a/net/cert/internal/nist_pkits_unittest.h b/net/cert/internal/nist_pkits_unittest.h index 6a454020..265f332 100644 --- a/net/cert/internal/nist_pkits_unittest.h +++ b/net/cert/internal/nist_pkits_unittest.h
@@ -5,9 +5,38 @@ #ifndef NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_ #define NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_ +#include <set> + #include "net/cert/internal/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" +namespace net { + +// Describes additional inputs to verification in the PKITS tests +// (which are referred to as "settings" in that document). +struct PkitsTestSettings { + // Default construction results in the "default settings". + PkitsTestSettings(); + ~PkitsTestSettings(); + + // Sets |initial_policy_set| to the specified policies. The + // policies are described as comma-separated symbolic strings like + // "anyPolicy" and "NIST-test-policy-1". + void SetInitialPolicySet(const char* const policy_names); + + // A set of policy OIDs to use for "initial-policy-set". + std::set<der::Input> initial_policy_set; + + // The value of "initial-explicit-policy". + bool initial_explicit_policy = false; + + // The value of "initial-policy-mapping-inhibit". + bool initial_policy_mapping_inhibit = false; + + // The value of "initial-inhibit-any-policy". + bool initial_inhibit_any_policy = false; +}; + // Parameterized test class for PKITS tests. // The instantiating code should define a PkitsTestDelegate with an appropriate // static Verify method, and then INSTANTIATE_TYPED_TEST_CASE_P for each @@ -17,7 +46,8 @@ public: template <size_t num_certs, size_t num_crls> bool Verify(const char* const (&cert_names)[num_certs], - const char* const (&crl_names)[num_crls]) { + const char* const (&crl_names)[num_crls], + const PkitsTestSettings& settings) { std::vector<std::string> cert_ders; for (const std::string& s : cert_names) cert_ders.push_back(net::ReadTestFileToString( @@ -26,11 +56,13 @@ for (const std::string& s : crl_names) crl_ders.push_back(net::ReadTestFileToString( "net/third_party/nist-pkits/crls/" + s + ".crl")); - return PkitsTestDelegate::Verify(cert_ders, crl_ders); + return PkitsTestDelegate::Verify(cert_ders, crl_ders, settings); } }; // Inline the generated test code: #include "net/third_party/nist-pkits/pkits_testcases-inl.h" +} // namespace net + #endif // NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_
diff --git a/net/cert/internal/path_builder_pkits_unittest.cc b/net/cert/internal/path_builder_pkits_unittest.cc index c9850208..81eceeef 100644 --- a/net/cert/internal/path_builder_pkits_unittest.cc +++ b/net/cert/internal/path_builder_pkits_unittest.cc
@@ -52,7 +52,8 @@ class PathBuilderPkitsTestDelegate { public: static bool Verify(std::vector<std::string> cert_ders, - std::vector<std::string> crl_ders) { + std::vector<std::string> crl_ders, + const PkitsTestSettings& settings) { if (cert_ders.empty()) { ADD_FAILURE() << "cert_ders is empty"; return false; @@ -112,7 +113,7 @@ "ValidDSASignaturesTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL"}; // DSA signatures are intentionally unsupported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.1.5 Valid DSA Parameter Inheritance Test5 @@ -124,7 +125,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL", "DSAParametersInheritedCACRL"}; // DSA signatures are intentionally unsupported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } class PkitsTest13SignatureVerificationCustomPathBuilderFoo @@ -139,7 +140,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA1CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.23 Valid RFC822 nameConstraints Test23 @@ -151,7 +152,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA2CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.25 Valid RFC822 nameConstraints Test25 @@ -163,7 +164,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA3CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.27 Valid DN and RFC822 nameConstraints Test27 @@ -176,7 +177,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA3CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.34 Valid URI nameConstraints Test34 @@ -187,7 +188,7 @@ "ValidURInameConstraintsTest34EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI1CACRL"}; // Name constraints on uniformResourceIdentifiers are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.36 Valid URI nameConstraints Test36 @@ -198,7 +199,7 @@ "ValidURInameConstraintsTest36EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI2CACRL"}; // Name constraints on uniformResourceIdentifiers are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } INSTANTIATE_TYPED_TEST_CASE_P(PathBuilder,
diff --git a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc index 2039a60d..8c16a3a6e 100644 --- a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc +++ b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
@@ -48,14 +48,16 @@ class VerifyCertificateChainPkitsTestDelegate { public: static bool Verify(std::vector<std::string> cert_ders, - std::vector<std::string> crl_ders) { + std::vector<std::string> crl_ders, + const PkitsTestSettings& settings) { if (cert_ders.empty()) { ADD_FAILURE() << "cert_ders is empty"; return false; } - // PKITS lists chains from trust anchor to target, VerifyCertificateChain - // takes them starting with the target and not including the trust anchor. + // PKITS lists chains from trust anchor to target, whereas + // VerifyCertificateChain takes them starting with the target and ending + // with the trust anchor. std::vector<scoped_refptr<net::ParsedCertificate>> input_chain; CertErrors parsing_errors; for (auto i = cert_ders.rbegin(); i != cert_ders.rend(); ++i) { @@ -97,7 +99,7 @@ "ValidDSASignaturesTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL"}; // DSA signatures are intentionally unsupported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.1.5 Valid DSA Parameter Inheritance Test5 @@ -109,7 +111,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL", "DSAParametersInheritedCACRL"}; // DSA signatures are intentionally unsupported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } class PkitsTest13SignatureVerificationCustom @@ -124,7 +126,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA1CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.23 Valid RFC822 nameConstraints Test23 @@ -136,7 +138,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA2CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.25 Valid RFC822 nameConstraints Test25 @@ -148,7 +150,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA3CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.27 Valid DN and RFC822 nameConstraints Test27 @@ -161,7 +163,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA3CRL"}; // Name constraints on rfc822Names are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.34 Valid URI nameConstraints Test34 @@ -172,7 +174,7 @@ "ValidURInameConstraintsTest34EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI1CACRL"}; // Name constraints on uniformResourceIdentifiers are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // Modified version of 4.13.36 Valid URI nameConstraints Test36 @@ -183,7 +185,7 @@ "ValidURInameConstraintsTest36EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI2CACRL"}; // Name constraints on uniformResourceIdentifiers are not supported. - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } INSTANTIATE_TYPED_TEST_CASE_P(VerifyCertificateChain,
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index dc6b262..6f5a1e5 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -109,7 +109,6 @@ ssl_config_service(nullptr), http_auth_handler_factory(nullptr), net_log(nullptr), - host_mapping_rules(nullptr), socket_performance_watcher_factory(nullptr), ignore_certificate_errors(false), testing_fixed_http_port(0),
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index d8e867f..89234cb 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h
@@ -21,6 +21,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" +#include "net/base/host_mapping_rules.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" #include "net/dns/host_resolver.h" @@ -95,7 +96,7 @@ HttpAuthHandlerFactory* http_auth_handler_factory; HttpServerProperties* http_server_properties; NetLog* net_log; - HostMappingRules* host_mapping_rules; + HostMappingRules host_mapping_rules; SocketPerformanceWatcherFactory* socket_performance_watcher_factory; bool ignore_certificate_errors; uint16_t testing_fixed_http_port;
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 669f04f..11b602c 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -219,7 +219,7 @@ } const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { - return session_->params().host_mapping_rules; + return &session_->params().host_mapping_rules; } void HttpStreamFactoryImpl::OnNewSpdySessionReady(
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc index b234702..986f9a3 100644 --- a/net/http/http_stream_factory_impl_job_controller.cc +++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -892,8 +892,7 @@ GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( const GURL& url, HostPortPair* endpoint) { - const HostMappingRules* mapping_rules = session_->params().host_mapping_rules; - if (mapping_rules && mapping_rules->RewriteHost(endpoint)) { + if (session_->params().host_mapping_rules.RewriteHost(endpoint)) { url::Replacements<char> replacements; const std::string port_str = base::UintToString(endpoint->port()); replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size()));
diff --git a/net/spdy/core/hpack/hpack_huffman_decoder.cc b/net/spdy/core/hpack/hpack_huffman_decoder.cc index 3e2fc9c..8513579 100644 --- a/net/spdy/core/hpack/hpack_huffman_decoder.cc +++ b/net/spdy/core/hpack/hpack_huffman_decoder.cc
@@ -292,9 +292,9 @@ return first_canonical + ordinal_in_length; } -char HpackHuffmanDecoder::CanonicalToSource(HuffmanWord canonical) { +uint8_t HpackHuffmanDecoder::CanonicalToSource(HuffmanWord canonical) { DCHECK_LT(canonical, 256u); - return static_cast<char>(kCanonicalToSymbol[canonical]); + return kCanonicalToSymbol[canonical]; } // TODO(jamessynge): Maybe further refactorings, including just passing in a
diff --git a/net/spdy/core/hpack/hpack_huffman_decoder.h b/net/spdy/core/hpack/hpack_huffman_decoder.h index d33fa581..8658b40 100644 --- a/net/spdy/core/hpack/hpack_huffman_decoder.h +++ b/net/spdy/core/hpack/hpack_huffman_decoder.h
@@ -57,9 +57,9 @@ static HuffmanWord DecodeToCanonical(HuffmanCodeLength code_length, HuffmanWord bits); - // Converts a canonical symbol to the source symbol (the char in the original + // Converts a canonical symbol to the source symbol (the octet in the original // string that was encoded). - static char CanonicalToSource(HuffmanWord canonical); + static uint8_t CanonicalToSource(HuffmanWord canonical); }; } // namespace net
diff --git a/net/spdy/core/hpack/hpack_huffman_decoder_test.cc b/net/spdy/core/hpack/hpack_huffman_decoder_test.cc index ddf1bcd..8ab010f 100644 --- a/net/spdy/core/hpack/hpack_huffman_decoder_test.cc +++ b/net/spdy/core/hpack/hpack_huffman_decoder_test.cc
@@ -47,7 +47,7 @@ return HpackHuffmanDecoder::DecodeToCanonical(code_length, bits); } - static char CanonicalToSource(HuffmanWord canonical) { + static uint8_t CanonicalToSource(HuffmanWord canonical) { return HpackHuffmanDecoder::CanonicalToSource(canonical); } }; @@ -68,8 +68,7 @@ if (canonical == 256u) { return canonical; } - return static_cast<unsigned char>( - HpackHuffmanDecoderPeer::CanonicalToSource(canonical)); + return HpackHuffmanDecoderPeer::CanonicalToSource(canonical); } void EncodeString(SpdyStringPiece input, SpdyString* encoded) {
diff --git a/net/third_party/nist-pkits/generate_tests.py b/net/third_party/nist-pkits/generate_tests.py index fe9f9b76..ac83c6f0 100644 --- a/net/third_party/nist-pkits/generate_tests.py +++ b/net/third_party/nist-pkits/generate_tests.py
@@ -32,13 +32,26 @@ output.write(');\n') -def generate_test(test_case_name, test_number, raw_test_name, certs, crls, should_validate, - output): +def bool_to_str(b): + return "true" if b else "false" + + +def output_test(test_case_name, test_number, raw_test_name, subpart_number, + info, certs, crls, sanitized_test_names, output): + '''Writes a test case to |output|, and appends the test name to + |sanitized_test_names|.''' sanitized_test_name = 'Section%s%s' % (test_number.split('.')[1], sanitize_name(raw_test_name)) + + if subpart_number is not None: + sanitized_test_name += "Subpart%d" % (subpart_number) + + sanitized_test_names.append(sanitized_test_name) + certs_formatted = ', '.join('"%s"' % n for n in certs) crls_formatted = ', '.join('"%s"' % n for n in crls) - assert_function = 'ASSERT_TRUE' if should_validate else 'ASSERT_FALSE' + assert_function = 'ASSERT_TRUE' if info.should_validate else 'ASSERT_FALSE' + output.write(''' // %(test_number)s %(raw_test_name)s WRAPPED_TYPED_TEST_P(%(test_case_name)s, %(sanitized_test_name)s) { @@ -48,24 +61,74 @@ const char* const crls[] = { %(crls_formatted)s }; - %(assert_function)s(this->Verify(certs, crls)); -} ''' % vars()) - return sanitized_test_name + default_settings = TestInfo(False) + + settings_str = '' + + # Output any non-default settings. Only settings that differ from + # the default settings are written, so as to keep the generated + # file more readable. + if info.initial_policy_set != default_settings.initial_policy_set: + settings_str += ''' settings.SetInitialPolicySet("%s"); +''' % (','.join(info.initial_policy_set)) + + if info.initial_explicit_policy != default_settings.initial_explicit_policy: + settings_str += ''' settings.initial_explicit_policy = %s; +''' % bool_to_str(info.initial_explicit_policy) + + if (info.initial_policy_mapping_inhibit != + default_settings.initial_policy_mapping_inhibit): + settings_str += ''' settings.initial_policy_mapping_inhibit = %s; +''' % bool_to_str(info.initial_policy_mapping_inhibit) + + if (info.initial_inhibit_any_policy != + default_settings.initial_inhibit_any_policy): + settings_str += '''settings.initial_inhibit_any_policy = %s; +''' % bool_to_str(info.initial_inhibit_any_policy) + + settings_param_str = '{}' + + if settings_str != '': + output.write(''' + // Custom settings + PkitsTestSettings settings; +''') + output.write(settings_str) + output.write('\n') + settings_param_str = 'settings' + + output.write(''' %(assert_function)s(this->Verify(certs, crls, %(settings_param_str)s)); +} +''' % vars()) # Matches a section header, ex: "4.1 Signature Verification" SECTION_MATCHER = re.compile('^\s*(\d+\.\d+)\s+(.+)\s*$') # Matches a test header, ex: "4.1.1 Valid Signatures Test1" TEST_MATCHER = re.compile('^\s*(\d+\.\d+.\d+)\s+(.+)\s*$') + +# Matches the various headers in a test specification. +EXPECTED_HEADER_MATCHER = re.compile('^\s*Expected Result:') +PROCEDURE_HEADER_MATCHER = re.compile('^\s*Procedure:') +PATH_HEADER_MATCHER = re.compile('^\s*Certification Path:') + +# Matches the Procedure text if using default settings. +USING_DEFAULT_SETTINGS_MATCHER = re.compile( + '^.*using the \s*default settings.*') + +# Matches the description text if using custom settings. +CUSTOM_SETTINGS_MATCHER = re.compile( + '.*this\s+test\s+be\s+validated\s+using\s+the\s+following\s+inputs:.*') + # Match an expected test result. Note that some results in the PDF have a typo # "path not should validate" instead of "path should not validate". TEST_RESULT_MATCHER = re.compile( - '^\s*Expected Result:.*path (should validate|' - 'should not validate|not should validate)') -PATH_HEADER_MATCHER = re.compile('^\s*Certification Path:') -# Matches a line in the certification path, ex: "\u2022 Good CA Cert, Good CA CRL" + '^.*path (should validate|should not validate|not should validate)') + +# Matches a line in the certification path, ex: +# "\u2022 Good CA Cert, Good CA CRL" PATH_MATCHER = re.compile('^\s*\xe2\x80\xa2\s*(.+)\s*$') # Matches a page number. These may appear in the middle of multi-line fields and # thus need to be ignored. @@ -73,30 +136,69 @@ # Matches if an entry in a certification path refers to a CRL, ex: # "onlySomeReasons CA2 CRL1". CRL_MATCHER = re.compile('^.*CRL\d*$') -def parse_test(lines, i, test_case_name, test_number, test_name, output): - expected_result = None - certs = [] - crls = [] + +class TestSections(object): + def __init__(self): + self.description_lines = [] + self.procedure_lines = [] + self.expected_result_lines = [] + self.cert_path_lines = [] + + +def parse_main_test_sections(lines, i): + result = TestSections() + + # Read the description lines (text after test name up until + # "Procedure:"). + result.description_lines = [] while i < len(lines): - result_match = TEST_RESULT_MATCHER.match(lines[i]) - i += 1 - if result_match: - expected_result = result_match.group(1) == 'should validate' + if PROCEDURE_HEADER_MATCHER.match(lines[i]): break + result.description_lines.append(lines[i]) + i += 1 + # Read the procedure lines (text starting at "Procedure:" and up until + # "Expected Result:". + result.procedure_lines = [] while i < len(lines): - path_match = PATH_HEADER_MATCHER.match(lines[i]) - i += 1 - if path_match: + if EXPECTED_HEADER_MATCHER.match(lines[i]): break + result.procedure_lines.append(lines[i]) + i += 1 + # Read the expected result lines (text starting at "Expected Result:" and up + # until "Certification Path:". + result.expected_result_lines = [] + while i < len(lines): + if PATH_HEADER_MATCHER.match(lines[i]): + break + result.expected_result_lines.append(lines[i]) + i += 1 + + # Read the certification path lines (text starting at "Certification Path:" + # and up until the next test title. + result.cert_path_lines = [] + while i < len(lines): + if TEST_MATCHER.match(lines[i]) or SECTION_MATCHER.match(lines[i]): + break + result.cert_path_lines.append(lines[i]) + i += 1 + + return i, result + + +def parse_cert_path_lines(lines): path_lines = [] - while i < len(lines): - line = lines[i].strip() - if TEST_MATCHER.match(line) or SECTION_MATCHER.match(line): - break - i += 1 + crls = [] + certs = [] + + for line in lines[1:]: + line = line.strip() + + if "is composed of the following objects:" in line: + continue + if not line or PAGE_NUMBER_MATCHER.match(line): continue path_match = PATH_MATCHER.match(line) @@ -114,13 +216,851 @@ else: certs.append(path) - assert certs - assert crls - assert expected_result is not None - sanitized_test_name = generate_test(test_case_name, test_number, test_name, - certs, crls, expected_result, output) + return certs, crls - return i, sanitized_test_name + +ANY_POLICY = 'anyPolicy' +TEST_POLICY_1 = 'NIST-test-policy-1' +TEST_POLICY_2 = 'NIST-test-policy-2' +TEST_POLICY_3 = 'NIST-test-policy-3' +TEST_POLICY_6 = 'NIST-test-policy-6' + +# TODO(eroman): This omits a few outputs from PKITS: +# +# * authorities-constrained-policy-set +# * user-constrained-policy-set +# * explicit-policy-indicator +# +# Consider adding the constrained policy sets in the future, if our +# verification code supports outputting them. +class TestInfo(object): + """This structure describes a test inputs and outputs""" + + def __init__(self, should_validate, + # These defaults come from section 3 of PKITS.pdf + initial_policy_set = [ANY_POLICY], + initial_explicit_policy = False, + initial_policy_mapping_inhibit = False, + initial_inhibit_any_policy = False): + self.should_validate = should_validate + self.initial_policy_set = initial_policy_set + self.initial_explicit_policy = initial_explicit_policy + self.initial_policy_mapping_inhibit = initial_policy_mapping_inhibit + self.initial_inhibit_any_policy = initial_inhibit_any_policy + + +TEST_OVERRIDES = { + '4.8.1': [ # All Certificates Same Policy Test1 + # 1. default settings, but with initial-explicit-policy set. The path + # should validate successfully + TestInfo(True, initial_explicit_policy=True), + + # 2. default settings, but with initial-explicit-policy set and + # initial-policy-set = {NIST-test-policy-1}. The path should validate + # successfully. + TestInfo(True, initial_explicit_policy=True, + initial_policy_set=[TEST_POLICY_1]), + + # 3. default settings, but with initial-explicit-policy set and + # initial-policy-set = {NIST-test-policy-2}. The path should not validate + # successfully. + TestInfo(False, initial_explicit_policy=True, + initial_policy_set=[TEST_POLICY_2]), + + # 4. default settings, but with initial-explicit-policy set and + # initial-policy-set = {NIST-test-policy-1, NIST-test-policy-2}. The path + # should validate successfully. + TestInfo(True, initial_explicit_policy=True, + initial_policy_set=[TEST_POLICY_1, TEST_POLICY_2]), + ], + + '4.8.2': [ # All Certificates No Policies Test2 + # 1. default settings. The path should validate successfully. + TestInfo(True), + + # 2. default settings, but with initial-explicit-policy set. The path + # should not validate successfully + TestInfo(False, initial_explicit_policy=True), + ], + + '4.8.3': [ # Different Policies Test3 + # 1. default settings. The path should validate successfully. + TestInfo(True), + + # 2. default settings, but with initial-explicit-policy set. The path + # should not validate successfully. + TestInfo(False, initial_explicit_policy=True), + + # 3. default settings, but with initial-explicit-policy set and + # initial-policy-set = {NIST-test-policy-1, NIST-test-policy-2}. The path + # should not validate successfully. + TestInfo(False, initial_explicit_policy=True, + initial_policy_set=[TEST_POLICY_1, TEST_POLICY_2]), + ], + + '4.8.4': [ # Different Policies Test4 + # Procedure: Validate Different Policies Test4 EE using the default + # settings or open and verify Signed Test Message 6.2.2.69 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. The explicit-policy-indicator + # will be set if the application can process the policyConstraints + # extension. If the application can process the policyConstraints extension + # then the path should not validate successfully. If the application can + # not process the policyConstraints extension, then the path should + # validate successfully. + TestInfo(False), + ], + + '4.8.5': [ # 4.8.5 Different Policies Test5 + # Procedure: Validate Different Policies Test5 EE using the default + # settings or open and verify Signed Test Message 6.2.2.70 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. The explicit-policy-indicator + # will be set if the application can process the policyConstraints + # extension. If the application can process the policyConstraints extension + # then the path should not validate successfully. If the application can + # not process the policyConstraints extension, then the path should + # validate successfully + TestInfo(False), + ], + + '4.8.6': [ # Overlapping Policies Test6 + # 1. default settings. The path should validate successfully. + TestInfo(True), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 3. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should not validate successfully. + TestInfo(False, initial_policy_set=[TEST_POLICY_2]), + ], + + '4.8.7': [ # Different Policies Test7 + # Procedure: Validate Different Policies Test7 EE using the default + # settings or open and verify Signed Test Message 6.2.2.72 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. If the + # explicit-policy-indicator will be set if the application can process the + # policyConstraints extension. If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. If the application can not process the policyConstraints + # extension, then the path should validate successfully. + TestInfo(False), + ], + + '4.8.8': [ # Different Policies Test8 + # Procedure: Validate Different Policies Test8 EE using the default + # settings or open and verify Signed Test Message 6.2.2.73 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. The explicit-policy-indicator + # will be set if the application can process the policyConstraints + # extension. If the application can process the policyConstraints extension + # then the path should not validate successfully. If the application can + # not process the policyConstraints extension, then the path should + # validate successfully. + TestInfo(False), + ], + + '4.8.9': [ # Different Policies Test9 + # Procedure: Validate Different Policies Test9 EE using the default + # settings or open and verify Signed Test Message 6.2.2.74 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. The explicit-policy-indicator + # will be set if the application can process the policyConstraints + # extension. If the application can process the policyConstraints + # extension, then the path should not validate successfully. If the + # application can not process the policyConstraints extension, then the + # path should validate successfully. + TestInfo(False), + ], + + '4.8.10': [ # All Certificates Same Policies Test10 + # 1. default settings. The path should validate successfully. + TestInfo(True), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 3. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_2]), + ], + + '4.8.11': [ # All Certificates AnyPolicy Test11 + # 1. default settings. The path should validate successfully. + TestInfo(True), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + ], + + '4.8.12': [ # Different Policies Test12 + # Procedure: Validate Different Policies Test12 EE using the default + # settings or open and verify Signed Test Message 6.2.2.77 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. The explicit-policy-indicator + # will be set if the application can process the policyConstraints + # extension. If the application can process the policyConstraints + # extension, then the path should not validate successfully. If the + # application can not process the policyConstraints extension, then the + # path should validate successfully. + TestInfo(False), + ], + + '4.8.13': [ # All Certificates Same Policies Test13 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_2]), + + # 3. default settings, but with initial-policy-set = {NIST-test-policy-3}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_3]), + ], + + '4.8.14': [ # AnyPolicy Test14 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should not validate successfully. + TestInfo(False, initial_policy_set=[TEST_POLICY_2]), + ], + + '4.8.15': [ # User Notice Qualifier Test15 + # Procedure: Validate User Notice Qualifier Test15 EE using the default + # settings or open and verify Signed Test Message 6.2.2.80 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be the same + # as the initial-explicit-policy indicator. If the initial-policy-set is + # any-policy or otherwise includes NIST-test-policy-1, then the + # user-constrained-policy-set will be {NIST-test-policy-1}. If not, the + # user-constrained-policy-set will be empty. If the initial-explicit-policy + # indicator is set and the initial-policy-set does not include + # NIST-test-policy-1, then the path should be rejected, otherwise it should + # validate successfully. If the path validates successfully, then the + # application should display the user notice. + TestInfo(True), + ], + + '4.8.16': [ # User Notice Qualifier Test16 + # Procedure: Validate User Notice Qualifier Test16 EE using the default + # settings or open and verify Signed Test Message 6.2.2.81 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be the same + # as the initial-explicit-policy indicator. If the initial-policy-set is + # any-policy or otherwise includes NIST-test-policy-1, then the + # user-constrained-policy-set will be {NIST-test-policy-1}. If not, the + # user-constrained-policy-set will be empty. If the initial-explicit-policy + # indicator is set and the initial-policy-set does not include + # NIST-test-policy-1, then the path should be rejected, otherwise it should + # validate successfully. If the path validates successfully, then the + # application should display the user notice associated with + # NIST-test-policy-1. The user notice associated with NIST-test-policy-2 + # should not be displayed. + TestInfo(True), + ], + + '4.8.17': [ # User Notice Qualifier Test17 + # Procedure: Validate User Notice Qualifier Test17 EE using the default + # settings or open and verify Signed Test Message 6.2.2.82 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be the same + # as the initial-explicit-policy indicator. If the initial-policy-set is + # any-policy or otherwise includes NIST-test-policy-1, then the + # user-constrained-policy-set will be {NIST-test-policy-1}. If not, the + # user-constrained-policy-set will be empty. If the initial-explicit-policy + # indicator is set and the initial-policy-set does not include + # NIST-test-policy-1, then the path should be rejected, otherwise it should + # validate successfully. If the path validates successfully, then the + # application should display the user notice associated with anyPolicy. + TestInfo(True), + ], + + '4.8.18': [ # User Notice Qualifier Test18 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully and the qualifier associated with + # NIST-test-policy-1 in the end entity certificate should be displayed. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should validate successfully and the qualifier associated with + # anyPolicy in the end entity certificate should be displayed. + TestInfo(True, initial_policy_set=[TEST_POLICY_2]), + ], + + '4.8.19': [ # User Notice Qualifier Test19 + # Procedure: Validate User Notice Qualifier Test19 EE using the default + # settings or open and verify Signed Test Message 6.2.2.84 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be the same + # as the initial-explicit-policy indicator. If the initial-policy-set is + # any-policy or otherwise includes NIST-test-policy-1, then the + # user-constrained-policy-set will be {NIST-test-policy-1}. If not, the + # user-constrained-policy-set will be empty. If the initial-explicit-policy + # indicator is set and the initial-policy-set does not include + # NIST-test-policy-1, then the path should be rejected, otherwise it should + # validate successfully. Since the explicitText exceeds the maximum size + # of 200 characters, the application may choose to reject the certificate. + # If the application accepts the certificate, display of the user notice is + # optional. + TestInfo(True), + ], + + '4.8.20': [ # CPS Pointer Qualifier Test20 + # Procedure: Validate CPS Pointer Qualifier Test20 EE using the default + # settings or open and verify Signed Test Message 6.2.2.85 using the + # default settings. (If possible, it is recommended that this test be run + # with the initial-explicit-policy indicator set. If this can not be done, + # manually check that the authorities-constrained-policy-set and + # user-constrained-policy-set are correct.) + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be the same + # as the initial-explicit-policy indicator. If the initial-policy-set is + # any-policy or otherwise includes NIST-test-policy-1, then the + # user-constrained-policy-set will be {NIST-test-policy-1}. If not, the + # user-constrained-policy-set will be empty. If the initial-explicit-policy + # indicator is set and the initial-policy-set does not include + # NIST-test-policy-1, then the path should be rejected, otherwise it should + # validate successfully. The CPS pointer in the qualifier should be + # associated with NIST-testpolicy-1 in the + # authorities-constrained-policy-set (and in the user-constrained-policy-set + # if NIST-test-policy-1 is in that set). There are no processing + # requirements associated with the CPS pointer qualifier. + TestInfo(True, initial_explicit_policy=True, + initial_policy_set=[TEST_POLICY_1]), + ], + + '4.10.1': [ # Valid Policy Mapping Test1 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should not validate successfully. + TestInfo(False, initial_policy_set=[TEST_POLICY_2]), + + # 3. default settings, but with initial-policy-mapping-inhibit set. The + # path should not validate successfully. + TestInfo(False, initial_policy_mapping_inhibit=True), + ], + + '4.10.2': [ # Invalid Policy Mapping Test2 + # 1. default settings. The path should not validate successfully. + TestInfo(False), + + # 2. default settings, but with initial-policy-mapping-inhibit set. The + # path should not validate successfully. + TestInfo(False, initial_policy_mapping_inhibit=True), + ], + + '4.10.3': [ # Valid Policy Mapping Test3 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should not validate successfully. + TestInfo(False, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_2]), + ], + + '4.10.4': [ # Invalid Policy Mapping Test4 + # Procedure: Validate Invalid Policy Mapping Test4 EE using the default + # settings or open and verify Signed Test Message 6.2.2.97 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should be rejected, otherwise + # it should validate successfully. + TestInfo(False), + ], + + '4.10.5': [ # Valid Policy Mapping Test5 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-6}. + # The path should not validate successfully. + TestInfo(False, initial_policy_set=[TEST_POLICY_6]), + ], + + '4.10.6': [ # Valid Policy Mapping Test6 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-6}. + # The path should not validate successfully. + TestInfo(False, initial_policy_set=[TEST_POLICY_6]), + ], + + '4.10.9': [ # Valid Policy Mapping Test9 + # Procedure: Validate Valid Policy Mapping Test9 EE using the default + # settings or open and verify Signed Test Message 6.2.2.102 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1}. If not, the user-constrained-policy-set will be + # empty. If the initial-policy-set does not include NIST-test-policy-1 (and + # the application can process the policyConstraints extension), then the + # path should be rejected, otherwise it should validate successfully. + TestInfo(True), + ], + + '4.10.10': [ # Invalid Policy Mapping Test10 + # Procedure: Validate Invalid Policy Mapping Test10 EE using the default + # settings or open and verify Signed Test Message 6.2.2.103 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should be rejected, otherwise + # it should validate successfully. + TestInfo(False), + ], + + '4.10.11': [ # Valid Policy Mapping Test11 + # Procedure: Validate Valid Policy Mapping Test11 EE using the default + # settings or open and verify Signed Test Message 6.2.2.104 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1}. If not, the user-constrained-policy-set will be + # empty. If the initial-policy-set does not include NIST-test-policy-1 (and + # the application can process the policyConstraints extension), then the + # path should be rejected, otherwise it should validate successfully. + TestInfo(True), + ], + + '4.10.12': [ # Valid Policy Mapping Test12 + # 1. default settings, but with initial-policy-set = {NIST-test-policy-1}. + # The path should validate successfully and the application should display + # the user notice associated with NIST-test-policy-3 in the end entity + # certificate. + TestInfo(True, initial_policy_set=[TEST_POLICY_1]), + + # 2. default settings, but with initial-policy-set = {NIST-test-policy-2}. + # The path should validate successfully and the application should display + # the user notice associated with anyPolicy in the end entity certificate. + TestInfo(True, initial_policy_set=[TEST_POLICY_2]), + ], + + '4.10.13': [ # Valid Policy Mapping Test13 + # Procedure: Validate Valid Policy Mapping Test13 EE using the default + # settings or open and verify Signed Test Message 6.2.2.106 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1}. If not, the user-constrained-policy-set will be + # empty. If the initial-policy-set does not include NIST-test-policy-1 (and + # the application can process the policyConstraints extension), then the + # path should be rejected, otherwise it should validate successfully. If + # the path is accepted, the application should display the user notice + # associated with NIST-testpolicy-1 in the intermediate certificate. + TestInfo(True), + ], + + '4.10.14': [ # Valid Policy Mapping Test14 + # Procedure: Validate Valid Policy Mapping Test14 EE using the default + # settings or open and verify Signed Test Message 6.2.2.107 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1}. If not, the user-constrained-policy-set will be + # empty. If the initial-policy-set does not include NIST-test-policy-1 (and + # the application can process the policyConstraints extension), then the + # path should be rejected, otherwise it should validate successfully. If + # the path is accepted, the application should display the user notice + # associated with anyPolicy in the intermediate certificate + TestInfo(True), + ], + + '4.11.1': [ # Invalid inhibitPolicyMapping Test1 + # Procedure: Validate Invalid inhibitPolicyMapping Test1 EE using the + # default settings or open and verify Signed Test Message 6.2.2.108 using + # the default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty. The explicit-policy-indicator + # will be set. The path should not validate successfully. + TestInfo(False), + ], + + '4.11.2': [ # Valid inhibitPolicyMapping Test2 + # Procedure: Validate Valid inhibitPolicyMapping Test2 EE using the default + # settings or open and verify Signed Test Message 6.2.2.109 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set. If + # the initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the path should validate successfully. + TestInfo(True), + ], + + '4.11.3': [ # Invalid inhibitPolicyMapping Test3 + # Procedure: Validate Invalid inhibitPolicyMapping Test3 EE using the + # default settings or open and verify Signed Test Message 6.2.2.110 using + # the default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.11.4': [ # Valid inhibitPolicyMapping Test4 + # Procedure: Validate Valid inhibitPolicyMapping Test4 EE using the default + # settings or open and verify Signed Test Message 6.2.2.111 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-2} and the explicit-policy-indicator will be set. If + # the initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-2, then the path should validate successfully. + TestInfo(True), + ], + + '4.11.5': [ # Invalid inhibitPolicyMapping Test5 + # Procedure: Validate Invalid inhibitPolicyMapping Test5 EE using the + # default settings or open and verify Signed Test Message 6.2.2.112 using + # the default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.11.6': [ # Invalid inhibitPolicyMapping Test6 + # Procedure: Validate Invalid inhibitPolicyMapping Test6 EE using the + # default settings or open and verify Signed Test Message 6.2.2.113 using + # the default settings. + # + # Expected Result: The authorities-constrained-policy-set and the + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.11.7': [ # Valid Self-Issued inhibitPolicyMapping Test7 + # Procedure: Validate Valid Self-Issued inhibitPolicyMapping Test7 EE using + # the default settings or open and verify Signed Test Message 6.2.2.114 + # using the default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set. If + # the initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the path should validate successfully. + TestInfo(True), + ], + + '4.11.8': [ # Invalid Self-Issued inhibitPolicyMapping Test8 + # Procedure: Validate Invalid Self-Issued inhibitPolicyMapping Test8 EE + # using the default settings or open and verify Signed Test Message + # 6.2.2.115 using the default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.11.9': [ # Invalid Self-Issued inhibitPolicyMapping Test9 + # Procedure: Validate Invalid Self-Issued inhibitPolicyMapping Test9 EE + # using the default settings or open and verify Signed Test Message + # 6.2.2.116 using the default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.11.10': [ # Invalid Self-Issued inhibitPolicyMapping Test10 + # Procedure: Validate Invalid Self-Issued inhibitPolicyMapping Test10 EE + # using the default settings or open and verify Signed Test Message + # 6.2.2.117 using the default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.11.11': [ # Invalid Self-Issued inhibitPolicyMapping Test11 + # Procedure: Validate Invalid Self-Issued inhibitPolicyMapping Test11 EE + # using the default settings or open and verify Signed Test Message + # 6.2.2.118 using the default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set. The path should not validate + # successfully. + TestInfo(False), + ], + + '4.12.1': [ # Invalid inhibitAnyPolicy Test1 + # Procedure: Validate Invalid inhibitAnyPolicy Test1 EE using the default + # settings or open and verify Signed Test Message 6.2.2.119 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(False), + ], + + '4.12.2': [ # Valid inhibitAnyPolicy Test2 + # Procedure: Validate Valid inhibitAnyPolicy Test2 EE using the default + # settings or open and verify Signed Test Message 6.2.2.120 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1} and the path should validate successfully. If not, + # then the user-constrained-policy-set will be empty. If the + # user-constrained-policy-set is empty and the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + + TestInfo(True), + ], + + '4.12.3': [ # inhibitAnyPolicy Test3 + # 1. default settings. The path should validate successfully. + TestInfo(True), + + # 2. default settings, but with initial-inhibit-any-policy set. The path + # should not validate successfully. + TestInfo(False, initial_inhibit_any_policy=True), + ], + + '4.12.4': [ # Invalid inhibitAnyPolicy Test4 + # Procedure: Validate Invalid inhibitAnyPolicy Test4 EE using the default + # settings or open and verify Signed Test Message 6.2.2.122 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(False), + ], + + '4.12.5': [ # Invalid inhibitAnyPolicy Test5 + # Procedure: Validate Invalid inhibitAnyPolicy Test5 EE using the default + # settings or open and verify Signed Test Message 6.2.2.123 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(False), + ], + + '4.12.6': [ # Invalid inhibitAnyPolicy Test6 + # Procedure: Validate Invalid inhibitAnyPolicy Test6 EE using the default + # settings or open and verify Signed Test Message 6.2.2.124 using the + # default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(False), + ], + + '4.12.7': [ # Valid Self-Issued inhibitAnyPolicy Test7 + # Procedure: Validate Valid Self-Issued inhibitAnyPolicy Test7 EE using the + # default settings or open and verify Signed Test Message 6.2.2.125 using + # the default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1} and the path should validate successfully. If not, + # then the user-constrained-policy-set will be empty. If the + # user-constrained-policy-set is empty and the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(True), + ], + + '4.12.8': [ # Invalid Self-Issued inhibitAnyPolicy Test8 + # Procedure: Validate Invalid Self-Issued inhibitAnyPolicy Test8 EE using + # the default settings or open and verify Signed Test Message 6.2.2.126 + # using the default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(False), + ], + + '4.12.9': [ # Valid Self-Issued inhibitAnyPolicy Test9 + # Procedure: Validate Valid Self-Issued inhibitAnyPolicy Test9 EE using the + # default settings or open and verify Signed Test Message 6.2.2.127 using + # the default settings. + # + # Expected Result: The authorities-constrained-policy-set will be + # {NIST-test-policy-1} and the explicit-policy-indicator will be set (if + # the application can process the policyConstraints extension). If the + # initial-policy-set is any-policy or otherwise includes + # NIST-test-policy-1, then the user-constrained-policy-set will be + # {NIST-test-policy-1} and the path should validate successfully. If not, + # then the user-constrained-policy-set will be empty. If the + # user-constrained-policy-set is empty and the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(True), + ], + + '4.12.10': [ # Invalid Self-Issued inhibitAnyPolicy Test10 + # Procedure: Validate Invalid Self-Issued inhibitAnyPolicy Test10 EE using + # the default settings or open and verify Signed Test Message 6.2.2.128 + # using the default settings. + # + # Expected Result: The authorities-constrained-policy-set and + # user-constrained-policy-set will be empty and the + # explicit-policy-indicator will be set (if the application can process the + # policyConstraints extension). If the application can process the + # policyConstraints extension, then the path should not validate + # successfully. + TestInfo(False), + ], +} + + +def parse_test(lines, i, test_case_name, test_number, test_name, + sanitized_test_names, output): + # Start by doing a coarse level of parsing that separates out the lines for + # the main sections. + i, test_sections = parse_main_test_sections(lines, i) + + certs, crls = parse_cert_path_lines(test_sections.cert_path_lines) + + # Most tests have a formulaic specification: they use the default + # settings, and have one expectation. These are easily parsed and are handled + # programmatically. In contrast, many of the policies tests have a more + # complicated specification which involves multiple subtests having various + # settings, as well as expectations described in terms of supported + # extensions. Rather than try to handle all the nuanced language, these are + # handled manually via "overrides". + overrides = TEST_OVERRIDES.get(test_number, None) + + if overrides is None: + # Verify that the test description doesn't include numbered subparts (those + # are not handled here). + if CUSTOM_SETTINGS_MATCHER.match(" ".join(test_sections.description_lines)): + sys.stderr.write('Unexpected custom settings for %s\n' % test_number) + sys.exit(1) + + # Verify that the test is using only default settings. + if not USING_DEFAULT_SETTINGS_MATCHER.match( + " ".join(test_sections.procedure_lines)): + sys.stderr.write('Unexpected procedure for %s: %s\n' % + (test_number, " ".join(test_section.procedure_lines))) + sys.exit(1) + + # Check whether expected result is validation success or failure. + result_match = TEST_RESULT_MATCHER.match( + test_sections.expected_result_lines[0]) + if not result_match: + sys.stderr.write('Unknown expectation for %s:\n%s\n' % ( + test_number, " ".join(test_sections.expected_result_lines))) + sys.exit(1) + # Initializes with default settings. + info = TestInfo(result_match.group(1) == 'should validate') + + output_test(test_case_name, test_number, test_name, None, info, certs, + crls, sanitized_test_names, output) + else: + # The overrides may have a series of inputs (settings) and outputs + # (success/failure) for this test. Output each as a separate test case. + for subpart_i in range(len(overrides)): + info = overrides[subpart_i] + # If the test has only 1 subpart, don't number it. + subpart_number = subpart_i + 1 if len(overrides) > 1 else None + output_test(test_case_name, test_number, test_name, subpart_number, info, + certs, crls, sanitized_test_names, output) + + return i def main(): @@ -164,17 +1104,12 @@ finalize_test_case(test_case_name, sanitized_test_names, output) sanitized_test_names = [] - # TODO(mattm): Handle certificate policies tests. - if section_match.group(1) in ('4.8', '4.9', '4.10', '4.11', '4.12'): - test_case_name = None - output.write('\n// Skipping section %s\n' % section_match.group(1)) - continue - test_case_name = 'PkitsTest%02d%s' % ( int(section_match.group(1).split('.')[-1]), sanitize_name(section_match.group(2))) output.write('\ntemplate <typename PkitsTestDelegate>\n') - output.write('class %s : public PkitsTest<PkitsTestDelegate> {};\n' % test_case_name) + output.write('class %s : public PkitsTest<PkitsTestDelegate> {};\n' % + test_case_name) output.write('TYPED_TEST_CASE_P(%s);\n' % test_case_name) if match: @@ -183,10 +1118,8 @@ if not test_case_name: output.write('// Skipped %s %s\n' % (test_number, test_name)) continue - i, sanitized_test_name = parse_test(lines, i, test_case_name, test_number, - test_name, output) - if sanitized_test_name: - sanitized_test_names.append(sanitized_test_name) + i, parse_test(lines, i, test_case_name, test_number, + test_name, sanitized_test_names, output) if test_case_name: finalize_test_case(test_case_name, sanitized_test_names, output)
diff --git a/net/third_party/nist-pkits/pkits_testcases-inl.h b/net/third_party/nist-pkits/pkits_testcases-inl.h index 22f3c47d..7ff0864 100644 --- a/net/third_party/nist-pkits/pkits_testcases-inl.h +++ b/net/third_party/nist-pkits/pkits_testcases-inl.h
@@ -17,7 +17,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "ValidCertificatePathTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.1.2 Invalid CA Signature Test2 @@ -26,7 +26,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "BadSignedCACert", "InvalidCASignatureTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BadSignedCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.1.3 Invalid EE Signature Test3 @@ -35,7 +35,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "InvalidEESignatureTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.1.4 Valid DSA Signatures Test4 @@ -44,7 +44,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "DSACACert", "ValidDSASignaturesTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.1.5 Valid DSA Parameter Inheritance Test5 @@ -55,7 +55,7 @@ "ValidDSAParameterInheritanceTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL", "DSAParametersInheritedCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.1.6 Invalid DSA Signature Test6 @@ -64,7 +64,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "DSACACert", "InvalidDSASignatureTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "DSACACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P(PkitsTest01SignatureVerification, @@ -86,7 +86,7 @@ "BadnotBeforeDateCACert", "InvalidCAnotBeforeDateTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BadnotBeforeDateCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.2.2 Invalid EE notBefore Date Test2 @@ -95,7 +95,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "InvalidEEnotBeforeDateTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.2.3 Valid pre2000 UTC notBefore Date Test3 @@ -104,7 +104,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "Validpre2000UTCnotBeforeDateTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.2.4 Valid GeneralizedTime notBefore Date Test4 @@ -113,7 +113,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "ValidGeneralizedTimenotBeforeDateTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.2.5 Invalid CA notAfter Date Test5 @@ -123,7 +123,7 @@ "BadnotAfterDateCACert", "InvalidCAnotAfterDateTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BadnotAfterDateCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.2.6 Invalid EE notAfter Date Test6 @@ -132,7 +132,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "InvalidEEnotAfterDateTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.2.7 Invalid pre2000 UTC EE notAfter Date Test7 @@ -141,7 +141,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "Invalidpre2000UTCEEnotAfterDateTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.2.8 Valid GeneralizedTime notAfter Date Test8 @@ -150,7 +150,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "ValidGeneralizedTimenotAfterDateTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -174,7 +174,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "InvalidNameChainingTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.3.2 Invalid Name Chaining Order Test2 @@ -184,7 +184,7 @@ "NameOrderingCACert", "InvalidNameChainingOrderTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "NameOrderCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.3.3 Valid Name Chaining Whitespace Test3 @@ -193,7 +193,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "ValidNameChainingWhitespaceTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.4 Valid Name Chaining Whitespace Test4 @@ -202,7 +202,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "ValidNameChainingWhitespaceTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.5 Valid Name Chaining Capitalization Test5 @@ -211,7 +211,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "ValidNameChainingCapitalizationTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.6 Valid Name Chaining UIDs Test6 @@ -220,7 +220,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "UIDCACert", "ValidNameUIDsTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "UIDCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.7 Valid RFC3280 Mandatory Attribute Types Test7 @@ -231,7 +231,7 @@ "ValidRFC3280MandatoryAttributeTypesTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "RFC3280MandatoryAttributeTypesCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.8 Valid RFC3280 Optional Attribute Types Test8 @@ -242,7 +242,7 @@ "ValidRFC3280OptionalAttributeTypesTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "RFC3280OptionalAttributeTypesCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.9 Valid UTF8String Encoded Names Test9 @@ -253,7 +253,7 @@ "ValidUTF8StringEncodedNamesTest9EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "UTF8StringEncodedNamesCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.10 Valid Rollover from PrintableString to UTF8String Test10 @@ -266,7 +266,7 @@ "ValidRolloverfromPrintableStringtoUTF8StringTest10EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "RolloverfromPrintableStringtoUTF8StringCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.3.11 Valid UTF8String Case Insensitive Match Test11 @@ -277,7 +277,7 @@ "ValidUTF8StringCaseInsensitiveMatchTest11EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "UTF8StringCaseInsensitiveMatchCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -305,7 +305,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "NoCRLCACert", "InvalidMissingCRLTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.2 Invalid Revoked CA Test2 @@ -315,7 +315,7 @@ "RevokedsubCACert", "InvalidRevokedCATest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", "RevokedsubCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.3 Invalid Revoked EE Test3 @@ -324,7 +324,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", "InvalidRevokedEETest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.4 Invalid Bad CRL Signature Test4 @@ -334,7 +334,7 @@ "BadCRLSignatureCACert", "InvalidBadCRLSignatureTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BadCRLSignatureCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.5 Invalid Bad CRL Issuer Name Test5 @@ -344,7 +344,7 @@ "BadCRLIssuerNameCACert", "InvalidBadCRLIssuerNameTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BadCRLIssuerNameCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.6 Invalid Wrong CRL Test6 @@ -353,7 +353,7 @@ const char* const certs[] = {"TrustAnchorRootCertificate", "WrongCRLCACert", "InvalidWrongCRLTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "WrongCRLCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.7 Valid Two CRLs Test7 @@ -363,7 +363,7 @@ "ValidTwoCRLsTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "TwoCRLsCAGoodCRL", "TwoCRLsCABadCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.4.8 Invalid Unknown CRL Entry Extension Test8 @@ -374,7 +374,7 @@ "InvalidUnknownCRLEntryExtensionTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "UnknownCRLEntryExtensionCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.9 Invalid Unknown CRL Extension Test9 @@ -384,7 +384,7 @@ "UnknownCRLExtensionCACert", "InvalidUnknownCRLExtensionTest9EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "UnknownCRLExtensionCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.10 Invalid Unknown CRL Extension Test10 @@ -394,7 +394,7 @@ "UnknownCRLExtensionCACert", "InvalidUnknownCRLExtensionTest10EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "UnknownCRLExtensionCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.11 Invalid Old CRL nextUpdate Test11 @@ -404,7 +404,7 @@ "OldCRLnextUpdateCACert", "InvalidOldCRLnextUpdateTest11EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "OldCRLnextUpdateCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.12 Invalid pre2000 CRL nextUpdate Test12 @@ -416,7 +416,7 @@ "uctiontoSection4.4formoreinformation."}; const char* const crls[] = {"TrustAnchorRootCRL", "pre2000CRLnextUpdateCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.13 Valid GeneralizedTime CRL nextUpdate Test13 @@ -427,7 +427,7 @@ "ValidGeneralizedTimeCRLnextUpdateTest13EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GeneralizedTimeCRLnextUpdateCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.4.14 Valid Negative Serial Number Test14 @@ -438,7 +438,7 @@ "ValidNegativeSerialNumberTest14EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "NegativeSerialNumberCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.4.15 Invalid Negative Serial Number Test15 @@ -449,7 +449,7 @@ "InvalidNegativeSerialNumberTest15EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "NegativeSerialNumberCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.16 Valid Long Serial Number Test16 @@ -459,7 +459,7 @@ "LongSerialNumberCACert", "ValidLongSerialNumberTest16EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "LongSerialNumberCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.4.17 Valid Long Serial Number Test17 @@ -469,7 +469,7 @@ "LongSerialNumberCACert", "ValidLongSerialNumberTest17EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "LongSerialNumberCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.4.18 Invalid Long Serial Number Test18 @@ -479,7 +479,7 @@ "LongSerialNumberCACert", "InvalidLongSerialNumberTest18EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "LongSerialNumberCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.19 Valid Separate Certificate and CRL Keys Test19 @@ -492,7 +492,7 @@ "ValidSeparateCertificateandCRLKeysTest19EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "SeparateCertificateandCRLKeysCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.4.20 Invalid Separate Certificate and CRL Keys Test20 @@ -505,7 +505,7 @@ "InvalidSeparateCertificateandCRLKeysTest20EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "SeparateCertificateandCRLKeysCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.4.21 Invalid Separate Certificate and CRL Keys Test21 @@ -518,7 +518,7 @@ "InvalidSeparateCertificateandCRLKeysTest21EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "SeparateCertificateandCRLKeysCA2CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -559,7 +559,7 @@ "ValidBasicSelfIssuedOldWithNewTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedNewKeyCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.5.2 Invalid Basic Self-Issued Old With New Test2 @@ -571,7 +571,7 @@ "InvalidBasicSelfIssuedOldWithNewTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedNewKeyCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.5.3 Valid Basic Self-Issued New With Old Test3 @@ -584,7 +584,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedOldKeySelfIssuedCertCRL", "BasicSelfIssuedOldKeyCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.5.4 Valid Basic Self-Issued New With Old Test4 @@ -597,7 +597,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedOldKeySelfIssuedCertCRL", "BasicSelfIssuedOldKeyCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.5.5 Invalid Basic Self-Issued New With Old Test5 @@ -610,7 +610,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedOldKeySelfIssuedCertCRL", "BasicSelfIssuedOldKeyCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.5.6 Valid Basic Self-Issued CRL Signing Key Test6 @@ -623,7 +623,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedCRLSigningKeyCRLCertCRL", "BasicSelfIssuedCRLSigningKeyCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.5.7 Invalid Basic Self-Issued CRL Signing Key Test7 @@ -636,7 +636,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedCRLSigningKeyCRLCertCRL", "BasicSelfIssuedCRLSigningKeyCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.5.8 Invalid Basic Self-Issued CRL Signing Key Test8 @@ -649,7 +649,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "BasicSelfIssuedCRLSigningKeyCRLCertCRL", "BasicSelfIssuedCRLSigningKeyCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -676,7 +676,7 @@ "InvalidMissingbasicConstraintsTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "MissingbasicConstraintsCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.2 Invalid cA False Test2 @@ -687,7 +687,7 @@ "InvalidcAFalseTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "basicConstraintsCriticalcAFalseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.3 Invalid cA False Test3 @@ -698,7 +698,7 @@ "InvalidcAFalseTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "basicConstraintsNotCriticalcAFalseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.4 Valid basicConstraints Not Critical Test4 @@ -709,7 +709,7 @@ "ValidbasicConstraintsNotCriticalTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "basicConstraintsNotCriticalCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.6.5 Invalid pathLenConstraint Test5 @@ -720,7 +720,7 @@ "pathLenConstraint0subCACert", "InvalidpathLenConstraintTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint0CACRL", "pathLenConstraint0subCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.6 Invalid pathLenConstraint Test6 @@ -731,7 +731,7 @@ "pathLenConstraint0subCACert", "InvalidpathLenConstraintTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint0CACRL", "pathLenConstraint0subCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.7 Valid pathLenConstraint Test7 @@ -741,7 +741,7 @@ "pathLenConstraint0CACert", "ValidpathLenConstraintTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint0CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.6.8 Valid pathLenConstraint Test8 @@ -751,7 +751,7 @@ "pathLenConstraint0CACert", "ValidpathLenConstraintTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint0CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.6.9 Invalid pathLenConstraint Test9 @@ -764,7 +764,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint6CACRL", "pathLenConstraint6subCA0CRL", "pathLenConstraint6subsubCA00CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.10 Invalid pathLenConstraint Test10 @@ -777,7 +777,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint6CACRL", "pathLenConstraint6subCA0CRL", "pathLenConstraint6subsubCA00CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.11 Invalid pathLenConstraint Test11 @@ -793,7 +793,7 @@ "pathLenConstraint6subCA1CRL", "pathLenConstraint6subsubCA11CRL", "pathLenConstraint6subsubsubCA11XCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.12 Invalid pathLenConstraint Test12 @@ -809,7 +809,7 @@ "pathLenConstraint6subCA1CRL", "pathLenConstraint6subsubCA11CRL", "pathLenConstraint6subsubsubCA11XCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.13 Valid pathLenConstraint Test13 @@ -825,7 +825,7 @@ "pathLenConstraint6subCA4CRL", "pathLenConstraint6subsubCA41CRL", "pathLenConstraint6subsubsubCA41XCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.6.14 Valid pathLenConstraint Test14 @@ -841,7 +841,7 @@ "pathLenConstraint6subCA4CRL", "pathLenConstraint6subsubCA41CRL", "pathLenConstraint6subsubsubCA41XCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.6.15 Valid Self-Issued pathLenConstraint Test15 @@ -852,7 +852,7 @@ "pathLenConstraint0SelfIssuedCACert", "ValidSelfIssuedpathLenConstraintTest15EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint0CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.6.16 Invalid Self-Issued pathLenConstraint Test16 @@ -864,7 +864,7 @@ "InvalidSelfIssuedpathLenConstraintTest16EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint0CACRL", "pathLenConstraint0subCA2CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.6.17 Valid Self-Issued pathLenConstraint Test17 @@ -878,7 +878,7 @@ "ValidSelfIssuedpathLenConstraintTest17EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "pathLenConstraint1CACRL", "pathLenConstraint1subCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -913,7 +913,7 @@ "InvalidkeyUsageCriticalkeyCertSignFalseTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "keyUsageCriticalkeyCertSignFalseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.7.2 Invalid keyUsage Not Critical keyCertSign False Test2 @@ -924,7 +924,7 @@ "InvalidkeyUsageNotCriticalkeyCertSignFalseTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "keyUsageNotCriticalkeyCertSignFalseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.7.3 Valid keyUsage Not Critical Test3 @@ -934,7 +934,7 @@ "keyUsageNotCriticalCACert", "ValidkeyUsageNotCriticalTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "keyUsageNotCriticalCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.7.4 Invalid keyUsage Critical cRLSign False Test4 @@ -945,7 +945,7 @@ "InvalidkeyUsageCriticalcRLSignFalseTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "keyUsageCriticalcRLSignFalseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.7.5 Invalid keyUsage Not Critical cRLSign False Test5 @@ -956,7 +956,7 @@ "InvalidkeyUsageNotCriticalcRLSignFalseTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "keyUsageNotCriticalcRLSignFalseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -967,78 +967,1291 @@ Section7InvalidkeyUsageCriticalcRLSignFalseTest4, Section7InvalidkeyUsageNotCriticalcRLSignFalseTest5); -// Skipping section 4.8 -// Skipped 4.8.1 All Certificates Same Policy Test1 -// Skipped 4.8.2 All Certificates No Policies Test2 -// Skipped 4.8.3 Different Policies Test3 -// Skipped 4.8.4 Different Policies Test4 -// Skipped 4.8.5 Different Policies Test5 -// Skipped 4.8.6 Overlapping Policies Test6 -// Skipped 4.8.7 Different Policies Test7 -// Skipped 4.8.8 Different Policies Test8 -// Skipped 4.8.9 Different Policies Test9 -// Skipped 4.8.10 All Certificates Same Policies Test10 -// Skipped 4.8.11 All Certificates AnyPolicy Test11 -// Skipped 4.8.12 Different Policies Test12 -// Skipped 4.8.13 All Certificates Same Policies Test13 -// Skipped 4.8.14 AnyPolicy Test14 -// Skipped 4.8.15 User Notice Qualifier Test15 -// Skipped 4.8.16 User Notice Qualifier Test16 -// Skipped 4.8.17 User Notice Qualifier Test17 -// Skipped 4.8.18 User Notice Qualifier Test18 -// Skipped 4.8.19 User Notice Qualifier Test19 -// Skipped 4.8.20 CPS Pointer Qualifier Test20 +template <typename PkitsTestDelegate> +class PkitsTest08CertificatePolicies : public PkitsTest<PkitsTestDelegate> {}; +TYPED_TEST_CASE_P(PkitsTest08CertificatePolicies); -// Skipping section 4.9 -// Skipped 4.9.1 Valid RequireExplicitPolicy Test1 -// Skipped 4.9.2 Valid RequireExplicitPolicy Test2 -// Skipped 4.9.3 Invalid RequireExplicitPolicy Test3 -// Skipped 4.9.4 Valid RequireExplicitPolicy Test4 -// Skipped 4.9.5 Invalid RequireExplicitPolicy Test5 -// Skipped 4.9.6 Valid Self-Issued requireExplicitPolicy Test6 -// Skipped 4.9.7 Invalid Self-Issued requireExplicitPolicy Test7 -// Skipped 4.9.8 Invalid Self-Issued requireExplicitPolicy Test8 +// 4.8.1 All Certificates Same Policy Test1 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePolicyTest1Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "ValidCertificatePathTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; -// Skipping section 4.10 -// Skipped 4.10.1 Valid Policy Mapping Test1 -// Skipped 4.10.2 Invalid Policy Mapping Test2 -// Skipped 4.10.3 Valid Policy Mapping Test3 -// Skipped 4.10.4 Invalid Policy Mapping Test4 -// Skipped 4.10.5 Valid Policy Mapping Test5 -// Skipped 4.10.6 Valid Policy Mapping Test6 -// Skipped 4.10.7 Invalid Mapping From anyPolicy Test7 -// Skipped 4.10.8 Invalid Mapping To anyPolicy Test8 -// Skipped 4.10.9 Valid Policy Mapping Test9 -// Skipped 4.10.10 Invalid Policy Mapping Test10 -// Skipped 4.10.11 Valid Policy Mapping Test11 -// Skipped 4.10.12 Valid Policy Mapping Test12 -// Skipped 4.10.13 Valid Policy Mapping Test13 -// Skipped 4.10.14 Valid Policy Mapping Test14 + // Custom settings + PkitsTestSettings settings; + settings.initial_explicit_policy = true; -// Skipping section 4.11 -// Skipped 4.11.1 Invalid inhibitPolicyMapping Test1 -// Skipped 4.11.2 Valid inhibitPolicyMapping Test2 -// Skipped 4.11.3 Invalid inhibitPolicyMapping Test3 -// Skipped 4.11.4 Valid inhibitPolicyMapping Test4 -// Skipped 4.11.5 Invalid inhibitPolicyMapping Test5 -// Skipped 4.11.6 Invalid inhibitPolicyMapping Test6 -// Skipped 4.11.7 Valid Self-Issued inhibitPolicyMapping Test7 -// Skipped 4.11.8 Invalid Self-Issued inhibitPolicyMapping Test8 -// Skipped 4.11.9 Invalid Self-Issued inhibitPolicyMapping Test9 -// Skipped 4.11.10 Invalid Self-Issued inhibitPolicyMapping Test10 -// Skipped 4.11.11 Invalid Self-Issued inhibitPolicyMapping Test11 + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} -// Skipping section 4.12 -// Skipped 4.12.1 Invalid inhibitAnyPolicy Test1 -// Skipped 4.12.2 Valid inhibitAnyPolicy Test2 -// Skipped 4.12.3 inhibitAnyPolicy Test3 -// Skipped 4.12.4 Invalid inhibitAnyPolicy Test4 -// Skipped 4.12.5 Invalid inhibitAnyPolicy Test5 -// Skipped 4.12.6 Invalid inhibitAnyPolicy Test6 -// Skipped 4.12.7 Valid Self-Issued inhibitAnyPolicy Test7 -// Skipped 4.12.8 Invalid Self-Issued inhibitAnyPolicy Test8 -// Skipped 4.12.9 Valid Self-Issued inhibitAnyPolicy Test9 -// Skipped 4.12.10 Invalid Self-Issued inhibitAnyPolicy Test10 +// 4.8.1 All Certificates Same Policy Test1 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePolicyTest1Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "ValidCertificatePathTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + settings.initial_explicit_policy = true; + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.1 All Certificates Same Policy Test1 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePolicyTest1Subpart3) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "ValidCertificatePathTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + settings.initial_explicit_policy = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.8.1 All Certificates Same Policy Test1 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePolicyTest1Subpart4) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "ValidCertificatePathTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1,NIST-test-policy-2"); + settings.initial_explicit_policy = true; + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.2 All Certificates No Policies Test2 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesNoPoliciesTest2Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", "NoPoliciesCACert", + "AllCertificatesNoPoliciesTest2EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "NoPoliciesCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.2 All Certificates No Policies Test2 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesNoPoliciesTest2Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", "NoPoliciesCACert", + "AllCertificatesNoPoliciesTest2EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "NoPoliciesCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.initial_explicit_policy = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.8.3 Different Policies Test3 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest3Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "PoliciesP2subCACert", + "DifferentPoliciesTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "PoliciesP2subCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.3 Different Policies Test3 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest3Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "PoliciesP2subCACert", + "DifferentPoliciesTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "PoliciesP2subCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.initial_explicit_policy = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.8.3 Different Policies Test3 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest3Subpart3) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "PoliciesP2subCACert", + "DifferentPoliciesTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "PoliciesP2subCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1,NIST-test-policy-2"); + settings.initial_explicit_policy = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.8.4 Different Policies Test4 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest4) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "GoodsubCACert", "DifferentPoliciesTest4EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "GoodsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.8.5 Different Policies Test5 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest5) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "PoliciesP2subCA2Cert", + "DifferentPoliciesTest5EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "PoliciesP2subCA2CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.8.6 Overlapping Policies Test6 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8OverlappingPoliciesTest6Subpart1) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "PoliciesP1234CACert", + "PoliciesP1234subCAP123Cert", "PoliciesP1234subsubCAP123P12Cert", + "OverlappingPoliciesTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP1234CACRL", + "PoliciesP1234subCAP123CRL", + "PoliciesP1234subsubCAP123P12CRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.6 Overlapping Policies Test6 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8OverlappingPoliciesTest6Subpart2) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "PoliciesP1234CACert", + "PoliciesP1234subCAP123Cert", "PoliciesP1234subsubCAP123P12Cert", + "OverlappingPoliciesTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP1234CACRL", + "PoliciesP1234subCAP123CRL", + "PoliciesP1234subsubCAP123P12CRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.6 Overlapping Policies Test6 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8OverlappingPoliciesTest6Subpart3) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "PoliciesP1234CACert", + "PoliciesP1234subCAP123Cert", "PoliciesP1234subsubCAP123P12Cert", + "OverlappingPoliciesTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP1234CACRL", + "PoliciesP1234subCAP123CRL", + "PoliciesP1234subsubCAP123P12CRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.8.7 Different Policies Test7 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest7) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP123CACert", "PoliciesP123subCAP12Cert", + "PoliciesP123subsubCAP12P1Cert", + "DifferentPoliciesTest7EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP123CACRL", + "PoliciesP123subCAP12CRL", + "PoliciesP123subsubCAP12P1CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.8.8 Different Policies Test8 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest8) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP12CACert", "PoliciesP12subCAP1Cert", + "PoliciesP12subsubCAP1P2Cert", + "DifferentPoliciesTest8EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP12CACRL", + "PoliciesP12subCAP1CRL", + "PoliciesP12subsubCAP1P2CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.8.9 Different Policies Test9 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest9) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "PoliciesP123CACert", + "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P2Cert", + "PoliciesP123subsubsubCAP12P2P1Cert", "DifferentPoliciesTest9EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", + "PoliciesP123subsubCAP2P2CRL", "PoliciesP123subsubsubCAP12P2P1CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.8.10 All Certificates Same Policies Test10 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePoliciesTest10Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP12CACert", + "AllCertificatesSamePoliciesTest10EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP12CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.10 All Certificates Same Policies Test10 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePoliciesTest10Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP12CACert", + "AllCertificatesSamePoliciesTest10EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP12CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.10 All Certificates Same Policies Test10 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePoliciesTest10Subpart3) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP12CACert", + "AllCertificatesSamePoliciesTest10EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP12CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.11 All Certificates AnyPolicy Test11 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesAnyPolicyTest11Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", "anyPolicyCACert", + "AllCertificatesanyPolicyTest11EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "anyPolicyCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.11 All Certificates AnyPolicy Test11 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesAnyPolicyTest11Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", "anyPolicyCACert", + "AllCertificatesanyPolicyTest11EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "anyPolicyCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.12 Different Policies Test12 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8DifferentPoliciesTest12) { + const char* const certs[] = {"TrustAnchorRootCertificate", "PoliciesP3CACert", + "DifferentPoliciesTest12EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP3CACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.8.13 All Certificates Same Policies Test13 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePoliciesTest13Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP123CACert", + "AllCertificatesSamePoliciesTest13EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP123CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.13 All Certificates Same Policies Test13 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePoliciesTest13Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP123CACert", + "AllCertificatesSamePoliciesTest13EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP123CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.13 All Certificates Same Policies Test13 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePoliciesTest13Subpart3) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP123CACert", + "AllCertificatesSamePoliciesTest13EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP123CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-3"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.14 AnyPolicy Test14 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AnyPolicyTest14Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", "anyPolicyCACert", + "AnyPolicyTest14EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "anyPolicyCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.14 AnyPolicy Test14 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8AnyPolicyTest14Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", "anyPolicyCACert", + "AnyPolicyTest14EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "anyPolicyCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.8.15 User Notice Qualifier Test15 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8UserNoticeQualifierTest15) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "UserNoticeQualifierTest15EE"}; + const char* const crls[] = {"TrustAnchorRootCRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.16 User Notice Qualifier Test16 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8UserNoticeQualifierTest16) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "UserNoticeQualifierTest16EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.17 User Notice Qualifier Test17 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8UserNoticeQualifierTest17) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "UserNoticeQualifierTest17EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.18 User Notice Qualifier Test18 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8UserNoticeQualifierTest18Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP12CACert", + "UserNoticeQualifierTest18EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP12CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.18 User Notice Qualifier Test18 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8UserNoticeQualifierTest18Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PoliciesP12CACert", + "UserNoticeQualifierTest18EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "PoliciesP12CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.8.19 User Notice Qualifier Test19 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8UserNoticeQualifierTest19) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "UserNoticeQualifierTest19EE"}; + const char* const crls[] = {"TrustAnchorRootCRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.8.20 CPS Pointer Qualifier Test20 +WRAPPED_TYPED_TEST_P(PkitsTest08CertificatePolicies, + Section8CPSPointerQualifierTest20) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "CPSPointerQualifierTest20EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + settings.initial_explicit_policy = true; + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +WRAPPED_REGISTER_TYPED_TEST_CASE_P( + PkitsTest08CertificatePolicies, + Section8AllCertificatesSamePolicyTest1Subpart1, + Section8AllCertificatesSamePolicyTest1Subpart2, + Section8AllCertificatesSamePolicyTest1Subpart3, + Section8AllCertificatesSamePolicyTest1Subpart4, + Section8AllCertificatesNoPoliciesTest2Subpart1, + Section8AllCertificatesNoPoliciesTest2Subpart2, + Section8DifferentPoliciesTest3Subpart1, + Section8DifferentPoliciesTest3Subpart2, + Section8DifferentPoliciesTest3Subpart3, + Section8DifferentPoliciesTest4, + Section8DifferentPoliciesTest5, + Section8OverlappingPoliciesTest6Subpart1, + Section8OverlappingPoliciesTest6Subpart2, + Section8OverlappingPoliciesTest6Subpart3, + Section8DifferentPoliciesTest7, + Section8DifferentPoliciesTest8, + Section8DifferentPoliciesTest9, + Section8AllCertificatesSamePoliciesTest10Subpart1, + Section8AllCertificatesSamePoliciesTest10Subpart2, + Section8AllCertificatesSamePoliciesTest10Subpart3, + Section8AllCertificatesAnyPolicyTest11Subpart1, + Section8AllCertificatesAnyPolicyTest11Subpart2, + Section8DifferentPoliciesTest12, + Section8AllCertificatesSamePoliciesTest13Subpart1, + Section8AllCertificatesSamePoliciesTest13Subpart2, + Section8AllCertificatesSamePoliciesTest13Subpart3, + Section8AnyPolicyTest14Subpart1, + Section8AnyPolicyTest14Subpart2, + Section8UserNoticeQualifierTest15, + Section8UserNoticeQualifierTest16, + Section8UserNoticeQualifierTest17, + Section8UserNoticeQualifierTest18Subpart1, + Section8UserNoticeQualifierTest18Subpart2, + Section8UserNoticeQualifierTest19, + Section8CPSPointerQualifierTest20); + +template <typename PkitsTestDelegate> +class PkitsTest09RequireExplicitPolicy : public PkitsTest<PkitsTestDelegate> {}; +TYPED_TEST_CASE_P(PkitsTest09RequireExplicitPolicy); + +// 4.9.1 Valid RequireExplicitPolicy Test1 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9ValidRequireExplicitPolicyTest1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy10CACert", + "requireExplicitPolicy10subCACert", + "requireExplicitPolicy10subsubCACert", + "requireExplicitPolicy10subsubsubCACert", + "ValidrequireExplicitPolicyTest1EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "requireExplicitPolicy10CACRL", + "requireExplicitPolicy10subCACRL", "requireExplicitPolicy10subsubCACRL", + "requireExplicitPolicy10subsubsubCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.9.2 Valid RequireExplicitPolicy Test2 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9ValidRequireExplicitPolicyTest2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy5CACert", + "requireExplicitPolicy5subCACert", + "requireExplicitPolicy5subsubCACert", + "requireExplicitPolicy5subsubsubCACert", + "ValidrequireExplicitPolicyTest2EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "requireExplicitPolicy5CACRL", + "requireExplicitPolicy5subCACRL", "requireExplicitPolicy5subsubCACRL", + "requireExplicitPolicy5subsubsubCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.9.3 Invalid RequireExplicitPolicy Test3 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9InvalidRequireExplicitPolicyTest3) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy4CACert", + "requireExplicitPolicy4subCACert", + "requireExplicitPolicy4subsubCACert", + "requireExplicitPolicy4subsubsubCACert", + "InvalidrequireExplicitPolicyTest3EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "requireExplicitPolicy4CACRL", + "requireExplicitPolicy4subCACRL", "requireExplicitPolicy4subsubCACRL", + "requireExplicitPolicy4subsubsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.9.4 Valid RequireExplicitPolicy Test4 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9ValidRequireExplicitPolicyTest4) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy0CACert", + "requireExplicitPolicy0subCACert", + "requireExplicitPolicy0subsubCACert", + "requireExplicitPolicy0subsubsubCACert", + "ValidrequireExplicitPolicyTest4EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "requireExplicitPolicy0CACRL", + "requireExplicitPolicy0subCACRL", "requireExplicitPolicy0subsubCACRL", + "requireExplicitPolicy0subsubsubCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.9.5 Invalid RequireExplicitPolicy Test5 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9InvalidRequireExplicitPolicyTest5) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy7CACert", + "requireExplicitPolicy7subCARE2Cert", + "requireExplicitPolicy7subsubCARE2RE4Cert", + "requireExplicitPolicy7subsubsubCARE2RE4Cert", + "InvalidrequireExplicitPolicyTest5EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "requireExplicitPolicy7CACRL", + "requireExplicitPolicy7subCARE2CRL", + "requireExplicitPolicy7subsubCARE2RE4CRL", + "requireExplicitPolicy7subsubsubCARE2RE4CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.9.6 Valid Self-Issued requireExplicitPolicy Test6 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9ValidSelfIssuedrequireExplicitPolicyTest6) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy2CACert", + "requireExplicitPolicy2SelfIssuedCACert", + "ValidSelfIssuedrequireExplicitPolicyTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "requireExplicitPolicy2CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.9.7 Invalid Self-Issued requireExplicitPolicy Test7 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9InvalidSelfIssuedrequireExplicitPolicyTest7) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy2CACert", + "requireExplicitPolicy2SelfIssuedCACert", + "requireExplicitPolicy2subCACert", + "InvalidSelfIssuedrequireExplicitPolicyTest7EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "requireExplicitPolicy2CACRL", + "requireExplicitPolicy2subCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.9.8 Invalid Self-Issued requireExplicitPolicy Test8 +WRAPPED_TYPED_TEST_P(PkitsTest09RequireExplicitPolicy, + Section9InvalidSelfIssuedrequireExplicitPolicyTest8) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "requireExplicitPolicy2CACert", + "requireExplicitPolicy2SelfIssuedCACert", + "requireExplicitPolicy2subCACert", + "requireExplicitPolicy2SelfIssuedsubCACert", + "InvalidSelfIssuedrequireExplicitPolicyTest8EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "requireExplicitPolicy2CACRL", + "requireExplicitPolicy2subCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +WRAPPED_REGISTER_TYPED_TEST_CASE_P( + PkitsTest09RequireExplicitPolicy, + Section9ValidRequireExplicitPolicyTest1, + Section9ValidRequireExplicitPolicyTest2, + Section9InvalidRequireExplicitPolicyTest3, + Section9ValidRequireExplicitPolicyTest4, + Section9InvalidRequireExplicitPolicyTest5, + Section9ValidSelfIssuedrequireExplicitPolicyTest6, + Section9InvalidSelfIssuedrequireExplicitPolicyTest7, + Section9InvalidSelfIssuedrequireExplicitPolicyTest8); + +template <typename PkitsTestDelegate> +class PkitsTest10PolicyMappings : public PkitsTest<PkitsTestDelegate> {}; +TYPED_TEST_CASE_P(PkitsTest10PolicyMappings); + +// 4.10.1 Valid Policy Mapping Test1 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest1Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "Mapping1to2CACert", + "ValidPolicyMappingTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "Mapping1to2CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.10.1 Valid Policy Mapping Test1 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest1Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "Mapping1to2CACert", + "ValidPolicyMappingTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "Mapping1to2CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.10.1 Valid Policy Mapping Test1 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest1Subpart3) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "Mapping1to2CACert", + "ValidPolicyMappingTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "Mapping1to2CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.initial_policy_mapping_inhibit = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.10.2 Invalid Policy Mapping Test2 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10InvalidPolicyMappingTest2Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "Mapping1to2CACert", + "InvalidPolicyMappingTest2EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "Mapping1to2CACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.10.2 Invalid Policy Mapping Test2 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10InvalidPolicyMappingTest2Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "Mapping1to2CACert", + "InvalidPolicyMappingTest2EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "Mapping1to2CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.initial_policy_mapping_inhibit = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.10.3 Valid Policy Mapping Test3 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest3Subpart1) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P12Mapping1to3CACert", + "P12Mapping1to3subCACert", "P12Mapping1to3subsubCACert", + "ValidPolicyMappingTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P12Mapping1to3CACRL", + "P12Mapping1to3subCACRL", + "P12Mapping1to3subsubCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.10.3 Valid Policy Mapping Test3 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest3Subpart2) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P12Mapping1to3CACert", + "P12Mapping1to3subCACert", "P12Mapping1to3subsubCACert", + "ValidPolicyMappingTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P12Mapping1to3CACRL", + "P12Mapping1to3subCACRL", + "P12Mapping1to3subsubCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.10.4 Invalid Policy Mapping Test4 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10InvalidPolicyMappingTest4) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P12Mapping1to3CACert", + "P12Mapping1to3subCACert", "P12Mapping1to3subsubCACert", + "InvalidPolicyMappingTest4EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P12Mapping1to3CACRL", + "P12Mapping1to3subCACRL", + "P12Mapping1to3subsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.10.5 Valid Policy Mapping Test5 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest5Subpart1) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P1Mapping1to234CACert", + "P1Mapping1to234subCACert", "ValidPolicyMappingTest5EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P1Mapping1to234CACRL", + "P1Mapping1to234subCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.10.5 Valid Policy Mapping Test5 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest5Subpart2) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P1Mapping1to234CACert", + "P1Mapping1to234subCACert", "ValidPolicyMappingTest5EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P1Mapping1to234CACRL", + "P1Mapping1to234subCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-6"); + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.10.6 Valid Policy Mapping Test6 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest6Subpart1) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P1Mapping1to234CACert", + "P1Mapping1to234subCACert", "ValidPolicyMappingTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P1Mapping1to234CACRL", + "P1Mapping1to234subCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.10.6 Valid Policy Mapping Test6 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest6Subpart2) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "P1Mapping1to234CACert", + "P1Mapping1to234subCACert", "ValidPolicyMappingTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P1Mapping1to234CACRL", + "P1Mapping1to234subCACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-6"); + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.10.7 Invalid Mapping From anyPolicy Test7 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10InvalidMappingFromanyPolicyTest7) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "MappingFromanyPolicyCACert", + "InvalidMappingFromanyPolicyTest7EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "MappingFromanyPolicyCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.10.8 Invalid Mapping To anyPolicy Test8 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10InvalidMappingToanyPolicyTest8) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "MappingToanyPolicyCACert", + "InvalidMappingToanyPolicyTest8EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "MappingToanyPolicyCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.10.9 Valid Policy Mapping Test9 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest9) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "PanyPolicyMapping1to2CACert", + "ValidPolicyMappingTest9EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "PanyPolicyMapping1to2CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.10.10 Invalid Policy Mapping Test10 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10InvalidPolicyMappingTest10) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "GoodsubCAPanyPolicyMapping1to2CACert", + "InvalidPolicyMappingTest10EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "GoodsubCAPanyPolicyMapping1to2CACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.10.11 Valid Policy Mapping Test11 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest11) { + const char* const certs[] = {"TrustAnchorRootCertificate", "GoodCACert", + "GoodsubCAPanyPolicyMapping1to2CACert", + "ValidPolicyMappingTest11EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL", + "GoodsubCAPanyPolicyMapping1to2CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.10.12 Valid Policy Mapping Test12 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest12Subpart1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "P12Mapping1to3CACert", + "ValidPolicyMappingTest12EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P12Mapping1to3CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-1"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.10.12 Valid Policy Mapping Test12 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest12Subpart2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "P12Mapping1to3CACert", + "ValidPolicyMappingTest12EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "P12Mapping1to3CACRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.SetInitialPolicySet("NIST-test-policy-2"); + + ASSERT_TRUE(this->Verify(certs, crls, settings)); +} + +// 4.10.13 Valid Policy Mapping Test13 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest13) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "P1anyPolicyMapping1to2CACert", + "ValidPolicyMappingTest13EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "P1anyPolicyMapping1to2CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.10.14 Valid Policy Mapping Test14 +WRAPPED_TYPED_TEST_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest14) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "P1anyPolicyMapping1to2CACert", + "ValidPolicyMappingTest14EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "P1anyPolicyMapping1to2CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +WRAPPED_REGISTER_TYPED_TEST_CASE_P(PkitsTest10PolicyMappings, + Section10ValidPolicyMappingTest1Subpart1, + Section10ValidPolicyMappingTest1Subpart2, + Section10ValidPolicyMappingTest1Subpart3, + Section10InvalidPolicyMappingTest2Subpart1, + Section10InvalidPolicyMappingTest2Subpart2, + Section10ValidPolicyMappingTest3Subpart1, + Section10ValidPolicyMappingTest3Subpart2, + Section10InvalidPolicyMappingTest4, + Section10ValidPolicyMappingTest5Subpart1, + Section10ValidPolicyMappingTest5Subpart2, + Section10ValidPolicyMappingTest6Subpart1, + Section10ValidPolicyMappingTest6Subpart2, + Section10InvalidMappingFromanyPolicyTest7, + Section10InvalidMappingToanyPolicyTest8, + Section10ValidPolicyMappingTest9, + Section10InvalidPolicyMappingTest10, + Section10ValidPolicyMappingTest11, + Section10ValidPolicyMappingTest12Subpart1, + Section10ValidPolicyMappingTest12Subpart2, + Section10ValidPolicyMappingTest13, + Section10ValidPolicyMappingTest14); + +template <typename PkitsTestDelegate> +class PkitsTest11InhibitPolicyMapping : public PkitsTest<PkitsTestDelegate> {}; +TYPED_TEST_CASE_P(PkitsTest11InhibitPolicyMapping); + +// 4.11.1 Invalid inhibitPolicyMapping Test1 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidinhibitPolicyMappingTest1) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitPolicyMapping0CACert", + "inhibitPolicyMapping0subCACert", "InvalidinhibitPolicyMappingTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping0CACRL", + "inhibitPolicyMapping0subCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.2 Valid inhibitPolicyMapping Test2 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11ValidinhibitPolicyMappingTest2) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitPolicyMapping1P12CACert", + "inhibitPolicyMapping1P12subCACert", "ValidinhibitPolicyMappingTest2EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P12CACRL", + "inhibitPolicyMapping1P12subCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.11.3 Invalid inhibitPolicyMapping Test3 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidinhibitPolicyMappingTest3) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P12CACert", + "inhibitPolicyMapping1P12subCACert", + "inhibitPolicyMapping1P12subsubCACert", + "InvalidinhibitPolicyMappingTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P12CACRL", + "inhibitPolicyMapping1P12subCACRL", + "inhibitPolicyMapping1P12subsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.4 Valid inhibitPolicyMapping Test4 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11ValidinhibitPolicyMappingTest4) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P12CACert", + "inhibitPolicyMapping1P12subCACert", + "inhibitPolicyMapping1P12subsubCACert", + "ValidinhibitPolicyMappingTest4EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P12CACRL", + "inhibitPolicyMapping1P12subCACRL", + "inhibitPolicyMapping1P12subsubCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.11.5 Invalid inhibitPolicyMapping Test5 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidinhibitPolicyMappingTest5) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping5CACert", + "inhibitPolicyMapping5subCACert", + "inhibitPolicyMapping5subsubCACert", + "inhibitPolicyMapping5subsubsubCACert", + "InvalidinhibitPolicyMappingTest5EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "inhibitPolicyMapping5CACRL", + "inhibitPolicyMapping5subCACRL", "inhibitPolicyMapping5subsubCACRL", + "inhibitPolicyMapping5subsubsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.6 Invalid inhibitPolicyMapping Test6 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidinhibitPolicyMappingTest6) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P12CACert", + "inhibitPolicyMapping1P12subCAIPM5Cert", + "inhibitPolicyMapping1P12subsubCAIPM5Cert", + "InvalidinhibitPolicyMappingTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P12CACRL", + "inhibitPolicyMapping1P12subCAIPM5CRL", + "inhibitPolicyMapping1P12subsubCAIPM5CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.7 Valid Self-Issued inhibitPolicyMapping Test7 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11ValidSelfIssuedinhibitPolicyMappingTest7) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P1CACert", + "inhibitPolicyMapping1P1SelfIssuedCACert", + "inhibitPolicyMapping1P1subCACert", + "ValidSelfIssuedinhibitPolicyMappingTest7EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P1CACRL", + "inhibitPolicyMapping1P1subCACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.11.8 Invalid Self-Issued inhibitPolicyMapping Test8 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidSelfIssuedinhibitPolicyMappingTest8) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P1CACert", + "inhibitPolicyMapping1P1SelfIssuedCACert", + "inhibitPolicyMapping1P1subCACert", + "inhibitPolicyMapping1P1subsubCACert", + "InvalidSelfIssuedinhibitPolicyMappingTest8EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "inhibitPolicyMapping1P1CACRL", + "inhibitPolicyMapping1P1subCACRL", "inhibitPolicyMapping1P1subsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.9 Invalid Self-Issued inhibitPolicyMapping Test9 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidSelfIssuedinhibitPolicyMappingTest9) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P1CACert", + "inhibitPolicyMapping1P1SelfIssuedCACert", + "inhibitPolicyMapping1P1subCACert", + "inhibitPolicyMapping1P1subsubCACert", + "InvalidSelfIssuedinhibitPolicyMappingTest9EE"}; + const char* const crls[] = { + "TrustAnchorRootCRL", "inhibitPolicyMapping1P1CACRL", + "inhibitPolicyMapping1P1subCACRL", "inhibitPolicyMapping1P1subsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.10 Invalid Self-Issued inhibitPolicyMapping Test10 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidSelfIssuedinhibitPolicyMappingTest10) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P1CACert", + "inhibitPolicyMapping1P1SelfIssuedCACert", + "inhibitPolicyMapping1P1subCACert", + "inhibitPolicyMapping1P1SelfIssuedsubCACert", + "InvalidSelfIssuedinhibitPolicyMappingTest10EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P1CACRL", + "inhibitPolicyMapping1P1subCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.11.11 Invalid Self-Issued inhibitPolicyMapping Test11 +WRAPPED_TYPED_TEST_P(PkitsTest11InhibitPolicyMapping, + Section11InvalidSelfIssuedinhibitPolicyMappingTest11) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitPolicyMapping1P1CACert", + "inhibitPolicyMapping1P1SelfIssuedCACert", + "inhibitPolicyMapping1P1subCACert", + "inhibitPolicyMapping1P1SelfIssuedsubCACert", + "InvalidSelfIssuedinhibitPolicyMappingTest11EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", + "inhibitPolicyMapping1P1CACRL", + "inhibitPolicyMapping1P1subCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +WRAPPED_REGISTER_TYPED_TEST_CASE_P( + PkitsTest11InhibitPolicyMapping, + Section11InvalidinhibitPolicyMappingTest1, + Section11ValidinhibitPolicyMappingTest2, + Section11InvalidinhibitPolicyMappingTest3, + Section11ValidinhibitPolicyMappingTest4, + Section11InvalidinhibitPolicyMappingTest5, + Section11InvalidinhibitPolicyMappingTest6, + Section11ValidSelfIssuedinhibitPolicyMappingTest7, + Section11InvalidSelfIssuedinhibitPolicyMappingTest8, + Section11InvalidSelfIssuedinhibitPolicyMappingTest9, + Section11InvalidSelfIssuedinhibitPolicyMappingTest10, + Section11InvalidSelfIssuedinhibitPolicyMappingTest11); + +template <typename PkitsTestDelegate> +class PkitsTest12InhibitAnyPolicy : public PkitsTest<PkitsTestDelegate> {}; +TYPED_TEST_CASE_P(PkitsTest12InhibitAnyPolicy); + +// 4.12.1 Invalid inhibitAnyPolicy Test1 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12InvalidinhibitAnyPolicyTest1) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitAnyPolicy0CACert", + "InvalidinhibitAnyPolicyTest1EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy0CACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.12.2 Valid inhibitAnyPolicy Test2 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12ValidinhibitAnyPolicyTest2) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitAnyPolicy0CACert", + "ValidinhibitAnyPolicyTest2EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy0CACRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.12.3 inhibitAnyPolicy Test3 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12inhibitAnyPolicyTest3Subpart1) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1subCA1Cert", "inhibitAnyPolicyTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA1CRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.12.3 inhibitAnyPolicy Test3 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12inhibitAnyPolicyTest3Subpart2) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1subCA1Cert", "inhibitAnyPolicyTest3EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA1CRL"}; + + // Custom settings + PkitsTestSettings settings; + settings.initial_inhibit_any_policy = true; + + ASSERT_FALSE(this->Verify(certs, crls, settings)); +} + +// 4.12.4 Invalid inhibitAnyPolicy Test4 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12InvalidinhibitAnyPolicyTest4) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1subCA1Cert", "InvalidinhibitAnyPolicyTest4EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA1CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.12.5 Invalid inhibitAnyPolicy Test5 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12InvalidinhibitAnyPolicyTest5) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy5CACert", + "inhibitAnyPolicy5subCACert", "inhibitAnyPolicy5subsubCACert", + "InvalidinhibitAnyPolicyTest5EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy5CACRL", + "inhibitAnyPolicy5subCACRL", + "inhibitAnyPolicy5subsubCACRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.12.6 Invalid inhibitAnyPolicy Test6 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12InvalidinhibitAnyPolicyTest6) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1subCAIAP5Cert", "InvalidinhibitAnyPolicyTest6EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCAIAP5CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.12.7 Valid Self-Issued inhibitAnyPolicy Test7 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12ValidSelfIssuedinhibitAnyPolicyTest7) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1SelfIssuedCACert", "inhibitAnyPolicy1subCA2Cert", + "ValidSelfIssuedinhibitAnyPolicyTest7EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA2CRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.12.8 Invalid Self-Issued inhibitAnyPolicy Test8 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12InvalidSelfIssuedinhibitAnyPolicyTest8) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1SelfIssuedCACert", + "inhibitAnyPolicy1subCA2Cert", + "inhibitAnyPolicy1subsubCA2Cert", + "InvalidSelfIssuedinhibitAnyPolicyTest8EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA2CRL", + "inhibitAnyPolicy1subsubCA2CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +// 4.12.9 Valid Self-Issued inhibitAnyPolicy Test9 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12ValidSelfIssuedinhibitAnyPolicyTest9) { + const char* const certs[] = {"TrustAnchorRootCertificate", + "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1SelfIssuedCACert", + "inhibitAnyPolicy1subCA2Cert", + "inhibitAnyPolicy1SelfIssuedsubCA2Cert", + "ValidSelfIssuedinhibitAnyPolicyTest9EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA2CRL"}; + ASSERT_TRUE(this->Verify(certs, crls, {})); +} + +// 4.12.10 Invalid Self-Issued inhibitAnyPolicy Test10 +WRAPPED_TYPED_TEST_P(PkitsTest12InhibitAnyPolicy, + Section12InvalidSelfIssuedinhibitAnyPolicyTest10) { + const char* const certs[] = { + "TrustAnchorRootCertificate", "inhibitAnyPolicy1CACert", + "inhibitAnyPolicy1SelfIssuedCACert", "inhibitAnyPolicy1subCA2Cert", + "InvalidSelfIssuedinhibitAnyPolicyTest10EE"}; + const char* const crls[] = {"TrustAnchorRootCRL", "inhibitAnyPolicy1CACRL", + "inhibitAnyPolicy1subCA2CRL"}; + ASSERT_FALSE(this->Verify(certs, crls, {})); +} + +WRAPPED_REGISTER_TYPED_TEST_CASE_P( + PkitsTest12InhibitAnyPolicy, + Section12InvalidinhibitAnyPolicyTest1, + Section12ValidinhibitAnyPolicyTest2, + Section12inhibitAnyPolicyTest3Subpart1, + Section12inhibitAnyPolicyTest3Subpart2, + Section12InvalidinhibitAnyPolicyTest4, + Section12InvalidinhibitAnyPolicyTest5, + Section12InvalidinhibitAnyPolicyTest6, + Section12ValidSelfIssuedinhibitAnyPolicyTest7, + Section12InvalidSelfIssuedinhibitAnyPolicyTest8, + Section12ValidSelfIssuedinhibitAnyPolicyTest9, + Section12InvalidSelfIssuedinhibitAnyPolicyTest10); template <typename PkitsTestDelegate> class PkitsTest13NameConstraints : public PkitsTest<PkitsTestDelegate> {}; @@ -1051,7 +2264,7 @@ "nameConstraintsDN1CACert", "ValidDNnameConstraintsTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.2 Invalid DN nameConstraints Test2 @@ -1061,7 +2274,7 @@ "nameConstraintsDN1CACert", "InvalidDNnameConstraintsTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.3 Invalid DN nameConstraints Test3 @@ -1071,7 +2284,7 @@ "nameConstraintsDN1CACert", "InvalidDNnameConstraintsTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.4 Valid DN nameConstraints Test4 @@ -1081,7 +2294,7 @@ "nameConstraintsDN1CACert", "ValidDNnameConstraintsTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.5 Valid DN nameConstraints Test5 @@ -1091,7 +2304,7 @@ "nameConstraintsDN2CACert", "ValidDNnameConstraintsTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN2CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.6 Valid DN nameConstraints Test6 @@ -1101,7 +2314,7 @@ "nameConstraintsDN3CACert", "ValidDNnameConstraintsTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN3CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.7 Invalid DN nameConstraints Test7 @@ -1111,7 +2324,7 @@ "nameConstraintsDN3CACert", "InvalidDNnameConstraintsTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN3CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.8 Invalid DN nameConstraints Test8 @@ -1121,7 +2334,7 @@ "nameConstraintsDN4CACert", "InvalidDNnameConstraintsTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN4CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.9 Invalid DN nameConstraints Test9 @@ -1131,7 +2344,7 @@ "nameConstraintsDN4CACert", "InvalidDNnameConstraintsTest9EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN4CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.10 Invalid DN nameConstraints Test10 @@ -1141,7 +2354,7 @@ "nameConstraintsDN5CACert", "InvalidDNnameConstraintsTest10EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN5CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.11 Valid DN nameConstraints Test11 @@ -1151,7 +2364,7 @@ "nameConstraintsDN5CACert", "ValidDNnameConstraintsTest11EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN5CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.12 Invalid DN nameConstraints Test12 @@ -1162,7 +2375,7 @@ "nameConstraintsDN1subCA1Cert", "InvalidDNnameConstraintsTest12EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA1CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.13 Invalid DN nameConstraints Test13 @@ -1173,7 +2386,7 @@ "nameConstraintsDN1subCA2Cert", "InvalidDNnameConstraintsTest13EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA2CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.14 Valid DN nameConstraints Test14 @@ -1184,7 +2397,7 @@ "nameConstraintsDN1subCA2Cert", "ValidDNnameConstraintsTest14EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA2CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.15 Invalid DN nameConstraints Test15 @@ -1195,7 +2408,7 @@ "nameConstraintsDN3subCA1Cert", "InvalidDNnameConstraintsTest15EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN3CACRL", "nameConstraintsDN3subCA1CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.16 Invalid DN nameConstraints Test16 @@ -1206,7 +2419,7 @@ "nameConstraintsDN3subCA1Cert", "InvalidDNnameConstraintsTest16EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN3CACRL", "nameConstraintsDN3subCA1CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.17 Invalid DN nameConstraints Test17 @@ -1217,7 +2430,7 @@ "nameConstraintsDN3subCA2Cert", "InvalidDNnameConstraintsTest17EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN3CACRL", "nameConstraintsDN3subCA2CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.18 Valid DN nameConstraints Test18 @@ -1228,7 +2441,7 @@ "nameConstraintsDN3subCA2Cert", "ValidDNnameConstraintsTest18EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN3CACRL", "nameConstraintsDN3subCA2CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.19 Valid Self-Issued DN nameConstraints Test19 @@ -1238,7 +2451,7 @@ "TrustAnchorRootCertificate", "nameConstraintsDN1CACert", "nameConstraintsDN1SelfIssuedCACert", "ValidDNnameConstraintsTest19EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.20 Invalid Self-Issued DN nameConstraints Test20 @@ -1248,7 +2461,7 @@ "nameConstraintsDN1CACert", "InvalidDNnameConstraintsTest20EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.21 Valid RFC822 nameConstraints Test21 @@ -1259,7 +2472,7 @@ "ValidRFC822nameConstraintsTest21EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA1CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.22 Invalid RFC822 nameConstraints Test22 @@ -1270,7 +2483,7 @@ "InvalidRFC822nameConstraintsTest22EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA1CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.23 Valid RFC822 nameConstraints Test23 @@ -1281,7 +2494,7 @@ "ValidRFC822nameConstraintsTest23EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA2CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.24 Invalid RFC822 nameConstraints Test24 @@ -1292,7 +2505,7 @@ "InvalidRFC822nameConstraintsTest24EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA2CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.25 Valid RFC822 nameConstraints Test25 @@ -1303,7 +2516,7 @@ "ValidRFC822nameConstraintsTest25EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA3CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.26 Invalid RFC822 nameConstraints Test26 @@ -1314,7 +2527,7 @@ "InvalidRFC822nameConstraintsTest26EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsRFC822CA3CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.27 Valid DN and RFC822 nameConstraints Test27 @@ -1326,7 +2539,7 @@ "ValidDNandRFC822nameConstraintsTest27EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA3CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.28 Invalid DN and RFC822 nameConstraints Test28 @@ -1338,7 +2551,7 @@ "InvalidDNandRFC822nameConstraintsTest28EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA3CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.29 Invalid DN and RFC822 nameConstraints Test29 @@ -1350,7 +2563,7 @@ "InvalidDNandRFC822nameConstraintsTest29EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDN1CACRL", "nameConstraintsDN1subCA3CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.30 Valid DNS nameConstraints Test30 @@ -1360,7 +2573,7 @@ "nameConstraintsDNS1CACert", "ValidDNSnameConstraintsTest30EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDNS1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.31 Invalid DNS nameConstraints Test31 @@ -1370,7 +2583,7 @@ "nameConstraintsDNS1CACert", "InvalidDNSnameConstraintsTest31EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDNS1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.32 Valid DNS nameConstraints Test32 @@ -1380,7 +2593,7 @@ "nameConstraintsDNS2CACert", "ValidDNSnameConstraintsTest32EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDNS2CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.33 Invalid DNS nameConstraints Test33 @@ -1390,7 +2603,7 @@ "nameConstraintsDNS2CACert", "InvalidDNSnameConstraintsTest33EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDNS2CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.34 Valid URI nameConstraints Test34 @@ -1400,7 +2613,7 @@ "nameConstraintsURI1CACert", "ValidURInameConstraintsTest34EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.35 Invalid URI nameConstraints Test35 @@ -1410,7 +2623,7 @@ "nameConstraintsURI1CACert", "InvalidURInameConstraintsTest35EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.36 Valid URI nameConstraints Test36 @@ -1420,7 +2633,7 @@ "nameConstraintsURI2CACert", "ValidURInameConstraintsTest36EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI2CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.13.37 Invalid URI nameConstraints Test37 @@ -1430,7 +2643,7 @@ "nameConstraintsURI2CACert", "InvalidURInameConstraintsTest37EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsURI2CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.13.38 Invalid DNS nameConstraints Test38 @@ -1440,7 +2653,7 @@ "nameConstraintsDNS1CACert", "InvalidDNSnameConstraintsTest38EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "nameConstraintsDNS1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -1495,7 +2708,7 @@ "distributionPoint1CACert", "ValiddistributionPointTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.2 Invalid distributionPoint Test2 @@ -1505,7 +2718,7 @@ "distributionPoint1CACert", "InvaliddistributionPointTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.3 Invalid distributionPoint Test3 @@ -1515,7 +2728,7 @@ "distributionPoint1CACert", "InvaliddistributionPointTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint1CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.4 Valid distributionPoint Test4 @@ -1525,7 +2738,7 @@ "distributionPoint1CACert", "ValiddistributionPointTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint1CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.5 Valid distributionPoint Test5 @@ -1535,7 +2748,7 @@ "distributionPoint2CACert", "ValiddistributionPointTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint2CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.6 Invalid distributionPoint Test6 @@ -1545,7 +2758,7 @@ "distributionPoint2CACert", "InvaliddistributionPointTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint2CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.7 Valid distributionPoint Test7 @@ -1555,7 +2768,7 @@ "distributionPoint2CACert", "ValiddistributionPointTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint2CACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.8 Invalid distributionPoint Test8 @@ -1565,7 +2778,7 @@ "distributionPoint2CACert", "InvaliddistributionPointTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint2CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.9 Invalid distributionPoint Test9 @@ -1575,7 +2788,7 @@ "distributionPoint2CACert", "InvaliddistributionPointTest9EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "distributionPoint2CACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.10 Valid No issuingDistributionPoint Test10 @@ -1586,7 +2799,7 @@ "ValidNoissuingDistributionPointTest10EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "NoissuingDistributionPointCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.11 Invalid onlyContainsUserCerts CRL Test11 @@ -1597,7 +2810,7 @@ "InvalidonlyContainsUserCertsTest11EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "onlyContainsUserCertsCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.12 Invalid onlyContainsCACerts CRL Test12 @@ -1607,7 +2820,7 @@ "onlyContainsCACertsCACert", "InvalidonlyContainsCACertsTest12EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "onlyContainsCACertsCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.13 Valid onlyContainsCACerts CRL Test13 @@ -1617,7 +2830,7 @@ "onlyContainsCACertsCACert", "ValidonlyContainsCACertsTest13EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "onlyContainsCACertsCACRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.14 Invalid onlyContainsAttributeCerts Test14 @@ -1628,7 +2841,7 @@ "InvalidonlyContainsAttributeCertsTest14EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "onlyContainsAttributeCertsCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.15 Invalid onlySomeReasons Test15 @@ -1640,7 +2853,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA1compromiseCRL", "onlySomeReasonsCA1otherreasonsCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.16 Invalid onlySomeReasons Test16 @@ -1652,7 +2865,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA1compromiseCRL", "onlySomeReasonsCA1otherreasonsCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.17 Invalid onlySomeReasons Test17 @@ -1663,7 +2876,7 @@ "InvalidonlySomeReasonsTest17EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA2CRL1", "onlySomeReasonsCA2CRL2"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.18 Valid onlySomeReasons Test18 @@ -1675,7 +2888,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA3compromiseCRL", "onlySomeReasonsCA3otherreasonsCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.19 Valid onlySomeReasons Test19 @@ -1687,7 +2900,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA4compromiseCRL", "onlySomeReasonsCA4otherreasonsCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.20 Invalid onlySomeReasons Test20 @@ -1699,7 +2912,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA4compromiseCRL", "onlySomeReasonsCA4otherreasonsCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.21 Invalid onlySomeReasons Test21 @@ -1711,7 +2924,7 @@ const char* const crls[] = {"TrustAnchorRootCRL", "onlySomeReasonsCA4compromiseCRL", "onlySomeReasonsCA4otherreasonsCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.22 Valid IDP with indirectCRL Test22 @@ -1721,7 +2934,7 @@ "indirectCRLCA1Cert", "ValidIDPwithindirectCRLTest22EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA1CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.23 Invalid IDP with indirectCRL Test23 @@ -1731,7 +2944,7 @@ "indirectCRLCA1Cert", "InvalidIDPwithindirectCRLTest23EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA1CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.24 Valid IDP with indirectCRL Test24 @@ -1741,7 +2954,7 @@ "indirectCRLCA2Cert", "indirectCRLCA1Cert", "ValidIDPwithindirectCRLTest24EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA1CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.25 Valid IDP with indirectCRL Test25 @@ -1751,7 +2964,7 @@ "indirectCRLCA2Cert", "indirectCRLCA1Cert", "ValidIDPwithindirectCRLTest25EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA1CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.26 Invalid IDP with indirectCRL Test26 @@ -1761,7 +2974,7 @@ "indirectCRLCA2Cert", "indirectCRLCA1Cert", "InvalidIDPwithindirectCRLTest26EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA1CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.27 Invalid cRLIssuer Test27 @@ -1771,7 +2984,7 @@ "indirectCRLCA2Cert", "GoodCACert", "InvalidcRLIssuerTest27EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "GoodCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.28 Valid cRLIssuer Test28 @@ -1782,7 +2995,7 @@ "indirectCRLCA3cRLIssuerCert", "ValidcRLIssuerTest28EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA3CRL", "indirectCRLCA3cRLIssuerCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.29 Valid cRLIssuer Test29 @@ -1793,7 +3006,7 @@ "indirectCRLCA3cRLIssuerCert", "ValidcRLIssuerTest29EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA3CRL", "indirectCRLCA3cRLIssuerCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.30 Valid cRLIssuer Test30 @@ -1804,7 +3017,7 @@ "indirectCRLCA4cRLIssuerCert", "ValidcRLIssuerTest30EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA4cRLIssuerCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.31 Invalid cRLIssuer Test31 @@ -1814,7 +3027,7 @@ "indirectCRLCA5Cert", "indirectCRLCA6Cert", "InvalidcRLIssuerTest31EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA5CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.32 Invalid cRLIssuer Test32 @@ -1824,7 +3037,7 @@ "indirectCRLCA5Cert", "indirectCRLCA6Cert", "InvalidcRLIssuerTest32EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA5CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.33 Valid cRLIssuer Test33 @@ -1834,7 +3047,7 @@ "indirectCRLCA5Cert", "indirectCRLCA6Cert", "ValidcRLIssuerTest33EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA5CRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.14.34 Invalid cRLIssuer Test34 @@ -1844,7 +3057,7 @@ "indirectCRLCA5Cert", "InvalidcRLIssuerTest34EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA5CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.14.35 Invalid cRLIssuer Test35 @@ -1854,7 +3067,7 @@ "indirectCRLCA5Cert", "InvalidcRLIssuerTest35EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "indirectCRLCA5CRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P( @@ -1907,7 +3120,7 @@ "InvaliddeltaCRLIndicatorNoBaseTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLIndicatorNoBaseCACRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.15.2 Valid delta-CRL Test2 @@ -1916,7 +3129,7 @@ "ValiddeltaCRLTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA1CRL", "deltaCRLCA1deltaCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.15.3 Invalid delta-CRL Test3 @@ -1925,7 +3138,7 @@ "InvaliddeltaCRLTest3EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA1CRL", "deltaCRLCA1deltaCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.15.4 Invalid delta-CRL Test4 @@ -1934,7 +3147,7 @@ "InvaliddeltaCRLTest4EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA1CRL", "deltaCRLCA1deltaCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.15.5 Valid delta-CRL Test5 @@ -1943,7 +3156,7 @@ "ValiddeltaCRLTest5EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA1CRL", "deltaCRLCA1deltaCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.15.6 Invalid delta-CRL Test6 @@ -1952,7 +3165,7 @@ "InvaliddeltaCRLTest6EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA1CRL", "deltaCRLCA1deltaCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.15.7 Valid delta-CRL Test7 @@ -1961,7 +3174,7 @@ "ValiddeltaCRLTest7EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA1CRL", "deltaCRLCA1deltaCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.15.8 Valid delta-CRL Test8 @@ -1970,7 +3183,7 @@ "ValiddeltaCRLTest8EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA2CRL", "deltaCRLCA2deltaCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.15.9 Invalid delta-CRL Test9 @@ -1979,7 +3192,7 @@ "InvaliddeltaCRLTest9EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA2CRL", "deltaCRLCA2deltaCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } // 4.15.10 Invalid delta-CRL Test10 @@ -1988,7 +3201,7 @@ "InvaliddeltaCRLTest10EE"}; const char* const crls[] = {"TrustAnchorRootCRL", "deltaCRLCA3CRL", "deltaCRLCA3deltaCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P(PkitsTest15DeltaCRLs, @@ -2016,7 +3229,7 @@ "TrustAnchorRootCertificate", "ValidUnknownNotCriticalCertificateExtensionTest1EE"}; const char* const crls[] = {"TrustAnchorRootCRL"}; - ASSERT_TRUE(this->Verify(certs, crls)); + ASSERT_TRUE(this->Verify(certs, crls, {})); } // 4.16.2 Invalid Unknown Critical Certificate Extension Test2 @@ -2026,7 +3239,7 @@ "TrustAnchorRootCertificate", "InvalidUnknownCriticalCertificateExtensionTest2EE"}; const char* const crls[] = {"TrustAnchorRootCRL"}; - ASSERT_FALSE(this->Verify(certs, crls)); + ASSERT_FALSE(this->Verify(certs, crls, {})); } WRAPPED_REGISTER_TYPED_TEST_CASE_P(
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index 3309974b..605ff7e 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc
@@ -192,8 +192,7 @@ URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {} URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams() - : host_mapping_rules(nullptr), - ignore_certificate_errors(false), + : ignore_certificate_errors(false), testing_fixed_http_port(0), testing_fixed_https_port(0), enable_http2(true),
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h index a622625..45526b0a 100644 --- a/net/url_request/url_request_context_builder.h +++ b/net/url_request/url_request_context_builder.h
@@ -94,7 +94,7 @@ void ConfigureSessionParams(HttpNetworkSession::Params* params) const; // These fields mirror those in HttpNetworkSession::Params; - HostMappingRules* host_mapping_rules; + HostMappingRules host_mapping_rules; bool ignore_certificate_errors; uint16_t testing_fixed_http_port; uint16_t testing_fixed_https_port;
diff --git a/remoting/client/gesture_interpreter.cc b/remoting/client/gesture_interpreter.cc index c5ae592..7cf7e72 100644 --- a/remoting/client/gesture_interpreter.cc +++ b/remoting/client/gesture_interpreter.cc
@@ -8,7 +8,7 @@ #include "base/time/time.h" #include "remoting/client/chromoting_session.h" #include "remoting/client/display/renderer_proxy.h" -#include "remoting/client/input/direct_input_strategy.h" +#include "remoting/client/input/direct_touch_input_strategy.h" #include "remoting/client/input/trackpad_input_strategy.h" namespace { @@ -41,7 +41,7 @@ void GestureInterpreter::SetInputMode(InputMode mode) { switch (mode) { case DIRECT_INPUT_MODE: - input_strategy_.reset(new DirectInputStrategy()); + input_strategy_.reset(new DirectTouchInputStrategy()); break; case TRACKPAD_INPUT_MODE: input_strategy_.reset(new TrackpadInputStrategy(viewport_)); @@ -64,7 +64,7 @@ float scale, GestureState state) { AbortAnimations(); - SetGestureInProgress(InputStrategy::ZOOM, state != GESTURE_ENDED); + SetGestureInProgress(TouchInputStrategy::ZOOM, state != GESTURE_ENDED); input_strategy_->HandleZoom({pivot_x, pivot_y}, scale, &viewport_); } @@ -101,11 +101,11 @@ if (state == GESTURE_BEGAN) { StartInputFeedback(cursor_position.x, cursor_position.y, - InputStrategy::DRAG_FEEDBACK); + TouchInputStrategy::DRAG_FEEDBACK); } bool is_dragging_mode = state != GESTURE_ENDED; - SetGestureInProgress(InputStrategy::DRAG, is_dragging_mode); + SetGestureInProgress(TouchInputStrategy::DRAG, is_dragging_mode); input_stub_->SendMouseEvent(cursor_position.x, cursor_position.y, protocol::MouseEvent_MouseButton_BUTTON_LEFT, is_dragging_mode); @@ -162,7 +162,7 @@ gesture_in_progress_, &viewport_)) { // Cursor position changed. ViewMatrix::Point cursor_position = input_strategy_->GetCursorPosition(); - if (gesture_in_progress_ != InputStrategy::DRAG) { + if (gesture_in_progress_ != TouchInputStrategy::DRAG) { // Drag() will inject the position so don't need to do that in that case. InjectCursorPosition(cursor_position.x, cursor_position.y); } @@ -195,7 +195,7 @@ } ViewMatrix::Point cursor_position = input_strategy_->GetCursorPosition(); StartInputFeedback(cursor_position.x, cursor_position.y, - InputStrategy::TAP_FEEDBACK); + TouchInputStrategy::TAP_FEEDBACK); input_stub_->SendMouseEvent(cursor_position.x, cursor_position.y, button, true); @@ -203,10 +203,11 @@ false); } -void GestureInterpreter::SetGestureInProgress(InputStrategy::Gesture gesture, - bool is_in_progress) { +void GestureInterpreter::SetGestureInProgress( + TouchInputStrategy::Gesture gesture, + bool is_in_progress) { if (!is_in_progress && gesture_in_progress_ == gesture) { - gesture_in_progress_ = InputStrategy::NONE; + gesture_in_progress_ = TouchInputStrategy::NONE; return; } gesture_in_progress_ = gesture; @@ -215,7 +216,7 @@ void GestureInterpreter::StartInputFeedback( float cursor_x, float cursor_y, - InputStrategy::InputFeedbackType feedback_type) { + TouchInputStrategy::TouchFeedbackType feedback_type) { // This radius is on the view's coordinates. Need to be converted to desktop // coordinate. float feedback_radius = input_strategy_->GetFeedbackRadius(feedback_type);
diff --git a/remoting/client/gesture_interpreter.h b/remoting/client/gesture_interpreter.h index 66642e5..abe6871 100644 --- a/remoting/client/gesture_interpreter.h +++ b/remoting/client/gesture_interpreter.h
@@ -7,7 +7,7 @@ #include <memory> -#include "remoting/client/input/input_strategy.h" +#include "remoting/client/input/touch_input_strategy.h" #include "remoting/client/ui/desktop_viewport.h" #include "remoting/client/ui/fling_animation.h" #include "remoting/proto/event.pb.h" @@ -91,21 +91,21 @@ void InjectCursorPosition(float x, float y); - void SetGestureInProgress(InputStrategy::Gesture gesture, + void SetGestureInProgress(TouchInputStrategy::Gesture gesture, bool is_in_progress); // Starts the given feedback at (cursor_x, cursor_y) if the feedback radius // is non-zero. void StartInputFeedback(float cursor_x, float cursor_y, - InputStrategy::InputFeedbackType feedback_type); + TouchInputStrategy::TouchFeedbackType feedback_type); InputMode input_mode_ = UNDEFINED_INPUT_MODE; - std::unique_ptr<InputStrategy> input_strategy_; + std::unique_ptr<TouchInputStrategy> input_strategy_; DesktopViewport viewport_; RendererProxy* renderer_; ChromotingSession* input_stub_; - InputStrategy::Gesture gesture_in_progress_; + TouchInputStrategy::Gesture gesture_in_progress_; FlingAnimation pan_animation_; FlingAnimation scroll_animation_;
diff --git a/remoting/client/input/BUILD.gn b/remoting/client/input/BUILD.gn index c6e3279..5dc460e2 100644 --- a/remoting/client/input/BUILD.gn +++ b/remoting/client/input/BUILD.gn
@@ -5,9 +5,8 @@ source_set("input") { sources = [ "client_input_injector.h", - "direct_input_strategy.cc", - "direct_input_strategy.h", - "input_strategy.h", + "direct_touch_input_strategy.cc", + "direct_touch_input_strategy.h", "key_event_mapper.cc", "key_event_mapper.h", "keyboard_input_strategy.h", @@ -21,6 +20,7 @@ "text_keyboard_input_strategy.h", "touch_input_scaler.cc", "touch_input_scaler.h", + "touch_input_strategy.h", "trackpad_input_strategy.cc", "trackpad_input_strategy.h", ]
diff --git a/remoting/client/input/direct_input_strategy.cc b/remoting/client/input/direct_input_strategy.cc deleted file mode 100644 index b8a35b7..0000000 --- a/remoting/client/input/direct_input_strategy.cc +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/client/input/direct_input_strategy.h" - -#include "remoting/client/ui/desktop_viewport.h" - -namespace remoting { - -namespace { - -const float kTapFeedbackRadius = 25.f; -const float kDragFeedbackRadius = 55.f; - -} // namespace - -DirectInputStrategy::DirectInputStrategy() {} - -DirectInputStrategy::~DirectInputStrategy() {} - -void DirectInputStrategy::HandleZoom(const ViewMatrix::Point& pivot, - float scale, - DesktopViewport* viewport) { - viewport->ScaleDesktop(pivot.x, pivot.y, scale); -} - -bool DirectInputStrategy::HandlePan(const ViewMatrix::Vector2D& translation, - Gesture simultaneous_gesture, - DesktopViewport* viewport) { - if (simultaneous_gesture == DRAG) { - // If the user is dragging something, we should synchronize the movement - // with the object that the user is trying to move on the desktop, rather - // than moving the desktop around. - ViewMatrix::Vector2D viewport_movement = - viewport->GetTransformation().Invert().MapVector(translation); - viewport->MoveViewport(viewport_movement.x, viewport_movement.y); - return false; - } - - viewport->MoveDesktop(translation.x, translation.y); - return false; -} - -bool DirectInputStrategy::TrackTouchInput(const ViewMatrix::Point& touch_point, - const DesktopViewport& viewport) { - ViewMatrix::Point new_position = - viewport.GetTransformation().Invert().MapPoint(touch_point); - if (!viewport.IsPointWithinDesktopBounds(new_position)) { - return false; - } - cursor_position_ = new_position; - return true; -} - -ViewMatrix::Point DirectInputStrategy::GetCursorPosition() const { - return cursor_position_; -} - -ViewMatrix::Vector2D DirectInputStrategy::MapScreenVectorToDesktop( - const ViewMatrix::Vector2D& delta, - const DesktopViewport& viewport) const { - return viewport.GetTransformation().Invert().MapVector(delta); -} - -float DirectInputStrategy::GetFeedbackRadius(InputFeedbackType type) const { - switch (type) { - case InputFeedbackType::TAP_FEEDBACK: - return kTapFeedbackRadius; - case InputFeedbackType::DRAG_FEEDBACK: - return kDragFeedbackRadius; - } - NOTREACHED(); - return 0.f; -} - -bool DirectInputStrategy::IsCursorVisible() const { - return false; -} - -} // namespace remoting
diff --git a/remoting/client/input/direct_touch_input_strategy.cc b/remoting/client/input/direct_touch_input_strategy.cc new file mode 100644 index 0000000..5b4647a --- /dev/null +++ b/remoting/client/input/direct_touch_input_strategy.cc
@@ -0,0 +1,84 @@ +// 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 "remoting/client/input/direct_touch_input_strategy.h" + +#include "remoting/client/ui/desktop_viewport.h" + +namespace remoting { + +namespace { + +const float kTapFeedbackRadius = 25.f; +const float kDragFeedbackRadius = 55.f; + +} // namespace + +DirectTouchInputStrategy::DirectTouchInputStrategy() {} + +DirectTouchInputStrategy::~DirectTouchInputStrategy() {} + +void DirectTouchInputStrategy::HandleZoom(const ViewMatrix::Point& pivot, + float scale, + DesktopViewport* viewport) { + viewport->ScaleDesktop(pivot.x, pivot.y, scale); +} + +bool DirectTouchInputStrategy::HandlePan( + const ViewMatrix::Vector2D& translation, + Gesture simultaneous_gesture, + DesktopViewport* viewport) { + if (simultaneous_gesture == DRAG) { + // If the user is dragging something, we should synchronize the movement + // with the object that the user is trying to move on the desktop, rather + // than moving the desktop around. + ViewMatrix::Vector2D viewport_movement = + viewport->GetTransformation().Invert().MapVector(translation); + viewport->MoveViewport(viewport_movement.x, viewport_movement.y); + return false; + } + + viewport->MoveDesktop(translation.x, translation.y); + return false; +} + +bool DirectTouchInputStrategy::TrackTouchInput( + const ViewMatrix::Point& touch_point, + const DesktopViewport& viewport) { + ViewMatrix::Point new_position = + viewport.GetTransformation().Invert().MapPoint(touch_point); + if (!viewport.IsPointWithinDesktopBounds(new_position)) { + return false; + } + cursor_position_ = new_position; + return true; +} + +ViewMatrix::Point DirectTouchInputStrategy::GetCursorPosition() const { + return cursor_position_; +} + +ViewMatrix::Vector2D DirectTouchInputStrategy::MapScreenVectorToDesktop( + const ViewMatrix::Vector2D& delta, + const DesktopViewport& viewport) const { + return viewport.GetTransformation().Invert().MapVector(delta); +} + +float DirectTouchInputStrategy::GetFeedbackRadius( + TouchFeedbackType type) const { + switch (type) { + case TouchFeedbackType::TAP_FEEDBACK: + return kTapFeedbackRadius; + case TouchFeedbackType::DRAG_FEEDBACK: + return kDragFeedbackRadius; + } + NOTREACHED(); + return 0.f; +} + +bool DirectTouchInputStrategy::IsCursorVisible() const { + return false; +} + +} // namespace remoting
diff --git a/remoting/client/input/direct_input_strategy.h b/remoting/client/input/direct_touch_input_strategy.h similarity index 66% rename from remoting/client/input/direct_input_strategy.h rename to remoting/client/input/direct_touch_input_strategy.h index ef83851..08a63cc61 100644 --- a/remoting/client/input/direct_input_strategy.h +++ b/remoting/client/input/direct_touch_input_strategy.h
@@ -2,22 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef REMOTING_CLIENT_INPUT_DIRECT_INPUT_STRATEGY_H_ -#define REMOTING_CLIENT_INPUT_DIRECT_INPUT_STRATEGY_H_ +#ifndef REMOTING_CLIENT_INPUT_DIRECT_TOUCH_INPUT_STRATEGY_H_ +#define REMOTING_CLIENT_INPUT_DIRECT_TOUCH_INPUT_STRATEGY_H_ -#include "remoting/client/input/input_strategy.h" +#include "remoting/client/input/touch_input_strategy.h" namespace remoting { // This strategy directly translates all operations on the OpenGL view into // corresponding operations on the desktop. It doesn't maintain the cursor // positions separately -- the positions come from the location of the touch. -class DirectInputStrategy : public InputStrategy { +class DirectTouchInputStrategy : public TouchInputStrategy { public: - DirectInputStrategy(); - ~DirectInputStrategy() override; + DirectTouchInputStrategy(); + ~DirectTouchInputStrategy() override; - // InputStrategy overrides. + // TouchInputStrategy overrides. void HandleZoom(const ViewMatrix::Point& pivot, float scale, @@ -36,7 +36,7 @@ const ViewMatrix::Vector2D& delta, const DesktopViewport& viewport) const override; - float GetFeedbackRadius(InputFeedbackType type) const override; + float GetFeedbackRadius(TouchFeedbackType type) const override; bool IsCursorVisible() const override; @@ -44,9 +44,9 @@ ViewMatrix::Point cursor_position_{0.f, 0.f}; // TouchInputStrategy is neither copyable nor movable. - DirectInputStrategy(const DirectInputStrategy&) = delete; - DirectInputStrategy& operator=(const DirectInputStrategy&) = delete; + DirectTouchInputStrategy(const DirectTouchInputStrategy&) = delete; + DirectTouchInputStrategy& operator=(const DirectTouchInputStrategy&) = delete; }; } // namespace remoting -#endif // REMOTING_CLIENT_INPUT_DIRECT_INPUT_STRATEGY_H_ +#endif // REMOTING_CLIENT_INPUT_DIRECT_TOUCH_INPUT_STRATEGY_H_
diff --git a/remoting/client/input/input_strategy.h b/remoting/client/input/touch_input_strategy.h similarity index 89% rename from remoting/client/input/input_strategy.h rename to remoting/client/input/touch_input_strategy.h index 72f70d5..60eec61f 100644 --- a/remoting/client/input/input_strategy.h +++ b/remoting/client/input/touch_input_strategy.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef REMOTING_CLIENT_INPUT_INPUT_STRATEGY_H_ -#define REMOTING_CLIENT_INPUT_INPUT_STRATEGY_H_ +#ifndef REMOTING_CLIENT_TOUCH_INPUT_INPUT_STRATEGY_H_ +#define REMOTING_CLIENT_TOUCH_INPUT_INPUT_STRATEGY_H_ #include "remoting/client/ui/view_matrix.h" @@ -13,9 +13,9 @@ // This is an interface used by GestureInterpreter to customize the way gestures // are handled. -class InputStrategy { +class TouchInputStrategy { public: - enum InputFeedbackType { + enum TouchFeedbackType { TAP_FEEDBACK, DRAG_FEEDBACK, }; @@ -26,7 +26,7 @@ DRAG, }; - virtual ~InputStrategy() {} + virtual ~TouchInputStrategy() {} // Called when the GestureInterpreter receives a zoom gesture. The // implementation is responsible for modifying the viewport and observing the @@ -68,7 +68,7 @@ // coordinate for the given input type. The feedback will then be shown on the // cursor positions returned by GetCursorPosition(). Return 0 if no feedback // should be shown. - virtual float GetFeedbackRadius(InputFeedbackType type) const = 0; + virtual float GetFeedbackRadius(TouchFeedbackType type) const = 0; // Returns true if the input strategy maintains a visible cursor on the // desktop. @@ -76,4 +76,4 @@ }; } // namespace remoting -#endif // REMOTING_CLIENT_INPUT_INPUT_STRATEGY_H_ +#endif // REMOTING_CLIENT_TOUCH_INPUT_INPUT_STRATEGY_H_
diff --git a/remoting/client/input/trackpad_input_strategy.cc b/remoting/client/input/trackpad_input_strategy.cc index b669871..b38c625 100644 --- a/remoting/client/input/trackpad_input_strategy.cc +++ b/remoting/client/input/trackpad_input_strategy.cc
@@ -73,11 +73,11 @@ return delta; } -float TrackpadInputStrategy::GetFeedbackRadius(InputFeedbackType type) const { +float TrackpadInputStrategy::GetFeedbackRadius(TouchFeedbackType type) const { switch (type) { - case InputFeedbackType::TAP_FEEDBACK: + case TouchFeedbackType::TAP_FEEDBACK: return kTapFeedbackRadius; - case InputFeedbackType::DRAG_FEEDBACK: + case TouchFeedbackType::DRAG_FEEDBACK: return kDragFeedbackRadius; } NOTREACHED();
diff --git a/remoting/client/input/trackpad_input_strategy.h b/remoting/client/input/trackpad_input_strategy.h index abee68f..edf325f 100644 --- a/remoting/client/input/trackpad_input_strategy.h +++ b/remoting/client/input/trackpad_input_strategy.h
@@ -5,18 +5,18 @@ #ifndef REMOTING_CLIENT_INPUT_TRACKPAD_INPUT_STRATEGY_H_ #define REMOTING_CLIENT_INPUT_TRACKPAD_INPUT_STRATEGY_H_ -#include "remoting/client/input/input_strategy.h" +#include "remoting/client/input/touch_input_strategy.h" namespace remoting { // This strategy simulate the trackpad's behavior. It keeps a visible cursor // with positions independent of the location of the touch events. -class TrackpadInputStrategy : public InputStrategy { +class TrackpadInputStrategy : public TouchInputStrategy { public: TrackpadInputStrategy(const DesktopViewport& viewport); ~TrackpadInputStrategy() override; - // InputStrategy overrides. + // TouchInputStrategy overrides. void HandleZoom(const ViewMatrix::Point& pivot, float scale, DesktopViewport* viewport) override; @@ -34,7 +34,7 @@ const ViewMatrix::Vector2D& delta, const DesktopViewport& viewport) const override; - float GetFeedbackRadius(InputFeedbackType type) const override; + float GetFeedbackRadius(TouchFeedbackType type) const override; bool IsCursorVisible() const override;
diff --git a/services/resource_coordinator/BUILD.gn b/services/resource_coordinator/BUILD.gn index b31809c..b1a8500a 100644 --- a/services/resource_coordinator/BUILD.gn +++ b/services/resource_coordinator/BUILD.gn
@@ -64,6 +64,7 @@ "memory_instrumentation/process_map_unittest.cc", "public/cpp/memory_instrumentation/client_process_impl_unittest.cc", "public/cpp/tracing/chrome_trace_event_agent_unittest.cc", + "tracing/agent_registry_unittest.cc", "tracing/recorder_unittest.cc", ]
diff --git a/services/resource_coordinator/tracing/BUILD.gn b/services/resource_coordinator/tracing/BUILD.gn index 866a179..e578dfcd 100644 --- a/services/resource_coordinator/tracing/BUILD.gn +++ b/services/resource_coordinator/tracing/BUILD.gn
@@ -4,6 +4,8 @@ source_set("lib") { sources = [ + "agent_registry.cc", + "agent_registry.h", "recorder.cc", "recorder.h", ]
diff --git a/services/resource_coordinator/tracing/agent_registry.cc b/services/resource_coordinator/tracing/agent_registry.cc new file mode 100644 index 0000000..d87a055 --- /dev/null +++ b/services/resource_coordinator/tracing/agent_registry.cc
@@ -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. + +#include "services/resource_coordinator/tracing/agent_registry.h" + +#include <string> +#include <utility> + +#include "base/callback_forward.h" +#include "base/logging.h" +#include "base/threading/thread_checker.h" +#include "services/service_manager/public/cpp/bind_source_info.h" + +namespace { +tracing::AgentRegistry* g_agent_registry; +} + +namespace tracing { + +AgentRegistry::AgentEntry::AgentEntry(size_t id, + AgentRegistry* agent_registry, + mojom::AgentPtr agent, + const std::string& label, + mojom::TraceDataType type, + bool supports_explicit_clock_sync) + : id_(id), + agent_registry_(agent_registry), + agent_(std::move(agent)), + label_(label), + type_(type), + supports_explicit_clock_sync_(supports_explicit_clock_sync) { + DCHECK(!label.empty()); + agent_.set_connection_error_handler(base::BindRepeating( + &AgentRegistry::AgentEntry::OnConnectionError, base::Unretained(this))); +} + +AgentRegistry::AgentEntry::~AgentEntry() = default; + +void AgentRegistry::AgentEntry::SetDisconnectClosure( + base::OnceClosure closure) { + DCHECK(closure_.is_null()); + closure_ = std::move(closure); +} + +bool AgentRegistry::AgentEntry::RemoveDisconnectClosure() { + bool closure_was_set = !closure_.is_null(); + closure_.Reset(); + return closure_was_set; +} + +void AgentRegistry::AgentEntry::OnConnectionError() { + // Run the disconnect closure if it is set. We should mark |closure_| as + // movable so that the version of |Run| that takes an rvalue reference is + // selected not the version that takes a const reference. The former is for + // once callbacks and the latter is for repeating callbacks. + if (!closure_.is_null()) + std::move(closure_).Run(); + agent_registry_->UnregisterAgent(id_); +} + +// static +AgentRegistry* AgentRegistry::GetInstance() { + return g_agent_registry; +} + +AgentRegistry::AgentRegistry() { + DCHECK(!g_agent_registry); + g_agent_registry = this; +} + +AgentRegistry::~AgentRegistry() { + // For testing only. + g_agent_registry = nullptr; +} + +void AgentRegistry::BindAgentRegistryRequest( + const service_manager::BindSourceInfo& source_info, + mojom::AgentRegistryRequest request) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + bindings_.AddBinding(this, std::move(request)); +} + +void AgentRegistry::SetAgentInitializationCallback( + const AgentInitializationCallback& callback) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + agent_initialization_callback_ = callback; + ForAllAgents([this](AgentEntry* agent_entry) { + agent_initialization_callback_.Run(agent_entry); + }); +} + +void AgentRegistry::RemoveAgentInitializationCallback() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + agent_initialization_callback_.Reset(); +} + +void AgentRegistry::RegisterAgent(mojom::AgentPtr agent, + const std::string& label, + mojom::TraceDataType type, + bool supports_explicit_clock_sync) { + auto id = next_agent_id_++; + auto entry = base::MakeUnique<AgentEntry>(id, this, std::move(agent), label, + type, supports_explicit_clock_sync); + if (!agent_initialization_callback_.is_null()) + agent_initialization_callback_.Run(entry.get()); + auto result = agents_.insert(std::make_pair(id, std::move(entry))); + DCHECK(result.second); +} + +void AgentRegistry::UnregisterAgent(size_t agent_id) { + size_t num_deleted = agents_.erase(agent_id); + DCHECK_EQ(1u, num_deleted); +} + +} // namespace tracing
diff --git a/services/resource_coordinator/tracing/agent_registry.h b/services/resource_coordinator/tracing/agent_registry.h new file mode 100644 index 0000000..6841978c --- /dev/null +++ b/services/resource_coordinator/tracing/agent_registry.h
@@ -0,0 +1,109 @@ +// 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 SERVICES_RESOURCE_COORDINATOR_TRACING_AGENT_REGISTRY_H_ +#define SERVICES_RESOURCE_COORDINATOR_TRACING_AGENT_REGISTRY_H_ + +#include <map> +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/threading/thread_checker.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/resource_coordinator/public/interfaces/tracing/tracing.mojom.h" +#include "services/service_manager/public/cpp/bind_source_info.h" + +namespace tracing { + +class AgentRegistry : public mojom::AgentRegistry { + public: + class AgentEntry { + public: + AgentEntry(size_t id, + AgentRegistry* agent_registry, + mojom::AgentPtr agent, + const std::string& label, + mojom::TraceDataType type, + bool supports_explicit_clock_sync); + ~AgentEntry(); + + // Currently, at most one callback when the tracing agent is disconnected is + // enough. We can generalize this later if several parts of the service need + // to get notified when an agent disconnects. + void SetDisconnectClosure(base::OnceClosure closure); + bool RemoveDisconnectClosure(); + + mojom::Agent* agent() const { return agent_.get(); } + const std::string& label() const { return label_; } + mojom::TraceDataType type() const { return type_; } + bool supports_explicit_clock_sync() const { + return supports_explicit_clock_sync_; + } + + private: + void OnConnectionError(); + + const size_t id_; + AgentRegistry* agent_registry_; + mojom::AgentPtr agent_; + const std::string label_; + const mojom::TraceDataType type_; + const bool supports_explicit_clock_sync_; + base::OnceClosure closure_; + + DISALLOW_COPY_AND_ASSIGN(AgentEntry); + }; + + // A function to be run for every agent that registers itself. + using AgentInitializationCallback = + base::RepeatingCallback<void(AgentEntry*)>; + + static AgentRegistry* GetInstance(); + + AgentRegistry(); + + void BindAgentRegistryRequest( + const service_manager::BindSourceInfo& source_info, + mojom::AgentRegistryRequest request); + void SetAgentInitializationCallback( + const AgentInitializationCallback& callback); + void RemoveAgentInitializationCallback(); + + template <typename FunctionType> + void ForAllAgents(FunctionType function) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + for (const auto& key_value : agents_) { + function(key_value.second.get()); + } + } + + private: + friend std::default_delete<AgentRegistry>; + friend class AgentRegistryTest; // For testing. + + ~AgentRegistry() override; + + // mojom::AgentRegistry + void RegisterAgent(mojom::AgentPtr agent, + const std::string& label, + mojom::TraceDataType type, + bool supports_explicit_clock_sync) override; + + void UnregisterAgent(size_t agent_id); + + mojo::BindingSet<mojom::AgentRegistry> bindings_; + size_t next_agent_id_ = 0; + std::map<size_t, std::unique_ptr<AgentEntry>> agents_; + AgentInitializationCallback agent_initialization_callback_; + + THREAD_CHECKER(thread_checker_); + + DISALLOW_COPY_AND_ASSIGN(AgentRegistry); +}; + +} // namespace tracing + +#endif // SERVICES_RESOURCE_COORDINATOR_TRACING_AGENT_REGISTRY_H_
diff --git a/services/resource_coordinator/tracing/agent_registry_unittest.cc b/services/resource_coordinator/tracing/agent_registry_unittest.cc new file mode 100644 index 0000000..858e61e --- /dev/null +++ b/services/resource_coordinator/tracing/agent_registry_unittest.cc
@@ -0,0 +1,148 @@ +// 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 "services/resource_coordinator/tracing/agent_registry.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/resource_coordinator/public/interfaces/tracing/tracing.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace tracing { + +class MockAgent : public mojom::Agent { + public: + MockAgent() : binding_(this) {} + + mojom::AgentPtr CreateAgentPtr() { + return binding_.CreateInterfacePtrAndBind(); + } + + private: + // mojom::Agent + void StartTracing(const std::string& config, + mojom::RecorderPtr recorder, + const StartTracingCallback& callback) override {} + void StopAndFlush() override {} + void RequestClockSyncMarker( + const std::string& sync_id, + const RequestClockSyncMarkerCallback& callback) override {} + void RequestBufferStatus( + const RequestBufferStatusCallback& callback) override {} + void GetCategories(const GetCategoriesCallback& callback) override {} + + mojo::Binding<mojom::Agent> binding_; +}; + +class AgentRegistryTest : public testing::Test { + public: + void SetUp() override { + message_loop_.reset(new base::MessageLoop()); + registry_.reset(new AgentRegistry()); + } + + void TearDown() override { + registry_.reset(); + message_loop_.reset(); + } + + void RegisterAgent(mojom::AgentPtr agent, + const std::string& label, + mojom::TraceDataType type, + bool supports_explicit_clock_sync) { + registry_->RegisterAgent(std::move(agent), label, type, + supports_explicit_clock_sync); + } + + void RegisterAgent(mojom::AgentPtr agent) { + registry_->RegisterAgent(std::move(agent), "label", + mojom::TraceDataType::ARRAY, false); + } + + std::unique_ptr<AgentRegistry> registry_; + + private: + std::unique_ptr<base::MessageLoop> message_loop_; +}; + +TEST_F(AgentRegistryTest, RegisterAgent) { + MockAgent agent1; + RegisterAgent(agent1.CreateAgentPtr(), "TraceEvent", + mojom::TraceDataType::ARRAY, false); + size_t num_agents = 0; + registry_->ForAllAgents([&num_agents](AgentRegistry::AgentEntry* entry) { + num_agents++; + EXPECT_EQ("TraceEvent", entry->label()); + EXPECT_EQ(mojom::TraceDataType::ARRAY, entry->type()); + EXPECT_FALSE(entry->supports_explicit_clock_sync()); + }); + EXPECT_EQ(1u, num_agents); + + MockAgent agent2; + RegisterAgent(agent2.CreateAgentPtr(), "Power", mojom::TraceDataType::STRING, + true); + num_agents = 0; + registry_->ForAllAgents([&num_agents](AgentRegistry::AgentEntry* entry) { + num_agents++; + // Properties of |agent1| is already verified. + if (entry->label() == "TraceEvent") + return; + EXPECT_EQ("Power", entry->label()); + EXPECT_EQ(mojom::TraceDataType::STRING, entry->type()); + EXPECT_TRUE(entry->supports_explicit_clock_sync()); + }); + EXPECT_EQ(2u, num_agents); +} + +TEST_F(AgentRegistryTest, UnregisterAgent) { + base::RunLoop run_loop; + MockAgent agent1; + RegisterAgent(agent1.CreateAgentPtr()); + { + MockAgent agent2; + RegisterAgent(agent2.CreateAgentPtr()); + size_t num_agents = 0; + registry_->ForAllAgents( + [&num_agents](AgentRegistry::AgentEntry* entry) { num_agents++; }); + EXPECT_EQ(2u, num_agents); + } + run_loop.RunUntilIdle(); + + // |agent2| is not alive anymore. + size_t num_agents = 0; + registry_->ForAllAgents( + [&num_agents](AgentRegistry::AgentEntry* entry) { num_agents++; }); + EXPECT_EQ(1u, num_agents); +} + +TEST_F(AgentRegistryTest, AgentInitialization) { + size_t num_calls = 0; + MockAgent agent1; + RegisterAgent(agent1.CreateAgentPtr()); + registry_->SetAgentInitializationCallback(base::BindRepeating( + [](size_t* num_calls, tracing::AgentRegistry::AgentEntry* entry) { + (*num_calls)++; + }, + base::Unretained(&num_calls))); + // Since an agent was already registered, the callback should be run once. + EXPECT_EQ(1u, num_calls); + + // The callback should be run on future agents, too. + MockAgent agent2; + RegisterAgent(agent2.CreateAgentPtr()); + EXPECT_EQ(2u, num_calls); + + // The callback should not be run on future agents if it is removed. + registry_->RemoveAgentInitializationCallback(); + MockAgent agent3; + RegisterAgent(agent3.CreateAgentPtr()); + EXPECT_EQ(2u, num_calls); +} + +} // namespace tracing
diff --git a/services/ui/public/interfaces/window_manager.mojom b/services/ui/public/interfaces/window_manager.mojom index 0f659e62..563697d 100644 --- a/services/ui/public/interfaces/window_manager.mojom +++ b/services/ui/public/interfaces/window_manager.mojom
@@ -280,6 +280,16 @@ uint32 window_id) => (cc.mojom.LocalSurfaceId? local_surface_id); + // Configures the metrics for the displays and notifies observers. This is + // only applicable when WindowTree was created with a value of false for + // |automatically_create_display_roots|. This *must* be called after any + // display related changes to inform observers, for example, after calling + // SetDisplayRoot() this must be called to inform observers of the display + // changes. + SetDisplayConfiguration(array<display.mojom.Display> displays, + array<WmViewportMetrics> viewport_metrics, + int64 primary_display_id) => (bool success); + // The window manager has completed a request with the specific change id. WmResponse(uint32 change_id, bool response);
diff --git a/services/ui/service.cc b/services/ui/service.cc index 59b670f..5b2c9ca 100644 --- a/services/ui/service.cc +++ b/services/ui/service.cc
@@ -29,6 +29,7 @@ #include "services/ui/ime/ime_server_impl.h" #include "services/ui/ws/accessibility_manager.h" #include "services/ui/ws/display_binding.h" +#include "services/ui/ws/display_creation_config.h" #include "services/ui/ws/display_manager.h" #include "services/ui/ws/gpu_host.h" #include "services/ui/ws/user_activity_monitor.h" @@ -288,15 +289,19 @@ void Service::OnWillCreateTreeForWindowManager( bool automatically_create_display_roots) { - if (screen_manager_config_ != ScreenManagerConfig::UNKNOWN) + if (window_server_->display_creation_config() != + ws::DisplayCreationConfig::UNKNOWN) { return; + } DVLOG(3) << "OnWillCreateTreeForWindowManager " << automatically_create_display_roots; - screen_manager_config_ = automatically_create_display_roots - ? ScreenManagerConfig::INTERNAL - : ScreenManagerConfig::FORWARDING; - if (screen_manager_config_ == ScreenManagerConfig::FORWARDING) { + ws::DisplayCreationConfig config = automatically_create_display_roots + ? ws::DisplayCreationConfig::AUTOMATIC + : ws::DisplayCreationConfig::MANUAL; + window_server_->SetDisplayCreationConfig(config); + if (window_server_->display_creation_config() == + ws::DisplayCreationConfig::MANUAL) { #if defined(USE_OZONE) && defined(OS_CHROMEOS) screen_manager_ = base::MakeUnique<display::ScreenManagerForwarding>(); #else @@ -334,8 +339,9 @@ void Service::BindDisplayManagerRequest( const service_manager::BindSourceInfo& source_info, mojom::DisplayManagerRequest request) { - // DisplayManagerObservers generally expect there to be at least one display. - if (!window_server_->display_manager()->has_displays()) { + // Wait for the DisplayManager to be configured before binding display + // requests. Otherwise the client sees no displays. + if (!window_server_->display_manager()->IsReady()) { std::unique_ptr<PendingRequest> pending_request(new PendingRequest); pending_request->source_info = source_info; pending_request->dm_request.reset( @@ -392,7 +398,7 @@ const service_manager::BindSourceInfo& source_info, mojom::WindowTreeFactoryRequest request) { AddUserIfNecessary(source_info.identity); - if (!window_server_->display_manager()->has_displays()) { + if (!window_server_->display_manager()->IsReady()) { std::unique_ptr<PendingRequest> pending_request(new PendingRequest); pending_request->source_info = source_info; pending_request->wtf_request.reset(
diff --git a/services/ui/service.h b/services/ui/service.h index 6bf2463..6dd7d2f3 100644 --- a/services/ui/service.h +++ b/services/ui/service.h
@@ -66,20 +66,6 @@ ~Service() override; private: - // How the ScreenManager is configured. - enum ScreenManagerConfig { - // Initial state. - UNKNOWN, - - // ScreenManager runs locally. - INTERNAL, - - // Used when the window manager supplies a value of false for - // |automatically_create_display_roots|. In this config the ScreenManager - // is configured to forward calls. - FORWARDING, - }; - // Holds InterfaceRequests received before the first WindowTreeHost Display // has been established. struct PendingRequest; @@ -192,7 +178,6 @@ // Set to true in StartDisplayInit(). bool is_gpu_ready_ = false; - ScreenManagerConfig screen_manager_config_ = ScreenManagerConfig::UNKNOWN; DISALLOW_COPY_AND_ASSIGN(Service); };
diff --git a/services/ui/ws/BUILD.gn b/services/ui/ws/BUILD.gn index e24c44c..73659a52 100644 --- a/services/ui/ws/BUILD.gn +++ b/services/ui/ws/BUILD.gn
@@ -33,6 +33,7 @@ "display.h", "display_binding.cc", "display_binding.h", + "display_creation_config.h", "display_manager.cc", "display_manager.h", "drag_controller.cc",
diff --git a/services/ui/ws/cursor_location_manager.cc b/services/ui/ws/cursor_location_manager.cc index c26e15a3..a958716 100644 --- a/services/ui/ws/cursor_location_manager.cc +++ b/services/ui/ws/cursor_location_manager.cc
@@ -14,9 +14,9 @@ CursorLocationManager::~CursorLocationManager() {} void CursorLocationManager::OnMouseCursorLocationChanged( - const gfx::Point& point) { + const gfx::Point& point_in_dip) { current_cursor_location_ = static_cast<base::subtle::Atomic32>( - (point.x() & 0xFFFF) << 16 | (point.y() & 0xFFFF)); + (point_in_dip.x() & 0xFFFF) << 16 | (point_in_dip.y() & 0xFFFF)); if (cursor_location_memory()) { base::subtle::NoBarrier_Store(cursor_location_memory(), current_cursor_location_);
diff --git a/services/ui/ws/cursor_location_manager.h b/services/ui/ws/cursor_location_manager.h index 6096cdc..85d5a5e 100644 --- a/services/ui/ws/cursor_location_manager.h +++ b/services/ui/ws/cursor_location_manager.h
@@ -23,8 +23,8 @@ ~CursorLocationManager(); // Sets the current cursor location to |point|. Atomically writes the location - // to shared memory. - void OnMouseCursorLocationChanged(const gfx::Point& point); + // to shared memory. |point| should be in screen-coord and DIP. + void OnMouseCursorLocationChanged(const gfx::Point& point_in_dip); // Returns a read-only handle to the shared memory which contains the global // mouse cursor position. Each call returns a new handle.
diff --git a/services/ui/ws/display.cc b/services/ui/ws/display.cc index 4625f3ec..a355f19 100644 --- a/services/ui/ws/display.cc +++ b/services/ui/ws/display.cc
@@ -190,6 +190,8 @@ it != window_manager_display_root_map_.end(); ++it) { if (it->second == display_root) { window_manager_display_root_map_.erase(it); + if (window_manager_display_root_map_.empty()) + display_manager()->DestroyDisplay(this); return; } } @@ -299,10 +301,14 @@ const display::ViewportMetrics& metrics) { platform_display_->UpdateViewportMetrics(metrics); - if (root_->bounds().size() == metrics.bounds_in_pixels.size()) + SetBoundsInPixels(metrics.bounds_in_pixels); +} + +void Display::SetBoundsInPixels(const gfx::Rect& bounds_in_pixels) { + if (root_->bounds().size() == bounds_in_pixels.size()) return; - gfx::Rect new_bounds(metrics.bounds_in_pixels.size()); + gfx::Rect new_bounds(bounds_in_pixels.size()); root_->SetBounds(new_bounds, allocator_.GenerateId()); for (auto& pair : window_manager_display_root_map_) pair.second->root()->SetBounds(new_bounds, allocator_.GenerateId());
diff --git a/services/ui/ws/display.h b/services/ui/ws/display.h index 28cee3f..27e212c 100644 --- a/services/ui/ws/display.h +++ b/services/ui/ws/display.h
@@ -159,6 +159,8 @@ // Updates the size of display root ServerWindow and WM root ServerWindow(s). void OnViewportMetricsChanged(const display::ViewportMetrics& metrics); + void SetBoundsInPixels(const gfx::Rect& bounds_in_pixels); + // Returns the root window of the active user. ServerWindow* GetActiveRootWindow();
diff --git a/services/ui/ws/display_creation_config.h b/services/ui/ws/display_creation_config.h new file mode 100644 index 0000000..65b1f52 --- /dev/null +++ b/services/ui/ws/display_creation_config.h
@@ -0,0 +1,25 @@ +// 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 SERVICES_UI_WS_DISPLAY_CREATION_CONFIG_H_ +#define SERVICES_UI_WS_DISPLAY_CREATION_CONFIG_H_ + +namespace ui { +namespace ws { + +enum class DisplayCreationConfig { + // Initial state. + UNKNOWN, + + // Displays are created automatically based on the system. + AUTOMATIC, + + // Used when the window manager manually creates displays. + MANUAL, +}; + +} // namespace ws +} // namespace ui + +#endif // SERVICES_UI_WS_DISPLAY_CREATION_CONFIG_H_
diff --git a/services/ui/ws/display_manager.cc b/services/ui/ws/display_manager.cc index 6575884c..e64964b 100644 --- a/services/ui/ws/display_manager.cc +++ b/services/ui/ws/display_manager.cc
@@ -7,11 +7,14 @@ #include <vector> #include "base/memory/ptr_util.h" +#include "base/stl_util.h" #include "base/trace_event/trace_event.h" +#include "services/ui/display/screen_manager.h" #include "services/ui/display/viewport_metrics.h" #include "services/ui/ws/cursor_location_manager.h" #include "services/ui/ws/display.h" #include "services/ui/ws/display_binding.h" +#include "services/ui/ws/display_creation_config.h" #include "services/ui/ws/event_dispatcher.h" #include "services/ui/ws/frame_generator.h" #include "services/ui/ws/server_window.h" @@ -22,6 +25,8 @@ #include "services/ui/ws/window_manager_window_tree_factory.h" #include "services/ui/ws/window_server_delegate.h" #include "services/ui/ws/window_tree.h" +#include "ui/display/display_list.h" +#include "ui/display/screen_base.h" #include "ui/events/event_rewriter.h" #if defined(OS_CHROMEOS) @@ -54,11 +59,101 @@ DestroyAllDisplays(); } +void DisplayManager::OnDisplayCreationConfigSet() { + if (window_server_->display_creation_config() == + DisplayCreationConfig::MANUAL) { + for (const auto& pair : user_display_managers_) + pair.second->DisableAutomaticNotification(); + } else { + // In AUTOMATIC mode SetDisplayConfiguration() is never called. + got_initial_config_from_window_manager_ = true; + } +} + +bool DisplayManager::SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id) { + if (window_server_->display_creation_config() != + DisplayCreationConfig::MANUAL) { + DVLOG(1) << "SetDisplayConfiguration is only valid when roots manually " + "created"; + return false; + } + if (displays.size() != viewport_metrics.size()) { + DVLOG(1) << "SetDisplayConfiguration called with mismatch in sizes"; + return false; + } + size_t primary_display_index = displays.size(); + std::set<int64_t> display_ids; + for (size_t i = 0; i < displays.size(); ++i) { + const display::Display& display = displays[i]; + if (display.id() == display::kInvalidDisplayId) { + DVLOG(1) << "SetDisplayConfiguration passed invalid display id"; + return false; + } + if (!display_ids.insert(display.id()).second) { + DVLOG(1) << "SetDisplayConfiguration passed duplicate display id"; + return false; + } + if (display.id() == primary_display_id) + primary_display_index = i; + Display* ws_display = GetDisplayById(display.id()); + if (!ws_display) { + DVLOG(1) << "SetDisplayConfiguration passed unknown display id " + << display.id(); + return false; + } + } + if (primary_display_index == displays.size()) { + DVLOG(1) << "SetDisplayConfiguration primary id not in displays"; + return false; + } + + display::DisplayList& display_list = + display::ScreenManager::GetInstance()->GetScreen()->display_list(); + display_list.AddOrUpdateDisplay(displays[primary_display_index], + display::DisplayList::Type::PRIMARY); + for (size_t i = 0; i < displays.size(); ++i) { + Display* ws_display = GetDisplayById(displays[i].id()); + DCHECK(ws_display); + ws_display->SetDisplay(displays[i]); + ws_display->SetBoundsInPixels(viewport_metrics[i]->bounds_in_pixels); + if (i != primary_display_index) { + display_list.AddOrUpdateDisplay(displays[i], + display::DisplayList::Type::NOT_PRIMARY); + } + } + + std::set<int64_t> existing_display_ids; + for (const display::Display& display : display_list.displays()) + existing_display_ids.insert(display.id()); + std::set<int64_t> removed_display_ids = + base::STLSetDifference<std::set<int64_t>>(existing_display_ids, + display_ids); + for (int64_t display_id : removed_display_ids) + display_list.RemoveDisplay(display_id); + + for (auto& pair : user_display_managers_) + pair.second->CallOnDisplaysChanged(); + + if (!got_initial_config_from_window_manager_) { + got_initial_config_from_window_manager_ = true; + window_server_->delegate()->OnFirstDisplayReady(); + } + + return true; +} + UserDisplayManager* DisplayManager::GetUserDisplayManager( const UserId& user_id) { if (!user_display_managers_.count(user_id)) { user_display_managers_[user_id] = base::MakeUnique<UserDisplayManager>(window_server_, user_id); + if (window_server_->display_creation_config() == + DisplayCreationConfig::MANUAL) { + user_display_managers_[user_id]->DisableAutomaticNotification(); + } } return user_display_managers_[user_id].get(); } @@ -77,10 +172,19 @@ pending_displays_.insert(display); } -void DisplayManager::AddDisplayForWindowManager( +Display* DisplayManager::AddDisplayForWindowManager( + bool is_primary_display, const display::Display& display, const display::ViewportMetrics& metrics) { + DCHECK_EQ(DisplayCreationConfig::MANUAL, + window_server_->display_creation_config()); + const display::DisplayList::Type display_type = + is_primary_display ? display::DisplayList::Type::PRIMARY + : display::DisplayList::Type::NOT_PRIMARY; + display::ScreenManager::GetInstance()->GetScreen()->display_list().AddDisplay( + display, display_type); OnDisplayAdded(display, metrics); + return GetDisplayById(display.id()); } void DisplayManager::DestroyDisplay(Display* display) { @@ -180,7 +284,8 @@ void DisplayManager::OnDisplayAcceleratedWidgetAvailable(Display* display) { DCHECK_NE(0u, pending_displays_.count(display)); DCHECK_EQ(0u, displays_.count(display)); - const bool is_first_display = displays_.empty(); + const bool is_first_display = + displays_.empty() && got_initial_config_from_window_manager_; displays_.insert(display); pending_displays_.erase(display); if (event_rewriter_) @@ -199,26 +304,35 @@ const UserId& active_id) { WindowManagerState* previous_window_manager_state = window_server_->GetWindowManagerStateForUser(previously_active_id); - gfx::Point mouse_location_on_screen; + gfx::Point mouse_location_on_display; + int64_t mouse_display_id = 0; if (previous_window_manager_state) { - mouse_location_on_screen = previous_window_manager_state->event_dispatcher() - ->mouse_pointer_last_location(); + mouse_location_on_display = + previous_window_manager_state->event_dispatcher() + ->mouse_pointer_last_location(); + mouse_display_id = previous_window_manager_state->event_dispatcher() + ->mouse_pointer_display_id(); previous_window_manager_state->Deactivate(); } WindowManagerState* current_window_manager_state = window_server_->GetWindowManagerStateForUser(active_id); if (current_window_manager_state) - current_window_manager_state->Activate(mouse_location_on_screen); + current_window_manager_state->Activate(mouse_location_on_display, + mouse_display_id); +} + +void DisplayManager::CreateDisplay(const display::Display& display, + const display::ViewportMetrics& metrics) { + ws::Display* ws_display = new ws::Display(window_server_); + ws_display->SetDisplay(display); + ws_display->Init(metrics, nullptr); } void DisplayManager::OnDisplayAdded(const display::Display& display, const display::ViewportMetrics& metrics) { DVLOG(3) << "OnDisplayAdded: " << display.ToString(); - - ws::Display* ws_display = new ws::Display(window_server_); - ws_display->SetDisplay(display); - ws_display->Init(metrics, nullptr); + CreateDisplay(display, metrics); } void DisplayManager::OnDisplayRemoved(int64_t display_id) {
diff --git a/services/ui/ws/display_manager.h b/services/ui/ws/display_manager.h index 99bf820..2fc3a80 100644 --- a/services/ui/ws/display_manager.h +++ b/services/ui/ws/display_manager.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "services/ui/display/screen_manager_delegate.h" +#include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "services/ui/ws/ids.h" #include "services/ui/ws/user_id.h" #include "services/ui/ws/user_id_tracker_observer.h" @@ -37,6 +38,23 @@ DisplayManager(WindowServer* window_server, UserIdTracker* user_id_tracker); ~DisplayManager() override; + // Called once WindowServer::display_creation_config() has been determined. + void OnDisplayCreationConfigSet(); + + // Indicates the display configuration is valid. Set to true when the + // display_creation_config() has been determined and the config is + // AUTOMATIC, or MANUAL and the SetDisplayConfiguration() has been called. + bool got_initial_config_from_window_manager() const { + return got_initial_config_from_window_manager_; + } + + // Sets the display configuration from the window manager. Returns true + // on success, false if the arguments aren't valid. + bool SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id); + // Returns the UserDisplayManager for |user_id|. DisplayManager owns the // return value. UserDisplayManager* GetUserDisplayManager(const UserId& user_id); @@ -48,8 +66,9 @@ // TODO(sky): make add take a scoped_ptr. void AddDisplay(Display* display); // Called when the window manager explicitly adds a new display. - void AddDisplayForWindowManager(const display::Display& display, - const display::ViewportMetrics& metrics); + Display* AddDisplayForWindowManager(bool is_primary_display, + const display::Display& display, + const display::ViewportMetrics& metrics); void DestroyDisplay(Display* display); void DestroyAllDisplays(); const std::set<Display*>& displays() { return displays_; } @@ -73,7 +92,9 @@ WindowManagerDisplayRoot* GetWindowManagerDisplayRoot( const ServerWindow* window); - bool has_displays() const { return !displays_.empty(); } + bool IsReady() const { + return !displays_.empty() && got_initial_config_from_window_manager_; + } bool has_active_or_pending_displays() const { return !displays_.empty() || !pending_displays_.empty(); } @@ -93,6 +114,11 @@ void OnActiveUserIdChanged(const UserId& previously_active_id, const UserId& active_id) override; + void CreateDisplay(const display::Display& display, + const display::ViewportMetrics& metrics); + + // NOTE: these functions are *not* called when the WindowManager manually + // creates roots. // display::ScreenManagerDelegate: void OnDisplayAdded(const display::Display& display, const display::ViewportMetrics& metrics) override; @@ -120,6 +146,8 @@ // ID to use for next root node. ClientSpecificId next_root_id_; + bool got_initial_config_from_window_manager_ = false; + DISALLOW_COPY_AND_ASSIGN(DisplayManager); };
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index 83e8b37..bcea3cf9 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -76,15 +76,17 @@ mouse_button_down_ = false; } -void EventDispatcher::SetMousePointerScreenLocation( - const gfx::Point& screen_location) { +void EventDispatcher::SetMousePointerDisplayLocation( + const gfx::Point& display_location, + const int64_t display_id) { DCHECK(pointer_targets_.empty()); - mouse_pointer_last_location_ = screen_location; + mouse_pointer_last_location_ = display_location; + mouse_pointer_display_id_ = display_id; UpdateCursorProviderByLastKnownLocation(); // Write our initial location back to our shared screen coordinate. This // shouldn't cause problems because we already read the cursor before we // process any events in views during window construction. - delegate_->OnMouseCursorLocationChanged(screen_location); + delegate_->OnMouseCursorLocationChanged(display_location, display_id); } ui::CursorData EventDispatcher::GetCurrentMouseCursor() const { @@ -219,8 +221,8 @@ void EventDispatcher::UpdateNonClientAreaForCurrentWindow() { if (mouse_cursor_source_window_) { - DeepestWindow deepest_window = - FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_); + DeepestWindow deepest_window = FindDeepestVisibleWindowForEvents( + &mouse_pointer_last_location_, &mouse_pointer_display_id_); if (deepest_window.window == mouse_cursor_source_window_) { mouse_cursor_in_non_client_area_ = mouse_cursor_source_window_ ? deepest_window.in_non_client_area @@ -231,14 +233,14 @@ void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { if (!mouse_button_down_) { - DeepestWindow deepest_window = - FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_); + DeepestWindow deepest_window = FindDeepestVisibleWindowForEvents( + &mouse_pointer_last_location_, &mouse_pointer_display_id_); SetMouseCursorSourceWindow(deepest_window.window); if (mouse_cursor_source_window_) { mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area; } else { - gfx::Point location = mouse_pointer_last_location_; - SetMouseCursorSourceWindow(delegate_->GetRootWindowContaining(&location)); + SetMouseCursorSourceWindow(delegate_->GetRootWindowContaining( + &mouse_pointer_last_location_, &mouse_pointer_display_id_)); mouse_cursor_in_non_client_area_ = true; } } @@ -273,6 +275,7 @@ } void EventDispatcher::ProcessEvent(const ui::Event& event, + const int64_t display_id, AcceleratorMatchPhase match_phase) { #if !defined(NDEBUG) if (match_phase == AcceleratorMatchPhase::POST_ONLY) { @@ -287,6 +290,7 @@ previous_event_ = Event::Clone(event); previous_accelerator_match_phase_ = match_phase; #endif + event_display_id_ = display_id; if (event.IsKeyEvent()) { const ui::KeyEvent* key_event = event.AsKeyEvent(); if (!key_event->is_char() && match_phase == AcceleratorMatchPhase::ANY) { @@ -294,7 +298,7 @@ FindAccelerator(*key_event, ui::mojom::AcceleratorPhase::PRE_TARGET); if (pre_target) { delegate_->OnAccelerator( - pre_target->id(), event, + pre_target->id(), event_display_id_, event, EventDispatcherDelegate::AcceleratorPhase::PRE); return; } @@ -329,19 +333,19 @@ return; } ServerWindow* focused_window = - delegate_->GetFocusedWindowForEventDispatcher(); + delegate_->GetFocusedWindowForEventDispatcher(event_display_id_); if (focused_window) { // Assume key events are for the client area. const bool in_nonclient_area = false; const ClientSpecificId client_id = delegate_->GetEventTargetClientId(focused_window, in_nonclient_area); - delegate_->DispatchInputEventToWindow(focused_window, client_id, event, - post_target); + delegate_->DispatchInputEventToWindow( + focused_window, client_id, event_display_id_, event, post_target); return; } - delegate_->OnEventTargetNotFound(event); + delegate_->OnEventTargetNotFound(event, event_display_id_); if (post_target) - delegate_->OnAccelerator(post_target->id(), event, + delegate_->OnAccelerator(post_target->id(), event_display_id_, event, EventDispatcherDelegate::AcceleratorPhase::POST); } @@ -351,7 +355,9 @@ if (is_mouse_event) { mouse_pointer_last_location_ = event.root_location(); - delegate_->OnMouseCursorLocationChanged(event.root_location()); + mouse_pointer_display_id_ = event_display_id_; + delegate_->OnMouseCursorLocationChanged(event.root_location(), + event_display_id_); } // Release capture on pointer up. For mouse we only release if there are @@ -399,7 +405,9 @@ ServerWindow* capture_window = pointer_target.window; if (!capture_window) { gfx::Point event_location = event.root_location(); - capture_window = delegate_->GetRootWindowContaining(&event_location); + int64_t event_display_id = event_display_id_; + capture_window = delegate_->GetRootWindowContaining( + &event_location, &event_display_id); } delegate_->SetNativeCapture(capture_window); } @@ -481,8 +489,9 @@ EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( const ui::LocatedEvent& event) { PointerTarget pointer_target; - DeepestWindow deepest_window = - FindDeepestVisibleWindowForEvents(event.root_location()); + gfx::Point event_root_location(event.root_location()); + DeepestWindow deepest_window = FindDeepestVisibleWindowForEvents( + &event_root_location, &event_display_id_); pointer_target.window = modal_window_controller_.GetTargetForWindow(deepest_window.window); pointer_target.is_mouse_event = event.IsMousePointerEvent(); @@ -504,7 +513,7 @@ void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target, const ui::LocatedEvent& event) { if (!target.window) { - delegate_->OnEventTargetNotFound(event); + delegate_->OnEventTargetNotFound(event, event_display_id_); return; } @@ -526,7 +535,8 @@ clone->AsLocatedEvent()->set_location(location); // TODO(jonross): add post-target accelerator support once accelerators // support pointer events. - delegate_->DispatchInputEventToWindow(window, client_id, *clone, nullptr); + delegate_->DispatchInputEventToWindow(window, client_id, event_display_id_, + *clone, nullptr); } void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { @@ -581,12 +591,10 @@ } DeepestWindow EventDispatcher::FindDeepestVisibleWindowForEvents( - const gfx::Point& location) { - gfx::Point relative_location(location); - // For the case of no root. - ServerWindow* root = delegate_->GetRootWindowContaining(&relative_location); - return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, - relative_location) + gfx::Point* location, + int64_t* display_id) { + ServerWindow* root = delegate_->GetRootWindowContaining(location, display_id); + return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, *location) : DeepestWindow(); }
diff --git a/services/ui/ws/event_dispatcher.h b/services/ui/ws/event_dispatcher.h index 8b084d7..a99846e8 100644 --- a/services/ui/ws/event_dispatcher.h +++ b/services/ui/ws/event_dispatcher.h
@@ -59,10 +59,12 @@ // any events to the delegate. void Reset(); - void SetMousePointerScreenLocation(const gfx::Point& screen_location); + void SetMousePointerDisplayLocation(const gfx::Point& display_location, + const int64_t display_id); const gfx::Point& mouse_pointer_last_location() const { return mouse_pointer_last_location_; } + int64_t mouse_pointer_display_id() const { return mouse_pointer_display_id_; } // Returns the cursor for the current target, or POINTER if the mouse is not // over a valid target. @@ -142,7 +144,9 @@ // ANY and there is a matching accelerator with PRE_TARGET found, than only // OnAccelerator() is called. The expectation is after the PRE_TARGET has been // handled this is again called with an AcceleratorMatchPhase of POST_ONLY. - void ProcessEvent(const ui::Event& event, AcceleratorMatchPhase match_phase); + void ProcessEvent(const ui::Event& event, + const int64_t display_id, + AcceleratorMatchPhase match_phase); private: friend class test::EventDispatcherTestApi; @@ -234,7 +238,8 @@ Accelerator* FindAccelerator(const ui::KeyEvent& event, const ui::mojom::AcceleratorPhase phase); - DeepestWindow FindDeepestVisibleWindowForEvents(const gfx::Point& location); + DeepestWindow FindDeepestVisibleWindowForEvents(gfx::Point* location, + int64_t* display_id); // Clears the implicit captures in |pointer_targets_|, with the exception of // |window|. |window| may be null. |client_id| is the target client of @@ -265,9 +270,15 @@ ServerWindow* mouse_cursor_source_window_; bool mouse_cursor_in_non_client_area_; - // The on screen location of the mouse pointer. This can be outside the - // bounds of |mouse_cursor_source_window_|, which can capture the cursor. + // The location of the mouse pointer in display coordinates. This can be + // outside the bounds of |mouse_cursor_source_window_|, which can capture the + // cursor. gfx::Point mouse_pointer_last_location_; + // Id of the display |mouse_pointer_last_location_| is on. + int64_t mouse_pointer_display_id_ = display::kInvalidDisplayId; + + // Id of the display the most recent event is on. + int64_t event_display_id_ = display::kInvalidDisplayId; std::map<uint32_t, std::unique_ptr<Accelerator>> accelerators_;
diff --git a/services/ui/ws/event_dispatcher_delegate.h b/services/ui/ws/event_dispatcher_delegate.h index 69b7a1b..28a2a0a1 100644 --- a/services/ui/ws/event_dispatcher_delegate.h +++ b/services/ui/ws/event_dispatcher_delegate.h
@@ -31,11 +31,13 @@ }; virtual void OnAccelerator(uint32_t accelerator, + const int64_t display_id, const ui::Event& event, AcceleratorPhase phase) = 0; virtual void SetFocusedWindowFromEventDispatcher(ServerWindow* window) = 0; - virtual ServerWindow* GetFocusedWindowForEventDispatcher() = 0; + virtual ServerWindow* GetFocusedWindowForEventDispatcher( + const int64_t display_id) = 0; // Called when capture should be set on the native display. |window| is the // window capture is being set on. @@ -55,11 +57,13 @@ virtual void OnCaptureChanged(ServerWindow* new_capture, ServerWindow* old_capture) = 0; - virtual void OnMouseCursorLocationChanged(const gfx::Point& point) = 0; + virtual void OnMouseCursorLocationChanged(const gfx::Point& point, + const int64_t display_id) = 0; // Dispatches an event to the specific client. virtual void DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const ui::Event& event, Accelerator* accelerator) = 0; @@ -69,14 +73,20 @@ bool in_nonclient_area) = 0; // Returns the window to start searching from at the specified location, or - // null if there is a no window containing |location|. |location| should be in - // screen coordinates and if a window is returned then |location| will be - // updated to be relative to the origin of the window. - virtual ServerWindow* GetRootWindowContaining(gfx::Point* location) = 0; + // null if there is a no window containing |location_in_display|. + // |location_in_display| is in display coordinates and in pixels. + // |location_in_display| and |display_id| are updated if the window we + // found is on a different display than the originated display. + // TODO(riajiang): No need to update |location_in_display| and |display_id| + // after ozone drm can tell us the right display the cursor is on for + // drag-n-drop events. crbug.com/726470 + virtual ServerWindow* GetRootWindowContaining(gfx::Point* location_in_display, + int64_t* display_id) = 0; // Called when event dispatch could not find a target. OnAccelerator may still // be called. - virtual void OnEventTargetNotFound(const ui::Event& event) = 0; + virtual void OnEventTargetNotFound(const ui::Event& event, + const int64_t display_id) = 0; protected: virtual ~EventDispatcherDelegate() {}
diff --git a/services/ui/ws/event_dispatcher_unittest.cc b/services/ui/ws/event_dispatcher_unittest.cc index e6d241b..be3217a 100644 --- a/services/ui/ws/event_dispatcher_unittest.cc +++ b/services/ui/ws/event_dispatcher_unittest.cc
@@ -106,13 +106,15 @@ private: // EventDispatcherDelegate: void OnAccelerator(uint32_t accelerator, + const int64_t display_id, const ui::Event& event, AcceleratorPhase phase) override { EXPECT_EQ(0u, last_accelerator_); last_accelerator_ = accelerator; last_accelerator_phase_ = phase; } - ServerWindow* GetFocusedWindowForEventDispatcher() override { + ServerWindow* GetFocusedWindowForEventDispatcher( + const int64_t display_id) override { return focused_window_; } void SetNativeCapture(ServerWindow* window) override {} @@ -125,9 +127,11 @@ ServerWindow* old_capture_window) override { lost_capture_window_ = old_capture_window; } - void OnMouseCursorLocationChanged(const gfx::Point& point) override {} + void OnMouseCursorLocationChanged(const gfx::Point& point, + const int64_t display_id) override {} void DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const ui::Event& event, Accelerator* accelerator) override { std::unique_ptr<DispatchedEventDetails> details(new DispatchedEventDetails); @@ -141,10 +145,12 @@ bool in_nonclient_area) override { return in_nonclient_area ? kNonclientAreaId : kClientAreaId; } - ServerWindow* GetRootWindowContaining(gfx::Point* location) override { + ServerWindow* GetRootWindowContaining(gfx::Point* location_in_display, + int64_t* display_id) override { return root_; } - void OnEventTargetNotFound(const ui::Event& event) override { + void OnEventTargetNotFound(const ui::Event& event, + const int64_t display_id) override { last_event_target_not_found_ = ui::Event::Clone(event); } @@ -200,7 +206,7 @@ const MouseEventTest& test = tests[i]; ASSERT_FALSE(dispatcher_delegate->has_queued_events()) << " unexpected queued events before running " << i; - dispatcher->ProcessEvent(ui::PointerEvent(test.input_event), + dispatcher->ProcessEvent(ui::PointerEvent(test.input_event), 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -341,7 +347,7 @@ const ui::PointerEvent ui_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(ui_event, + event_dispatcher()->ProcessEvent(ui_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -360,7 +366,7 @@ TEST_F(EventDispatcherTest, ProcessEventNoTarget) { // Send event without a target. ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); - event_dispatcher()->ProcessEvent(key, + event_dispatcher()->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Event wasn't dispatched to a target. @@ -425,7 +431,7 @@ dispatcher->AddAccelerator(accelerator_1, std::move(matcher)); ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(accelerator_1, event_dispatcher_delegate->GetAndClearLastAccelerator()); @@ -433,24 +439,24 @@ // ignoring. key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN | ui::EF_NUM_LOCK_ON); - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(accelerator_1, event_dispatcher_delegate->GetAndClearLastAccelerator()); key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_NONE); - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator()); uint32_t accelerator_2 = 2; matcher = ui::CreateKeyMatcher(ui::mojom::KeyboardCode::W, ui::mojom::kEventFlagNone); dispatcher->AddAccelerator(accelerator_2, std::move(matcher)); - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(accelerator_2, event_dispatcher_delegate->GetAndClearLastAccelerator()); dispatcher->RemoveAccelerator(accelerator_2); - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator()); } @@ -468,7 +474,7 @@ ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); // The post-target accelerator should be fired if there is no focused window. - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(accelerator_1, event_dispatcher_delegate->GetAndClearLastAccelerator()); std::unique_ptr<DispatchedEventDetails> details = @@ -480,7 +486,7 @@ event_dispatcher_delegate->SetFocusedWindowFromEventDispatcher(child.get()); // With a focused window the event should be dispatched. - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator()); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(details); @@ -492,7 +498,7 @@ EXPECT_FALSE(accelerator_weak_ptr); // Post deletion there should be no accelerator - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator()); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(details); @@ -527,14 +533,14 @@ // Dispatch for ANY, which should trigger PRE and not call // DispatchInputEventToWindow(). ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); - dispatcher->ProcessEvent(key, EventDispatcher::AcceleratorMatchPhase::ANY); + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::ANY); EXPECT_EQ(EventDispatcherDelegate::AcceleratorPhase::PRE, event_dispatcher_delegate->last_accelerator_phase()); EXPECT_EQ(pre_id, event_dispatcher_delegate->GetAndClearLastAccelerator()); EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); // Dispatch for POST, which should trigger POST. - dispatcher->ProcessEvent(key, + dispatcher->ProcessEvent(key, 0, EventDispatcher::AcceleratorMatchPhase::POST_ONLY); std::unique_ptr<DispatchedEventDetails> details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); @@ -645,7 +651,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(press_event, + dispatcher->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Events should target child and be in the non-client area. @@ -660,7 +666,7 @@ const ui::PointerEvent move_event( ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(17, 18), gfx::Point(17, 18), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, 0)); - dispatcher->ProcessEvent(move_event, + dispatcher->ProcessEvent(move_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Still same target. @@ -673,7 +679,7 @@ const ui::PointerEvent release_event(ui::MouseEvent( ui::ET_MOUSE_RELEASED, gfx::Point(17, 18), gfx::Point(17, 18), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(release_event, + dispatcher->ProcessEvent(release_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // The event should not have been dispatched to the delegate. @@ -687,7 +693,7 @@ const ui::PointerEvent press_event2(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(21, 22), gfx::Point(21, 22), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(press_event2, + dispatcher->ProcessEvent(press_event2, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(event_dispatcher_delegate->has_queued_events()); @@ -718,7 +724,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(28, 11), gfx::Point(28, 11), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(press_event, + event_dispatcher()->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Events should target child and be in the client area. @@ -740,7 +746,7 @@ const ui::PointerEvent move1(ui::MouseEvent( ui::ET_MOUSE_MOVED, gfx::Point(11, 11), gfx::Point(11, 11), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, 0)); - event_dispatcher()->ProcessEvent(move1, + event_dispatcher()->ProcessEvent(move1, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Event went through the child window and hit the root. @@ -755,7 +761,7 @@ const ui::PointerEvent move2(ui::MouseEvent( ui::ET_MOUSE_MOVED, gfx::Point(11, 12), gfx::Point(11, 12), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, 0)); - event_dispatcher()->ProcessEvent(move2, + event_dispatcher()->ProcessEvent(move2, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Mouse exits the root. @@ -786,7 +792,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(press_event, + dispatcher->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); @@ -800,7 +806,7 @@ const ui::PointerEvent touch_event(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(53, 54), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2))); - dispatcher->ProcessEvent(touch_event, + dispatcher->ProcessEvent(touch_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); @@ -824,7 +830,7 @@ const ui::PointerEvent touch_event1(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(touch_event1, + dispatcher->ProcessEvent(touch_event1, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); @@ -834,7 +840,7 @@ const ui::PointerEvent drag_event1(ui::TouchEvent( ui::ET_TOUCH_MOVED, gfx::Point(53, 54), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(drag_event1, + dispatcher->ProcessEvent(drag_event1, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(child1.get(), details->window); @@ -843,7 +849,7 @@ const ui::PointerEvent touch_event2(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2))); - dispatcher->ProcessEvent(touch_event2, + dispatcher->ProcessEvent(touch_event2, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(child2.get(), details->window); @@ -852,13 +858,13 @@ const ui::PointerEvent drag_event2(ui::TouchEvent( ui::ET_TOUCH_MOVED, gfx::Point(13, 14), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2))); - dispatcher->ProcessEvent(drag_event2, + dispatcher->ProcessEvent(drag_event2, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(child2.get(), details->window); // Drag again with id 1, child1 should continue to get it. - dispatcher->ProcessEvent(drag_event1, + dispatcher->ProcessEvent(drag_event1, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(child1.get(), details->window); @@ -867,14 +873,14 @@ const ui::PointerEvent touch_release(ui::TouchEvent( ui::ET_TOUCH_RELEASED, gfx::Point(54, 55), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(touch_release, + dispatcher->ProcessEvent(touch_release, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(child1.get(), details->window); const ui::PointerEvent touch_event3(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2))); - dispatcher->ProcessEvent(touch_event3, + dispatcher->ProcessEvent(touch_event3, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(child2.get(), details->window); @@ -894,7 +900,7 @@ const ui::PointerEvent touch_event1(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(touch_event1, + dispatcher->ProcessEvent(touch_event1, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); @@ -907,7 +913,7 @@ const ui::PointerEvent drag_event1(ui::TouchEvent( ui::ET_TOUCH_MOVED, gfx::Point(53, 54), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(drag_event1, + dispatcher->ProcessEvent(drag_event1, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(nullptr, details.get()); @@ -928,7 +934,7 @@ const ui::PointerEvent ui_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(8, 9), gfx::Point(8, 9), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(ui_event, + dispatcher->ProcessEvent(ui_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); @@ -938,7 +944,7 @@ const ui::PointerEvent release_event(ui::MouseEvent( ui::ET_MOUSE_RELEASED, gfx::Point(8, 9), gfx::Point(8, 9), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(release_event, + dispatcher->ProcessEvent(release_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); @@ -948,7 +954,7 @@ // Change the extended hit test region and send event in extended hit test // region. Should result in exit for root, followed by press for child. child->set_extended_hit_test_region(gfx::Insets(5, 5, 5, 5)); - dispatcher->ProcessEvent(ui_event, + dispatcher->ProcessEvent(ui_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_EQ(root, details->window); @@ -1014,7 +1020,7 @@ const ui::PointerEvent left_press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(left_press_event, + dispatcher->ProcessEvent(left_press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Events should target child. @@ -1031,7 +1037,7 @@ ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(right_press_event, + dispatcher->ProcessEvent(right_press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(IsMouseButtonDown()); @@ -1041,7 +1047,7 @@ ui::ET_MOUSE_RELEASED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(left_release_event, + dispatcher->ProcessEvent(left_release_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(IsMouseButtonDown()); @@ -1050,7 +1056,7 @@ const ui::PointerEvent touch_event(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(15, 15), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2))); - dispatcher->ProcessEvent(touch_event, + dispatcher->ProcessEvent(touch_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(IsMouseButtonDown()); @@ -1060,7 +1066,7 @@ ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(15, 5), gfx::Point(15, 5), base::TimeTicks(), ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(move_event, + dispatcher->ProcessEvent(move_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_TRUE(IsMouseButtonDown()); @@ -1070,7 +1076,7 @@ ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(right_release_event, + dispatcher->ProcessEvent(right_release_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); EXPECT_FALSE(IsMouseButtonDown()); @@ -1082,7 +1088,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(press_event, + dispatcher->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Events should target the root. @@ -1142,7 +1148,7 @@ const ui::PointerEvent touch_event(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(touch_event, + dispatcher->ProcessEvent(touch_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); } @@ -1175,7 +1181,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), gfx::Point(15, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(press_event, + dispatcher->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Events should target the root. @@ -1196,7 +1202,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - dispatcher->ProcessEvent(press_event, + dispatcher->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1208,7 +1214,7 @@ const ui::PointerEvent touch_event(ui::TouchEvent( ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1))); - dispatcher->ProcessEvent(touch_event, + dispatcher->ProcessEvent(touch_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); } @@ -1279,7 +1285,7 @@ const ui::PointerEvent press_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(6, 6), gfx::Point(6, 6), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(press_event, + event_dispatcher()->ProcessEvent(press_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); // Events should target child and be in the client area. @@ -1301,7 +1307,7 @@ ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); event_dispatcher()->ProcessEvent( - pointer_event, EventDispatcher::AcceleratorMatchPhase::ANY); + pointer_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); @@ -1323,7 +1329,7 @@ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, touch_id))); event_dispatcher()->ProcessEvent( - pointer_event, EventDispatcher::AcceleratorMatchPhase::ANY); + pointer_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); @@ -1350,7 +1356,7 @@ const ui::PointerEvent ui_event(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(ui_event, + event_dispatcher()->ProcessEvent(ui_event, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1394,7 +1400,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), gfx::Point(15, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1427,7 +1433,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(55, 15), gfx::Point(55, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1463,7 +1469,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(75, 15), gfx::Point(75, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1500,7 +1506,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(25, 25), gfx::Point(25, 25), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1529,7 +1535,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), gfx::Point(15, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1559,7 +1565,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(45, 15), gfx::Point(45, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = @@ -1609,7 +1615,7 @@ ui::PointerEvent(ui::TouchEvent( ui::ET_TOUCH_PRESSED, kTouchData[i].location, base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0))), - EventDispatcher::AcceleratorMatchPhase::ANY); + 0, EventDispatcher::AcceleratorMatchPhase::ANY); std::unique_ptr<DispatchedEventDetails> details = test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); ASSERT_TRUE(details) << " details is nullptr " << i; @@ -1620,7 +1626,7 @@ ui::PointerEvent(ui::TouchEvent( ui::ET_TOUCH_RELEASED, kTouchData[i].location, base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0))), - EventDispatcher::AcceleratorMatchPhase::ANY); + 0, EventDispatcher::AcceleratorMatchPhase::ANY); test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); } } @@ -1737,7 +1743,7 @@ const ui::PointerEvent mouse_pressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), gfx::Point(15, 15), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); - event_dispatcher()->ProcessEvent(mouse_pressed, + event_dispatcher()->ProcessEvent(mouse_pressed, 0, EventDispatcher::AcceleratorMatchPhase::ANY); event_dispatcher()->SetCaptureWindow(w11.get(), kClientAreaId); @@ -1870,7 +1876,7 @@ root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); c1->SetBounds(gfx::Rect(10, 10, 20, 20)); - event_dispatcher()->SetMousePointerScreenLocation(gfx::Point(15, 15)); + event_dispatcher()->SetMousePointerDisplayLocation(gfx::Point(15, 15), 0); EXPECT_EQ(c1.get(), event_dispatcher()->mouse_cursor_source_window()); c1.reset(); EXPECT_EQ(nullptr, event_dispatcher()->mouse_cursor_source_window());
diff --git a/services/ui/ws/platform_display_default.cc b/services/ui/ws/platform_display_default.cc index d576a8d..b474dcf 100644 --- a/services/ui/ws/platform_display_default.cc +++ b/services/ui/ws/platform_display_default.cc
@@ -178,15 +178,6 @@ return widget_; } -void PlatformDisplayDefault::UpdateEventRootLocation(ui::LocatedEvent* event) { - // TODO(riajiang): This is broken for HDPI because it mixes PPs and DIPs. See - // http://crbug.com/701036 for details. - const display::Display& display = delegate_->GetDisplay(); - gfx::Point location = event->location(); - location.Offset(display.bounds().x(), display.bounds().y()); - event->set_root_location(location); -} - void PlatformDisplayDefault::OnBoundsChanged(const gfx::Rect& new_bounds) { // We only care if the window size has changed. if (new_bounds.size() == metrics_.bounds_in_pixels.size()) @@ -202,9 +193,8 @@ } void PlatformDisplayDefault::DispatchEvent(ui::Event* event) { - if (event->IsLocatedEvent()) - UpdateEventRootLocation(event->AsLocatedEvent()); - + // Event location and event root location are the same, and both in pixels + // and display coordinates. if (event->IsScrollEvent()) { // TODO(moshayedi): crbug.com/602859. Dispatch scroll events as // they are once we have proper support for scroll events. @@ -261,6 +251,7 @@ std::move(compositor_frame_sink_client), mojo::MakeRequest(&display_private)); + display_private->SetDisplayVisible(true); frame_generator_ = base::MakeUnique<FrameGenerator>(); auto frame_sink_client_binding = base::MakeUnique<CompositorFrameSinkClientBinding>(
diff --git a/services/ui/ws/platform_display_default.h b/services/ui/ws/platform_display_default.h index 5ca1ba6..3e28a60f 100644 --- a/services/ui/ws/platform_display_default.h +++ b/services/ui/ws/platform_display_default.h
@@ -19,7 +19,6 @@ class EventSink; class ImageCursors; -class LocatedEvent; class PlatformWindow; namespace ws { @@ -52,13 +51,6 @@ FrameGenerator* GetFrameGenerator() override; private: - // Update the root_location of located events to be relative to the origin - // of this display. For example, if the origin of this display is (1800, 0) - // and the location of the event is (100, 200) then the root_location will be - // updated to be (1900, 200). - // TODO(riajiang): This is totally broken with HDPI. - void UpdateEventRootLocation(ui::LocatedEvent* event); - // ui::PlatformWindowDelegate: void OnBoundsChanged(const gfx::Rect& new_bounds) override; void OnDamageRect(const gfx::Rect& damaged_region) override;
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc index f9735fe..9ee891f 100644 --- a/services/ui/ws/test_utils.cc +++ b/services/ui/ws/test_utils.cc
@@ -7,11 +7,13 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/strings/string_number_conversions.h" #include "cc/output/copy_output_request.h" #include "gpu/ipc/client/gpu_channel_host.h" #include "services/service_manager/public/interfaces/connector.mojom.h" #include "services/ui/public/interfaces/cursor/cursor.mojom.h" #include "services/ui/ws/display_binding.h" +#include "services/ui/ws/display_creation_config.h" #include "services/ui/ws/display_manager.h" #include "services/ui/ws/window_manager_access_policy.h" #include "services/ui/ws/window_manager_window_tree_factory.h" @@ -524,6 +526,17 @@ return true; } +void TestWindowServerDelegate::OnWillCreateTreeForWindowManager( + bool automatically_create_display_roots) { + if (window_server_->display_creation_config() != + DisplayCreationConfig::UNKNOWN) { + return; + } + window_server_->SetDisplayCreationConfig( + automatically_create_display_roots ? DisplayCreationConfig::AUTOMATIC + : DisplayCreationConfig::MANUAL); +} + // WindowServerTestHelper --------------------------------------------------- WindowServerTestHelper::WindowServerTestHelper() @@ -621,6 +634,42 @@ // ---------------------------------------------------------------------------- +TestDisplayManagerObserver::TestDisplayManagerObserver() : binding_(this) {} + +TestDisplayManagerObserver::~TestDisplayManagerObserver() = default; + +mojom::DisplayManagerObserverPtr TestDisplayManagerObserver::GetPtr() { + return binding_.CreateInterfacePtrAndBind(); +} + +std::string TestDisplayManagerObserver::GetAndClearObserverCalls() { + std::string result; + std::swap(observer_calls_, result); + return result; +} + +std::string TestDisplayManagerObserver::DisplayIdsToString( + const std::vector<mojom::WsDisplayPtr>& wm_displays) { + std::string display_ids; + for (const auto& wm_display : wm_displays) { + if (!display_ids.empty()) + display_ids += " "; + display_ids += base::Int64ToString(wm_display->display.id()); + } + return display_ids; +} + +void TestDisplayManagerObserver::OnDisplaysChanged( + std::vector<mojom::WsDisplayPtr> displays, + int64_t primary_display_id, + int64_t internal_display_id) { + if (!observer_calls_.empty()) + observer_calls_ += "\n"; + observer_calls_ += "OnDisplaysChanged " + DisplayIdsToString(displays); +} + +// ----------------------------------------------------------------------------- + void AddWindowManager(WindowServer* window_server, const UserId& user_id, bool automatically_create_display_roots) {
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h index b5a9886..5cadb9d 100644 --- a/services/ui/ws/test_utils.h +++ b/services/ui/ws/test_utils.h
@@ -207,9 +207,11 @@ void DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const ui::Event& event, Accelerator* accelerator) { - wms_->DispatchInputEventToWindow(target, client_id, event, accelerator); + wms_->DispatchInputEventToWindow(target, client_id, display_id, event, + accelerator); } ClientSpecificId GetEventTargetClientId(ServerWindow* window, @@ -597,6 +599,8 @@ mojom::WindowTreeRequest* tree_request, mojom::WindowTreeClientPtr* client) override; bool IsTestConfig() const override; + void OnWillCreateTreeForWindowManager( + bool automatically_create_display_roots) override; private: WindowServer* window_server_ = nullptr; @@ -690,6 +694,32 @@ // ----------------------------------------------------------------------------- +class TestDisplayManagerObserver : public mojom::DisplayManagerObserver { + public: + TestDisplayManagerObserver(); + ~TestDisplayManagerObserver() override; + + mojom::DisplayManagerObserverPtr GetPtr(); + + std::string GetAndClearObserverCalls(); + + private: + std::string DisplayIdsToString( + const std::vector<mojom::WsDisplayPtr>& wm_displays); + + // mojom::DisplayManagerObserver: + void OnDisplaysChanged(std::vector<mojom::WsDisplayPtr> displays, + int64_t primary_display_id, + int64_t internal_display_id) override; + + mojo::Binding<mojom::DisplayManagerObserver> binding_; + std::string observer_calls_; + + DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerObserver); +}; + +// ----------------------------------------------------------------------------- + // Adds a new WM to |window_server| for |user_id|. Creates // WindowManagerWindowTreeFactory and associated WindowTree for the WM. void AddWindowManager(WindowServer* window_server,
diff --git a/services/ui/ws/user_display_manager.cc b/services/ui/ws/user_display_manager.cc index b32c531..f52663f 100644 --- a/services/ui/ws/user_display_manager.cc +++ b/services/ui/ws/user_display_manager.cc
@@ -33,6 +33,18 @@ UserDisplayManager::~UserDisplayManager() {} +void UserDisplayManager::DisableAutomaticNotification() { + DCHECK(notify_automatically_); + notify_automatically_ = false; +} + +void UserDisplayManager::CallOnDisplaysChanged() { + display_manager_observers_.ForAllPtrs( + [this](mojom::DisplayManagerObserver* observer) { + CallOnDisplaysChanged(observer); + }); +} + void UserDisplayManager::OnFrameDecorationValuesChanged() { got_valid_frame_decorations_ = true; CallOnDisplaysChangedIfNecessary(); @@ -100,13 +112,10 @@ } void UserDisplayManager::CallOnDisplaysChangedIfNecessary() { - if (!ShouldCallOnDisplaysChanged()) + if (!notify_automatically_ || !ShouldCallOnDisplaysChanged()) return; - display_manager_observers_.ForAllPtrs( - [this](mojom::DisplayManagerObserver* observer) { - CallOnDisplaysChanged(observer); - }); + CallOnDisplaysChanged(); } void UserDisplayManager::CallOnDisplaysChanged(
diff --git a/services/ui/ws/user_display_manager.h b/services/ui/ws/user_display_manager.h index 755bb70..8b889cda 100644 --- a/services/ui/ws/user_display_manager.h +++ b/services/ui/ws/user_display_manager.h
@@ -29,6 +29,11 @@ const UserId& user_id); ~UserDisplayManager() override; + void DisableAutomaticNotification(); + + // Unconditionally calls OnDisplayChanged() on observers. + void CallOnDisplaysChanged(); + // Called when the frame decorations for this user change. void OnFrameDecorationValuesChanged(); @@ -78,6 +83,12 @@ mojo::InterfacePtrSet<mojom::DisplayManagerObserver> display_manager_observers_; + // If true DisplayManagerObservers are notified any time there is a display + // change. If false, observers are only notified when CallOnDisplaysChanged() + // is explicitly called. This value is true in automatic display creation and + // false when in manual mode. + bool notify_automatically_ = true; + DISALLOW_COPY_AND_ASSIGN(UserDisplayManager); };
diff --git a/services/ui/ws/user_display_manager_unittest.cc b/services/ui/ws/user_display_manager_unittest.cc index f2b3417..f6bbcf7c 100644 --- a/services/ui/ws/user_display_manager_unittest.cc +++ b/services/ui/ws/user_display_manager_unittest.cc
@@ -36,52 +36,6 @@ const char kUserId1[] = "123"; -class TestDisplayManagerObserver : public mojom::DisplayManagerObserver { - public: - TestDisplayManagerObserver() : binding_(this) {} - ~TestDisplayManagerObserver() override {} - - mojom::DisplayManagerObserverPtr GetPtr() { - return binding_.CreateInterfacePtrAndBind(); - } - - std::string GetAndClearObserverCalls() { - std::string result; - std::swap(observer_calls_, result); - return result; - } - - private: - void AddCall(const std::string& call) { - if (!observer_calls_.empty()) - observer_calls_ += "\n"; - observer_calls_ += call; - } - - std::string DisplayIdsToString( - const std::vector<mojom::WsDisplayPtr>& wm_displays) { - std::string display_ids; - for (const auto& wm_display : wm_displays) { - if (!display_ids.empty()) - display_ids += " "; - display_ids += base::Int64ToString(wm_display->display.id()); - } - return display_ids; - } - - // mojom::DisplayManagerObserver: - void OnDisplaysChanged(std::vector<mojom::WsDisplayPtr> displays, - int64_t primary_display_id, - int64_t internal_display_id) override { - AddCall("OnDisplaysChanged " + DisplayIdsToString(displays)); - } - - mojo::Binding<mojom::DisplayManagerObserver> binding_; - std::string observer_calls_; - - DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerObserver); -}; - mojom::FrameDecorationValuesPtr CreateDefaultFrameDecorationValues() { return mojom::FrameDecorationValues::New(); }
diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc index 6657f15..a36a9b1 100644 --- a/services/ui/ws/window_manager_state.cc +++ b/services/ui/ws/window_manager_state.cc
@@ -13,6 +13,7 @@ #include "services/ui/ws/accelerator.h" #include "services/ui/ws/cursor_location_manager.h" #include "services/ui/ws/display.h" +#include "services/ui/ws/display_creation_config.h" #include "services/ui/ws/display_manager.h" #include "services/ui/ws/platform_display.h" #include "services/ui/ws/server_window.h" @@ -22,6 +23,7 @@ #include "services/ui/ws/window_server.h" #include "services/ui/ws/window_tree.h" #include "ui/events/event.h" +#include "ui/gfx/geometry/dip_util.h" namespace ui { namespace ws { @@ -154,9 +156,14 @@ mojom::FrameDecorationValuesPtr values) { got_frame_decoration_values_ = true; frame_decoration_values_ = values.Clone(); - display_manager() - ->GetUserDisplayManager(user_id()) - ->OnFrameDecorationValuesChanged(); + UserDisplayManager* user_display_manager = + display_manager()->GetUserDisplayManager(user_id()); + user_display_manager->OnFrameDecorationValuesChanged(); + if (window_server()->display_creation_config() == + DisplayCreationConfig::MANUAL && + display_manager()->got_initial_config_from_window_manager()) { + user_display_manager->CallOnDisplaysChanged(); + } } bool WindowManagerState::SetCapture(ServerWindow* window, @@ -273,10 +280,12 @@ return window_server()->user_id_tracker()->active_id() == user_id(); } -void WindowManagerState::Activate(const gfx::Point& mouse_location_on_screen) { +void WindowManagerState::Activate(const gfx::Point& mouse_location_on_display, + const int64_t display_id) { SetAllRootWindowsVisible(true); event_dispatcher_.Reset(); - event_dispatcher_.SetMousePointerScreenLocation(mouse_location_on_screen); + event_dispatcher_.SetMousePointerDisplayLocation(mouse_location_on_display, + display_id); } void WindowManagerState::Deactivate() { @@ -321,9 +330,9 @@ DCHECK(details->event->IsKeyEvent()); if (!properties.empty()) details->event->AsKeyEvent()->SetProperties(properties); - event_processing_display_id_ = details->display_id; event_dispatcher_.ProcessEvent( - *details->event, EventDispatcher::AcceleratorMatchPhase::POST_ONLY); + *details->event, details->display_id, + EventDispatcher::AcceleratorMatchPhase::POST_ONLY); } else { // We're not going to process the event any further, notify event observers. // We don't do this first to ensure we don't send an event twice to clients. @@ -395,8 +404,8 @@ if (result == mojom::EventResult::UNHANDLED && details->post_target_accelerator) { - OnAccelerator(details->post_target_accelerator->id(), *details->event, - AcceleratorPhase::POST); + OnAccelerator(details->post_target_accelerator->id(), details->display_id, + *details->event, AcceleratorPhase::POST); } ProcessNextEventFromQueue(); @@ -417,9 +426,8 @@ void WindowManagerState::ProcessEventImpl(const ui::Event& event, int64_t display_id) { // Debug accelerators are always checked and don't interfere with processing. - ProcessDebugAccelerator(event); - event_processing_display_id_ = display_id; - event_dispatcher_.ProcessEvent(event, + ProcessDebugAccelerator(event, display_id); + event_dispatcher_.ProcessEvent(event, display_id, EventDispatcher::AcceleratorMatchPhase::ANY); } @@ -447,8 +455,8 @@ if (queued_event->processed_target->IsValid()) { DispatchInputEventToWindowImpl( queued_event->processed_target->window(), - queued_event->processed_target->client_id(), *queued_event->event, - queued_event->processed_target->accelerator()); + queued_event->processed_target->client_id(), queued_event->display_id, + *queued_event->event, queued_event->processed_target->accelerator()); return; } } @@ -457,6 +465,7 @@ void WindowManagerState::DispatchInputEventToWindowImpl( ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const ui::Event& event, base::WeakPtr<Accelerator> accelerator) { DCHECK(target); @@ -470,7 +479,8 @@ WindowTree* tree = window_server()->GetTreeWithId(client_id); DCHECK(tree); - ScheduleInputEventTimeout(tree, target, event, EventDispatchPhase::TARGET); + ScheduleInputEventTimeout(tree, target, display_id, event, + EventDispatchPhase::TARGET); in_flight_event_details_->post_target_accelerator = accelerator; // Ignore |tree| because it will receive the event via normal dispatch. @@ -491,20 +501,22 @@ debug_accelerators_.push_back(accelerator); } -void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event) { +void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event, + const int64_t display_id) { if (event.type() != ui::ET_KEY_PRESSED) return; const ui::KeyEvent& key_event = *event.AsKeyEvent(); for (const DebugAccelerator& accelerator : debug_accelerators_) { if (accelerator.Matches(key_event)) { - HandleDebugAccelerator(accelerator.type); + HandleDebugAccelerator(accelerator.type, display_id); break; } } } -void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type) { +void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type, + const int64_t display_id) { #if DCHECK_IS_ON() // Error so it will be collected in system logs. for (Display* display : display_manager()->displays()) { @@ -515,7 +527,7 @@ << display_root->root()->GetDebugWindowHierarchy(); } } - ServerWindow* focused_window = GetFocusedWindowForEventDispatcher(); + ServerWindow* focused_window = GetFocusedWindowForEventDispatcher(display_id); LOG(ERROR) << "Focused window: " << (focused_window ? focused_window->id().ToString() : "(null)"); #endif @@ -523,11 +535,12 @@ void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree, ServerWindow* target, + const int64_t display_id, const Event& event, EventDispatchPhase phase) { std::unique_ptr<InFlightEventDetails> details = - base::MakeUnique<InFlightEventDetails>( - this, tree, event_processing_display_id_, event, phase); + base::MakeUnique<InFlightEventDetails>(this, tree, display_id, event, + phase); // TOOD(sad): Adjust this delay, possibly make this dynamic. const base::TimeDelta max_delay = base::debug::BeingDebugged() @@ -540,10 +553,24 @@ in_flight_event_details_ = std::move(details); } +bool WindowManagerState::ConvertPointToScreen(const int64_t display_id, + gfx::Point* point) { + Display* display = display_manager()->GetDisplayById(display_id); + if (display) { + const display::Display& originated_display = display->GetDisplay(); + *point = gfx::ConvertPointToDIP(originated_display.device_scale_factor(), + *point); + *point += originated_display.bounds().origin().OffsetFromOrigin(); + return true; + } + return false; +} + //////////////////////////////////////////////////////////////////////////////// // EventDispatcherDelegate: void WindowManagerState::OnAccelerator(uint32_t accelerator_id, + const int64_t display_id, const ui::Event& event, AcceleratorPhase phase) { DCHECK(IsActive()); @@ -551,7 +578,7 @@ WindowTree::AcceleratorCallback ack_callback; if (needs_ack) { DCHECK(!in_flight_event_details_); - ScheduleInputEventTimeout(window_tree_, nullptr, event, + ScheduleInputEventTimeout(window_tree_, nullptr, display_id, event, EventDispatchPhase::PRE_TARGET_ACCELERATOR); ack_callback = base::BindOnce(&WindowManagerState::OnAcceleratorAck, @@ -566,14 +593,15 @@ window_server()->SetFocusedWindow(new_focused_window); } -ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher() { +ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher( + const int64_t display_id) { ServerWindow* focused_window = window_server()->GetFocusedWindow(); if (focused_window) return focused_window; // When none of the windows have focus return the window manager's root. for (auto& display_root_ptr : window_manager_display_roots_) { - if (display_root_ptr->display()->GetId() == event_processing_display_id_) + if (display_root_ptr->display()->GetId() == display_id) return display_root_ptr->GetClientVisibleRoot(); } if (!window_manager_display_roots_.empty()) @@ -611,15 +639,23 @@ window_server()->ProcessCaptureChanged(new_capture, old_capture); } -void WindowManagerState::OnMouseCursorLocationChanged(const gfx::Point& point) { - window_server() - ->display_manager() - ->GetCursorLocationManager(user_id()) - ->OnMouseCursorLocationChanged(point); +void WindowManagerState::OnMouseCursorLocationChanged( + const gfx::Point& point_in_display, + const int64_t display_id) { + gfx::Point point_in_screen(point_in_display); + if (ConvertPointToScreen(display_id, &point_in_screen)) { + window_server() + ->display_manager() + ->GetCursorLocationManager(user_id()) + ->OnMouseCursorLocationChanged(point_in_screen); + } + // If the display the |point_in_display| is on has been deleted, keep the old + // cursor location. } void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const ui::Event& event, Accelerator* accelerator) { DCHECK(IsActive()); @@ -628,15 +664,15 @@ if (in_flight_event_details_) { std::unique_ptr<ProcessedEventTarget> processed_event_target( new ProcessedEventTarget(target, client_id, accelerator)); - QueueEvent(event, std::move(processed_event_target), - event_processing_display_id_); + QueueEvent(event, std::move(processed_event_target), display_id); return; } base::WeakPtr<Accelerator> weak_accelerator; if (accelerator) weak_accelerator = accelerator->GetWeakPtr(); - DispatchInputEventToWindowImpl(target, client_id, event, weak_accelerator); + DispatchInputEventToWindowImpl(target, client_id, display_id, event, + weak_accelerator); } ClientSpecificId WindowManagerState::GetEventTargetClientId( @@ -668,16 +704,19 @@ } ServerWindow* WindowManagerState::GetRootWindowContaining( - gfx::Point* location) { + gfx::Point* location_in_display, + int64_t* display_id) { if (window_manager_display_roots_.empty()) return nullptr; - // TODO(riajiang): This is broken for HDPI because it mixes PPs and DIPs. See - // http://crbug.com/701036 for details. + gfx::Point location_in_screen(*location_in_display); + if (!ConvertPointToScreen(*display_id, &location_in_screen)) + return nullptr; + WindowManagerDisplayRoot* target_display_root = nullptr; for (auto& display_root_ptr : window_manager_display_roots_) { if (display_root_ptr->display()->GetDisplay().bounds().Contains( - *location)) { + location_in_screen)) { target_display_root = display_root_ptr.get(); break; } @@ -686,22 +725,30 @@ // TODO(kylechar): Better handle locations outside the window. Overlapping X11 // windows, dragging and touch sensors need to be handled properly. if (!target_display_root) { - DVLOG(1) << "Invalid event location " << location->ToString(); + DVLOG(1) << "Invalid event location " << location_in_display->ToString() + << " / display id " << *display_id; target_display_root = window_manager_display_roots_.begin()->get(); } - // Translate the location to be relative to the display instead of relative - // to the screen space. - gfx::Point origin = - target_display_root->display()->GetDisplay().bounds().origin(); - *location -= origin.OffsetFromOrigin(); + // Update |location_in_display| and |display_id| if the target display is + // different from the originated display, e.g. drag-and-drop. + if (*display_id != target_display_root->display()->GetId()) { + gfx::Point origin = + target_display_root->display()->GetDisplay().bounds().origin(); + *location_in_display = location_in_screen - origin.OffsetFromOrigin(); + *location_in_display = gfx::ConvertPointToPixel( + target_display_root->display()->GetDisplay().device_scale_factor(), + *location_in_display); + *display_id = target_display_root->display()->GetId(); + } + return target_display_root->GetClientVisibleRoot(); } -void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) { +void WindowManagerState::OnEventTargetNotFound(const ui::Event& event, + const int64_t display_id) { window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */ - nullptr /* ignore_tree */, - event_processing_display_id_); + nullptr /* ignore_tree */, display_id); if (event.IsMousePointerEvent()) UpdateNativeCursorFromDispatcher(); }
diff --git a/services/ui/ws/window_manager_state.h b/services/ui/ws/window_manager_state.h index ce897244..68e808b 100644 --- a/services/ui/ws/window_manager_state.h +++ b/services/ui/ws/window_manager_state.h
@@ -96,7 +96,8 @@ // Returns true if this is the WindowManager of the active user. bool IsActive() const; - void Activate(const gfx::Point& mouse_location_on_screen); + void Activate(const gfx::Point& mouse_location_on_display, + const int64_t display_id); void Deactivate(); // Processes an event from PlatformDisplay. @@ -221,6 +222,7 @@ // Dispatches the event to the appropriate client and starts the ack timer. void DispatchInputEventToWindowImpl(ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const Event& event, base::WeakPtr<Accelerator> accelerator); @@ -229,37 +231,51 @@ // Finds the debug accelerator for |event| and if one is found calls // HandleDebugAccelerator(). - void ProcessDebugAccelerator(const Event& event); + void ProcessDebugAccelerator(const Event& event, const int64_t display_id); // Runs the specified debug accelerator. - void HandleDebugAccelerator(DebugAcceleratorType type); + void HandleDebugAccelerator(DebugAcceleratorType type, + const int64_t display_id); // Called when waiting for an event or accelerator to be processed by |tree|. void ScheduleInputEventTimeout(WindowTree* tree, ServerWindow* target, + const int64_t display_id, const Event& event, EventDispatchPhase phase); + // Helper function to convert |point| to be in screen coordinates. |point| as + // the input should be in display-physical-pixel space, and the output is in + // screen-dip space. Returns true if the |point| is successfully converted, + // false otherwise. + bool ConvertPointToScreen(const int64_t display_id, gfx::Point* point); + // EventDispatcherDelegate: void OnAccelerator(uint32_t accelerator_id, + const int64_t display_id, const Event& event, AcceleratorPhase phase) override; void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override; - ServerWindow* GetFocusedWindowForEventDispatcher() override; + ServerWindow* GetFocusedWindowForEventDispatcher( + const int64_t display_id) override; void SetNativeCapture(ServerWindow* window) override; void ReleaseNativeCapture() override; void UpdateNativeCursorFromDispatcher() override; void OnCaptureChanged(ServerWindow* new_capture, ServerWindow* old_capture) override; - void OnMouseCursorLocationChanged(const gfx::Point& point) override; + void OnMouseCursorLocationChanged(const gfx::Point& point, + const int64_t display_id) override; void DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, + const int64_t display_id, const Event& event, Accelerator* accelerator) override; ClientSpecificId GetEventTargetClientId(const ServerWindow* window, bool in_nonclient_area) override; - ServerWindow* GetRootWindowContaining(gfx::Point* location) override; - void OnEventTargetNotFound(const Event& event) override; + ServerWindow* GetRootWindowContaining(gfx::Point* location_in_display, + int64_t* display_id) override; + void OnEventTargetNotFound(const Event& event, + const int64_t display_id) override; // ServerWindowObserver: void OnWindowEmbeddedAppDisconnected(ServerWindow* window) override; @@ -288,9 +304,6 @@ // All the active WindowManagerDisplayRoots. WindowManagerDisplayRoots window_manager_display_roots_; - // Id of the display the current event being processed originated from. - int64_t event_processing_display_id_ = 0; - // Set of WindowManagerDisplayRoots corresponding to Displays that have been // destroyed. WindowManagerDisplayRoots are not destroyed immediately when // the Display is destroyed to allow the client to destroy the window when it
diff --git a/services/ui/ws/window_manager_state_unittest.cc b/services/ui/ws/window_manager_state_unittest.cc index 9b1bfe32..d1dc651 100644 --- a/services/ui/ws/window_manager_state_unittest.cc +++ b/services/ui/ws/window_manager_state_unittest.cc
@@ -47,6 +47,7 @@ ServerWindow** server_window); void DispatchInputEventToWindow(ServerWindow* target, + const int64_t display_id, const ui::Event& event, Accelerator* accelerator); void OnEventAckTimeout(ClientSpecificId client_id); @@ -138,11 +139,13 @@ void WindowManagerStateTest::DispatchInputEventToWindow( ServerWindow* target, + const int64_t display_id, const ui::Event& event, Accelerator* accelerator) { WindowManagerStateTestApi test_api(window_manager_state_); ClientSpecificId client_id = test_api.GetEventTargetClientId(target, false); - test_api.DispatchInputEventToWindow(target, client_id, event, accelerator); + test_api.DispatchInputEventToWindow(target, client_id, display_id, event, + accelerator); } void WindowManagerStateTest::OnEventAckTimeout( @@ -182,8 +185,10 @@ EXPECT_TRUE(state); ServerWindow* target = window(); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); - DispatchInputEventToWindow(target, key, nullptr); + DispatchInputEventToWindow(target, display->GetId(), key, nullptr); WindowTree* target_tree = window_tree(); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); @@ -201,7 +206,9 @@ std::unique_ptr<Accelerator> accelerator = CreateAccelerator(); ServerWindow* target = window(); - DispatchInputEventToWindow(target, key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), key, accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -350,7 +357,9 @@ std::unique_ptr<Accelerator> accelerator = CreateAccelerator(); ServerWindow* target = window(); - DispatchInputEventToWindow(target, key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), key, accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -368,7 +377,9 @@ std::unique_ptr<Accelerator> accelerator(CreateAccelerator()); ServerWindow* target = window(); - DispatchInputEventToWindow(target, key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), key, accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -387,7 +398,9 @@ std::unique_ptr<Accelerator> accelerator(CreateAccelerator()); ServerWindow* target = window(); - DispatchInputEventToWindow(target, key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), key, accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -401,7 +414,8 @@ uint32_t accelerator_id = 2; std::unique_ptr<Accelerator> accelerator2( new Accelerator(accelerator_id, *matcher)); - DispatchInputEventToWindow(target, key2, accelerator2.get()); + DispatchInputEventToWindow(target, display->GetId(), key2, + accelerator2.get()); EXPECT_TRUE(tracker->changes()->empty()); WindowTreeTestApi(window_tree()).AckOldestEvent(); @@ -418,7 +432,9 @@ std::unique_ptr<Accelerator> accelerator = CreateAccelerator(); ServerWindow* target = window(); - DispatchInputEventToWindow(target, key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), key, accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -441,7 +457,9 @@ ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); std::unique_ptr<Accelerator> accelerator = CreateAccelerator(); - DispatchInputEventToWindow(target, key, accelerator.get()); + const Display* display = target_tree->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), key, accelerator.get()); TestChangeTracker* tracker = embed_connection->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=2,1 event_action=7", @@ -459,10 +477,12 @@ ServerWindow* target = window(); TestChangeTracker* tracker = window_tree_client()->tracker(); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), EF_LEFT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON); - DispatchInputEventToWindow(target, press, nullptr); + DispatchInputEventToWindow(target, display->GetId(), press, nullptr); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=1", ChangesToDescription1(*tracker->changes())[0]); @@ -474,7 +494,7 @@ ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(5, 5), gfx::Point(5, 5), base::TimeTicks(), EF_LEFT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON); - DispatchInputEventToWindow(target, release, nullptr); + DispatchInputEventToWindow(target, display->GetId(), release, nullptr); EXPECT_EQ(0u, tracker->changes()->size()); // Destroying a window tree with an event in queue shouldn't crash. @@ -485,7 +505,10 @@ TEST_F(WindowManagerStateTest, AckTimeout) { ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); std::unique_ptr<Accelerator> accelerator = CreateAccelerator(); - DispatchInputEventToWindow(window(), key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(window()); + DCHECK(display); + DispatchInputEventToWindow(window(), display->GetId(), key, + accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -520,9 +543,12 @@ ASSERT_TRUE(embed_client_proxy); // Send an event to the embed window. It should go to the embedded client. + const Display* display = embed_tree->GetDisplay(embedder_window); + DCHECK(display); ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), base::TimeTicks(), 0, 0); - DispatchInputEventToWindow(embedder_window, mouse, nullptr); + DispatchInputEventToWindow(embedder_window, display->GetId(), mouse, + nullptr); ASSERT_EQ(1u, embed_client_proxy->tracker()->changes()->size()); EXPECT_EQ(CHANGE_TYPE_INPUT_EVENT, (*embed_client_proxy->tracker()->changes())[0].type); @@ -543,9 +569,12 @@ // Send an event to the embed window. But this time, it should reach the // embedder. + const Display* display = embed_tree->GetDisplay(embedder_window); + DCHECK(display); ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), base::TimeTicks(), 0, 0); - DispatchInputEventToWindow(embedder_window, mouse, nullptr); + DispatchInputEventToWindow(embedder_window, display->GetId(), mouse, + nullptr); ASSERT_EQ(0u, embed_client_proxy->tracker()->changes()->size()); ASSERT_EQ(1u, embedder_client->tracker()->changes()->size()); EXPECT_EQ(CHANGE_TYPE_INPUT_EVENT, @@ -577,7 +606,8 @@ DCHECK(nested_embed_window->parent()); mouse = ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), base::TimeTicks(), 0, 0); - DispatchInputEventToWindow(nested_embed_window, mouse, nullptr); + DispatchInputEventToWindow(nested_embed_window, display->GetId(), mouse, + nullptr); ASSERT_EQ(0u, nested_embed_client_proxy->tracker()->changes()->size()); ASSERT_EQ(0u, embed_client_proxy->tracker()->changes()->size()); @@ -597,7 +627,10 @@ ui::EF_CONTROL_DOWN); std::unique_ptr<Accelerator> accelerator = CreateAccelerator(); ServerWindow* target = window(); - DispatchInputEventToWindow(target, accelerator_key, accelerator.get()); + const Display* display = window_tree()->GetDisplay(target); + DCHECK(display); + DispatchInputEventToWindow(target, display->GetId(), accelerator_key, + accelerator.get()); TestChangeTracker* tracker = window_tree_client()->tracker(); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", @@ -610,7 +643,8 @@ // shouldn't be called. ui::KeyEvent non_accelerator_key(ui::ET_KEY_PRESSED, ui::VKEY_T, ui::EF_CONTROL_DOWN); - DispatchInputEventToWindow(target, non_accelerator_key, nullptr); + DispatchInputEventToWindow(target, display->GetId(), non_accelerator_key, + nullptr); ASSERT_EQ(1u, tracker->changes()->size()); EXPECT_EQ("InputEvent window=1,1 event_action=7", ChangesToDescription1(*tracker->changes())[0]);
diff --git a/services/ui/ws/window_manager_window_tree_factory.cc b/services/ui/ws/window_manager_window_tree_factory.cc index 89711f2..ab38d7b2 100644 --- a/services/ui/ws/window_manager_window_tree_factory.cc +++ b/services/ui/ws/window_manager_window_tree_factory.cc
@@ -5,6 +5,7 @@ #include "services/ui/ws/window_manager_window_tree_factory.h" #include "base/bind.h" +#include "services/ui/ws/display_creation_config.h" #include "services/ui/ws/window_manager_window_tree_factory_set.h" #include "services/ui/ws/window_server.h" #include "services/ui/ws/window_server_delegate.h" @@ -39,9 +40,13 @@ if (binding_.is_bound()) binding_.Close(); - window_manager_window_tree_factory_set_->window_server() - ->delegate() - ->OnWillCreateTreeForWindowManager(automatically_create_display_roots); + // If the config is MANUAL, then all WindowManagers must connect as MANUAL. + if (!automatically_create_display_roots && + GetWindowServer()->display_creation_config() == + DisplayCreationConfig::AUTOMATIC) { + DVLOG(1) << "CreateWindowTree() called with manual and automatic."; + return; + } SetWindowTree(GetWindowServer()->CreateTreeForWindowManager( user_id_, std::move(window_tree_request), std::move(window_tree_client),
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index 67b31254..812240d 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -11,6 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "services/ui/ws/display.h" +#include "services/ui/ws/display_creation_config.h" #include "services/ui/ws/display_manager.h" #include "services/ui/ws/frame_generator.h" #include "services/ui/ws/gpu_host.h" @@ -69,7 +70,8 @@ next_wm_change_id_(0), gpu_host_(new GpuHost(this)), window_manager_window_tree_factory_set_(this, &user_id_tracker_), - frame_sink_manager_client_binding_(this) { + frame_sink_manager_client_binding_(this), + display_creation_config_(DisplayCreationConfig::UNKNOWN) { user_id_tracker_.AddObserver(this); OnUserIdAdded(user_id_tracker_.active_id()); gpu_host_->CreateFrameSinkManager( @@ -94,6 +96,13 @@ display_manager_.reset(); } +void WindowServer::SetDisplayCreationConfig(DisplayCreationConfig config) { + DCHECK(tree_map_.empty()); + DCHECK_EQ(DisplayCreationConfig::UNKNOWN, display_creation_config_); + display_creation_config_ = config; + display_manager_->OnDisplayCreationConfigSet(); +} + ServerWindow* WindowServer::CreateServerWindow( const WindowId& id, const std::map<std::string, std::vector<uint8_t>>& properties) { @@ -150,6 +159,9 @@ mojom::WindowTreeRequest window_tree_request, mojom::WindowTreeClientPtr window_tree_client, bool automatically_create_display_roots) { + delegate_->OnWillCreateTreeForWindowManager( + automatically_create_display_roots); + std::unique_ptr<WindowTree> window_tree(new WindowTree( this, user_id, nullptr, base::WrapUnique(new WindowManagerAccessPolicy))); std::unique_ptr<WindowTreeBinding> window_tree_binding =
diff --git a/services/ui/ws/window_server.h b/services/ui/ws/window_server.h index f79cf963..f072f77 100644 --- a/services/ui/ws/window_server.h +++ b/services/ui/ws/window_server.h
@@ -42,6 +42,8 @@ class WindowTree; class WindowTreeBinding; +enum class DisplayCreationConfig; + // WindowServer manages the set of clients of the window server (all the // WindowTrees) as well as providing the root of the hierarchy. class WindowServer : public ServerWindowDelegate, @@ -66,6 +68,11 @@ GpuHost* gpu_host() { return gpu_host_.get(); } + void SetDisplayCreationConfig(DisplayCreationConfig config); + DisplayCreationConfig display_creation_config() const { + return display_creation_config_; + } + // Creates a new ServerWindow. The return value is owned by the caller, but // must be destroyed before WindowServer. ServerWindow* CreateServerWindow( @@ -388,6 +395,8 @@ frame_sink_manager_client_binding_; cc::mojom::FrameSinkManagerPtr frame_sink_manager_; + DisplayCreationConfig display_creation_config_; + DISALLOW_COPY_AND_ASSIGN(WindowServer); };
diff --git a/services/ui/ws/window_server_delegate.cc b/services/ui/ws/window_server_delegate.cc index 1250bade..6d1194b 100644 --- a/services/ui/ws/window_server_delegate.cc +++ b/services/ui/ws/window_server_delegate.cc
@@ -21,8 +21,5 @@ return nullptr; } -void WindowServerDelegate::OnWillCreateTreeForWindowManager( - bool automatically_create_display_roots) {} - } // namespace ws } // namespace ui
diff --git a/services/ui/ws/window_server_delegate.h b/services/ui/ws/window_server_delegate.h index 5256e11..6588bec 100644 --- a/services/ui/ws/window_server_delegate.h +++ b/services/ui/ws/window_server_delegate.h
@@ -57,7 +57,7 @@ // WindowManagerWindowTreeFactory. |automatically_create_display_roots| // mirrors that of CreateWindowTree(). See it for details. virtual void OnWillCreateTreeForWindowManager( - bool automatically_create_display_roots); + bool automatically_create_display_roots) = 0; protected: virtual ~WindowServerDelegate() {}
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc index c758775..6e8ca14 100644 --- a/services/ui/ws/window_tree.cc +++ b/services/ui/ws/window_tree.cc
@@ -283,8 +283,7 @@ DCHECK(window_manager_state_); // Only called for window manager. DVLOG(3) << "SetDisplayRoot client=" << id_ << " global window_id=" << client_window_id.id; - Display* display = - window_server_->display_manager()->GetDisplayById(display_to_create.id()); + Display* display = display_manager()->GetDisplayById(display_to_create.id()); if (display) { DVLOG(1) << "SetDisplayRoot called with existing display " << display_to_create.id(); @@ -310,23 +309,14 @@ return nullptr; } - const display::DisplayList::Type display_type = - is_primary_display ? display::DisplayList::Type::PRIMARY - : display::DisplayList::Type::NOT_PRIMARY; - display::ScreenManager::GetInstance()->GetScreen()->display_list().AddDisplay( - display_to_create, display_type); display::ViewportMetrics viewport_metrics; viewport_metrics.bounds_in_pixels = transport_viewport_metrics.bounds_in_pixels; viewport_metrics.device_scale_factor = transport_viewport_metrics.device_scale_factor; viewport_metrics.ui_scale_factor = transport_viewport_metrics.ui_scale_factor; - window_server_->display_manager()->AddDisplayForWindowManager( - display_to_create, viewport_metrics); - - // OnDisplayAdded() should trigger creation of the Display. - display = - window_server_->display_manager()->GetDisplayById(display_to_create.id()); + display = display_manager()->AddDisplayForWindowManager( + is_primary_display, display_to_create, viewport_metrics); DCHECK(display); WindowManagerDisplayRoot* display_root = display->GetWindowManagerDisplayRootForUser( @@ -1155,7 +1145,7 @@ roots_.erase(window); if (window->id().client_id == id_) { - // This cllient created the window. If this client is the window manager and + // This client created the window. If this client is the window manager and // display roots are manually created, then |window| is a display root and // needs be cleaned. if (window_manager_state_ && !automatically_create_display_roots_) { @@ -1980,7 +1970,7 @@ void WindowTree::GetCursorLocationMemory( const GetCursorLocationMemoryCallback& callback) { - callback.Run(window_server_->display_manager() + callback.Run(display_manager() ->GetCursorLocationManager(user_id_) ->GetCursorLocationMemory()); } @@ -2202,7 +2192,7 @@ return; } // Use the first display. - std::set<Display*> displays = window_server_->display_manager()->displays(); + std::set<Display*> displays = display_manager()->displays(); if (displays.empty()) return; @@ -2240,6 +2230,15 @@ callback.Run(display_root->current_local_surface_id()); } +void WindowTree::SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id, + const SetDisplayConfigurationCallback& callback) { + callback.Run(display_manager()->SetDisplayConfiguration( + displays, std::move(viewport_metrics), primary_display_id)); +} + void WindowTree::WmResponse(uint32_t change_id, bool response) { if (window_server_->in_move_loop() && window_server_->GetCurrentMoveLoopChangeId() == change_id) {
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h index e95912c..45fef34 100644 --- a/services/ui/ws/window_tree.h +++ b/services/ui/ws/window_tree.h
@@ -516,6 +516,11 @@ bool is_primary_display, Id window_id, const SetDisplayRootCallback& callback) override; + void SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id, + const SetDisplayConfigurationCallback& callback) override; void WmResponse(uint32_t change_id, bool response) override; void WmSetBoundsResponse(uint32_t change_id) override; void WmRequestClose(Id transport_window_id) override;
diff --git a/services/ui/ws/window_tree_unittest.cc b/services/ui/ws/window_tree_unittest.cc index cff48cc..83b9de09 100644 --- a/services/ui/ws/window_tree_unittest.cc +++ b/services/ui/ws/window_tree_unittest.cc
@@ -11,8 +11,10 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" #include "services/service_manager/public/interfaces/connector.mojom.h" +#include "services/ui/common/task_runner_test_base.h" #include "services/ui/common/types.h" #include "services/ui/common/util.h" #include "services/ui/public/interfaces/window_tree.mojom.h" @@ -25,6 +27,7 @@ #include "services/ui/ws/test_change_tracker.h" #include "services/ui/ws/test_server_window_delegate.h" #include "services/ui/ws/test_utils.h" +#include "services/ui/ws/user_display_manager.h" #include "services/ui/ws/window_manager_access_policy.h" #include "services/ui/ws/window_manager_display_root.h" #include "services/ui/ws/window_server.h" @@ -121,6 +124,19 @@ DISALLOW_COPY_AND_ASSIGN(TestMoveLoopWindowManager); }; +// This creates a WindowTree similar to how connecting via WindowTreeFactory +// creates a tree. +WindowTree* CreateTreeViaFactory(WindowServer* window_server, + const UserId& user_id, + TestWindowTreeBinding** binding) { + WindowTree* tree = new WindowTree(window_server, user_id, nullptr, + base::MakeUnique<DefaultAccessPolicy>()); + *binding = new TestWindowTreeBinding(tree); + window_server->AddTree(base::WrapUnique(tree), base::WrapUnique(*binding), + nullptr); + return tree; +} + } // namespace // ----------------------------------------------------------------------------- @@ -180,13 +196,7 @@ // a WindowTreeFactory does. WindowTree* CreateNewTree(const UserId& user_id, TestWindowTreeBinding** binding) { - WindowTree* tree = - new WindowTree(window_server(), user_id, nullptr, - base::WrapUnique(new DefaultAccessPolicy)); - *binding = new TestWindowTreeBinding(tree); - window_server()->AddTree(base::WrapUnique(tree), base::WrapUnique(*binding), - nullptr); - return tree; + return CreateTreeViaFactory(window_server(), user_id, binding); } protected: @@ -1516,7 +1526,7 @@ } // Used to test the window manager configured to manually create displays roots. -class WindowTreeManualDisplayTest : public testing::Test { +class WindowTreeManualDisplayTest : public TaskRunnerTestBase { public: WindowTreeManualDisplayTest() {} ~WindowTreeManualDisplayTest() override {} @@ -1533,6 +1543,7 @@ protected: // testing::Test: void SetUp() override { + TaskRunnerTestBase::SetUp(); screen_manager_.Init(window_server()->display_manager()); window_server()->user_id_tracker()->AddUserId(kTestUserId1); } @@ -1548,6 +1559,7 @@ const bool automatically_create_display_roots = false; AddWindowManager(window_server(), kTestUserId1, automatically_create_display_roots); + WindowManagerState* window_manager_state = window_server()->GetWindowManagerStateForUser(kTestUserId1); ASSERT_TRUE(window_manager_state); @@ -1593,6 +1605,143 @@ .empty()); } +TEST_F(WindowTreeManualDisplayTest, + DisplayManagerObserverNotifiedWithManualRoots) { + const bool automatically_create_display_roots = false; + AddWindowManager(window_server(), kTestUserId1, + automatically_create_display_roots); + + TestDisplayManagerObserver display_manager_observer; + DisplayManager* display_manager = window_server()->display_manager(); + UserDisplayManager* user_display_manager = + display_manager->GetUserDisplayManager(kTestUserId1); + ASSERT_TRUE(user_display_manager); + user_display_manager->AddObserver(display_manager_observer.GetPtr()); + + // Observer should not have been notified yet. + // + // NOTE: the RunUntilIdle() calls are necessary anytime the calls are checked + // as the observer is called via mojo, which is async. + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + + // Set frame decorations, again observer should not be notified. + WindowManagerState* window_manager_state = + window_server()->GetWindowManagerStateForUser(kTestUserId1); + ASSERT_TRUE(window_manager_state); + WindowTree* window_manager_tree = window_manager_state->window_tree(); + window_manager_state->SetFrameDecorationValues( + mojom::FrameDecorationValues::New()); + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + + // Create a window for the windowmanager and set it as the root. + ClientWindowId display_root_id = BuildClientWindowId(window_manager_tree, 10); + ASSERT_TRUE(window_manager_tree->NewWindow(display_root_id, + ServerWindow::Properties())); + ServerWindow* display_root = + window_manager_tree->GetWindowByClientId(display_root_id); + ASSERT_TRUE(display_root); + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + + // Add a new display. + display::Display display1 = MakeDisplay(0, 0, 1024, 768, 1.0f); + const int64_t display_id1 = 101; + display1.set_id(display_id1); + mojom::WmViewportMetrics metrics1; + metrics1.bounds_in_pixels = display1.bounds(); + metrics1.device_scale_factor = 1.5; + metrics1.ui_scale_factor = 2.5; + const bool is_primary_display = true; + ASSERT_TRUE(WindowTreeTestApi(window_manager_tree) + .ProcessSetDisplayRoot(display1, metrics1, is_primary_display, + display_root_id)); + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + + // Configure the displays. + std::vector<display::Display> displays; + displays.push_back(display1); + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics; + viewport_metrics.push_back(ui::mojom::WmViewportMetrics::New(metrics1)); + ASSERT_TRUE(display_manager->SetDisplayConfiguration( + displays, std::move(viewport_metrics), display_id1)); + RunUntilIdle(); + EXPECT_EQ("OnDisplaysChanged " + std::to_string(display_id1), + display_manager_observer.GetAndClearObserverCalls()); + + // Create a window for the windowmanager and set it as the root. + ClientWindowId display_root_id2 = + BuildClientWindowId(window_manager_tree, 11); + ASSERT_TRUE(window_manager_tree->NewWindow(display_root_id2, + ServerWindow::Properties())); + ServerWindow* display_root2 = + window_manager_tree->GetWindowByClientId(display_root_id); + ASSERT_TRUE(display_root2); + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + + // Add another display. + display::Display display2 = MakeDisplay(0, 0, 1024, 768, 1.0f); + const int64_t display_id2 = 102; + display2.set_id(display_id2); + mojom::WmViewportMetrics metrics2; + metrics2.bounds_in_pixels = display2.bounds(); + metrics2.device_scale_factor = 1.5; + metrics2.ui_scale_factor = 2.5; + ASSERT_TRUE( + WindowTreeTestApi(window_manager_tree) + .ProcessSetDisplayRoot(display2, metrics2, false, display_root_id2)); + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + + // Make |display2| the default, and resize both displays. + display1.set_bounds(gfx::Rect(0, 0, 1024, 1280)); + metrics1.bounds_in_pixels = display1.bounds(); + displays.clear(); + displays.push_back(display1); + + display2.set_bounds(gfx::Rect(0, 0, 500, 600)); + metrics2.bounds_in_pixels = display2.bounds(); + displays.push_back(display2); + + viewport_metrics.push_back(ui::mojom::WmViewportMetrics::New(metrics1)); + viewport_metrics.push_back(ui::mojom::WmViewportMetrics::New(metrics2)); + ASSERT_TRUE(display_manager->SetDisplayConfiguration( + displays, std::move(viewport_metrics), display_id2)); + RunUntilIdle(); + EXPECT_EQ("OnDisplaysChanged " + std::to_string(display_id1) + " " + + std::to_string(display_id2), + display_manager_observer.GetAndClearObserverCalls()); + + // Delete the second display, no notification should be sent. + EXPECT_TRUE(window_manager_tree->DeleteWindow(display_root_id2)); + RunUntilIdle(); + EXPECT_TRUE(display_manager_observer.GetAndClearObserverCalls().empty()); + EXPECT_FALSE(display_manager->GetDisplayById(display_id2)); + + // Set the config back to only the first. + displays.clear(); + displays.push_back(display1); + + viewport_metrics.push_back(ui::mojom::WmViewportMetrics::New(metrics1)); + ASSERT_TRUE(display_manager->SetDisplayConfiguration( + displays, std::move(viewport_metrics), display_id1)); + RunUntilIdle(); + EXPECT_EQ("OnDisplaysChanged " + std::to_string(display_id1), + display_manager_observer.GetAndClearObserverCalls()); + + // The display list should not have display2. + display::DisplayList& display_list = + display::ScreenManager::GetInstance()->GetScreen()->display_list(); + EXPECT_TRUE(display_list.FindDisplayById(display_id2) == + display_list.displays().end()); + ASSERT_TRUE(display_list.GetPrimaryDisplayIterator() != + display_list.displays().end()); + EXPECT_EQ(display_id1, display_list.GetPrimaryDisplayIterator()->id()); +} + } // namespace test } // namespace ws } // namespace ui
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index ebf06c239..5ea6c46 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -122,6 +122,8 @@ # ====== Paint team owned tests to here ====== #### external/wpt/css/css-position-3 +crbug.com/702927 external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom.html [ Failure ] +crbug.com/702927 external/wpt/css/css-position-3/position-sticky-table-thead-top.html [ Failure ] crbug.com/702927 external/wpt/css/css-position-3/position-sticky-table-tr-top.html [ Failure ] crbug.com/702927 external/wpt/css/css-position-3/position-sticky-table-tr-bottom.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom-ref.html new file mode 100644 index 0000000..a89dd6a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom-ref.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky bottom constraint should behave correctly for <tfoot> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; +}); +</script> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> + +<div>You should see three green boxes above. No red should be visible.</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom.html new file mode 100644 index 0000000..17fe3599 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-tfoot-bottom.html
@@ -0,0 +1,121 @@ +<!DOCTYPE html> +<title>position:sticky bottom constraint should behave correctly for <tfoot> elements</title> +<link rel="match" href="position-sticky-table-tfoot-bottom-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky bottom constraint behaves correctly for <tfoot> elements" /> + +<style> +table { + border-collapse:collapse; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + bottom: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; +}); +</script> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot class="sticky"> + <tr><th><div></div></th></tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot class="sticky"> + <tr><th><div></div></th></tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot class="sticky"> + <tr><th><div></div></th></tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div>You should see three green boxes above. No red should be visible.</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-thead-top-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-thead-top-ref.html new file mode 100644 index 0000000..f313d60 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-thead-top-ref.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky top constraint should behave correctly for <thead> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> + +<div>You should see three green boxes above. No red should be visible.</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-thead-top.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-thead-top.html new file mode 100644 index 0000000..560a45e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-position-3/position-sticky-table-thead-top.html
@@ -0,0 +1,121 @@ +<!DOCTYPE html> +<title>position:sticky top constraint should behave correctly for <thead> elements</title> +<link rel="match" href="position-sticky-table-thead-top-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky top constraint behaves correctly for <thead> elements" /> + +<style> +table { + border-collapse:collapse; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + top: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr><th><div></div></th></tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr><th><div></div></th></tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr><th><div></div></th></tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div>You should see three green boxes above. No red should be visible.</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/sticky/sticky-position-works-with-scroll-apis.html b/third_party/WebKit/LayoutTests/fast/css/sticky/sticky-position-works-with-scroll-apis.html new file mode 100644 index 0000000..6c58672 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/sticky/sticky-position-works-with-scroll-apis.html
@@ -0,0 +1,130 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> +body { + margin: 0; +} + +#scroller { + height: 100px; + width: 200px; + overflow-y: scroll; +} + +.paddingBefore { + height: 150px; +} + +#sticky { + height: 50px; + position: sticky; + top: 20px; +} + +.paddingAfter { + height: 500px; +} +</style> + +<div id="scroller"> + <div class="paddingBefore"></div> + <div id="writer"></div> + <div id="sticky"></div> + <div class="paddingAfter"></div> +</div> + +<script> +if (window.internals) { + internals.settings.setCSSStickyPositionEnabled(true); +} + +// These tests currently mimic the behavior of Firefox for the interaction +// between scrollIntoView() and position:sticky, where the offset location of +// the sticky element is used to determine how far to scroll. This means that +// scrollIntoView() may scroll even when the sticky is already 'in view', and +// attempts to scroll so that the offset position of the sticky is at the top +// of the screen. +// +// TODO(smcgruer): Update tests once http://crbug.com/664246 is resolved. + +test(function() { + var scroller = document.getElementById('scroller'); + var sticky = document.getElementById('sticky'); + var writer = document.getElementById('writer'); + + // Clean the writer. + writer.innerHTML = ''; + + // With no scroll, the sticky element is outside the scroller viewport. + scroller.scrollTop = 0; + + // Deliberately dirty layout to make sure that scrollIntoView() still works. + writer.innerHTML = '<div style="height: 50px;"></div>'; + + sticky.scrollIntoView(); + assert_equals(scroller.scrollTop, 200); +}, "scrollIntoView should scroll when sticky is not visible"); + +test(function() { + var scroller = document.getElementById('scroller'); + var sticky = document.getElementById('sticky'); + var writer = document.getElementById('writer'); + + // Clean the writer. + writer.innerHTML = ''; + + // Scroll so that the sticky element is past the top of the scroller + // viewport, and is thus sticking. + scroller.scrollTop = 200; + + // Deliberately dirty layout to make sure that scrollIntoView() still works. + writer.innerHTML = '<div style="height: 10px;"></div>'; + + // See comment above tests for why this shifts by an additional 20 pixels. + sticky.scrollIntoView(); + assert_equals(scroller.scrollTop, 230); +}, "scrollIntoView should scroll when sticky is already in view"); + +test(function() { + var scroller = document.getElementById('scroller'); + var sticky = document.getElementById('sticky'); + var writer = document.getElementById('writer'); + + // Clean the writer. + writer.innerHTML = ''; + + // With no scroll, the sticky element is outside the scroller viewport. + scroller.scrollTop = 0; + + // Deliberately dirty layout to make sure that scrollIntoViewIfNeeded() + // still works. + writer.innerHTML = '<div style="height: 70px;"></div>'; + + sticky.scrollIntoViewIfNeeded(); + assert_equals(scroller.scrollTop, 195); +}, "scrollIntoViewIfNeeded should scroll when sticky is not visible"); + +test(function() { + var scroller = document.getElementById('scroller'); + var sticky = document.getElementById('sticky'); + var writer = document.getElementById('writer'); + + // Clean the writer. + writer.innerHTML = ''; + + // Scroll so that the sticky element is at the top of the scroller viewport. + scroller.scrollTop = 150; + + // Deliberately dirty layout to make sure that scrollIntoViewIfNeeded() + // still works. + writer.innerHTML = '<div style="height: 20px;"></div>'; + + // The scroll top moves to 170 due to scroll-anchoring, but should then not + // shift if we call scrollIntoViewIfNeeded. + assert_equals(scroller.scrollTop, 170); + sticky.scrollIntoViewIfNeeded(); + assert_equals(scroller.scrollTop, 170); +}, "scrollIntoViewIfNeeded should not scroll when sticky is already in view"); +</script> +
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/blank.html b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/blank.html new file mode 100644 index 0000000..8de20fe --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/blank.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<title>Informs the test runner when this page has loaded</title> +<script> +window.addEventListener('DOMContentLoaded', () => { + if (window.testRunner) + testRunner.notifyDone(); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/xslt-document-insertion.xsl b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/xslt-document-insertion.xsl new file mode 100644 index 0000000..8dc9150 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/xslt-document-insertion.xsl
@@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="/"> + <html> + <title>Checks that an XSLT-generated HTML doc allows first-party cookies</title> + <script> + if (window.testRunner) { + testRunner.waitUntilDone(); + testRunner.dumpAsText(); + testRunner.dumpChildFramesAsText(); + } + </script> + <body> + <iframe allow="payment" src="http://127.0.0.1:8000/feature-policy/resources/blank.html"></iframe> + </body> + </html> + </xsl:template> +</xsl:stylesheet>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/xslt-document-insertion-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/xslt-document-insertion-expected.txt new file mode 100644 index 0000000..fd6f97229 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/xslt-document-insertion-expected.txt
@@ -0,0 +1,6 @@ + + +-------- +Frame: '<!--framePath //<!--frame0-->-->' +-------- +
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/xslt-document-insertion.xml b/third_party/WebKit/LayoutTests/http/tests/feature-policy/xslt-document-insertion.xml new file mode 100644 index 0000000..f9d0dafd --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/xslt-document-insertion.xml
@@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="utf-8"?> +<?xml-stylesheet type="text/xsl" href="resources/xslt-document-insertion.xsl"?> +<body/>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/resources/get-interface-names.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/resources/get-interface-names.js deleted file mode 100644 index 7b9b1696..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/resources/get-interface-names.js +++ /dev/null
@@ -1,37 +0,0 @@ -function get_interface_names(global_object, interface_names) { - var result = []; - function collect_property_info(object, property_name, output) { - var descriptor = Object.getOwnPropertyDescriptor(object, property_name); - if ('value' in descriptor) { - if (typeof descriptor.value === 'function') { - output.push(' method ' + property_name); - } else { - output.push(' attribute ' + property_name); - } - } else { - if (descriptor.get) { - output.push(' getter ' + property_name); - } - if (descriptor.set) { - output.push(' setter ' + property_name); - } - } - } - interface_names.sort(); - interface_names.forEach(function(interface_name) { - if (this[interface_name] === undefined) { - return; - } - result.push('interface ' + interface_name); - var property_names = - Object.getOwnPropertyNames(this[interface_name].prototype); - var property_strings = []; - property_names.forEach(function(property_name) { - collect_property_info(this[interface_name].prototype, - property_name, - property_strings); - }); - result.push.apply(result, property_strings.sort()); - }); - return result.join("\n");; -}
diff --git a/third_party/WebKit/LayoutTests/svg/as-image/adopt-while-async-svg-load-is-in-progress-crash.html b/third_party/WebKit/LayoutTests/svg/as-image/adopt-while-async-svg-load-is-in-progress-crash.html new file mode 100644 index 0000000..dfcb1075 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/as-image/adopt-while-async-svg-load-is-in-progress-crash.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +var t = async_test("Garbage collection of ImageResourceContent while " + + "asynchronous loading of SVG is in progress " + + "shouldn't crash. crbug.com/726220"); +var img; + +function step1() { + setTimeout(t.step_func(step2), 0); + + // 1. Creating an <img> element with SVG of which loading is not completed + // synchronously. + img = document.createElement('img'); + img.src='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><foreignObject><body xmlns="http://www.w3.org/1999/xhtml"><marquee></marquee></body></foreignObject></svg>'; + document.body.appendChild(img); + assert_false(img.complete); +} + +function step2() { + // 2. Adopt the <img> to a new document. + newdoc = document.implementation.createDocument("svg", null); + newdoc.adoptNode(img); + + // 3. Do garbage collection. The oold ImageResourceContent is garbage + // collected while async SVG loading is still in progress. + gc(); + + setTimeout(t.step_func_done(), 100); +} + +</script> +<body onload="setTimeout(t.step_func(step1), 0)"></body>
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 234401cb..4f428b56 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -5644,6 +5644,48 @@ return 0; } +void Document::SetFeaturePolicy(const String& feature_policy_header) { + if (!RuntimeEnabledFeatures::featurePolicyEnabled()) + return; + + WebFeaturePolicy* parent_feature_policy = nullptr; + WebParsedFeaturePolicy container_policy; + Vector<String> messages; + const WebParsedFeaturePolicy& parsed_header = + ParseFeaturePolicy(feature_policy_header, GetSecurityOrigin(), &messages); + + // If this frame is not the main frame, then get the appropriate parent policy + // and container policy to construct the policy for this frame. + if (frame_) { + if (!frame_->IsMainFrame()) { + parent_feature_policy = + frame_->Tree().Parent()->GetSecurityContext()->GetFeaturePolicy(); + } + if (frame_->Owner()) + container_policy = frame_->Owner()->ContainerPolicy(); + } + + // Check that if there is a parent frame, that its feature policy is + // correctly initialized. Crash if that is not the case. (Temporary crash for + // isolating the cause of https://crbug.com/722333) + // Note that even with this check removed, the process will stil crash in + // feature_policy.cc when it attempts to dereference parent_feature_policy. + // This check is to distinguish between two possible causes. + if (!container_policy.empty()) + CHECK(frame_ && (frame_->IsMainFrame() || parent_feature_policy)); + + InitializeFeaturePolicy(parsed_header, container_policy, + parent_feature_policy); + + for (const auto& message : messages) { + AddConsoleMessage( + ConsoleMessage::Create(kOtherMessageSource, kErrorMessageLevel, + "Error with Feature-Policy header: " + message)); + } + if (frame_ && !parsed_header.empty()) + frame_->Client()->DidSetFeaturePolicyHeader(parsed_header); +} + void Document::InitSecurityContext(const DocumentInit& initializer) { DCHECK(!GetSecurityOrigin()); @@ -5653,6 +5695,7 @@ cookie_url_ = KURL(kParsedURLString, g_empty_string); SetSecurityOrigin(SecurityOrigin::CreateUnique()); InitContentSecurityPolicy(); + SetFeaturePolicy(g_empty_string); // Unique security origins cannot have a suborigin return; } @@ -5753,6 +5796,8 @@ if (GetSecurityOrigin()->HasSuborigin()) EnforceSuborigin(*GetSecurityOrigin()->GetSuborigin()); + + SetFeaturePolicy(g_empty_string); } void Document::InitContentSecurityPolicy(ContentSecurityPolicy* csp) {
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index a9a4333..1b4703b 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1336,6 +1336,8 @@ CoreProbeSink* GetProbeSink() final; + void SetFeaturePolicy(const String& feature_policy_header); + protected: Document(const DocumentInit&, DocumentClassFlags = kDefaultDocumentClass);
diff --git a/third_party/WebKit/Source/core/dom/SecurityContext.cpp b/third_party/WebKit/Source/core/dom/SecurityContext.cpp index e5777d0..24cb6329 100644 --- a/third_party/WebKit/Source/core/dom/SecurityContext.cpp +++ b/third_party/WebKit/Source/core/dom/SecurityContext.cpp
@@ -105,7 +105,6 @@ const WebParsedFeaturePolicy& parsed_header, const WebParsedFeaturePolicy& container_policy, const WebFeaturePolicy* parent_feature_policy) { - DCHECK(!feature_policy_); WebSecurityOrigin origin = WebSecurityOrigin(security_origin_); feature_policy_ = Platform::Current()->CreateFeaturePolicy( parent_feature_policy, container_policy, parsed_header, origin);
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp index 7315099..ab71a5b0 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -443,6 +443,12 @@ if (focused_element->IsTextControl()) return focused_element->ContainsIncludingHostElements(*current); + if (ComputeVisibleSelectionInFlatTree().IsNone()) { + // TODO(editing-dev): We should avoid any case where VSInFlatTree is none + // but VSInDOMTree is not none. + DLOG(FATAL) << ComputeVisibleSelectionInDOMTree(); + } + // Selection has focus if it contains the focused element. const PositionInFlatTree& focused_position = PositionInFlatTree::FirstPositionInNode(focused_element);
diff --git a/third_party/WebKit/Source/core/editing/markers/TextMatchMarker.h b/third_party/WebKit/Source/core/editing/markers/TextMatchMarker.h index b7025f5..74c69dd4 100644 --- a/third_party/WebKit/Source/core/editing/markers/TextMatchMarker.h +++ b/third_party/WebKit/Source/core/editing/markers/TextMatchMarker.h
@@ -75,10 +75,12 @@ State state_; }; -DEFINE_TYPE_CASTS(TextMatchMarker, DocumentMarker, marker, true, true); +DEFINE_TYPE_CASTS(TextMatchMarker, + DocumentMarker, + marker, + marker->GetType() == DocumentMarker::kTextMatch, + marker.GetType() == DocumentMarker::kTextMatch); } // namespace blink -WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::TextMatchMarker); - #endif
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index ae8a328..4a71b34e 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1616,6 +1616,7 @@ kHTMLOListElementStartGetterReversedWithoutStartAttribute = 2011, kCredentialManagerPreventSilentAccess = 2012, kNetInfoEffectiveType = 2013, + kV8SpeechRecognition_Start_Method = 2014, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp index 214e27b..4657b6d 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp
@@ -10,11 +10,14 @@ #include "core/frame/LocalFrameView.h" #include "core/frame/VisualViewport.h" #include "core/frame/WebLocalFrameBase.h" +#include "core/input/ContextMenuAllowedScope.h" #include "core/input/EventHandler.h" +#include "core/page/ContextMenuController.h" #include "core/page/DragActions.h" #include "core/page/DragController.h" #include "core/page/DragData.h" #include "core/page/DragSession.h" +#include "core/page/FocusController.h" #include "core/page/Page.h" #include "core/page/PointerLockController.h" #include "platform/UserGestureIndicator.h" @@ -284,4 +287,19 @@ } } +void WebFrameWidgetBase::ShowContextMenu(WebMenuSourceType source_type) { + if (!GetPage()) + return; + + GetPage()->GetContextMenuController().ClearContextMenu(); + { + ContextMenuAllowedScope scope; + if (LocalFrame* focused_frame = + GetPage()->GetFocusController().FocusedFrame()) { + focused_frame->GetEventHandler().ShowNonLocatedContextMenu(nullptr, + source_type); + } + } +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h index 843c2e3..3d8d07af 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h
@@ -82,6 +82,7 @@ void DidAcquirePointerLock() override; void DidNotAcquirePointerLock() override; void DidLosePointerLock() override; + void ShowContextMenu(WebMenuSourceType) override; protected: enum DragAction { kDragEnter, kDragOver };
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 7b04491..463937a 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -914,6 +914,9 @@ return nullptr; } + if (MemoryCoordinator::IsLowEndDevice()) + surface->DisableDeferral(kDisableDeferralReasonLowEndDevice); + CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kGPUAccelerated2DCanvasImageBufferCreated); return std::move(surface);
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp index a3466a0..5e6d31b 100644 --- a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
@@ -508,21 +508,18 @@ } void HTMLVideoElement::MediaRemotingStopped() { - // Early return because this was already called when media remoting was - // disabled. - if (media_remoting_status_ == MediaRemotingStatus::kDisabled) - return; - DCHECK(media_remoting_status_ == MediaRemotingStatus::kStarted); + DCHECK(media_remoting_status_ == MediaRemotingStatus::kDisabled || + media_remoting_status_ == MediaRemotingStatus::kStarted); + if (media_remoting_status_ != MediaRemotingStatus::kDisabled) + media_remoting_status_ = MediaRemotingStatus::kNotStarted; DCHECK(remoting_interstitial_); - media_remoting_status_ = MediaRemotingStatus::kNotStarted; remoting_interstitial_->Hide(); } void HTMLVideoElement::DisableMediaRemoting() { + media_remoting_status_ = MediaRemotingStatus::kDisabled; if (GetWebMediaPlayer()) GetWebMediaPlayer()->RequestRemotePlaybackDisabled(true); - media_remoting_status_ = MediaRemotingStatus::kDisabled; - MediaRemotingStopped(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp index b5c5260..6bdcd59f 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp
@@ -15,7 +15,9 @@ namespace { const unsigned CanvasFontCacheMaxFonts = 50; +const unsigned CanvasFontCacheMaxFontsLowEnd = 5; const unsigned CanvasFontCacheHardMaxFonts = 250; +const unsigned CanvasFontCacheHardMaxFontsLowEnd = 20; const unsigned CanvasFontCacheHiddenMaxFonts = 1; const int defaultFontSize = 10; const char defaultFontFamily[] = "sans-serif"; @@ -45,12 +47,15 @@ } unsigned CanvasFontCache::MaxFonts() { - return CanvasFontCacheMaxFonts; + return MemoryCoordinator::IsLowEndDevice() ? CanvasFontCacheMaxFontsLowEnd + : CanvasFontCacheMaxFonts; } unsigned CanvasFontCache::HardMaxFonts() { return document_->hidden() ? CanvasFontCacheHiddenMaxFonts - : CanvasFontCacheHardMaxFonts; + : (MemoryCoordinator::IsLowEndDevice() + ? CanvasFontCacheHardMaxFontsLowEnd + : CanvasFontCacheHardMaxFonts); } bool CanvasFontCache::GetFontUsingDefaultStyle(const String& font_string,
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index e2748316..2ffab13 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -995,41 +995,6 @@ frame_->GetPage()->DidCommitLoad(frame_); } -void SetFeaturePolicy(Document* document, const String& feature_policy_header) { - if (!RuntimeEnabledFeatures::featurePolicyEnabled()) - return; - LocalFrame* frame = document->GetFrame(); - WebFeaturePolicy* parent_feature_policy = - frame->IsMainFrame() - ? nullptr - : frame->Tree().Parent()->GetSecurityContext()->GetFeaturePolicy(); - Vector<String> messages; - const WebParsedFeaturePolicy& parsed_header = ParseFeaturePolicy( - feature_policy_header, frame->GetSecurityContext()->GetSecurityOrigin(), - &messages); - WebParsedFeaturePolicy container_policy; - if (frame->Owner()) - container_policy = frame->Owner()->ContainerPolicy(); - // Check that if there is a parent frame, that its feature policy is - // correctly initialized. Crash if that is not the case. (Temporary crash for - // isolating the cause of https://crbug.com/722333) - // Note that even with this check removed, the process will stil crash in - // feature_policy.cc when it attempts to dereference parent_feature_policy. - // This check is to distinguish between two possible causes. - if (!container_policy.empty()) - CHECK(frame->IsMainFrame() || parent_feature_policy); - frame->GetSecurityContext()->InitializeFeaturePolicy( - parsed_header, container_policy, parent_feature_policy); - - for (auto& message : messages) { - document->AddConsoleMessage( - ConsoleMessage::Create(kOtherMessageSource, kErrorMessageLevel, - "Error with Feature-Policy header: " + message)); - } - if (!parsed_header.empty()) - frame->Client()->DidSetFeaturePolicyHeader(parsed_header); -} - // static bool DocumentLoader::ShouldClearWindowName( const LocalFrame& frame, @@ -1096,8 +1061,8 @@ // FeaturePolicy is reset in the browser process on commit, so this needs to // be initialized and replicated to the browser process after commit messages // are sent in didCommitNavigation(). - SetFeaturePolicy(document, - response_.HttpHeaderField(HTTPNames::Feature_Policy)); + document->SetFeaturePolicy( + response_.HttpHeaderField(HTTPNames::Feature_Policy)); GetFrameLoader().DispatchDidClearDocumentOfWindowObject(); }
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index d235c5f..51c7354 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -577,6 +577,9 @@ } void SVGImage::ServiceAnimations(double monotonic_animation_start_time) { + if (!GetImageObserver()) + return; + // If none of our observers (sic!) are visible, or for some other reason // does not want us to keep running animations, stop them until further // notice (next paint.)
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp index de6e9ec..5af954d 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
@@ -114,11 +114,12 @@ // The SVGImageChromeClient object's lifetime is dependent on // the ImageObserver (an ImageResourceContent) of its image. Should it - // be dead and about to be lazily swept out, do not proceed. + // be dead and about to be lazily swept out, then GetImageObserver() + // becomes null and we do not proceed. // // TODO(Oilpan): move (SVG)Image to the Oilpan heap, and avoid // this explicit lifetime check. - if (ThreadHeap::WillObjectBeLazilySwept(image_->GetImageObserver())) + if (!image_->GetImageObserver()) return; image_->ServiceAnimations(MonotonicallyIncreasingTime());
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js index 87dd668..61184bd 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js
@@ -244,30 +244,18 @@ * @param {!SDK.DOMNode} node * @return {!Promise} */ - requestPartialAXTree(node) { - /** - * @this {Accessibility.AccessibilityModel} - * @param {?string} error - * @param {!Array<!Protocol.Accessibility.AXNode>=} payloads - */ - function parsePayload(error, payloads) { - if (error) { - console.error('AccessibilityAgent.getAXNodeChain(): ' + error); - return null; - } + async requestPartialAXTree(node) { + var payloads = await this._agent.getPartialAXTree(node.id, true); + if (!payloads) + return; - if (!payloads) - return; + for (var payload of payloads) + new Accessibility.AccessibilityNode(this, payload); - for (var payload of payloads) - new Accessibility.AccessibilityNode(this, payload); - - for (var axNode of this._axIdToAXNode.values()) { - for (var axChild of axNode.children()) - axChild._setParentNode(axNode); - } + for (var axNode of this._axIdToAXNode.values()) { + for (var axChild of axNode.children()) + axChild._setParentNode(axNode); } - return this._agent.getPartialAXTree(node.id, true, parsePayload.bind(this)); } /**
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 12c747f..5470571 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
@@ -47,7 +47,6 @@ ref_types = {} NON_PROMISIFIED_DOMAINS = frozenset([ - "Accessibility", "Animation", "ApplicationCache", "CacheStorage",
diff --git a/third_party/WebKit/Source/modules/speech/SpeechRecognition.idl b/third_party/WebKit/Source/modules/speech/SpeechRecognition.idl index a1b29ced..27f29ed 100644 --- a/third_party/WebKit/Source/modules/speech/SpeechRecognition.idl +++ b/third_party/WebKit/Source/modules/speech/SpeechRecognition.idl
@@ -43,7 +43,7 @@ [RuntimeEnabled=MediaStreamSpeech] attribute MediaStreamTrack? audioTrack; // methods to drive the speech interaction - [RaisesException] void start(); + [RaisesException, Measure] void start(); [ImplementedAs=stopFunction] void stop(); void abort();
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h b/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h index d22c298e..365cb14d 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h
@@ -116,6 +116,7 @@ kDisableDeferralReasonDrawImageOfAnimated2dCanvas = 4, kDisableDeferralReasonSubPixelTextAntiAliasingSupport = 5, kDisableDeferralDrawImageWithTextureBackedSourceImage = 6, + kDisableDeferralReasonLowEndDevice = 7, kDisableDeferralReasonCount, };
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h index faecfa1..b3e30393 100644 --- a/third_party/WebKit/Source/platform/graphics/Image.h +++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -229,9 +229,11 @@ // TODO(Oilpan): consider having Image on the Oilpan heap and // turn this into a Member<>. // - // The observer (an ImageResourceContent) is an untraced member, with the - // ImageResourceContent being responsible for clearing itself out. - UntracedMember<ImageObserver> image_observer_; + // The observer (an ImageResourceContent) is responsible for clearing + // itself out when it switches to another Image. + // When the ImageResourceContent is garbage collected while Image is still + // alive, |image_observer_| is cleared by WeakPersistent mechanism. + WeakPersistent<ImageObserver> image_observer_; PaintImage::Id stable_image_id_; };
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp index 6e8101b..45a340d 100644 --- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp +++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
@@ -220,6 +220,8 @@ case kDisableDeferralDrawImageWithTextureBackedSourceImage: return RecordingImageBufferSurface:: kFallbackReasonDrawImageWithTextureBackedSourceImage; + // The LowEndDevice reason should only be used on Canvas2DLayerBridge. + case kDisableDeferralReasonLowEndDevice: case kDisableDeferralReasonCount: NOTREACHED(); break;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index c747a7a..12e2e3b5 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -3500,18 +3500,12 @@ } void WebViewImpl::ShowContextMenu(WebMenuSourceType source_type) { - if (!GetPage()) + if (!MainFrameImpl()) return; - GetPage()->GetContextMenuController().ClearContextMenu(); - { - ContextMenuAllowedScope scope; - if (LocalFrame* focused_frame = ToLocalFrame( - GetPage()->GetFocusController().FocusedOrMainFrame())) { - focused_frame->GetEventHandler().ShowNonLocatedContextMenu(nullptr, - source_type); - } - } + // If MainFrameImpl() is non-null, then FrameWidget() will also be non-null. + DCHECK(MainFrameImpl()->FrameWidget()); + MainFrameImpl()->FrameWidget()->ShowContextMenu(source_type); } void WebViewImpl::DidCloseContextMenu() {
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index ba65d8f..116282d 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -150,6 +150,7 @@ void DidAcquirePointerLock() override; void DidNotAcquirePointerLock() override; void DidLosePointerLock() override; + void ShowContextMenu(WebMenuSourceType) override; // WebView methods: virtual bool IsWebView() const { return true; } @@ -230,7 +231,6 @@ unsigned inactive_background_color, unsigned inactive_foreground_color) override; void PerformCustomContextMenuAction(unsigned action) override; - void ShowContextMenu(WebMenuSourceType) override; void DidCloseContextMenu() override; void HidePopups() override; void SetPageOverlayColor(WebColor) override;
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index 661727b..dad995b 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -2457,7 +2457,7 @@ EXPECT_TRUE(main_frame->GetFrame()->Selection().IsCaretBlinkingSuspended()); // Caret blinking is still suspended after showing context menu. - web_view->ShowContextMenu(kMenuSourceMouse); + web_view->GetWidget()->ShowContextMenu(kMenuSourceMouse); EXPECT_TRUE(main_frame->GetFrame()->Selection().IsCaretBlinkingSuspended()); // Caret blinking will be resumed only after context menu is closed.
diff --git a/third_party/WebKit/public/web/WebView.h b/third_party/WebKit/public/web/WebView.h index c55118ba..04b8b90 100644 --- a/third_party/WebKit/public/web/WebView.h +++ b/third_party/WebKit/public/web/WebView.h
@@ -31,7 +31,6 @@ #ifndef WebView_h #define WebView_h -#include "WebMenuSourceType.h" #include "WebWidget.h" #include "public/platform/WebColor.h" #include "public/platform/WebDisplayMode.h" @@ -389,9 +388,6 @@ virtual void PerformCustomContextMenuAction(unsigned action) = 0; - // Shows a context menu for the currently focused element. - virtual void ShowContextMenu(WebMenuSourceType) = 0; - // Notify that context menu has been closed. virtual void DidCloseContextMenu() = 0;
diff --git a/third_party/WebKit/public/web/WebWidget.h b/third_party/WebKit/public/web/WebWidget.h index 4dae362..1985722 100644 --- a/third_party/WebKit/public/web/WebWidget.h +++ b/third_party/WebKit/public/web/WebWidget.h
@@ -40,9 +40,10 @@ #include "public/platform/WebRect.h" #include "public/platform/WebSize.h" #include "public/platform/WebTextInputInfo.h" -#include "WebCompositionUnderline.h" -#include "WebRange.h" -#include "WebTextDirection.h" +#include "public/web/WebCompositionUnderline.h" +#include "public/web/WebMenuSourceType.h" +#include "public/web/WebRange.h" +#include "public/web/WebTextDirection.h" namespace blink { @@ -224,6 +225,9 @@ return false; } + // Called by client to request showing the context menu. + virtual void ShowContextMenu(WebMenuSourceType) {} + protected: ~WebWidget() {} };
diff --git a/third_party/android_media/BUILD.gn b/third_party/android_media/BUILD.gn new file mode 100644 index 0000000..a4a375ae --- /dev/null +++ b/third_party/android_media/BUILD.gn
@@ -0,0 +1,26 @@ +# 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. + +import("//build/config/android/rules.gni") + +assert(is_android) + +android_resources("android_media_resources") { + custom_package = "org.chromium.third_party.android.media" + resource_dirs = [ "java/res" ] + deps = [ + "//third_party/android_tools:android_support_v7_appcompat_java", + "//third_party/android_tools:android_support_v7_mediarouter_java", + ] +} + +android_library("android_media_java") { + java_files = + [ "java/src/org/chromium/third_party/android/media/MediaController.java" ] + deps = [ + ":android_media_resources", + "//third_party/android_tools:android_support_v7_appcompat_java", + "//third_party/android_tools:android_support_v7_mediarouter_java", + ] +}
diff --git a/third_party/android_media/LICENSE b/third_party/android_media/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/android_media/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/android_media/OWNERS b/third_party/android_media/OWNERS new file mode 100644 index 0000000..d88be63 --- /dev/null +++ b/third_party/android_media/OWNERS
@@ -0,0 +1,3 @@ +aberent@chromium.org +dgn@chromium.org +avayvod@chromium.org \ No newline at end of file
diff --git a/third_party/android_media/README.chromium b/third_party/android_media/README.chromium new file mode 100644 index 0000000..5ca4a46 --- /dev/null +++ b/third_party/android_media/README.chromium
@@ -0,0 +1,20 @@ +Name: MediaController Android sample. +URL: https://android.googlesource.com/platform/development/+/b356564/samples/Support4Demos/src/com/example/android/supportv4/media/MediaController.java +Version: 74c5bcff29959931c8a4b15e4afa613975a47f4c +License: Apache 2.0 +Security Critical: no + +Description: +This contains a modified copy of MediaController.java and the associated +resources. + +MediaController.java is based on a public Android sample that was +available as part of the Android support libraries installation (see +https://developer.android.com/tools/support-library/index.html). It is +also available from: +https://android.googlesource.com/platform/development/+/b356564/samples/Support4Demos/src/com/example/android/supportv4/media/MediaController.java + +Local Modifications: +- TransportController and TransportMediator are replaced with a custom + interface +- minor bug fixes.
diff --git a/third_party/android_media/java/res/layout/media_controller.xml b/third_party/android_media/java/res/layout/media_controller.xml new file mode 100644 index 0000000..734b4b9 --- /dev/null +++ b/third_party/android_media/java/res/layout/media_controller.xml
@@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- This file is taken from the Android codebase. + samples/Support4Demos/res/layout/media_controller.xml +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingTop="4dip" + android:orientation="horizontal"> + + <!-- Android Lint is giving a false warning that layout_width and layout_height are not + set for buttons below, however MediaButton style sets the width and the height. --> + <!--suppress RequiredSize --> + <ImageButton + android:id="@+id/prev" + android:contentDescription="@null" + style="@android:style/MediaButton.Previous" /> + <!--suppress RequiredSize --> + <ImageButton + android:id="@+id/rew" + android:contentDescription="@null" + style="@android:style/MediaButton.Rew" /> + <!--suppress RequiredSize --> + <ImageButton + android:id="@+id/pause" + android:contentDescription="@null" + style="@android:style/MediaButton.Play" /> + <!--suppress RequiredSize --> + <ImageButton + android:id="@+id/ffwd" + android:contentDescription="@null" + style="@android:style/MediaButton.Ffwd" /> + <!--suppress RequiredSize --> + <ImageButton + android:id="@+id/next" + android:contentDescription="@null" + style="@android:style/MediaButton.Next" /> + + </LinearLayout> + + <LinearLayout + android:id="@+id/mediacontroller_progress_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <TextView android:id="@+id/time_current" + android:textSize="14sp" + android:textStyle="bold" + android:paddingTop="4dip" + android:paddingStart="4dip" + android:layout_gravity="center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingEnd="4dip" + android:textColor="@color/cast_media_controller_text" /> + + <SeekBar + android:id="@+id/mediacontroller_progress_bar" + style="?android:attr/progressBarStyleHorizontal" + android:layout_width="0dip" + android:layout_weight="1" + android:layout_height="32dip" /> + + <TextView android:id="@+id/time" + android:textSize="14sp" + android:textStyle="bold" + android:paddingTop="4dip" + android:paddingEnd="4dip" + android:layout_gravity="center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingStart="4dip" + android:textColor="@color/cast_media_controller_text" /> + </LinearLayout> + +</LinearLayout> +
diff --git a/third_party/android_media/java/res/values/colors.xml b/third_party/android_media/java/res/values/colors.xml new file mode 100644 index 0000000..d6c6e3c --- /dev/null +++ b/third_party/android_media/java/res/values/colors.xml
@@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<resources> + <!-- Cast colors --> + <!-- This is the same as the internal Android color "dim_foreground_dark" + which is used in MediaController. --> + <color name="cast_media_controller_text">#bebebe</color> + +</resources>
diff --git a/third_party/android_media/java/src/org/chromium/third_party/android/media/MediaController.java b/third_party/android_media/java/src/org/chromium/third_party/android/media/MediaController.java new file mode 100644 index 0000000..fd6b7f2 --- /dev/null +++ b/third_party/android_media/java/src/org/chromium/third_party/android/media/MediaController.java
@@ -0,0 +1,391 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.chromium.third_party.android.media; + +import android.content.Context; +import android.support.v4.media.session.PlaybackStateCompat; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.SeekBar; +import android.widget.TextView; + +import org.chromium.third_party.android.media.R; + +import java.util.Formatter; +import java.util.Locale; + +/** + * Helper for implementing media controls in an application. + * We use this custom version instead of {@link android.widget.MediaController} so that we can + * customize the look as we want. This file is taken directly from the public Android sample for + * supportv4, with tiny bug fixes. + */ +public class MediaController extends FrameLayout { + /** + * The interface that allows media controller to actually control media and provides some + * essential metadata for the UI like the current position, duration, etc. + */ + public interface Delegate { + /** + * Called when the user wants to resume or start. + */ + void play(); + + /** + * Called when the user wants to pause. + */ + void pause(); + + /** + * Called when the user wants to seek. + */ + void seekTo(long pos); + + /** + * @return the current media duration, in milliseconds. + */ + long getDuration(); + + /** + * @return the current playback position, in milliseconds. + */ + long getPosition(); + + /** + * @return if the media is currently playing. + */ + boolean isPlaying(); + + /** + * @return a combination of {@link PlaybackStateCompat} flags defining what UI elements will + * be available to the user. + */ + long getActionFlags(); + } + + private Delegate mDelegate; + private Context mContext; + private ViewGroup mProgressGroup; + private SeekBar mProgressBar; + private TextView mEndTime, mCurrentTime; + private boolean mDragging; + private boolean mUseFastForward; + private boolean mListenersSet; + private boolean mShowNext, mShowPrev; + private View.OnClickListener mNextListener, mPrevListener; + private StringBuilder mFormatBuilder; + private Formatter mFormatter; + private ImageButton mPauseButton; + private ImageButton mFfwdButton; + private ImageButton mRewButton; + private ImageButton mNextButton; + private ImageButton mPrevButton; + + public MediaController(Context context, AttributeSet attrs) { + super(context, attrs); + mContext = context; + mUseFastForward = true; + LayoutInflater inflate = + (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflate.inflate(R.layout.media_controller, this, true); + initControllerView(); + } + + public MediaController(Context context, boolean useFastForward) { + super(context); + mContext = context; + mUseFastForward = useFastForward; + } + + public MediaController(Context context) { + this(context, true); + } + + public void setDelegate(Delegate delegate) { + mDelegate = delegate; + updatePausePlay(); + } + + private void initControllerView() { + mPauseButton = (ImageButton) findViewById(R.id.pause); + if (mPauseButton != null) { + mPauseButton.requestFocus(); + mPauseButton.setOnClickListener(mPauseListener); + } + + mFfwdButton = (ImageButton) findViewById(R.id.ffwd); + if (mFfwdButton != null) { + mFfwdButton.setOnClickListener(mFfwdListener); + mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); + } + + mRewButton = (ImageButton) findViewById(R.id.rew); + if (mRewButton != null) { + mRewButton.setOnClickListener(mRewListener); + mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); + } + + // By default these are hidden. They will be enabled when setPrevNextListeners() is called + mNextButton = (ImageButton) findViewById(R.id.next); + if (mNextButton != null && !mListenersSet) { + mNextButton.setVisibility(View.GONE); + } + mPrevButton = (ImageButton) findViewById(R.id.prev); + if (mPrevButton != null && !mListenersSet) { + mPrevButton.setVisibility(View.GONE); + } + + mProgressGroup = (ViewGroup) findViewById(R.id.mediacontroller_progress_container); + + if (mProgressGroup != null) { + mProgressBar = (SeekBar) mProgressGroup.findViewById(R.id.mediacontroller_progress_bar); + if (mProgressBar != null) { + mProgressBar.setOnSeekBarChangeListener(mSeekListener); + mProgressBar.setMax(1000); + } + } + + mEndTime = (TextView) findViewById(R.id.time); + mCurrentTime = (TextView) findViewById(R.id.time_current); + mFormatBuilder = new StringBuilder(); + mFormatter = new Formatter(mFormatBuilder, Locale.getDefault()); + + installPrevNextListeners(); + } + + /** + * Disable pause or seek buttons if the stream cannot be paused or seeked. + * This requires the control interface to be a MediaPlayerControlExt + */ + void updateButtons() { + if (mDelegate == null) return; + + long flags = mDelegate.getActionFlags(); + boolean enabled = isEnabled(); + if (mPauseButton != null) { + boolean needPlayPauseButton = (flags & PlaybackStateCompat.ACTION_PLAY) != 0 + || (flags & PlaybackStateCompat.ACTION_PAUSE) != 0; + mPauseButton.setEnabled(enabled && needPlayPauseButton); + } + if (mRewButton != null) { + mRewButton.setEnabled(enabled && (flags & PlaybackStateCompat.ACTION_REWIND) != 0); + } + if (mFfwdButton != null) { + mFfwdButton.setEnabled( + enabled && (flags & PlaybackStateCompat.ACTION_FAST_FORWARD) != 0); + } + if (mPrevButton != null) { + mShowPrev = + (flags & PlaybackStateCompat.ACTION_SKIP_TO_NEXT) != 0 || mPrevListener != null; + mPrevButton.setEnabled(enabled && mShowPrev); + } + if (mNextButton != null) { + mShowNext = (flags & PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS) != 0 + || mNextListener != null; + mNextButton.setEnabled(enabled && mShowNext); + } + } + + public void refresh() { + updateProgress(); + updateButtons(); + updatePausePlay(); + } + + private String stringForTime(int timeMs) { + int totalSeconds = timeMs / 1000; + + int seconds = totalSeconds % 60; + int minutes = (totalSeconds / 60) % 60; + int hours = totalSeconds / 3600; + + mFormatBuilder.setLength(0); + if (hours > 0) { + return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString(); + } else { + return mFormatter.format("%02d:%02d", minutes, seconds).toString(); + } + } + + public long updateProgress() { + if (mDelegate == null || mDragging) return 0; + + long position = mDelegate.getPosition(); + long duration = mDelegate.getDuration(); + if (duration <= 0) { + // If there is no valid duration, hide the progress bar and time indicators. + if (mProgressGroup != null) mProgressGroup.setVisibility(View.INVISIBLE); + } else if (mProgressBar != null) { + if (mProgressGroup != null) mProgressGroup.setVisibility(View.VISIBLE); + // use long to avoid overflow + long pos = 1000L * position / duration; + mProgressBar.setProgress((int) pos); + mProgressBar.setSecondaryProgress((int) pos); + } + + if (mEndTime != null) mEndTime.setText(stringForTime((int) duration)); + if (mCurrentTime != null) mCurrentTime.setText(stringForTime((int) position)); + + return position; + } + + private View.OnClickListener mPauseListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + doPauseResume(); + } + }; + + private void updatePausePlay() { + if (mDelegate == null || mPauseButton == null) return; + + if (mDelegate.isPlaying()) { + mPauseButton.setImageResource(android.R.drawable.ic_media_pause); + } else { + mPauseButton.setImageResource(android.R.drawable.ic_media_play); + } + } + + private void doPauseResume() { + if (mDelegate == null) return; + + if (mDelegate.isPlaying()) { + mDelegate.pause(); + } else { + mDelegate.play(); + } + updatePausePlay(); + } + + // There are two scenarios that can trigger the seekbar listener to trigger: + // + // The first is the user using the touchpad to adjust the posititon of the + // seekbar's thumb. In this case onStartTrackingTouch is called followed by + // a number of onProgressChanged notifications, concluded by onStopTrackingTouch. + // We're setting the field "mDragging" to true for the duration of the dragging + // session to avoid jumps in the position in case of ongoing playback. + // + // The second scenario involves the user operating the scroll ball, in this + // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications, + // we will simply apply the updated position without suspending regular updates. + private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() { + @Override + public void onStartTrackingTouch(SeekBar bar) { + mDragging = true; + } + + @Override + public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { + if (mDelegate == null) return; + + if (!fromuser) { + // We're not interested in programmatically generated changes to + // the progress bar's position. + return; + } + + long duration = mDelegate.getDuration(); + long newposition = (duration * progress) / 1000L; + mDelegate.seekTo(newposition); + if (mCurrentTime != null) mCurrentTime.setText(stringForTime((int) newposition)); + } + + @Override + public void onStopTrackingTouch(SeekBar bar) { + mDragging = false; + updateProgress(); + updatePausePlay(); + } + }; + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + updateButtons(); + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(MediaController.class.getName()); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(MediaController.class.getName()); + } + + private View.OnClickListener mRewListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mDelegate == null) return; + + long pos = mDelegate.getPosition(); + pos -= 5000; // milliseconds + mDelegate.seekTo(pos); + updateProgress(); + } + }; + + private View.OnClickListener mFfwdListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mDelegate == null) return; + + long pos = mDelegate.getPosition(); + pos += 15000; // milliseconds + mDelegate.seekTo(pos); + updateProgress(); + } + }; + + private void installPrevNextListeners() { + if (mNextButton != null) { + mNextButton.setOnClickListener(mNextListener); + mNextButton.setEnabled(mShowNext); + } + + if (mPrevButton != null) { + mPrevButton.setOnClickListener(mPrevListener); + mPrevButton.setEnabled(mShowPrev); + } + } + + public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) { + mNextListener = next; + mPrevListener = prev; + mListenersSet = true; + + installPrevNextListeners(); + + if (mNextButton != null) { + mNextButton.setVisibility(View.VISIBLE); + mShowNext = true; + } + if (mPrevButton != null) { + mPrevButton.setVisibility(View.VISIBLE); + mShowPrev = true; + } + } +}
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt index e9c4d4bd..04d47f04 100644 --- a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt +++ b/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt
@@ -5,3 +5,4 @@ v1.3 db5eaf6e83a10e809b96375212d5c9dbbe517624 v1.4 9afe32eb4676d4bcceae81605a3be6aa0e5be3d5 v1.5 a02e2f95aa6f741f2be0ae03a4829e21fd749cf3 +v1.6 43b876df3398687dfa1ae059ef2f64009c76254e
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 index 40e771c..5c6216fb6 100644 --- a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 +++ b/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1
@@ -1 +1 @@ -a02e2f95aa6f741f2be0ae03a4829e21fd749cf3 \ No newline at end of file +43b876df3398687dfa1ae059ef2f64009c76254e \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt index 06abccf..7b87608 100644 --- a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt +++ b/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt
@@ -8,3 +8,4 @@ vvv 64-bit v1.4 3e0cc24655847c7b922149754324a189e7092310 v1.5 5d6d55728c7c728cef5416f37b0b71615719474e +v1.6 abcdae2281956a76aa3b98d2e8f05a1975170dd0
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 index 33fec988..2877b099 100644 --- a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 +++ b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1
@@ -1 +1 @@ -5d6d55728c7c728cef5416f37b0b71615719474e \ No newline at end of file +abcdae2281956a76aa3b98d2e8f05a1975170dd0 \ No newline at end of file
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index e66118f6..17a0858 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -287,6 +287,7 @@ <classpathentry kind="lib" path="out/Debug/lib.java/sync/android/sync_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/sync/test_support_proto_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_data_chart/android_data_chart_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_media/android_media_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_protobuf/protobuf_nano_javalib.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_swipe_refresh/android_swipe_refresh_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/cacheinvalidation/cacheinvalidation_javalib.jar"/>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 79756bc..0afb7ec 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3408,6 +3408,8 @@ <int value="3" label="Direct pixel write."/> <int value="4" label="Draw image of animated 2d canvas"/> <int value="5" label="Sub-pixel text anti-aliasing support (expect 0)"/> + <int value="6" label="drawImage called with a texture backed source image"/> + <int value="7" label="Running on low-end device"/> </enum> <enum name="CanvasHibernationEvent" type="int"> @@ -15073,6 +15075,7 @@ label="HTMLOListElementStartGetterReversedWithoutStartAttribute"/> <int value="2012" label="CredentialManagerPreventSilentAccess"/> <int value="2013" label="NetInfoEffectiveType"/> + <int value="2014" label="V8SpeechRecognition_Start_Method"/> </enum> <enum name="FeedbackSource" type="int"> @@ -21683,6 +21686,7 @@ <int value="-1463410070" label="IPH_DemoMode:enabled"/> <int value="-1460462432" label="disable-media-source"/> <int value="-1456004000" label="VrShell:disabled"/> + <int value="-1450576851" label="OmniboxUIExperimentVerticalLayout:enabled"/> <int value="-1443796945" label="OfflinePagesSharing:disabled"/> <int value="-1440440375" label="WebVrAutopresent:enabled"/> <int value="-1440152291" label="disable-gesture-typing"/> @@ -22445,6 +22449,7 @@ <int value="1318073661" label="MaterialDesignExtensions:enabled"/> <int value="1319725131" label="enable-distance-field-text"/> <int value="1320201920" label="enable-touchpad-three-finger-click"/> + <int value="1330264457" label="OmniboxUIExperimentVerticalLayout:disabled"/> <int value="1344833841" label="ImeThread:enabled"/> <int value="1351830811" label="do-not-ignore-autocomplete-off"/> <int value="1352447982" label="enable-lcd-text"/>
diff --git a/tools/perf/page_sets/webrtc_cases.py b/tools/perf/page_sets/webrtc_cases.py index 50e5e57..a6cacbaf 100644 --- a/tools/perf/page_sets/webrtc_cases.py +++ b/tools/perf/page_sets/webrtc_cases.py
@@ -140,5 +140,9 @@ class WebrtcExpectations(story.expectations.StoryExpectations): def SetExpectations(self): - self.DisableStory('multiple_peerconnections', [story.expectations.ALL], + self.DisableStory('multiple_peerconnections', + [story.expectations.ALL], 'crbug.com/725502') + self.DisableStory('30s_datachannel_transfer', + [story.expectations.ALL_DESKTOP], + 'crbug.com/726811')
diff --git a/ui/aura/mus/window_manager_delegate.h b/ui/aura/mus/window_manager_delegate.h index e1876e56..8ba30ad 100644 --- a/ui/aura/mus/window_manager_delegate.h +++ b/ui/aura/mus/window_manager_delegate.h
@@ -91,6 +91,13 @@ // DisplayInitParams on the returned object. virtual WindowTreeHostMusInitParams CreateInitParamsForNewDisplay() = 0; + // Configures the displays. This is used when the window manager manually + // configures display roots. + virtual void SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id) = 0; + protected: virtual ~WindowManagerClient() {} };
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 5b3a58f..0b93d12 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -193,6 +193,12 @@ GetWindowTreeHostMus(target)->SendEventToSink(event); } +// Use for acks from mus that are expected to always succeed and if they don't +// a crash is triggered. +void OnAckMustSucceed(bool success) { + CHECK(success); +} + } // namespace WindowTreeClient::WindowTreeClient( @@ -1869,6 +1875,18 @@ window_manager_client_->WmRequestClose(WindowMus::Get(window)->server_id()); } +void WindowTreeClient::SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id) { + DCHECK_EQ(displays.size(), viewport_metrics.size()); + if (window_manager_client_) { + window_manager_client_->SetDisplayConfiguration( + displays, std::move(viewport_metrics), primary_display_id, + base::Bind(&OnAckMustSucceed)); + } +} + void WindowTreeClient::OnWindowTreeHostBoundsWillChange( WindowTreeHostMus* window_tree_host, const gfx::Rect& bounds) {
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index 41a22f9..06acb9a 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -477,6 +477,10 @@ void RequestClose(Window* window) override; bool WaitForInitialDisplays() override; WindowTreeHostMusInitParams CreateInitParamsForNewDisplay() override; + void SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id) override; // Overriden from WindowTreeHostMusDelegate: void OnWindowTreeHostBoundsWillChange(WindowTreeHostMus* window_tree_host,
diff --git a/ui/aura/test/mus/test_window_manager_client.cc b/ui/aura/test/mus/test_window_manager_client.cc index 11154fb7..0131e12 100644 --- a/ui/aura/test/mus/test_window_manager_client.cc +++ b/ui/aura/test/mus/test_window_manager_client.cc
@@ -44,6 +44,12 @@ Id window_id, const SetDisplayRootCallback& callback) {} +void TestWindowManagerClient::SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<::ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id, + const SetDisplayConfigurationCallback& callback) {} + void TestWindowManagerClient::WmResponse(uint32_t change_id, bool response) {} void TestWindowManagerClient::WmSetBoundsResponse(uint32_t change_id) {}
diff --git a/ui/aura/test/mus/test_window_manager_client.h b/ui/aura/test/mus/test_window_manager_client.h index 468f6d1..87373d231 100644 --- a/ui/aura/test/mus/test_window_manager_client.h +++ b/ui/aura/test/mus/test_window_manager_client.h
@@ -41,6 +41,11 @@ bool is_primary_display, Id window_id, const SetDisplayRootCallback& callback) override; + void SetDisplayConfiguration( + const std::vector<display::Display>& displays, + std::vector<::ui::mojom::WmViewportMetricsPtr> viewport_metrics, + int64_t primary_display_id, + const SetDisplayConfigurationCallback& callback) override; void WmResponse(uint32_t change_id, bool response) override; void WmSetBoundsResponse(uint32_t change_id) override; void WmRequestClose(Id transport_window_id) override;
diff --git a/ui/display/display.h b/ui/display/display.h index 03c9ddd..acb4535 100644 --- a/ui/display/display.h +++ b/ui/display/display.h
@@ -209,6 +209,8 @@ Rotation rotation_ = ROTATE_0; TouchSupport touch_support_ = TOUCH_SUPPORT_UNKNOWN; gfx::Size maximum_cursor_size_; + // NOTE: this is not currently written to the mojom as it is not used in + // aura. gfx::ICCProfile icc_profile_; int color_depth_; int depth_per_component_;
diff --git a/ui/display/display_list.cc b/ui/display/display_list.cc index b5f830a..74eb5c9b 100644 --- a/ui/display/display_list.cc +++ b/ui/display/display_list.cc
@@ -52,6 +52,13 @@ return base::WrapUnique(new DisplayListObserverLock(this)); } +void DisplayList::AddOrUpdateDisplay(const Display& display, Type type) { + if (FindDisplayById(display.id()) == displays_.end()) + AddDisplay(display, type); + else + UpdateDisplay(display, type); +} + uint32_t DisplayList::UpdateDisplay(const Display& display) { return UpdateDisplay(display, GetTypeByDisplayId(display.id())); }
diff --git a/ui/display/display_list.h b/ui/display/display_list.h index 20a454d..295dc3f 100644 --- a/ui/display/display_list.h +++ b/ui/display/display_list.h
@@ -64,6 +64,8 @@ // callers release the last lock they call the observers appropriately. std::unique_ptr<DisplayListObserverLock> SuspendObserverUpdates(); + void AddOrUpdateDisplay(const Display& display, Type type); + // Updates the cached display based on display.id(). This returns a bitmask // of the changed values suitable for passing to // DisplayObserver::OnDisplayMetricsChanged().
diff --git a/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc b/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc index 6724c75..ecd4513 100644 --- a/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc
@@ -56,7 +56,7 @@ MapValue(abs_info.value, &tmp); } -bool GamepadEventConverterEvdev::Axis::MapValue(uint16_t value, +bool GamepadEventConverterEvdev::Axis::MapValue(int value, double* mapped_value) { *mapped_value = value * scale_ + offset_; // As the definition of linux input_absinfo.flat, value within the range of @@ -185,7 +185,7 @@ void GamepadEventConverterEvdev::ProcessEvdevKey( uint16_t code, - uint16_t value, + int value, const base::TimeTicks& timestamp) { GamepadEventType mapped_type; uint16_t mapped_code; @@ -203,7 +203,7 @@ void GamepadEventConverterEvdev::ProcessEvdevAbs( uint16_t code, - uint16_t value, + int value, const base::TimeTicks& timestamp) { GamepadEventType mapped_type; uint16_t mapped_code;
diff --git a/ui/events/ozone/evdev/gamepad_event_converter_evdev.h b/ui/events/ozone/evdev/gamepad_event_converter_evdev.h index 7ec4d2a1..d1f233a 100644 --- a/ui/events/ozone/evdev/gamepad_event_converter_evdev.h +++ b/ui/events/ozone/evdev/gamepad_event_converter_evdev.h
@@ -46,12 +46,12 @@ private: // This function processes EV_KEY event from gamepad device. void ProcessEvdevKey(uint16_t code, - uint16_t value, + int value, const base::TimeTicks& timestamp); // This function processes EV_ABS event from gamepad device. void ProcessEvdevAbs(uint16_t code, - uint16_t value, + int value, const base::TimeTicks& timestamp); // This function releases all the keys and resets all the axises. @@ -82,7 +82,7 @@ GamepadEventType mapped_type, uint16_t mapped_code); - bool MapValue(uint16_t value, double* mapped_value); + bool MapValue(int value, double* mapped_value); GamepadEventType mapped_type();