diff --git a/BUILD.gn b/BUILD.gn index ff313e6..dc6b3d3 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -130,7 +130,6 @@ "//base:base_unittests", "//chrome/test:browser_tests", "//chrome/test:sync_integration_tests", - "//components/sync:sync_unit_tests", "//ipc:ipc_tests", "//media:media_unittests", "//media/midi:midi_unittests", @@ -185,7 +184,6 @@ "//base:base_unittests", "//chrome/installer", "//components:components_unittests", - "//components/sync:sync_unit_tests", "//net:net_unittests", "//skia:skia_unittests", "//sql:sql_unittests",
diff --git a/DEPS b/DEPS index 2431f726..2874103 100644 --- a/DEPS +++ b/DEPS
@@ -36,11 +36,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '2825bad08cc2ad63f0f11f50039c944914d07e0a', + 'skia_revision': 'ac09554dce518e9d4496771f648f3ae17eca857c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '17edea67a345a36f19a6ef15dd34edb2c88b2cc1', + 'v8_revision': '61be62536ea2689143396ddca6047016be8be5d2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -52,11 +52,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. - 'buildtools_revision': '88c6fc5bde77b9477345f0885cd88d4a57ad1844', + 'buildtools_revision': '9c6ad6f5cbc2f30989edc3504ec7f9d360542512', # 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': 'a72ab5e0908ca29cfda91b3037da9b74cb06b93f', + 'pdfium_revision': '32e693fe13105fab5baf81b334e932fce62d89b5', # 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. @@ -88,7 +88,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': 'd7bc1bf8cb0bcbf2dd998828cc65486b901db11d', + 'catapult_revision': 'd99dc42eec5fb0068857eb9e921940105a3e2a7d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -178,7 +178,7 @@ Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0', 'src/third_party/webgl/src': - Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'e3488c31e13202c8d41b92eb6b7358cd23e5e004', + Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'b57946dc8d26325c332f3644c646dcc795c68bdc', 'src/third_party/webdriver/pylib': Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
diff --git a/android_webview/browser/surfaces_instance.h b/android_webview/browser/surfaces_instance.h index eb01f71..5dec3d8b 100644 --- a/android_webview/browser/surfaces_instance.h +++ b/android_webview/browser/surfaces_instance.h
@@ -61,6 +61,10 @@ // cc::DisplayClient overrides. void DisplayOutputSurfaceLost() override {} void DisplaySetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {} + void DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const cc::RenderPassList& render_passes) override {} + void DisplayDidDrawAndSwap() override {} // cc::SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override;
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc index f149041..be7a4ae 100644 --- a/android_webview/native/aw_autofill_client.cc +++ b/android_webview/native/aw_autofill_client.cc
@@ -242,6 +242,12 @@ NOTIMPLEMENTED(); } +void AwAutofillClient::ConfirmCreditCardFillAssist( + const autofill::CreditCard& card, + const base::Closure& callback) { + NOTIMPLEMENTED(); +} + void AwAutofillClient::LoadRiskData( const base::Callback<void(const std::string&)>& callback) { NOTIMPLEMENTED();
diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h index ca4119d..ec350f5 100644 --- a/android_webview/native/aw_autofill_client.h +++ b/android_webview/native/aw_autofill_client.h
@@ -78,6 +78,8 @@ const autofill::CreditCard& card, std::unique_ptr<base::DictionaryValue> legal_message, const base::Closure& callback) override; + void ConfirmCreditCardFillAssist(const autofill::CreditCard& card, + const base::Closure& callback) override; void LoadRiskData( const base::Callback<void(const std::string&)>& callback) override; bool HasCreditCardScanFeature() override;
diff --git a/apps/DEPS b/apps/DEPS index d1ec499..f524516 100644 --- a/apps/DEPS +++ b/apps/DEPS
@@ -45,9 +45,11 @@ "(.*test\.cc|.*test_mac\.mm)": [ "+chrome/browser/browser_shutdown.h", "+chrome/browser/extensions/extension_browsertest.h", + "+chrome/browser/extensions/extension_error_reporter.h", "+chrome/browser/extensions/extension_test_message_listener.h", "+chrome/browser/extensions/test_extension_environment.h", "+chrome/browser/ui/browser.h", + "+chrome/browser/ui/simple_message_box_internal.h", "+chrome/test/base/in_process_browser_test.h", "+chrome/test/base/interactive_test_utils.h", "+chrome/test/base/testing_profile.h",
diff --git a/apps/app_load_service.cc b/apps/app_load_service.cc index eb4b5c6..c89a369 100644 --- a/apps/app_load_service.cc +++ b/apps/app_load_service.cc
@@ -64,8 +64,9 @@ ExtensionService* extension_service = ExtensionSystem::Get(profile_)->extension_service(); std::string extension_id; - if (!extensions::UnpackedInstaller::Create(extension_service)-> - LoadFromCommandLine(base::FilePath(extension_path), &extension_id)) { + if (!extensions::UnpackedInstaller::Create(extension_service) + ->LoadFromCommandLine(base::FilePath(extension_path), &extension_id, + true /* only_allow_apps */)) { return false; } @@ -81,8 +82,9 @@ ExtensionService* extension_service = ExtensionSystem::Get(profile_)->extension_service(); std::string extension_id; - return extensions::UnpackedInstaller::Create(extension_service)-> - LoadFromCommandLine(base::FilePath(extension_path), &extension_id); + return extensions::UnpackedInstaller::Create(extension_service) + ->LoadFromCommandLine(base::FilePath(extension_path), &extension_id, + true /* only_allow_apps */); } // static
diff --git a/apps/load_and_launch_browsertest.cc b/apps/load_and_launch_browsertest.cc index fc95dae..330a4f44 100644 --- a/apps/load_and_launch_browsertest.cc +++ b/apps/load_and_launch_browsertest.cc
@@ -8,13 +8,17 @@ #include "apps/switches.h" #include "base/process/launch.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/test_timeouts.h" #include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/simple_message_box_internal.h" #include "chrome/common/chrome_switches.h" #include "content/public/common/content_switches.h" #include "content/public/test/test_launcher.h" +#include "extensions/browser/extension_registry.h" #include "extensions/test/extension_test_message_listener.h" using extensions::PlatformAppBrowserTest; @@ -28,6 +32,8 @@ switches::kNoSandbox, }; +constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj"; + } // namespace // TODO(jackhou): Enable this test once it works on OSX. It currently does not @@ -112,18 +118,17 @@ namespace { -// TestFixture that appends --load-and-launch-app before calling BrowserMain. -class PlatformAppLoadAndLaunchBrowserTest : public PlatformAppBrowserTest { +// TestFixture that appends --load-and-launch-app with an app before calling +// BrowserMain. +class LoadAndLaunchPlatformAppBrowserTest : public PlatformAppBrowserTest { protected: - PlatformAppLoadAndLaunchBrowserTest() {} + LoadAndLaunchPlatformAppBrowserTest() {} void SetUpCommandLine(base::CommandLine* command_line) override { PlatformAppBrowserTest::SetUpCommandLine(command_line); - app_path_ = test_data_dir_ - .AppendASCII("platform_apps") - .AppendASCII("minimal"); - command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, - app_path_.value()); + base::FilePath app_path = + test_data_dir_.AppendASCII("platform_apps").AppendASCII("minimal"); + command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, app_path.value()); } void LoadAndLaunchApp() { @@ -136,9 +141,32 @@ } private: - base::FilePath app_path_; + DISALLOW_COPY_AND_ASSIGN(LoadAndLaunchPlatformAppBrowserTest); +}; - DISALLOW_COPY_AND_ASSIGN(PlatformAppLoadAndLaunchBrowserTest); +// TestFixture that appends --load-and-launch-app with an extension before +// calling BrowserMain. +class LoadAndLaunchExtensionBrowserTest : public PlatformAppBrowserTest { + protected: + LoadAndLaunchExtensionBrowserTest() {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + PlatformAppBrowserTest::SetUpCommandLine(command_line); + base::FilePath app_path = test_data_dir_.AppendASCII("good") + .AppendASCII("Extensions") + .AppendASCII(kTestExtensionId) + .AppendASCII("1.0.0.0"); + command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, app_path.value()); + } + + void SetUpInProcessBrowserTestFixture() override { + PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture(); + + // Skip showing the error message box to avoid freezing the main thread. + chrome::internal::g_should_skip_message_box_for_test = true; + } + + DISALLOW_COPY_AND_ASSIGN(LoadAndLaunchExtensionBrowserTest); }; } // namespace @@ -155,9 +183,32 @@ #endif // Case where Chrome is not running. -IN_PROC_BROWSER_TEST_F(PlatformAppLoadAndLaunchBrowserTest, +IN_PROC_BROWSER_TEST_F(LoadAndLaunchPlatformAppBrowserTest, MAYBE_LoadAndLaunchAppChromeNotRunning) { LoadAndLaunchApp(); } +IN_PROC_BROWSER_TEST_F(LoadAndLaunchExtensionBrowserTest, + LoadAndLaunchExtension) { + const std::vector<base::string16>* errors = + ExtensionErrorReporter::GetInstance()->GetErrors(); + +#if defined(GOOGLE_CHROME_BUILD) + // The error is skipped on official builds. + EXPECT_TRUE(errors->empty()); +#else + // Expect |extension_instead_of_app_error|. + EXPECT_EQ(1u, errors->size()); + EXPECT_NE(base::string16::npos, + errors->at(0).find(base::ASCIIToUTF16( + "App loading flags cannot be used to load extensions"))); +#endif + + extensions::ExtensionRegistry* registry = + extensions::ExtensionRegistry::Get(profile()); + EXPECT_EQ(nullptr, + registry->GetExtensionById( + kTestExtensionId, extensions::ExtensionRegistry::EVERYTHING)); +} + } // namespace apps
diff --git a/ash/mus/window_manager_application.cc b/ash/mus/window_manager_application.cc index 8e6aec9..66aab81 100644 --- a/ash/mus/window_manager_application.cc +++ b/ash/mus/window_manager_application.cc
@@ -78,7 +78,7 @@ // Destroy the WindowManager while still valid. This way we ensure // OnWillDestroyRootWindowController() is called (if it hasn't been already). window_manager_.reset(); - + gpu_service_.reset(); ShutdownComponents(); } @@ -96,7 +96,7 @@ } void WindowManagerApplication::OnStart(const shell::Identity& identity) { - ui::GpuService::Initialize(connector()); + gpu_service_ = ui::GpuService::Initialize(connector()); window_manager_.reset(new WindowManager(connector())); aura_init_.reset(new views::AuraInit(connector(), "ash_mus_resources.pak"));
diff --git a/ash/mus/window_manager_application.h b/ash/mus/window_manager_application.h index d2f4d27b..15b6d88 100644 --- a/ash/mus/window_manager_application.h +++ b/ash/mus/window_manager_application.h
@@ -28,6 +28,7 @@ namespace ui { class Event; +class GpuService; class WindowTreeClient; } @@ -108,6 +109,7 @@ std::vector<mojo::InterfaceRequest<mojom::UserWindowController>> user_window_controller_requests_; + std::unique_ptr<ui::GpuService> gpu_service_; std::unique_ptr<WindowManager> window_manager_; std::set<AcceleratorRegistrarImpl*> accelerator_registrars_;
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 512b88fa..737785cb 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -194,8 +194,7 @@ // ShelfLayoutManager ---------------------------------------------------------- ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf_widget) - : SnapToPixelLayoutManager(shelf_widget->GetNativeView()->parent()), - root_window_(shelf_widget->GetNativeView()->GetRootWindow()), + : root_window_(shelf_widget->GetNativeView()->GetRootWindow()), updating_bounds_(false), shelf_widget_(shelf_widget), workspace_controller_(NULL), @@ -500,20 +499,21 @@ } //////////////////////////////////////////////////////////////////////////////// -// ShelfLayoutManager, aura::LayoutManager implementation: +// ShelfLayoutManager, wm::WmSnapToPixelLayoutManager implementation: void ShelfLayoutManager::OnWindowResized() { LayoutShelf(); } -void ShelfLayoutManager::SetChildBounds(aura::Window* child, +void ShelfLayoutManager::SetChildBounds(WmWindow* child, const gfx::Rect& requested_bounds) { - SnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); + wm::WmSnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); // We may contain other widgets (such as frame maximize bubble) but they don't // effect the layout in anyway. if (!updating_bounds_ && - ((shelf_widget_->GetNativeView() == child) || - (shelf_widget_->status_area_widget()->GetNativeView() == child))) { + ((WmLookup::Get()->GetWindowForWidget(shelf_widget_) == child) || + (WmLookup::Get()->GetWindowForWidget( + shelf_widget_->status_area_widget()) == child))) { LayoutShelf(); } }
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index ebaa60a..1aa5039 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -14,10 +14,10 @@ #include "ash/common/wm/background_animator.h" #include "ash/common/wm/dock/docked_window_layout_manager_observer.h" #include "ash/common/wm/lock_state_observer.h" +#include "ash/common/wm/wm_snap_to_pixel_layout_manager.h" #include "ash/common/wm/workspace/workspace_types.h" #include "ash/common/wm_activation_observer.h" #include "ash/shelf/shelf_widget.h" -#include "ash/snap_to_pixel_layout_manager.h" #include "ash/wm/gestures/shelf_gesture_handler.h" #include "base/macros.h" #include "base/observer_list.h" @@ -52,7 +52,7 @@ public DockedWindowLayoutManagerObserver, public keyboard::KeyboardControllerObserver, public LockStateObserver, - public SnapToPixelLayoutManager, + public wm::WmSnapToPixelLayoutManager, public SessionStateObserver { public: explicit ShelfLayoutManager(ShelfWidget* shelf_widget); @@ -131,9 +131,9 @@ // shelf. Specifying 0 leads to use the default. void SetAnimationDurationOverride(int duration_override_in_ms); - // Overridden from SnapLayoutManager: + // Overridden from wm::WmSnapToPixelLayoutManager: void OnWindowResized() override; - void SetChildBounds(aura::Window* child, + void SetChildBounds(WmWindow* child, const gfx::Rect& requested_bounds) override; // Overridden from ShellObserver:
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 4a9d08f..d57e62c 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -24,6 +24,7 @@ #include "ash/shell.h" #include "ash/wm/status_area_layout_manager.h" #include "ash/wm/workspace_controller.h" +#include "base/memory/ptr_util.h" #include "grit/ash_resources.h" #include "ui/aura/window.h" #include "ui/base/resource/resource_bundle.h" @@ -364,9 +365,7 @@ shelf_layout_manager_ = new ShelfLayoutManager(this); shelf_layout_manager_->AddObserver(this); - aura::Window* shelf_container = - WmWindowAura::GetAuraWindow(wm_shelf_container); - shelf_container->SetLayoutManager(shelf_layout_manager_); + wm_shelf_container->SetLayoutManager(base::WrapUnique(shelf_layout_manager_)); shelf_layout_manager_->set_workspace_controller(workspace_controller); workspace_controller->SetShelf(shelf_layout_manager_); background_animator_.PaintBackground( @@ -382,12 +381,13 @@ status_area_widget_->Show(); WmShell::Get()->focus_cycler()->AddWidget(status_area_widget_); background_animator_.AddObserver(status_area_widget_); + wm_status_container->SetLayoutManager( + base::MakeUnique<StatusAreaLayoutManager>(this)); + aura::Window* shelf_container = + WmWindowAura::GetAuraWindow(wm_shelf_container); aura::Window* status_container = WmWindowAura::GetAuraWindow(wm_status_container); - status_container->SetLayoutManager( - new StatusAreaLayoutManager(status_container, this)); - shelf_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( new ShelfWindowTargeter(shelf_container, shelf_layout_manager_))); status_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
diff --git a/ash/wm/status_area_layout_manager.cc b/ash/wm/status_area_layout_manager.cc index 8eb8bc2..7c3a0fd2 100644 --- a/ash/wm/status_area_layout_manager.cc +++ b/ash/wm/status_area_layout_manager.cc
@@ -5,20 +5,19 @@ #include "ash/wm/status_area_layout_manager.h" #include "ash/common/system/status_area_widget.h" +#include "ash/common/wm_lookup.h" +#include "ash/common/wm_window.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shelf/shelf_widget.h" #include "base/auto_reset.h" -#include "ui/aura/window.h" -#include "ui/views/widget/widget.h" namespace ash { //////////////////////////////////////////////////////////////////////////////// // StatusAreaLayoutManager, public: -StatusAreaLayoutManager::StatusAreaLayoutManager(aura::Window* container, - ShelfWidget* shelf) - : SnapToPixelLayoutManager(container), in_layout_(false), shelf_(shelf) {} +StatusAreaLayoutManager::StatusAreaLayoutManager(ShelfWidget* shelf_widget) + : in_layout_(false), shelf_widget_(shelf_widget) {} StatusAreaLayoutManager::~StatusAreaLayoutManager() {} @@ -30,12 +29,15 @@ } void StatusAreaLayoutManager::SetChildBounds( - aura::Window* child, + WmWindow* child, const gfx::Rect& requested_bounds) { // Only need to have the shelf do a layout if the child changing is the status // area and the shelf isn't in the process of doing a layout. - if (child != shelf_->status_area_widget()->GetNativeView() || in_layout_) { - SnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); + if (child != + WmLookup::Get()->GetWindowForWidget( + shelf_widget_->status_area_widget()) || + in_layout_) { + wm::WmSnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); return; } @@ -44,7 +46,7 @@ if (requested_bounds == child->GetTargetBounds()) return; - SnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); + wm::WmSnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); LayoutStatusArea(); } @@ -53,11 +55,11 @@ void StatusAreaLayoutManager::LayoutStatusArea() { // Shelf layout manager may be already doing layout. - if (shelf_->shelf_layout_manager()->updating_bounds()) + if (shelf_widget_->shelf_layout_manager()->updating_bounds()) return; base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); - shelf_->shelf_layout_manager()->LayoutShelf(); + shelf_widget_->shelf_layout_manager()->LayoutShelf(); } } // namespace ash
diff --git a/ash/wm/status_area_layout_manager.h b/ash/wm/status_area_layout_manager.h index 77a844d2..9d276ae 100644 --- a/ash/wm/status_area_layout_manager.h +++ b/ash/wm/status_area_layout_manager.h
@@ -5,25 +5,24 @@ #ifndef ASH_WM_STATUS_AREA_LAYOUT_MANAGER_H_ #define ASH_WM_STATUS_AREA_LAYOUT_MANAGER_H_ -#include "ash/snap_to_pixel_layout_manager.h" -#include "base/compiler_specific.h" +#include "ash/common/wm/wm_snap_to_pixel_layout_manager.h" #include "base/macros.h" -#include "ui/aura/layout_manager.h" namespace ash { + class ShelfWidget; // StatusAreaLayoutManager is a layout manager responsible for the status area. // In any case when status area needs relayout it redirects this call to // ShelfLayoutManager. -class StatusAreaLayoutManager : public SnapToPixelLayoutManager { +class StatusAreaLayoutManager : public wm::WmSnapToPixelLayoutManager { public: - StatusAreaLayoutManager(aura::Window* container, ShelfWidget* shelf); + explicit StatusAreaLayoutManager(ShelfWidget* shelf_widget); ~StatusAreaLayoutManager() override; - // Overridden from aura::LayoutManager: + // Overridden from wm::WmSnapToPixelLayoutManager: void OnWindowResized() override; - void SetChildBounds(aura::Window* child, + void SetChildBounds(WmWindow* child, const gfx::Rect& requested_bounds) override; private: @@ -35,7 +34,7 @@ // Used to prevent calling itself again from SetChildBounds(). bool in_layout_; - ShelfWidget* shelf_; + ShelfWidget* shelf_widget_; DISALLOW_COPY_AND_ASSIGN(StatusAreaLayoutManager); };
diff --git a/base/synchronization/lock.h b/base/synchronization/lock.h index c2680cb..599984e 100644 --- a/base/synchronization/lock.h +++ b/base/synchronization/lock.h
@@ -61,13 +61,22 @@ void AssertAcquired() const; #endif // DCHECK_IS_ON() + // Whether Lock mitigates priority inversion when used from different thread + // priorities. + static bool HandlesMultipleThreadPriorities() { #if defined(OS_POSIX) - // Whether this platform has priority inheritance available. All locks will - // attempt to use the priority inheritance version if available. - static bool PriorityInheritanceAvailable() { + // POSIX mitigates priority inversion by setting the priority of a thread + // holding a Lock to the maximum priority of any other thread waiting on it. return internal::LockImpl::PriorityInheritanceAvailable(); - } +#elif defined(OS_WIN) + // Windows mitigates priority inversion by randomly boosting the priority of + // ready threads. + // https://msdn.microsoft.com/library/windows/desktop/ms684831.aspx + return true; +#else +#error Unsupported platform #endif + } #if defined(OS_POSIX) || defined(OS_WIN) // Both Windows and POSIX implementations of ConditionVariable need to be
diff --git a/base/task_scheduler/scheduler_lock_impl.cc b/base/task_scheduler/scheduler_lock_impl.cc index 7480e18..d60f259 100644 --- a/base/task_scheduler/scheduler_lock_impl.cc +++ b/base/task_scheduler/scheduler_lock_impl.cc
@@ -67,19 +67,30 @@ // Otherwise, make sure that the previous lock acquired is an allowed // predecessor. AutoLock auto_lock(allowed_predecessor_map_lock_); + // Using at() is exception-safe here as |lock| was registered already. const SchedulerLockImpl* allowed_predecessor = allowed_predecessor_map_.at(lock); DCHECK_EQ(acquired_locks->back(), allowed_predecessor); } + // Asserts that |lock|'s registered predecessor is safe. Because + // SchedulerLocks are registered at construction time and any predecessor + // specified on a SchedulerLock must already exist, the first registered + // SchedulerLock in a potential chain must have a null predecessor and is thus + // cycle-free. Any subsequent SchedulerLock with a predecessor must come from + // the set of registered SchedulerLocks. Since the registered SchedulerLocks + // only contain cycle-free SchedulerLocks, this subsequent SchedulerLock is + // itself cycle-free and may be safely added to the registered SchedulerLock + // set. void AssertSafePredecessor(const SchedulerLockImpl* lock) const { allowed_predecessor_map_lock_.AssertAcquired(); - for (const SchedulerLockImpl* predecessor = - allowed_predecessor_map_.at(lock); - predecessor != nullptr; - predecessor = allowed_predecessor_map_.at(predecessor)) { - DCHECK_NE(predecessor, lock) << - "Scheduler lock predecessor cycle detected."; + // Using at() is exception-safe here as |lock| was registered already. + const SchedulerLockImpl* predecessor = allowed_predecessor_map_.at(lock); + if (predecessor) { + DCHECK(allowed_predecessor_map_.find(predecessor) != + allowed_predecessor_map_.end()) + << "SchedulerLock was registered before its predecessor. " + << "Potential cycle detected"; } }
diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc index 6ee52aca..8e37639e 100644 --- a/base/task_scheduler/scheduler_worker.cc +++ b/base/task_scheduler/scheduler_worker.cc
@@ -49,9 +49,7 @@ mac::ScopedNSAutoreleasePool autorelease_pool; #endif -#if !defined(OS_LINUX) UpdateThreadPriority(GetDesiredThreadPriority()); -#endif // Get the sequence containing the next task to execute. scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); @@ -131,22 +129,29 @@ wake_up_event_.Reset(); } - // Returns the desired thread priority based on the worker priority and the - // current shutdown state. + // Returns the priority for which the thread should be set based on the + // priority hint, current shutdown state, and platform capabilities. ThreadPriority GetDesiredThreadPriority() { DCHECK(outer_); - if (outer_->task_tracker_->HasShutdownStarted() && - static_cast<int>(outer_->thread_priority_) < - static_cast<int>(ThreadPriority::NORMAL)) { + // All threads have a NORMAL priority when Lock doesn't handle multiple + // thread priorities. + if (!Lock::HandlesMultipleThreadPriorities()) + return ThreadPriority::NORMAL; + + // To avoid shutdown hangs, disallow a priority below NORMAL during + // shutdown. If thread priority cannot be increased, never allow a priority + // below NORMAL. + if (static_cast<int>(outer_->priority_hint_) < + static_cast<int>(ThreadPriority::NORMAL) && + (outer_->task_tracker_->HasShutdownStarted() || + !PlatformThread::CanIncreaseCurrentThreadPriority())) { return ThreadPriority::NORMAL; } - return outer_->thread_priority_; + + return outer_->priority_hint_; } - // Increasing the thread priority requires the CAP_SYS_NICE capability on - // Linux. -#if !defined(OS_LINUX) void UpdateThreadPriority(ThreadPriority desired_thread_priority) { if (desired_thread_priority == current_thread_priority_) return; @@ -154,7 +159,6 @@ PlatformThread::SetCurrentThreadPriority(desired_thread_priority); current_thread_priority_ = desired_thread_priority; } -#endif // !defined(OS_LINUX) PlatformThreadHandle thread_handle_; @@ -164,19 +168,19 @@ WaitableEvent wake_up_event_; // Current priority of this thread. May be different from - // |outer_->thread_priority_| during shutdown. + // |outer_->priority_hint_|. ThreadPriority current_thread_priority_; DISALLOW_COPY_AND_ASSIGN(Thread); }; std::unique_ptr<SchedulerWorker> SchedulerWorker::Create( - ThreadPriority thread_priority, + ThreadPriority priority_hint, std::unique_ptr<Delegate> delegate, TaskTracker* task_tracker, InitialState initial_state) { std::unique_ptr<SchedulerWorker> worker( - new SchedulerWorker(thread_priority, std::move(delegate), task_tracker)); + new SchedulerWorker(priority_hint, std::move(delegate), task_tracker)); // Creation happens before any other thread can reference this one, so no // synchronization is necessary. if (initial_state == SchedulerWorker::InitialState::ALIVE) { @@ -228,10 +232,10 @@ return !!thread_; } -SchedulerWorker::SchedulerWorker(ThreadPriority thread_priority, +SchedulerWorker::SchedulerWorker(ThreadPriority priority_hint, std::unique_ptr<Delegate> delegate, TaskTracker* task_tracker) - : thread_priority_(thread_priority), + : priority_hint_(priority_hint), delegate_(std::move(delegate)), task_tracker_(task_tracker) { DCHECK(delegate_);
diff --git a/base/task_scheduler/scheduler_worker.h b/base/task_scheduler/scheduler_worker.h index 71d4cbc..d741f95 100644 --- a/base/task_scheduler/scheduler_worker.h +++ b/base/task_scheduler/scheduler_worker.h
@@ -77,13 +77,15 @@ enum class InitialState { ALIVE, DETACHED }; - // Creates a SchedulerWorker with priority |thread_priority| that runs Tasks - // from Sequences returned by |delegate|. |task_tracker| is used to handle - // shutdown behavior of Tasks. If |worker_state| is DETACHED, the thread will - // be created upon a WakeUp(). Returns nullptr if creating the underlying - // platform thread fails during Create(). + // Creates a SchedulerWorker that runs Tasks from Sequences returned by + // |delegate|. |priority_hint| is the preferred thread priority; the actual + // thread priority depends on shutdown state and platform capabilities. + // |task_tracker| is used to handle shutdown behavior of Tasks. If + // |worker_state| is DETACHED, the thread will be created upon a WakeUp(). + // Returns nullptr if creating the underlying platform thread fails during + // Create(). static std::unique_ptr<SchedulerWorker> Create( - ThreadPriority thread_priority, + ThreadPriority priority_hint, std::unique_ptr<Delegate> delegate, TaskTracker* task_tracker, InitialState initial_state); @@ -133,7 +135,7 @@ // The underlying thread for this SchedulerWorker. std::unique_ptr<Thread> thread_; - const ThreadPriority thread_priority_; + const ThreadPriority priority_hint_; const std::unique_ptr<Delegate> delegate_; TaskTracker* const task_tracker_;
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.cc b/base/task_scheduler/scheduler_worker_pool_impl.cc index b97ce8dd..39a5e2e 100644 --- a/base/task_scheduler/scheduler_worker_pool_impl.cc +++ b/base/task_scheduler/scheduler_worker_pool_impl.cc
@@ -253,8 +253,7 @@ params.io_restriction(), params.suggested_reclaim_time(), task_tracker, delayed_task_manager)); - if (worker_pool->Initialize(params.thread_priority(), - params.max_threads(), + if (worker_pool->Initialize(params.priority_hint(), params.max_threads(), re_enqueue_sequence_callback)) { return worker_pool; } @@ -569,7 +568,7 @@ } bool SchedulerWorkerPoolImpl::Initialize( - ThreadPriority thread_priority, + ThreadPriority priority_hint, size_t max_threads, const ReEnqueueSequenceCallback& re_enqueue_sequence_callback) { AutoSchedulerLock auto_lock(idle_workers_stack_lock_); @@ -577,15 +576,12 @@ DCHECK(workers_.empty()); for (size_t i = 0; i < max_threads; ++i) { - std::unique_ptr<SchedulerWorker> worker = - SchedulerWorker::Create( - thread_priority, WrapUnique(new SchedulerWorkerDelegateImpl( - this, re_enqueue_sequence_callback, - &shared_priority_queue_, static_cast<int>(i))), - task_tracker_, - i == 0 - ? SchedulerWorker::InitialState::ALIVE - : SchedulerWorker::InitialState::DETACHED); + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( + priority_hint, WrapUnique(new SchedulerWorkerDelegateImpl( + this, re_enqueue_sequence_callback, + &shared_priority_queue_, static_cast<int>(i))), + task_tracker_, i == 0 ? SchedulerWorker::InitialState::ALIVE + : SchedulerWorker::InitialState::DETACHED); if (!worker) break; idle_workers_stack_.Push(worker.get());
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.h b/base/task_scheduler/scheduler_worker_pool_impl.h index 39ec9b8..379f3286 100644 --- a/base/task_scheduler/scheduler_worker_pool_impl.h +++ b/base/task_scheduler/scheduler_worker_pool_impl.h
@@ -104,7 +104,7 @@ DelayedTaskManager* delayed_task_manager); bool Initialize( - ThreadPriority thread_priority, + ThreadPriority priority_hint, size_t max_threads, const ReEnqueueSequenceCallback& re_enqueue_sequence_callback);
diff --git a/base/task_scheduler/scheduler_worker_pool_params.cc b/base/task_scheduler/scheduler_worker_pool_params.cc index 14ee584..d820460 100644 --- a/base/task_scheduler/scheduler_worker_pool_params.cc +++ b/base/task_scheduler/scheduler_worker_pool_params.cc
@@ -10,12 +10,12 @@ SchedulerWorkerPoolParams::SchedulerWorkerPoolParams( const std::string& name, - ThreadPriority thread_priority, + ThreadPriority priority_hint, IORestriction io_restriction, int max_threads, const TimeDelta& suggested_reclaim_time) : name_(name), - thread_priority_(thread_priority), + priority_hint_(priority_hint), io_restriction_(io_restriction), max_threads_(max_threads), suggested_reclaim_time_(suggested_reclaim_time) {}
diff --git a/base/task_scheduler/scheduler_worker_pool_params.h b/base/task_scheduler/scheduler_worker_pool_params.h index c66365b2..a084166 100644 --- a/base/task_scheduler/scheduler_worker_pool_params.h +++ b/base/task_scheduler/scheduler_worker_pool_params.h
@@ -23,25 +23,25 @@ // Construct a scheduler worker pool parameter object that instructs a // scheduler worker pool to use the label |name| and create up to - // |max_threads| threads of priority |thread_priority|. |io_restriction| - // indicates whether Tasks on the scheduler worker pool are allowed to make - // I/O calls. |suggested_reclaim_time| sets a suggestion on when to reclaim - // idle threads. The worker pool is free to ignore this value for performance - // or correctness reasons. - SchedulerWorkerPoolParams( - const std::string& name, - ThreadPriority thread_priority, - IORestriction io_restriction, - int max_threads, - const TimeDelta& suggested_reclaim_time); + // |max_threads| threads. |priority_hint| is the preferred thread priority; + // the actual thread priority depends on shutdown state and platform + // capabilities. |io_restriction| indicates whether Tasks on the scheduler + // worker pool are allowed to make I/O calls. |suggested_reclaim_time| sets a + // suggestion on when to reclaim idle threads. The worker pool is free to + // ignore this value for performance or correctness reasons. + SchedulerWorkerPoolParams(const std::string& name, + ThreadPriority priority_hint, + IORestriction io_restriction, + int max_threads, + const TimeDelta& suggested_reclaim_time); SchedulerWorkerPoolParams(SchedulerWorkerPoolParams&& other); SchedulerWorkerPoolParams& operator=(SchedulerWorkerPoolParams&& other); // Name of the pool. Used to label the pool's threads. const std::string& name() const { return name_; } - // Priority of the pool's threads. - ThreadPriority thread_priority() const { return thread_priority_; } + // Preferred priority for the pool's threads. + ThreadPriority priority_hint() const { return priority_hint_; } // Whether I/O is allowed in the pool. IORestriction io_restriction() const { return io_restriction_; } @@ -56,7 +56,7 @@ private: std::string name_; - ThreadPriority thread_priority_; + ThreadPriority priority_hint_; IORestriction io_restriction_; size_t max_threads_; TimeDelta suggested_reclaim_time_;
diff --git a/base/task_scheduler/scheduler_worker_unittest.cc b/base/task_scheduler/scheduler_worker_unittest.cc index fb94edc..ce63787 100644 --- a/base/task_scheduler/scheduler_worker_unittest.cc +++ b/base/task_scheduler/scheduler_worker_unittest.cc
@@ -474,21 +474,23 @@ } // namespace -// Increasing the thread priority requires the CAP_SYS_NICE capability on Linux. -#if !defined(OS_LINUX) TEST(TaskSchedulerWorkerTest, BumpPriorityOfAliveThreadDuringShutdown) { TaskTracker task_tracker; std::unique_ptr<ExpectThreadPriorityDelegate> delegate( new ExpectThreadPriorityDelegate); ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); - delegate_raw->SetExpectedThreadPriority(ThreadPriority::BACKGROUND); + delegate_raw->SetExpectedThreadPriority( + PlatformThread::CanIncreaseCurrentThreadPriority() + ? ThreadPriority::BACKGROUND + : ThreadPriority::NORMAL); std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, SchedulerWorker::InitialState::ALIVE); - // Verify that the initial thread priority is BACKGROUND. + // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread + // priority can't be increased). worker->WakeUp(); delegate_raw->WaitForPriorityVerifiedInGetWork(); @@ -500,7 +502,6 @@ worker->JoinForTesting(); } -#endif // defined(OS_LINUX) TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) { TaskTracker task_tracker;
diff --git a/base/task_scheduler/task_scheduler_impl_unittest.cc b/base/task_scheduler/task_scheduler_impl_unittest.cc index b49e5b9d..fe5a98f 100644 --- a/base/task_scheduler/task_scheduler_impl_unittest.cc +++ b/base/task_scheduler/task_scheduler_impl_unittest.cc
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/task_scheduler/scheduler_worker_pool_params.h" #include "base/task_scheduler/task_traits.h" @@ -53,7 +54,12 @@ // to run a Task with |traits|. // Note: ExecutionMode is verified inside TestTaskFactory. void VerifyTaskEnvironement(const TaskTraits& traits) { - EXPECT_EQ(traits.priority() == TaskPriority::BACKGROUND + const bool supports_background_priority = + Lock::HandlesMultipleThreadPriorities() && + PlatformThread::CanIncreaseCurrentThreadPriority(); + + EXPECT_EQ(supports_background_priority && + traits.priority() == TaskPriority::BACKGROUND ? ThreadPriority::BACKGROUND : ThreadPriority::NORMAL, PlatformThread::GetCurrentThreadPriority());
diff --git a/build/all.gyp b/build/all.gyp index 8a8417ed..04cd975 100644 --- a/build/all.gyp +++ b/build/all.gyp
@@ -310,7 +310,6 @@ '../net/net.gyp:net_unittests', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../ui/base/ui_base_tests.gyp:ui_base_unittests', '../ui/display/display.gyp:display_unittests', '../ui/gfx/gfx_tests.gyp:gfx_unittests', @@ -795,7 +794,6 @@ '../sandbox/sandbox.gyp:sandbox_linux_unittests_deps', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../testing/android/junit/junit_test.gyp:junit_unit_tests', '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests', '../third_party/WebKit/public/all.gyp:*', @@ -826,7 +824,6 @@ '../net/net.gyp:net_unittests_apk', '../skia/skia_tests.gyp:skia_unittests_apk', '../sql/sql.gyp:sql_unittests_apk', - '../components/sync.gyp:sync_unit_tests_apk', '../ui/android/ui_android.gyp:ui_android_unittests_apk', '../ui/android/ui_android.gyp:ui_junit_tests', '../ui/base/ui_base_tests.gyp:ui_base_unittests_apk', @@ -910,7 +907,6 @@ '../rlz/rlz.gyp:*', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests', '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests', @@ -949,7 +945,6 @@ '../remoting/remoting.gyp:remoting_unittests', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests', '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests', @@ -1021,7 +1016,6 @@ '../remoting/remoting.gyp:remoting_unittests', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests', '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests', @@ -1113,7 +1107,6 @@ '../remoting/remoting.gyp:remoting_unittests', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests', '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests', @@ -1169,7 +1162,6 @@ '../net/net.gyp:net_unittests', '../printing/printing.gyp:printing_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../ui/base/ui_base_tests.gyp:ui_base_unittests', '../ui/gfx/gfx_tests.gyp:gfx_unittests', '../ui/gl/gl_tests.gyp:gl_unittests', @@ -1250,7 +1242,6 @@ '../base/base.gyp:base_unittests', '../ipc/ipc.gyp:ipc_tests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', ], }], ['chromeos==1', {
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py index c80ba7f4..9bc2c80 100644 --- a/build/android/pylib/gtest/gtest_config.py +++ b/build/android/pylib/gtest/gtest_config.py
@@ -37,7 +37,6 @@ 'sandbox_linux_unittests', 'skia_unittests', 'sql_unittests', - 'sync_unit_tests', 'ui_android_unittests', 'ui_base_unittests', 'ui_touch_selection_unittests',
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py index f41881a..56755ba 100644 --- a/build/android/pylib/gtest/gtest_test_instance.py +++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -42,7 +42,6 @@ 'midi_unittests': 'media/midi/midi_unittests.isolate', 'net_unittests': 'net/net_unittests.isolate', 'sql_unittests': 'sql/sql_unittests.isolate', - 'sync_unit_tests': 'components/sync/sync_unit_tests.isolate', 'ui_base_unittests': 'ui/base/ui_base_tests.isolate', 'unit_tests': 'chrome/unit_tests.isolate', 'webkit_unit_tests':
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py index 62e62b803..3a69c36 100644 --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -48,7 +48,7 @@ _PARAMETERIZED_TEST_ANNOTATION = 'ParameterizedTest' _PARAMETERIZED_TEST_SET_ANNOTATION = 'ParameterizedTest$Set' -_NATIVE_CRASH_RE = re.compile('native crash', re.IGNORECASE) +_NATIVE_CRASH_RE = re.compile('(process|native) crash', re.IGNORECASE) _PICKLE_FORMAT_VERSION = 10
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 8c565aa6..e539df78 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -144,6 +144,9 @@ # Component build. Setting to true compiles targets declared as "components" # as shared libraries loaded dynamically. This speeds up development time. # When false, components will be linked statically. + # + # For more information see + # https://chromium.googlesource.com/chromium/src/+/master/docs/component_build.md is_component_build = is_debug && current_os != "ios" }
diff --git a/build/config/ios/BUILD.gn b/build/config/ios/BUILD.gn index 6b8896c..ac709ae 100644 --- a/build/config/ios/BUILD.gn +++ b/build/config/ios/BUILD.gn
@@ -28,13 +28,17 @@ cflags = common_flags ldflags = common_flags - # TODO(ios): Remove once Xcode's libc++ has LLVM r256325. - if (use_xcode_clang) { - cflags += [ + # TODO(crbug.com/634373): Remove once Xcode's libc++ has LLVM r256325. Most + # likely this means one Xcode 8 is released and required. + if (use_xcode_clang && get_path_info(ios_sdk_version, "name") != "10") { + common_cc_flags = [ "-isystem", rebase_path("//third_party/llvm-build/Release+Asserts/include/c++/v1", root_build_dir), ] + + cflags_cc = common_cc_flags + cflags_objcc = common_cc_flags } }
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni index aa78715..d3afc12 100644 --- a/build/config/ios/rules.gni +++ b/build/config/ios/rules.gni
@@ -6,6 +6,13 @@ import("//build/config/mac/base_rules.gni") import("//build/config/mac/symbols.gni") +_toolchain_suffix = "" +_is_fat_build = additional_toolchains != [] +if (_is_fat_build) { + _toolchain_suffix = "($default_toolchain)" + _is_fat_build_main_target = current_toolchain == default_toolchain +} + # Generates Info.plist files for Mac apps and frameworks. # # Arguments @@ -146,11 +153,6 @@ # The rest of the build, including the codesigning step, are the same for # thin and fat builds. - _is_fat_build = additional_toolchains != [] - if (_is_fat_build) { - _is_fat_build_main_target = current_toolchain == default_toolchain - } - _executable_extra_deps = [] _executable_extra_inputs = [] _executable_extra_ldflags = [] @@ -161,11 +163,6 @@ # # As the generation of the entitlement depends on the if (use_ios_simulator) { - _toolchain_suffix = "" - if (_is_fat_build && !_is_fat_build_main_target) { - _toolchain_suffix = "($default_toolchain)" - } - _generate_entitlements_target = _target_name + "_gen_entitlements" _generate_entitlements_target_with_toolchain_suffix = "$_generate_entitlements_target$_toolchain_suffix" @@ -763,12 +760,11 @@ # Template to package a shared library into an iOS framework bundle. # -# This template provides two targets to control whether the framework is -# merely built when targets depend on it, or whether it is linked as well: -# "$target_name" and "$target_name+link". -# -# See the //build/config/mac/base_rules.gni:framework_bundle for a discussion -# and examples. +# By default, the bundle target this template generates does not link the +# resulting framework into anything that depends on it. If a dependency wants +# a link-time (as well as build-time) dependency on the framework bundle, +# depend against "$target_name+link". If only the build-time dependency is +# required (e.g., for copying into another bundle), then use "$target_name". # # Arguments # @@ -791,6 +787,70 @@ # (optional) list of files. Needs to be defined and non-empty if # public_headers is defined and non-empty. # +# This template provides two targets for the resulting framework bundle. The +# link-time behavior varies depending on which of the two targets below is +# added as a dependency: +# - $target_name only adds a build-time dependency. Targets that depend on +# it will not link against the framework. +# - $target_name+link adds a build-time and link-time dependency. Targets +# that depend on it will link against the framework. +# +# The build-time-only dependency is used for when a target needs to use the +# framework either only for resources, or because the target loads it at run- +# time, via dlopen() or NSBundle. The link-time dependency will cause the +# dependee to have the framework loaded by dyld at launch. +# +# Example of build-time only dependency: +# +# framework_bundle("CoreTeleportation") { +# sources = [ ... ] +# } +# +# bundle_data("core_teleportation_bundle_data") { +# deps = [ ":CoreTeleportation" ] +# sources = [ "$root_out_dir/CoreTeleportation.framework" ] +# outputs = [ "{{bundle_root_dir}}/Frameworks/{{source_file_part}}" ] +# } +# +# app_bundle("GoatTeleporter") { +# sources = [ ... ] +# deps = [ +# ":core_teleportation_bundle_data", +# ] +# } +# +# The GoatTeleporter.app will not directly link against +# CoreTeleportation.framework, but it will be included in the bundle's +# Frameworks directory. +# +# Example of link-time dependency: +# +# framework_bundle("CoreTeleportation") { +# sources = [ ... ] +# ldflags = [ +# "-install_name", +# "@executable_path/../Frameworks/$target_name.framework" +# ] +# } +# +# bundle_data("core_teleportation_bundle_data") { +# deps = [ ":CoreTeleportation+link" ] +# sources = [ "$root_out_dir/CoreTeleportation.framework" ] +# outputs = [ "{{bundle_root_dir}}/Frameworks/{{source_file_part}}" ] +# } +# +# app_bundle("GoatTeleporter") { +# sources = [ ... ] +# deps = [ +# ":core_teleportation_bundle_data", +# ] +# } +# +# Note that the framework is still copied to the app's bundle, but dyld will +# load this library when the app is launched because it uses the "+link" +# target as a dependency. This also requires that the framework set its +# install_name so that dyld can locate it. +# # See "gn help shared_library" for more information on arguments supported # by shared library target. template("ios_framework_bundle") { @@ -799,38 +859,80 @@ if (defined(invoker.output_name)) { _output_name = invoker.output_name } - _framework_target = _target_name _has_public_headers = defined(invoker.public_headers) && invoker.public_headers != [] - _is_fat_build = additional_toolchains != [] - if (_is_fat_build) { - _is_fat_build_main_target = current_toolchain == default_toolchain - } - - # This template has a different expansion depending on whether public headers - # are defined or not. If no public headers are speficied, then is forwards to - # the generic "framework_bundle" target, otherwise if expands to targets that - # create header map mapping and corresponding config and configure them as - # dependencies of the generic "framework_bundle" target. - # - # The expansion is a bit different for multi-architecture builds (aka fat - # binary builds). Then the targets build for the non-default toolchain uses - # the same header map (if available) as the one used by the default toolchain. - - _toolchain_suffix = "" - if (_is_fat_build && !_is_fat_build_main_target) { - _toolchain_suffix = "($default_toolchain)" - } - if (_has_public_headers) { _framework_headers_target = _target_name + "_framework_headers" - _framework_public_config = _target_name + "_ios_public_config" - _framework_target = target_name + "_internal" + _framework_headers_config = _target_name + "_framework_headers_config" _headers_map_config = _target_name + "_headers_map" + } - if (!_is_fat_build || _is_fat_build_main_target) { + # The expansion of the template is different for fat and thin builds. For + # thin build (and default toolchain of a fat build), the template expands + # to a "shared_library" target to create the bundle shared library and a + # "create_bundle" target (the main target) to create the bundle structure. + # + # For a fat build, the template just expands to the "shared_library" target + # for the non-default toolchain, while the final library is created using + # "lipo" in the expansion of the template for the default toolchain. + # + # The "$target_name+link" group for the non-default toolchain depends on the + # target of the same name from the default toolchain as this is the target + # that defines the real framework bundle (it will support the current cpu + # as it is a fat framework). + + if (_is_fat_build && !_is_fat_build_main_target) { + shared_library(_target_name) { + forward_variables_from(invoker, + "*", + [ + "assert_no_deps", + "bundle_deps", + "code_signing_enabled", + "data_deps", + "info_plist", + "info_plist_target", + "output_name", + ]) + if (defined(visibility)) { + visibility += [ ":${_target_name}_shared_library($default_toolchain)" ] + } + output_name = _output_name + output_prefix_override = true + output_extension = "" + output_dir = "$target_out_dir/$_target_name" + + if (_has_public_headers) { + configs += [ + ":$_framework_headers_config$_toolchain_suffix", + ":$_headers_map_config$_toolchain_suffix", + ] + + if (!defined(deps)) { + deps = [] + } + deps += [ ":$_framework_headers_target$_toolchain_suffix" ] + } + } + + group(_target_name + "+link") { + forward_variables_from(invoker, + [ + "visibility", + "testonly", + ]) + public_deps = [ + ":$_target_name+link($default_toolchain)", + ] + } + + if (defined(invoker.bundle_deps)) { + assert(invoker.bundle_deps != [], "mark bundle_deps as used") + } + } else { + if (_has_public_headers) { _public_headers = invoker.public_headers _framework_name = _output_name + ".framework" _framework_root = "$root_out_dir/$_framework_name" @@ -901,7 +1003,7 @@ ] } - config(_framework_public_config) { + config(_framework_headers_config) { # The link settings are inherited from the framework_bundle config. cflags = [ "-F", @@ -909,9 +1011,178 @@ ] } } - } - if (!_is_fat_build || _is_fat_build_main_target) { + _code_signing_enabled = ios_enable_code_signing + if (defined(invoker.code_signing_enabled)) { + _code_signing_enabled = + invoker.code_signing_enabled && _code_signing_enabled + } + + # If the framework is unversioned, the final _target_name will be the + # create_bundle(_framework_target), otherwise an action with the name + # _target_name will depends on the the create_bundle() in order to prepare + # the versioned directory structure. + _framework_target = _target_name + _framework_name = _output_name + ".framework" + _framework_root_dir = "$root_out_dir/$_framework_name" + if (defined(invoker.framework_version) && invoker.framework_version != "") { + _framework_version = invoker.framework_version + _framework_root_dir += "/Versions/$_framework_version" + _framework_target = _target_name + "_create_bundle" + } + + _link_shared_library_target = target_name + "_shared_library" + _shared_library_dir = "$target_out_dir/$_link_shared_library_target" + + if (_code_signing_enabled) { + _link_shared_library_visibility = [ ":$_framework_target" ] + } else { + _shared_library_bundle_data = target_name + "_shared_library_bundle_data" + _link_shared_library_visibility = [ ":$_shared_library_bundle_data" ] + } + + if (_is_fat_build) { + _lipo_shared_library_target = _link_shared_library_target + _lipo_shared_library_visibility = _link_shared_library_visibility + + _link_shared_library_visibility = [] + _link_shared_library_visibility = [ ":$_lipo_shared_library_target" ] + _link_shared_library_target = target_name + "_arch_shared_library" + + _arch_shared_library_dir = "$target_out_dir/$_link_shared_library_target" + _shared_library_dir = "$target_out_dir/$_lipo_shared_library_target" + } + + shared_library(_link_shared_library_target) { + forward_variables_from(invoker, + "*", + [ + "assert_no_deps", + "bundle_deps", + "code_signing_enabled", + "data_deps", + "info_plist", + "info_plist_target", + "output_name", + "visibility", + ]) + visibility = _link_shared_library_visibility + output_name = _output_name + output_prefix_override = true + output_extension = "" + + if (!_is_fat_build) { + output_dir = _shared_library_dir + } else { + output_dir = _arch_shared_library_dir + } + + if (_has_public_headers) { + configs += [ ":$_headers_map_config$_toolchain_suffix" ] + + if (!defined(deps)) { + deps = [] + } + deps += [ ":$_framework_headers_target$_toolchain_suffix" ] + } + } + + if (_is_fat_build) { + action(_lipo_shared_library_target) { + forward_variables_from(invoker, [ "testonly" ]) + visibility = _lipo_shared_library_visibility + script = "//build/toolchain/mac/linker_driver.py" + outputs = [ + "$_shared_library_dir/$_output_name", + ] + inputs = [ + "$_arch_shared_library_dir/$_output_name", + ] + deps = [ + ":$_link_shared_library_target", + ] + foreach(_additional_toolchain, additional_toolchains) { + _additional_toolchain_target = "$_target_name($_additional_toolchain)" + deps += [ ":$_additional_toolchain_target" ] + inputs += [ get_label_info(_additional_toolchain_target, + "target_out_dir") + "/$_output_name" ] + } + args = [ + "xcrun", + "lipo", + "-create", + "-output", + rebase_path(outputs[0], root_build_dir), + ] + rebase_path(inputs, root_build_dir) + + if (enable_dsyms) { + outputs += [ "$root_out_dir/$_output_name.dSYM/" ] + args += + [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ] + } + + if (enable_stripping) { + # Check whether //build/config/mac:strip_all has been removed from + # the configs variable (as this is how stripping is disabled for a + # single target). + _strip_all_in_config = false + if (defined(invoker.configs)) { + foreach(_config, invoker.configs) { + if (_config == "//build/config/mac:strip_all") { + _strip_all_in_config = true + } + } + } + + if (_strip_all_in_config) { + args += [ "-Wcrl,strip,-x,-S" ] + + if (save_unstripped_output) { + outputs += [ outputs[0] + ".unstripped" ] + args += [ "-Wcrl,unstripped," + + rebase_path(get_path_info(outputs[0], "dir"), + root_build_dir) ] + } + } + } + } + } + + if (!_code_signing_enabled) { + bundle_data(_shared_library_bundle_data) { + visibility = [ ":$_framework_target" ] + forward_variables_from(invoker, [ "testonly" ]) + sources = [ + "$_shared_library_dir/$_output_name", + ] + outputs = [ + "{{bundle_executable_dir}}/$_output_name", + ] + if (_is_fat_build) { + public_deps = [ + ":$_lipo_shared_library_target", + ] + } else { + public_deps = [ + ":$_link_shared_library_target", + ] + } + } + } + + _framework_public_config = _target_name + "_public_config" + config(_framework_public_config) { + # TODO(sdefresne): should we have a framework_dirs similar to lib_dirs + # and include_dirs to avoid duplicate values on the command-line. + visibility = [ ":$_framework_target" ] + ldflags = [ + "-F", + rebase_path("$root_out_dir/.", root_build_dir), + ] + lib_dirs = [ root_out_dir ] + libs = [ _framework_name ] + } + _info_plist_target = _target_name + "_info_plist" _info_plist_bundle = _target_name + "_info_plist_bundle" ios_info_plist(_info_plist_target) { @@ -926,7 +1197,7 @@ } bundle_data(_info_plist_bundle) { - visibility = [ ":$_framework_target" ] + visibility = [ ":$_target_name" ] forward_variables_from(invoker, [ "testonly" ]) sources = get_target_outputs(":$_info_plist_target") outputs = [ @@ -936,83 +1207,131 @@ ":$_info_plist_target", ] } - } - framework_bundle(_framework_target) { - forward_variables_from(invoker, - "*", - [ - "output_name", - "public_headers", - "visibility", - ]) - output_name = _output_name + create_bundle(_framework_target) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + "public_configs", + "public_deps", + "testonly", + ]) - if (!_is_fat_build || _is_fat_build_main_target) { - if (!defined(bundle_deps)) { - bundle_deps = [] + if (defined(_framework_version)) { + visibility = [ ":$_target_name" ] + } else { + if (defined(invoker.visibility)) { + visibility = invoker.visibility + visibility += [ ":$_target_name+link" ] + } } - bundle_deps += [ ":$_info_plist_bundle" ] - } - - if (_has_public_headers) { - if (!defined(public_configs)) { - public_configs = [] - } - public_configs += [ ":$_framework_public_config$_toolchain_suffix" ] - } - - if (_has_public_headers) { - visibility = [ - ":$_target_name$_toolchain_suffix", - ":$_target_name+link$_toolchain_suffix", - ":$_target_name+bundle$_toolchain_suffix", - ] - configs += [ ":$_headers_map_config$_toolchain_suffix" ] if (!defined(deps)) { deps = [] } - deps += [ ":$_framework_headers_target$_toolchain_suffix" ] - } else { - if (defined(invoker.visibility)) { - visibility = invoker.visibility - visibility += [ ":$_target_name+link$_toolchain_suffix" ] + deps += [ ":$_info_plist_bundle" ] + + if (defined(invoker.bundle_deps)) { + if (!defined(deps)) { + deps = [] + } + deps += invoker.bundle_deps + } + + if (!_code_signing_enabled) { + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ ":$_shared_library_bundle_data" ] + } + + bundle_root_dir = _framework_root_dir + bundle_resources_dir = "$bundle_root_dir/Resources" + bundle_executable_dir = "$bundle_root_dir" + + if (_code_signing_enabled) { + if (!defined(deps)) { + deps = [] + } + + if (_is_fat_build) { + deps += [ ":$_lipo_shared_library_target" ] + } else { + deps += [ ":$_link_shared_library_target" ] + } + + _entitlements_path = "//build/config/ios/entitlements.plist" + if (defined(invoker.entitlements_path)) { + _entitlements_path = invoker.entitlements_path + } + + code_signing_script = "//build/config/ios/codesign.py" + code_signing_sources = [ + _entitlements_path, + "$_shared_library_dir/$_output_name", + ] + code_signing_outputs = [ + "$bundle_root_dir/$_output_name", + "$bundle_root_dir/_CodeSignature/CodeResources", + "$bundle_root_dir/embedded.mobileprovision", + ] + code_signing_args = [ + "-e=" + rebase_path(_entitlements_path, root_build_dir), + "code-sign-bundle", + "-i=" + ios_code_signing_identity, + "-b=" + + rebase_path("$_shared_library_dir/$_output_name", root_build_dir), + rebase_path(bundle_root_dir, root_build_dir), + ] } } - } - if (_has_public_headers) { - group(_target_name) { - forward_variables_from(invoker, - [ - "testonly", - "public_configs", - ]) + if (defined(_framework_version)) { + action(_target_name) { + forward_variables_from(invoker, [ "testonly" ]) - if (defined(invoker.visibility)) { - visibility = invoker.visibility - visibility += [ ":$_target_name+link" ] + if (defined(invoker.visibility)) { + visibility = invoker.visibility + visibility += [ ":$_target_name+link" ] + } + + script = "//build/config/mac/package_framework.py" + outputs = [ + "$root_out_dir/$_framework_name/Versions/Current", + ] + args = [ + "$_framework_name", + "$_framework_version", + ] + public_deps = [ + ":$_framework_target", + ] } - - public_deps = [ - ":$_framework_target$_toolchain_suffix", - ] } group(_target_name + "+link") { forward_variables_from(invoker, [ + "public_deps", + "public_configs", "testonly", "visibility", ]) - public_deps = [ - ":$_framework_target+link$_toolchain_suffix", - ] - } - } + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ ":$_target_name" ] + if (!defined(public_configs)) { + public_configs = [] + } + public_configs += [ ":$_framework_public_config" ] - if (!_is_fat_build || _is_fat_build_main_target) { + if (_has_public_headers) { + public_configs += [ ":$_framework_headers_config" ] + } + } + bundle_data(_target_name + "+bundle") { forward_variables_from(invoker, [ @@ -1020,7 +1339,7 @@ "visibility", ]) public_deps = [ - ":$_framework_target", + ":$_target_name", ] sources = [ "$root_out_dir/$_output_name.framework", @@ -1047,11 +1366,6 @@ _output_name = invoker.output_name } - _is_fat_build = additional_toolchains != [] - if (_is_fat_build) { - _is_fat_build_main_target = current_toolchain == default_toolchain - } - _xctest_target = _target_name _xctest_output = _output_name
diff --git a/build/config/mac/base_rules.gni b/build/config/mac/base_rules.gni index de36be4..4e34cb53c 100644 --- a/build/config/mac/base_rules.gni +++ b/build/config/mac/base_rules.gni
@@ -126,430 +126,6 @@ } } -# This is used as the base template for both iOS and Mac frameworks. -# -# By default, the bundle target this template generates does not link the -# resulting framework into anything that depends on it. If a dependency wants -# a link-time (as well as build-time) dependency on the framework bundle, -# depend against "$target_name+link". If only the build-time dependency is -# required (e.g., for copying into another bundle), then use "$target_name". -# -# Arguments -# -# output_name: -# (optional) string, name of the generated framework without the -# .framework suffix. If omitted, defaults to target_name. -# -# framework_version: -# (optional) string, version of the framework. Typically this is a -# single letter, like "A". If omitted, the Versions/ subdirectory -# structure will not be created, and build output will go directly -# into the framework subdirectory. -# -# This template provides two targets for the resulting framework bundle. The -# link-time behavior varies depending on which of the two targets below is -# added as a dependency: -# - $target_name only adds a build-time dependency. Targets that depend on -# it will not link against the framework. -# - $target_name+link adds a build-time and link-time dependency. Targets -# that depend on it will link against the framework. -# -# The build-time-only dependency is used for when a target needs to use the -# framework either only for resources, or because the target loads it at run- -# time, via dlopen() or NSBundle. The link-time dependency will cause the -# dependee to have the framework loaded by dyld at launch. -# -# Example of build-time only dependency: -# -# framework_bundle("CoreTeleportation") { -# sources = [ ... ] -# } -# -# bundle_data("core_teleportation_bundle_data") { -# deps = [ ":CoreTeleportation" ] -# sources = [ "$root_out_dir/CoreTeleportation.framework" ] -# outputs = [ "{{bundle_root_dir}}/Frameworks/{{source_file_part}}" ] -# } -# -# app_bundle("GoatTeleporter") { -# sources = [ ... ] -# deps = [ -# ":core_teleportation_bundle_data", -# ] -# } -# -# The GoatTeleporter.app will not directly link against -# CoreTeleportation.framework, but it will be included in the bundle's -# Frameworks directory. -# -# Example of link-time dependency: -# -# framework_bundle("CoreTeleportation") { -# sources = [ ... ] -# ldflags = [ -# "-install_name", -# "@executable_path/../Frameworks/$target_name.framework" -# ] -# } -# -# bundle_data("core_teleportation_bundle_data") { -# deps = [ ":CoreTeleportation+link" ] -# sources = [ "$root_out_dir/CoreTeleportation.framework" ] -# outputs = [ "{{bundle_root_dir}}/Frameworks/{{source_file_part}}" ] -# } -# -# app_bundle("GoatTeleporter") { -# sources = [ ... ] -# deps = [ -# ":core_teleportation_bundle_data", -# ] -# } -# -# Note that the framework is still copied to the app's bundle, but dyld will -# load this library when the app is launched because it uses the "+link" -# target as a dependency. This also requires that the framework set its -# install_name so that dyld can locate it. -# -# See "gn help shared_library" for more information on arguments supported -# by shared library target. -template("framework_bundle") { - _target_name = target_name - _output_name = target_name - if (defined(invoker.output_name)) { - _output_name = invoker.output_name - } - - _is_fat_build = is_ios && additional_toolchains != [] - if (_is_fat_build) { - _is_fat_build_main_target = current_toolchain == default_toolchain - } - - # The expansion of the template is different for fat and thin builds. For - # thin build (and default toolchain of a fat build), the template expands - # to a "shared_library" target to create the bundle shared library and a - # "create_bundle" target (the main target) to create the bundle structure. - # - # For a fat build, the template just expands to the "shared_library" target - # for the non-default toolchain, while the final library is created using - # "lipo" in the expansion of the template for the default toolchain. - # - # The "$target_name+link" group for the non-default toolchain depends on the - # target of the same name from the default toolchain as this is the target - # that defines the real framework bundle (it will support the current cpu - # as it is a fat framework). - - if (_is_fat_build && !_is_fat_build_main_target) { - shared_library(_target_name) { - forward_variables_from(invoker, - "*", - [ - "assert_no_deps", - "bundle_deps", - "code_signing_enabled", - "data_deps", - "info_plist", - "info_plist_target", - "output_name", - ]) - if (defined(visibility)) { - visibility += [ ":${_target_name}_shared_library($default_toolchain)" ] - } - output_name = _output_name - output_prefix_override = true - output_extension = "" - output_dir = "$target_out_dir/$_target_name" - } - - group(_target_name + "+link") { - forward_variables_from(invoker, - [ - "visibility", - "testonly", - ]) - public_deps = [ - ":$_target_name($default_toolchain)", - ] - } - - if (defined(invoker.bundle_deps)) { - assert(invoker.bundle_deps != [], "mark bundle_deps as used") - } - } else { - _code_signing_enabled = is_ios && ios_enable_code_signing - if (defined(invoker.code_signing_enabled)) { - _code_signing_enabled = - invoker.code_signing_enabled && _code_signing_enabled - } - - # If the framework is unversioned, the final _target_name will be the - # create_bundle(_framework_target), otherwise an action with the name - # _target_name will depends on the the create_bundle() in order to prepare - # the versioned directory structure. - _framework_target = _target_name - _framework_name = _output_name + ".framework" - _framework_root_dir = "$root_out_dir/$_framework_name" - if (defined(invoker.framework_version) && invoker.framework_version != "") { - _framework_version = invoker.framework_version - _framework_root_dir += "/Versions/$_framework_version" - _framework_target = _target_name + "_create_bundle" - } - - _link_shared_library_target = target_name + "_shared_library" - _shared_library_dir = "$target_out_dir/$_link_shared_library_target" - - if (_code_signing_enabled) { - _link_shared_library_visibility = [ ":$_framework_target" ] - } else { - _shared_library_bundle_data = target_name + "_shared_library_bundle_data" - _link_shared_library_visibility = [ ":$_shared_library_bundle_data" ] - } - - if (_is_fat_build) { - _lipo_shared_library_target = _link_shared_library_target - _lipo_shared_library_visibility = _link_shared_library_visibility - - _link_shared_library_visibility = [] - _link_shared_library_visibility = [ ":$_lipo_shared_library_target" ] - _link_shared_library_target = target_name + "_arch_shared_library" - - _arch_shared_library_dir = "$target_out_dir/$_link_shared_library_target" - _shared_library_dir = "$target_out_dir/$_lipo_shared_library_target" - } - - shared_library(_link_shared_library_target) { - forward_variables_from(invoker, - "*", - [ - "assert_no_deps", - "bundle_deps", - "code_signing_enabled", - "data_deps", - "info_plist", - "output_name", - "visibility", - ]) - visibility = _link_shared_library_visibility - output_name = _output_name - output_prefix_override = true - output_extension = "" - - if (!_is_fat_build) { - output_dir = _shared_library_dir - } else { - output_dir = _arch_shared_library_dir - } - } - - if (_is_fat_build) { - action(_lipo_shared_library_target) { - forward_variables_from(invoker, [ "testonly" ]) - visibility = _lipo_shared_library_visibility - script = "//build/toolchain/mac/linker_driver.py" - outputs = [ - "$_shared_library_dir/$_output_name", - ] - inputs = [ - "$_arch_shared_library_dir/$_output_name", - ] - deps = [ - ":$_link_shared_library_target", - ] - foreach(_additional_toolchain, additional_toolchains) { - _additional_toolchain_target = "$_target_name($_additional_toolchain)" - deps += [ ":$_additional_toolchain_target" ] - inputs += [ get_label_info(_additional_toolchain_target, - "target_out_dir") + "/$_output_name" ] - } - args = [ - "xcrun", - "lipo", - "-create", - "-output", - rebase_path(outputs[0], root_build_dir), - ] + rebase_path(inputs, root_build_dir) - - if (enable_dsyms) { - outputs += [ "$root_out_dir/$_output_name.dSYM/" ] - args += - [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ] - } - - if (enable_stripping) { - # Check whether //build/config/mac:strip_all has been removed from - # the configs variable (as this is how stripping is disabled for a - # single target). - _strip_all_in_config = false - if (defined(invoker.configs)) { - foreach(_config, invoker.configs) { - if (_config == "//build/config/mac:strip_all") { - _strip_all_in_config = true - } - } - } - - if (_strip_all_in_config) { - args += [ "-Wcrl,strip,-x,-S" ] - - if (save_unstripped_output) { - outputs += [ outputs[0] + ".unstripped" ] - args += [ "-Wcrl,unstripped," + - rebase_path(get_path_info(outputs[0], "dir"), - root_build_dir) ] - } - } - } - } - } - - if (!_code_signing_enabled) { - bundle_data(_shared_library_bundle_data) { - visibility = [ ":$_framework_target" ] - forward_variables_from(invoker, [ "testonly" ]) - sources = [ - "$_shared_library_dir/$_output_name", - ] - outputs = [ - "{{bundle_executable_dir}}/$_output_name", - ] - if (_is_fat_build) { - public_deps = [ - ":$_lipo_shared_library_target", - ] - } else { - public_deps = [ - ":$_link_shared_library_target", - ] - } - } - } - - _framework_public_config = _target_name + "_public_config" - config(_framework_public_config) { - # TODO(sdefresne): should we have a framework_dirs similar to lib_dirs - # and include_dirs to avoid duplicate values on the command-line. - visibility = [ ":$_framework_target" ] - ldflags = [ - "-F", - rebase_path("$root_out_dir/.", root_build_dir), - ] - lib_dirs = [ root_out_dir ] - libs = [ _framework_name ] - } - - create_bundle(_framework_target) { - forward_variables_from(invoker, - [ - "data_deps", - "deps", - "public_deps", - "testonly", - ]) - - if (defined(_framework_version)) { - visibility = [ ":$_target_name" ] - } else { - if (defined(invoker.visibility)) { - visibility = invoker.visibility - visibility += [ ":$_target_name+link" ] - } - } - - if (defined(invoker.bundle_deps)) { - if (!defined(deps)) { - deps = [] - } - deps += invoker.bundle_deps - } - - if (!_code_signing_enabled) { - if (!defined(public_deps)) { - public_deps = [] - } - public_deps += [ ":$_shared_library_bundle_data" ] - } - - bundle_root_dir = _framework_root_dir - bundle_resources_dir = "$bundle_root_dir/Resources" - bundle_executable_dir = "$bundle_root_dir" - - if (_code_signing_enabled) { - if (!defined(deps)) { - deps = [] - } - - if (_is_fat_build) { - deps += [ ":$_lipo_shared_library_target" ] - } else { - deps += [ ":$_link_shared_library_target" ] - } - - _entitlements_path = "//build/config/ios/entitlements.plist" - if (defined(invoker.entitlements_path)) { - _entitlements_path = invoker.entitlements_path - } - - code_signing_script = "//build/config/ios/codesign.py" - code_signing_sources = [ - _entitlements_path, - "$_shared_library_dir/$_output_name", - ] - code_signing_outputs = [ - "$bundle_root_dir/$_output_name", - "$bundle_root_dir/_CodeSignature/CodeResources", - "$bundle_root_dir/embedded.mobileprovision", - ] - code_signing_args = [ - "-e=" + rebase_path(_entitlements_path, root_build_dir), - "code-sign-bundle", - "-i=" + ios_code_signing_identity, - "-b=" + - rebase_path("$_shared_library_dir/$_output_name", root_build_dir), - rebase_path(bundle_root_dir, root_build_dir), - ] - } - } - - if (defined(_framework_version)) { - action(_target_name) { - forward_variables_from(invoker, [ "testonly" ]) - - if (defined(invoker.visibility)) { - visibility = invoker.visibility - visibility += [ ":$_target_name+link" ] - } - - script = "//build/config/mac/package_framework.py" - outputs = [ - "$root_out_dir/$_framework_name/Versions/Current", - ] - args = [ - "$_framework_name", - "$_framework_version", - ] - public_deps = [ - ":$_framework_target", - ] - } - } - - group(_target_name + "+link") { - forward_variables_from(invoker, - [ - "public_configs", - "testonly", - "visibility", - ]) - public_deps = [ - ":$_target_name", - ] - if (!defined(public_configs)) { - public_configs = [] - } - public_configs += [ ":$_framework_public_config" ] - } - } -} - # Template to combile .xib or .storyboard files. # # Arguments
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni index a221378..832f63595 100644 --- a/build/config/mac/rules.gni +++ b/build/config/mac/rules.gni
@@ -116,12 +116,11 @@ # Template to package a shared library into a Mac framework bundle. # -# This template provides two targets to control whether the framework is -# merely built when targets depend on it, or whether it is linked as well: -# "$target_name" and "$target_name+link". -# -# See the //build/config/mac/base_rules.gni:framework_bundle for a discussion -# and examples. +# By default, the bundle target this template generates does not link the +# resulting framework into anything that depends on it. If a dependency wants +# a link-time (as well as build-time) dependency on the framework bundle, +# depend against "$target_name+link". If only the build-time dependency is +# required (e.g., for copying into another bundle), then use "$target_name". # # Arguments # @@ -148,6 +147,70 @@ # (optional) string array, 'key=value' pairs for extra fields which are # specified in a source Info.plist template. # +# This template provides two targets for the resulting framework bundle. The +# link-time behavior varies depending on which of the two targets below is +# added as a dependency: +# - $target_name only adds a build-time dependency. Targets that depend on +# it will not link against the framework. +# - $target_name+link adds a build-time and link-time dependency. Targets +# that depend on it will link against the framework. +# +# The build-time-only dependency is used for when a target needs to use the +# framework either only for resources, or because the target loads it at run- +# time, via dlopen() or NSBundle. The link-time dependency will cause the +# dependee to have the framework loaded by dyld at launch. +# +# Example of build-time only dependency: +# +# mac_framework_bundle("CoreTeleportation") { +# sources = [ ... ] +# } +# +# bundle_data("core_teleportation_bundle_data") { +# deps = [ ":CoreTeleportation" ] +# sources = [ "$root_out_dir/CoreTeleportation.framework" ] +# outputs = [ "{{bundle_root_dir}}/Frameworks/{{source_file_part}}" ] +# } +# +# app_bundle("GoatTeleporter") { +# sources = [ ... ] +# deps = [ +# ":core_teleportation_bundle_data", +# ] +# } +# +# The GoatTeleporter.app will not directly link against +# CoreTeleportation.framework, but it will be included in the bundle's +# Frameworks directory. +# +# Example of link-time dependency: +# +# mac_framework_bundle("CoreTeleportation") { +# sources = [ ... ] +# ldflags = [ +# "-install_name", +# "@executable_path/../Frameworks/$target_name.framework" +# ] +# } +# +# bundle_data("core_teleportation_bundle_data") { +# deps = [ ":CoreTeleportation+link" ] +# sources = [ "$root_out_dir/CoreTeleportation.framework" ] +# outputs = [ "{{bundle_root_dir}}/Frameworks/{{source_file_part}}" ] +# } +# +# app_bundle("GoatTeleporter") { +# sources = [ ... ] +# deps = [ +# ":core_teleportation_bundle_data", +# ] +# } +# +# Note that the framework is still copied to the app's bundle, but dyld will +# load this library when the app is launched because it uses the "+link" +# target as a dependency. This also requires that the framework set its +# install_name so that dyld can locate it. +# # See "gn help shared_library" for more information on arguments supported # by shared library target. template("mac_framework_bundle") { @@ -183,13 +246,149 @@ ] } - framework_bundle(target_name) { - forward_variables_from(invoker, "*", [ "info_plist" ]) + _target_name = target_name + _output_name = target_name + if (defined(invoker.output_name)) { + _output_name = invoker.output_name + } + + # If the framework is unversioned, the final _target_name will be the + # create_bundle(_framework_target), otherwise an action with the name + # _target_name will depends on the the create_bundle() in order to prepare + # the versioned directory structure. + _framework_target = _target_name + _framework_name = _output_name + ".framework" + _framework_root_dir = "$root_out_dir/$_framework_name" + if (defined(invoker.framework_version) && invoker.framework_version != "") { + _framework_version = invoker.framework_version + _framework_root_dir += "/Versions/$_framework_version" + _framework_target = _target_name + "_create_bundle" + } + + _link_shared_library_target = target_name + "_shared_library" + _shared_library_bundle_data = target_name + "_shared_library_bundle_data" + + shared_library(_link_shared_library_target) { + forward_variables_from(invoker, + "*", + [ + "assert_no_deps", + "bundle_deps", + "code_signing_enabled", + "data_deps", + "info_plist", + "info_plist_target", + "output_name", + "visibility", + ]) + visibility = [ ":$_shared_library_bundle_data" ] + output_name = _output_name + output_prefix_override = true + output_extension = "" + output_dir = "$target_out_dir/$_link_shared_library_target" + } + + bundle_data(_shared_library_bundle_data) { + visibility = [ ":$_framework_target" ] + forward_variables_from(invoker, [ "testonly" ]) + sources = [ + "$target_out_dir/$_link_shared_library_target/$_output_name", + ] + outputs = [ + "{{bundle_executable_dir}}/$_output_name", + ] + public_deps = [ + ":$_link_shared_library_target", + ] + } + + _framework_public_config = _target_name + "_public_config" + config(_framework_public_config) { + # TODO(sdefresne): should we have a framework_dirs similar to lib_dirs + # and include_dirs to avoid duplicate values on the command-line. + visibility = [ ":$_framework_target" ] + ldflags = [ + "-F", + rebase_path("$root_out_dir/.", root_build_dir), + ] + lib_dirs = [ root_out_dir ] + libs = [ _framework_name ] + } + + create_bundle(_framework_target) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + "public_deps", + "testonly", + ]) + + if (defined(_framework_version)) { + visibility = [ ":$_target_name" ] + } else { + if (defined(invoker.visibility)) { + visibility = invoker.visibility + visibility += [ ":$_target_name+link" ] + } + } if (!defined(deps)) { deps = [] } deps += [ ":$_info_plist_bundle_data" ] + + if (defined(invoker.bundle_deps)) { + deps += invoker.bundle_deps + } + + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ ":$_shared_library_bundle_data" ] + + bundle_root_dir = _framework_root_dir + bundle_resources_dir = "$bundle_root_dir/Resources" + bundle_executable_dir = "$bundle_root_dir" + } + + if (defined(_framework_version)) { + action(_target_name) { + forward_variables_from(invoker, [ "testonly" ]) + + if (defined(invoker.visibility)) { + visibility = invoker.visibility + visibility += [ ":$_target_name+link" ] + } + + script = "//build/config/mac/package_framework.py" + outputs = [ + "$root_out_dir/$_framework_name/Versions/Current", + ] + args = [ + "$_framework_name", + "$_framework_version", + ] + public_deps = [ + ":$_framework_target", + ] + } + } + + group(_target_name + "+link") { + forward_variables_from(invoker, + [ + "public_configs", + "testonly", + "visibility", + ]) + public_deps = [ + ":$_target_name", + ] + if (!defined(public_configs)) { + public_configs = [] + } + public_configs += [ ":$_framework_public_config" ] } }
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index 08ecb8d..359453b 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -191,6 +191,30 @@ ] } } + } else if (is_win && is_asan) { + # Windows directly calls link.exe instead of the compiler driver when + # linking. Hence, pass the runtime libraries instead of -fsanitize=address. + # In the static-library build, libraries are different for executables + # and dlls, see link_executable and link_shared_library below. + # This here handles only the component build. + if (target_cpu == "x64") { + # Windows 64-bit. TODO(etienneb): Remove the assert when this is ready. + if (is_component_build) { + assert(false, "win/asan does not work in 64-bit yet") + libs = [ + "clang_rt.asan_dynamic-x86_64.lib", + "clang_rt.asan_dynamic_runtime_thunk-x86_64.lib", + ] + } + } else { + assert(target_cpu == "x86", "WinASan unsupported architecture") + if (is_component_build) { + libs = [ + "clang_rt.asan_dynamic-i386.lib", + "clang_rt.asan_dynamic_runtime_thunk-i386.lib", + ] + } + } } } @@ -246,36 +270,14 @@ [ "-fsanitize-blacklist=" + rebase_path("//tools/memory/asan/blacklist.txt", root_build_dir) ] } - - if (is_win) { - # In the static-library build, libraries are different for executables - # and dlls, see link_executable and link_shared_library below. - # This here handles only the component build. - if (target_cpu == "x64") { - # Windows 64-bit. - if (is_component_build) { - libs = [ - "clang_rt.asan_dynamic-x86_64.lib", - "clang_rt.asan_dynamic_runtime_thunk-x86_64.lib", - ] - } - } else { - assert(target_cpu == "x86", "WinASan unsupported architecture") - if (is_component_build) { - libs = [ - "clang_rt.asan_dynamic-i386.lib", - "clang_rt.asan_dynamic_runtime_thunk-i386.lib", - ] - } - } - } } } config("link_executable") { if (is_asan && is_win && !is_component_build) { if (target_cpu == "x64") { - # Windows 64-bit. + # Windows 64-bit. TODO(etienneb): Remove the assert when this is ready. + assert(false, "win/asan does not work in 64-bit yet") libs = [ "clang_rt.asan-x86_64.lib" ] } else { assert(target_cpu == "x86", "WinASan unsupported architecture") @@ -287,7 +289,8 @@ config("link_shared_library") { if (is_asan && is_win && !is_component_build) { if (target_cpu == "x64") { - # Windows 64-bit. + # Windows 64-bit. TODO(etienneb): Remove the assert when this is ready. + assert(false, "win/asan does not work in 64-bit yet") libs = [ "clang_rt.asan_dll_thunk-x86_64.lib" ] } else { assert(target_cpu == "x86", "WinASan unsupported architecture")
diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni index 16117223..ba1aec4 100644 --- a/build/config/sanitizers/sanitizers.gni +++ b/build/config/sanitizers/sanitizers.gni
@@ -90,6 +90,30 @@ sanitizer_coverage_flags = "" } +# Disable sanitizers for non-default toolchains. +if (current_toolchain != default_toolchain) { + is_asan = false + is_cfi = false + is_lsan = false + is_msan = false + is_syzyasan = false + is_tsan = false + is_ubsan = false + is_ubsan_null = false + is_ubsan_no_recover = false + is_ubsan_security = false + is_ubsan_vptr = false + msan_track_origins = 0 + sanitizer_coverage_flags = "" + use_cfi_diag = false + use_custom_libcxx = false + use_drfuzz = false + use_libfuzzer = false + use_prebuilt_instrumented_libraries = false + use_locally_built_instrumented_libraries = false + use_sanitizer_coverage = false +} + # Args that are in turn dependent on other args must be in a separate # declare_args block. User overrides are only applied at the end of a # declare_args block.
diff --git a/build/experimental/install-build-deps.py b/build/experimental/install-build-deps.py index 416eaa86..e5a2e80 100755 --- a/build/experimental/install-build-deps.py +++ b/build/experimental/install-build-deps.py
@@ -137,6 +137,7 @@ 'libsqlite3-0', 'libstdc++6', 'libx11-6', + 'libx11-xcb1', 'libxau6', 'libxcb1', 'libxcomposite1', @@ -167,6 +168,7 @@ 'libpixman-1-0-dbg', 'libsqlite3-0-dbg', 'libx11-6-dbg', + 'libx11-xcb1-dbg', 'libxau6-dbg', 'libxcb1-dbg', 'libxcomposite1-dbg',
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi index c9c582dd..7535ff394 100644 --- a/build/gn_migration.gypi +++ b/build/gn_migration.gypi
@@ -71,7 +71,6 @@ '../printing/printing.gyp:printing_unittests', '../skia/skia_tests.gyp:skia_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../testing/gmock.gyp:gmock_main', '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests', '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests', @@ -220,7 +219,6 @@ '../sandbox/sandbox.gyp:sandbox_linux_unittests_deps', '../skia/skia_tests.gyp:skia_unittests_apk', '../sql/sql.gyp:sql_unittests_apk', - '../components/sync.gyp:sync_unit_tests_apk', '../testing/android/junit/junit_test.gyp:junit_unit_tests', '../third_party/smhasher/smhasher.gyp:murmurhash3', '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests_apk', @@ -573,7 +571,6 @@ '../remoting/remoting.gyp:remoting_unittests_run', '../skia/skia_tests.gyp:skia_unittests_run', '../sql/sql.gyp:sql_unittests_run', - '../components/sync.gyp:sync_unit_tests_run', '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests_run', '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests_run', '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests_run',
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index f0ae0b14..832d116 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -125,18 +125,19 @@ lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcap2 libcups2 libexpat1 libffi6 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0 libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0 - libpng12-0 libspeechd2 libstdc++6 libsqlite3-0 libx11-6 libxau6 - libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 - libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1 libxtst6 - zlib1g $chromeos_lib_list" + libpng12-0 libspeechd2 libstdc++6 libsqlite3-0 libx11-6 libx11-xcb1 + libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 + libxext6 libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1 + libxtst6 zlib1g $chromeos_lib_list" # Debugging symbols for all of the run-time libraries dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libffi6-dbg libfontconfig1-dbg libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg - libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libxau6-dbg - libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg libxdamage1-dbg - libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg libxinerama1-dbg - libxrandr2-dbg libxrender1-dbg libxtst6-dbg zlib1g-dbg" + libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libx11-xcb1-dbg + libxau6-dbg libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg + libxdamage1-dbg libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg + libxinerama1-dbg libxrandr2-dbg libxrender1-dbg libxtst6-dbg + zlib1g-dbg" # Find the proper version of libstdc++6-4.x-dbg. if [ "x$lsb_release" = "xprecise" ]; then
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc index 4b27af0a..ef7465a 100644 --- a/build/sanitizers/tsan_suppressions.cc +++ b/build/sanitizers/tsan_suppressions.cc
@@ -270,6 +270,11 @@ // http://crbug.com/633145 "race:third_party/libjpeg_turbo/simd/jsimd_x86_64.c\n" +// Intentional test-only race for otherwise untestable code, won't fix. +// http://crbug.com/634383 +"race:ThreadTest_StartTwiceNonJoinableNotAllowed_Test::TestBody\n" +"race:ThreadTest_StartWithOptions_NonJoinable_Test::TestBody\n" + // End of suppressions. ; // Please keep this semicolon.
diff --git a/build/toolchain/BUILD.gn b/build/toolchain/BUILD.gn new file mode 100644 index 0000000..dacbd0f --- /dev/null +++ b/build/toolchain/BUILD.gn
@@ -0,0 +1,11 @@ +# 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. + +import("//build/toolchain/concurrent_links.gni") + +if (current_toolchain == default_toolchain) { + pool("link_pool") { + depth = concurrent_links + } +}
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 4cdd046..10a82bc 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -9,7 +9,6 @@ import("//build/toolchain/cc_wrapper.gni") import("//build/toolchain/goma.gni") import("//build/toolchain/toolchain.gni") -import("//build/toolchain/concurrent_links.gni") # This template defines a toolchain for something that works like gcc # (including clang). @@ -114,8 +113,6 @@ assert(defined(invoker.toolchain_os), "gcc_toolchain() must specify a \"toolchain_os\"") - # concurrent_links is picked up from the declare_arg(). - if (defined(invoker.cc_wrapper)) { cc_wrapper = invoker.cc_wrapper } @@ -279,6 +276,7 @@ soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". sofile = "{{output_dir}}/$soname" # Possibly including toolchain dir. rspfile = sofile + ".rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" if (defined(invoker.strip)) { unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" @@ -345,6 +343,7 @@ soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". sofile = "{{output_dir}}/$soname" rspfile = sofile + ".rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" if (defined(invoker.strip)) { unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" @@ -391,6 +390,7 @@ outfile = "{{output_dir}}/$exename" rspfile = "$outfile.rsp" unstripped_outfile = outfile + pool = "//build/toolchain:link_pool($default_toolchain)" # Use this for {{output_extension}} expansions unless a target manually # overrides it (in which case {{output_extension}} will be what the target @@ -474,28 +474,6 @@ } else { v8_current_cpu = current_cpu } - - # Disable sanitizers for non-default toolchains. - is_asan = false - is_cfi = false - is_lsan = false - is_msan = false - is_syzyasan = false - is_tsan = false - is_ubsan = false - is_ubsan_null = false - is_ubsan_no_recover = false - is_ubsan_security = false - is_ubsan_vptr = false - msan_track_origins = 0 - sanitizer_coverage_flags = "" - use_cfi_diag = false - use_custom_libcxx = false - use_drfuzz = false - use_libfuzzer = false - use_prebuilt_instrumented_libraries = false - use_locally_built_instrumented_libraries = false - use_sanitizer_coverage = false } forward_variables_from(invoker, [ "deps" ])
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index a08e568a..dea16eb 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -70,8 +70,6 @@ assert(defined(invoker.toolchain_os), "mac_toolchain() must specify a \"toolchain_os\"") - # concurrent_links is picked up from the declare_arg(). - if (use_goma) { assert(cc_wrapper == "", "Goma and cc_wrapper can't be used together.") _compiler_prefix = "$goma_dir/gomacc " @@ -197,6 +195,7 @@ tool("solink") { dylib = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # eg "./libfoo.dylib" rspfile = dylib + ".rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" # These variables are not built into GN but are helpers that implement # (1) linking to produce a .dylib, (2) extracting the symbols from that @@ -260,6 +259,7 @@ tool("solink_module") { sofile = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # eg "./libfoo.so" rspfile = sofile + ".rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" link_command = "$linker_driver $ld -bundle {{ldflags}} -o \"$sofile\" -Wl,-filelist,\"$rspfile\"" if (is_component_build) { @@ -294,6 +294,7 @@ tool("link") { outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}" rspfile = "$outfile.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" # Note about --filelist: Apple's linker reads the file list file and # interprets each newline-separated chunk of text as a file name. It
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 7d0b7d23..d726504 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -8,7 +8,6 @@ import("//build/config/win/visual_studio_version.gni") import("//build/toolchain/goma.gni") import("//build/toolchain/toolchain.gni") -import("//build/toolchain/concurrent_links.gni") # Should only be running on Windows. assert(is_win) @@ -49,11 +48,6 @@ # toolchain_os: current_os to pass as a build arg # environment: File name of environment file. template("msvc_toolchain") { - if (defined(invoker.concurrent_links)) { - # concurrent_links is picked up from the declare_arg() otherwise. - concurrent_links = invoker.concurrent_links - } - env = invoker.environment if (invoker.is_clang && host_os != "win") { @@ -182,6 +176,7 @@ libname = "${dllname}.lib" # e.g. foo.dll.lib pdbname = "${dllname}.pdb" rspfile = "${dllname}.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" command = "$python_path gyp-win-tool link-wrapper $env False $link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" @@ -214,6 +209,7 @@ dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e.g. foo.dll pdbname = "${dllname}.pdb" rspfile = "${dllname}.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" command = "$python_path gyp-win-tool link-wrapper $env False $link /nologo /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" @@ -237,6 +233,7 @@ exename = "{{output_dir}}/{{target_output_name}}{{output_extension}}" pdbname = "$exename.pdb" rspfile = "$exename.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" command = "$python_path gyp-win-tool link-wrapper $env False $link /nologo /OUT:$exename /PDB:$pdbname @$rspfile" @@ -353,7 +350,6 @@ template("win_x64_toolchains") { # TODO(mcgrathr): These assignments are only required because of # crbug.com/395883. Drop them if that ever gets fixed in GN. - concurrent_links = invoker.concurrent_links goma_prefix = invoker.goma_prefix x64_toolchain_data = invoker.x64_toolchain_data clang_cl = invoker.clang_cl @@ -391,7 +387,6 @@ win_x64_toolchains("x64") { # TODO(mcgrathr): These assignments are only required because of # crbug.com/395883. Drop them if that ever gets fixed in GN. - concurrent_links = concurrent_links goma_prefix = goma_prefix x64_toolchain_data = x64_toolchain_data } @@ -406,7 +401,6 @@ # TODO(mcgrathr): These assignments are only required because of # crbug.com/395883. Drop them if that ever gets fixed in GN. - concurrent_links = concurrent_links goma_prefix = goma_prefix x64_toolchain_data = x64_toolchain_data clang_cl = clang_cl
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 4137362..600920a7 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -604,8 +604,6 @@ "test/begin_frame_args_test.h", "test/begin_frame_source_test.cc", "test/begin_frame_source_test.h", - "test/failure_output_surface.cc", - "test/failure_output_surface.h", "test/fake_channel_impl.cc", "test/fake_channel_impl.h", "test/fake_client_picture_cache.cc",
diff --git a/cc/base/switches.cc b/cc/base/switches.cc index 82e4619..7de98ff 100644 --- a/cc/base/switches.cc +++ b/cc/base/switches.cc
@@ -55,6 +55,11 @@ const char kShowCompositedLayerBorders[] = "show-composited-layer-borders"; const char kUIShowCompositedLayerBorders[] = "ui-show-layer-borders"; +// Renders a green border around GL composited texture quads to help +// debug and study overlay support. +const char kGlCompositedTextureQuadBorder[] = + "gl-composited-texture-quad-border"; + // Draws a heads-up-display showing Frames Per Second as well as GPU memory // usage. If you also use --enable-logging=stderr --vmodule="head*=1" then FPS // will also be output to the console log.
diff --git a/cc/base/switches.h b/cc/base/switches.h index e39da61..439933765 100644 --- a/cc/base/switches.h +++ b/cc/base/switches.h
@@ -34,6 +34,7 @@ // Debug visualizations. CC_EXPORT extern const char kShowCompositedLayerBorders[]; CC_EXPORT extern const char kUIShowCompositedLayerBorders[]; +CC_EXPORT extern const char kGlCompositedTextureQuadBorder[]; CC_EXPORT extern const char kShowFPSCounter[]; CC_EXPORT extern const char kUIShowFPSCounter[]; CC_EXPORT extern const char kShowLayerAnimationBounds[];
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index d8250ea..a171014 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp
@@ -176,8 +176,6 @@ 'test/begin_frame_args_test.h', 'test/begin_frame_source_test.cc', 'test/begin_frame_source_test.h', - 'test/failure_output_surface.cc', - 'test/failure_output_surface.h', 'test/fake_channel_impl.cc', 'test/fake_channel_impl.h', 'test/fake_client_picture_cache.cc',
diff --git a/cc/layers/surface_layer_unittest.cc b/cc/layers/surface_layer_unittest.cc index 5f40deb..0597cd76 100644 --- a/cc/layers/surface_layer_unittest.cc +++ b/cc/layers/surface_layer_unittest.cc
@@ -174,14 +174,6 @@ // Check that SurfaceSequence is sent through swap promise. class SurfaceLayerSwapPromiseWithDraw : public SurfaceLayerSwapPromise { public: - SurfaceLayerSwapPromiseWithDraw() : SurfaceLayerSwapPromise() {} - - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - auto ret = FakeOutputSurface::CreateDelegating3d(); - output_surface_ = ret.get(); - return std::move(ret); - } - void ChangeTree() override { ++commit_count_; switch (commit_count_) { @@ -197,9 +189,9 @@ } } - void SwapBuffersCompleteOnThread() override { - std::vector<uint32_t>& satisfied = - output_surface_->last_sent_frame()->metadata.satisfies_sequences; + void DisplayReceivedCompositorFrameOnThread( + const CompositorFrame& frame) override { + const std::vector<uint32_t>& satisfied = frame.metadata.satisfies_sequences; EXPECT_LE(satisfied.size(), 1u); if (satisfied.size() == 1) { // Eventually the one SurfaceSequence should be satisfied, but only @@ -219,8 +211,6 @@ // callback. EXPECT_TRUE(satisfied_sequence_.is_null()); } - - FakeOutputSurface* output_surface_; }; SINGLE_AND_MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithDraw);
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 15d2131..39cad04 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -34,6 +34,7 @@ #include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" +#include "cc/test/test_delegating_output_surface.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/blocking_task_runner.h" @@ -631,12 +632,29 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { public: - TextureLayerImplWithMailboxThreadedCallback() - : callback_count_(0), - commit_count_(0) {} + TextureLayerImplWithMailboxThreadedCallback() = default; + + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + bool synchronous_composite = + !HasImplThread() && + !layer_tree_host()->settings().single_thread_proxy_scheduler; + // Allow relaim resources for this test so that mailboxes in the display + // will be returned inside the commit that replaces them. + bool force_disable_reclaim_resources = false; + return base::MakeUnique<TestDelegatingOutputSurface>( + compositor_context_provider, std::move(worker_context_provider), + CreateDisplayOutputSurface(compositor_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + layer_tree_host()->settings().renderer_settings, ImplThreadTaskRunner(), + synchronous_composite, force_disable_reclaim_resources); + } // Make sure callback is received on main and doesn't block the impl thread. - void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) { + void ReleaseCallback(char mailbox_char, + const gpu::SyncToken& sync_token, + bool lost_resource) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); EXPECT_FALSE(lost_resource); ++callback_count_; @@ -647,12 +665,15 @@ std::unique_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(base::Bind( &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback, - base::Unretained(this))); + base::Unretained(this), mailbox_char)); layer_->SetTextureMailbox( TextureMailbox(MailboxFromChar(mailbox_char), SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), GL_TEXTURE_2D), std::move(callback)); + // Damage the layer so we send a new frame with the new mailbox to the + // Display compositor. + layer_->SetNeedsDisplay(); } void BeginTest() override { @@ -703,32 +724,17 @@ layer_->SetTextureMailbox(TextureMailbox(), nullptr); break; case 4: - // With impl painting, the texture mailbox will still be on the impl - // thread when the commit finishes, because the layer is not drawble - // when it has no texture mailbox, and thus does not block the commit - // on activation. So, we wait for activation. - // TODO(danakj): fix this. crbug.com/277953 - layer_tree_host()->SetNeedsCommit(); - break; - case 5: EXPECT_EQ(4, callback_count_); // Restore a mailbox for the next step. SetMailbox('5'); break; - case 6: + case 5: // Case #5: remove layer from tree. Callback should *not* be called, the // mailbox is returned to the main thread. EXPECT_EQ(4, callback_count_); layer_->RemoveFromParent(); break; - case 7: - // With impl painting, the texture mailbox will still be on the impl - // thread when the commit finishes, because the layer is not around to - // block the commit on activation anymore. So, we wait for activation. - // TODO(danakj): fix this. crbug.com/277953 - layer_tree_host()->SetNeedsCommit(); - break; - case 8: + case 6: EXPECT_EQ(4, callback_count_); // Resetting the mailbox will call the callback now. layer_->SetTextureMailbox(TextureMailbox(), nullptr); @@ -745,8 +751,8 @@ private: base::ThreadChecker main_thread_; - int callback_count_; - int commit_count_; + int callback_count_ = 0; + int commit_count_ = 0; scoped_refptr<Layer> root_; scoped_refptr<TextureLayer> layer_; };
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc index 2af413d4..0394d12 100644 --- a/cc/output/delegating_renderer_unittest.cc +++ b/cc/output/delegating_renderer_unittest.cc
@@ -13,22 +13,7 @@ namespace cc { -class DelegatingRendererTest : public LayerTreeTest { - public: - DelegatingRendererTest() : LayerTreeTest(), output_surface_(NULL) {} - ~DelegatingRendererTest() override {} - - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - std::unique_ptr<FakeOutputSurface> output_surface = - FakeOutputSurface::CreateDelegating3d(); - output_surface_ = output_surface.get(); - return std::move(output_surface); - } - - protected: - TestWebGraphicsContext3D* context3d_; - FakeOutputSurface* output_surface_; -}; +class DelegatingRendererTest : public LayerTreeTest {}; class DelegatingRendererTestDraw : public DelegatingRendererTest { public: @@ -39,40 +24,30 @@ void AfterTest() override {} - DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) override { - EXPECT_EQ(0u, output_surface_->num_sent_frames()); - - const CompositorFrame* last_frame = output_surface_->last_sent_frame(); - EXPECT_EQ(nullptr, last_frame); - return DRAW_SUCCESS; - } - void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_EQ(0u, output_surface_->num_sent_frames()); + EXPECT_EQ(0, num_swaps_); drawn_viewport_ = host_impl->DeviceViewport(); } - void SwapBuffersCompleteOnThread() override { - EXPECT_EQ(1u, output_surface_->num_sent_frames()); + void DisplayReceivedCompositorFrameOnThread( + const CompositorFrame& frame) override { + EXPECT_EQ(1, ++num_swaps_); - const CompositorFrame* last_frame = output_surface_->last_sent_frame(); - DelegatedFrameData* last_frame_data = - last_frame->delegated_frame_data.get(); - ASSERT_TRUE(last_frame->delegated_frame_data); - EXPECT_FALSE(last_frame->gl_frame_data); + DelegatedFrameData* last_frame_data = frame.delegated_frame_data.get(); + ASSERT_TRUE(frame.delegated_frame_data); + EXPECT_FALSE(frame.gl_frame_data); EXPECT_EQ(drawn_viewport_, last_frame_data->render_pass_list.back()->output_rect); - EXPECT_EQ(0.5f, last_frame->metadata.min_page_scale_factor); - EXPECT_EQ(4.f, last_frame->metadata.max_page_scale_factor); + EXPECT_EQ(0.5f, frame.metadata.min_page_scale_factor); + EXPECT_EQ(4.f, frame.metadata.max_page_scale_factor); - EXPECT_EQ(0u, last_frame->delegated_frame_data->resource_list.size()); - EXPECT_EQ(1u, last_frame->delegated_frame_data->render_pass_list.size()); + EXPECT_EQ(0u, frame.delegated_frame_data->resource_list.size()); + EXPECT_EQ(1u, frame.delegated_frame_data->render_pass_list.size()); EndTest(); } + int num_swaps_ = 0; gfx::Rect drawn_viewport_; }; @@ -103,23 +78,17 @@ return draw_result; } - void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_EQ(0u, output_surface_->num_sent_frames()); - } + void DisplayReceivedCompositorFrameOnThread( + const CompositorFrame& frame) override { + ASSERT_TRUE(frame.delegated_frame_data); - void SwapBuffersCompleteOnThread() override { - EXPECT_EQ(1u, output_surface_->num_sent_frames()); - - const CompositorFrame* last_frame = output_surface_->last_sent_frame(); - ASSERT_TRUE(last_frame->delegated_frame_data); - - EXPECT_EQ(2u, last_frame->delegated_frame_data->render_pass_list.size()); + EXPECT_EQ(2u, frame.delegated_frame_data->render_pass_list.size()); // Each render pass has 10 resources in it. And the root render pass has a // mask resource used when drawing the child render pass, as well as its // replica (it's added twice). The number 10 may change if // AppendOneOfEveryQuadType() is updated, and the value here should be // updated accordingly. - EXPECT_EQ(22u, last_frame->delegated_frame_data->resource_list.size()); + EXPECT_EQ(22u, frame.delegated_frame_data->resource_list.size()); EndTest(); }
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 7783adb..75a3db5 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc
@@ -396,6 +396,8 @@ highp_threshold_min_(highp_threshold_min), highp_threshold_cache_(0), use_sync_query_(false), + gl_composited_texture_quad_border_( + settings->gl_composited_texture_quad_border), bound_geometry_(NO_BINDING) { DCHECK(gl_); DCHECK(context_support_); @@ -2554,6 +2556,28 @@ 6 * static_cast<int>(draw_cache_.matrix_data.size()), GL_UNSIGNED_SHORT, 0); + // Draw the border if requested. + if (gl_composited_texture_quad_border_) { + // When we draw the composited borders we have one flush per quad. + DCHECK_EQ(1u, draw_cache_.matrix_data.size()); + SetBlendEnabled(false); + const DebugBorderProgram* program = GetDebugBorderProgram(); + DCHECK(program && (program->initialized() || IsContextLost())); + SetUseProgram(program->program()); + + gl_->UniformMatrix4fv( + program->vertex_shader().matrix_location(), 1, false, + reinterpret_cast<float*>(&draw_cache_.matrix_data.front())); + + gl_->Uniform4f(program->fragment_shader().color_location(), 0.0f, 1.0f, + 0.0f, 1.0f); + + gl_->LineWidth(3.0f); + // The indices for the line are stored in the same array as the triangle + // indices. + gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0); + } + // Clear the cache. draw_cache_.program_id = -1; draw_cache_.uv_xform_data.resize(0); @@ -2678,6 +2702,8 @@ PrepareGeometry(CLIPPED_BINDING); clipped_geometry_->InitializeCustomQuadWithUVs(scaled_region, uv); FlushTextureQuadCache(CLIPPED_BINDING); + } else if (gl_composited_texture_quad_border_) { + FlushTextureQuadCache(SHARED_BINDING); } }
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index 685b016..4e5c59c 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h
@@ -532,6 +532,8 @@ // overlay resource. This means the GLRenderer needs its own ResourcePool. std::unique_ptr<ResourcePool> overlay_resource_pool_; + // If true, draw a green border after compositing a texture quad using GL. + bool gl_composited_texture_quad_border_; BoundGeometry bound_geometry_; DISALLOW_COPY_AND_ASSIGN(GLRenderer); };
diff --git a/cc/output/renderer_settings.cc b/cc/output/renderer_settings.cc index 23a3534f..308926c 100644 --- a/cc/output/renderer_settings.cc +++ b/cc/output/renderer_settings.cc
@@ -21,6 +21,7 @@ should_clear_root_render_pass(true), disable_display_vsync(false), release_overlay_resources_after_gpu_query(false), + gl_composited_texture_quad_border(false), refresh_rate(60.0), highp_threshold_min(0), texture_id_allocation_chunk_size(64),
diff --git a/cc/output/renderer_settings.h b/cc/output/renderer_settings.h index eac84966..16e8be9 100644 --- a/cc/output/renderer_settings.h +++ b/cc/output/renderer_settings.h
@@ -31,6 +31,8 @@ bool should_clear_root_render_pass; bool disable_display_vsync; bool release_overlay_resources_after_gpu_query; + bool gl_composited_texture_quad_border; + double refresh_rate; int highp_threshold_min; size_t texture_id_allocation_chunk_size;
diff --git a/cc/output/renderer_unittest.cc b/cc/output/renderer_unittest.cc index 9fe079a..e02110d 100644 --- a/cc/output/renderer_unittest.cc +++ b/cc/output/renderer_unittest.cc
@@ -42,7 +42,8 @@ public: explicit MockContextProvider( std::unique_ptr<TestWebGraphicsContext3D> context) - : TestContextProvider(base::MakeUnique<TestGLES2Interface>(), + : TestContextProvider(base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2Interface>(), std::move(context)) {} MOCK_METHOD0(DeleteCachedResources, void());
diff --git a/cc/playback/display_item_list.h b/cc/playback/display_item_list.h index bfc06c8..87a98fc 100644 --- a/cc/playback/display_item_list.h +++ b/cc/playback/display_item_list.h
@@ -118,8 +118,6 @@ const DisplayItemListSettings& display_list_settings); ~DisplayItemList(); - void ProcessAppendedItem(const DisplayItem* item); - RTree rtree_; // For testing purposes only. Whether to keep visual rects across calls to // Finalize().
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index fe35c7b..9ded1a21 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc
@@ -288,6 +288,8 @@ should_draw = false; } + client_->DisplayWillDrawAndSwap(should_draw, frame_data->render_pass_list); + if (should_draw) { gfx::Rect device_viewport_rect = external_viewport_.IsEmpty() ? gfx::Rect(current_surface_size_) @@ -339,6 +341,7 @@ DidSwapBuffersComplete(); } + client_->DisplayDidDrawAndSwap(); return true; }
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index 24942a9..0fc2fb0 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h
@@ -115,6 +115,7 @@ } bool has_scheduler() const { return !!scheduler_; } + DirectRenderer* renderer_for_testing() const { return renderer_.get(); } private: void InitializeRenderer(); @@ -124,8 +125,8 @@ gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_; const RendererSettings settings_; - DisplayClient* client_; - SurfaceManager* surface_manager_; + DisplayClient* client_ = nullptr; + SurfaceManager* surface_manager_ = nullptr; uint32_t compositor_surface_namespace_; SurfaceId current_surface_id_; gfx::Size current_surface_size_;
diff --git a/cc/surfaces/display_client.h b/cc/surfaces/display_client.h index 8f7be8b9..432b44ac 100644 --- a/cc/surfaces/display_client.h +++ b/cc/surfaces/display_client.h
@@ -5,6 +5,8 @@ #ifndef CC_SURFACES_DISPLAY_CLIENT_H_ #define CC_SURFACES_DISPLAY_CLIENT_H_ +#include "cc/quads/render_pass.h" + namespace cc { struct ManagedMemoryPolicy; @@ -13,6 +15,9 @@ virtual ~DisplayClient() {} virtual void DisplayOutputSurfaceLost() = 0; virtual void DisplaySetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; + virtual void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) = 0; + virtual void DisplayDidDrawAndSwap() = 0; }; } // namespace cc
diff --git a/cc/surfaces/display_unittest.cc b/cc/surfaces/display_unittest.cc index 74c6508..51e7fd6 100644 --- a/cc/surfaces/display_unittest.cc +++ b/cc/surfaces/display_unittest.cc
@@ -164,6 +164,9 @@ public: void DisplayOutputSurfaceLost() override {} void DisplaySetMemoryPolicy(const ManagedMemoryPolicy& policy) override {} + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) override {} + void DisplayDidDrawAndSwap() override {} }; void CopyCallback(bool* called, std::unique_ptr<CopyOutputResult> result) {
diff --git a/cc/surfaces/surface_display_output_surface.cc b/cc/surfaces/surface_display_output_surface.cc index 3b1d59d..294840b 100644 --- a/cc/surfaces/surface_display_output_surface.cc +++ b/cc/surfaces/surface_display_output_surface.cc
@@ -75,7 +75,7 @@ factory_.SubmitCompositorFrame( delegated_surface_id_, std::move(frame), - base::Bind(&SurfaceDisplayOutputSurface::SwapBuffersComplete, + base::Bind(&SurfaceDisplayOutputSurface::DidDrawCallback, base::Unretained(this))); } @@ -153,7 +153,19 @@ SetMemoryPolicy(policy); } -void SurfaceDisplayOutputSurface::SwapBuffersComplete() { +void SurfaceDisplayOutputSurface::DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const RenderPassList& render_passes) { + // This notification is not relevant to our client outside of tests. +} + +void SurfaceDisplayOutputSurface::DisplayDidDrawAndSwap() { + // This notification is not relevant to our client outside of tests. We + // unblock the client from DidDrawCallback() when the surface is going to + // be drawn. +} + +void SurfaceDisplayOutputSurface::DidDrawCallback() { // TODO(danakj): Why the lost check? if (!output_surface_lost_) client_->DidSwapBuffersComplete();
diff --git a/cc/surfaces/surface_display_output_surface.h b/cc/surfaces/surface_display_output_surface.h index f1bd5ea..d5f2d9f 100644 --- a/cc/surfaces/surface_display_output_surface.h +++ b/cc/surfaces/surface_display_output_surface.h
@@ -55,9 +55,12 @@ // DisplayClient implementation. void DisplayOutputSurfaceLost() override; void DisplaySetMemoryPolicy(const ManagedMemoryPolicy& policy) override; + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) override; + void DisplayDidDrawAndSwap() override; private: - void SwapBuffersComplete(); + void DidDrawCallback(); // This class is only meant to be used on a single thread. base::ThreadChecker thread_checker_;
diff --git a/cc/test/failure_output_surface.cc b/cc/test/failure_output_surface.cc deleted file mode 100644 index 64c9b8a..0000000 --- a/cc/test/failure_output_surface.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cc/test/failure_output_surface.h" - -namespace cc { - -FailureOutputSurface::FailureOutputSurface(bool is_delegating) - : FakeOutputSurface(nullptr, nullptr, is_delegating) {} - -bool FailureOutputSurface::BindToClient(OutputSurfaceClient* client) { - // This will force this output surface to not initialize in LTHI - // and eventually get back to LTH::DidFailToInitializeOutputSurface; - return false; -} - -} // namespace cc
diff --git a/cc/test/failure_output_surface.h b/cc/test/failure_output_surface.h deleted file mode 100644 index a7aca5b..0000000 --- a/cc/test/failure_output_surface.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_TEST_FAILURE_OUTPUT_SURFACE_H_ -#define CC_TEST_FAILURE_OUTPUT_SURFACE_H_ - -#include "base/macros.h" -#include "cc/test/fake_output_surface.h" - -namespace cc { - -class FailureOutputSurface : public FakeOutputSurface { - public: - explicit FailureOutputSurface(bool is_delegating); - - bool BindToClient(OutputSurfaceClient* client) override; - - private: - DISALLOW_COPY_AND_ASSIGN(FailureOutputSurface); -}; - -} // namespace cc - -#endif // CC_TEST_FAILURE_OUTPUT_SURFACE_H_
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index e985bcf5..f3748ca 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h
@@ -46,9 +46,8 @@ static std::unique_ptr<FakeOutputSurface> Create3d( std::unique_ptr<TestGLES2Interface> gl) { - return base::WrapUnique( - new FakeOutputSurface(TestContextProvider::Create(std::move(gl)), - TestContextProvider::CreateWorker(), false)); + return base::WrapUnique(new FakeOutputSurface( + TestContextProvider::Create(std::move(gl)), nullptr, false)); } static std::unique_ptr<FakeOutputSurface> Create3d(
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 901bff9..ae31dba 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -37,27 +37,49 @@ LayerTreePixelTest::~LayerTreePixelTest() {} -void LayerTreePixelTest::InitializeSettings(LayerTreeSettings* settings) { - // The PixelTestDelegatingOutputSurface will provide a BeginFrameSource. - settings->use_output_surface_begin_frame_source = true; -} - -std::unique_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface() { - // Always test Webview shenanigans. - gfx::Size surface_expansion_size(40, 60); - +std::unique_ptr<TestDelegatingOutputSurface> + LayerTreePixelTest::CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider>, + scoped_refptr<ContextProvider>) { scoped_refptr<TestInProcessContextProvider> compositor_context_provider; scoped_refptr<TestInProcessContextProvider> worker_context_provider; - scoped_refptr<TestInProcessContextProvider> display_context_provider; - std::unique_ptr<PixelTestOutputSurface> display_output_surface; if (test_type_ == PIXEL_TEST_GL) { compositor_context_provider = new TestInProcessContextProvider(nullptr); worker_context_provider = new TestInProcessContextProvider(compositor_context_provider.get()); - display_context_provider = new TestInProcessContextProvider(nullptr); + } + bool synchronous_composite = + !HasImplThread() && + !layer_tree_host()->settings().single_thread_proxy_scheduler; + // Allow resource reclaiming for partial raster tests to get back + // resources from the Display. + bool force_disable_reclaim_resources = false; + auto delegating_output_surface = + base::MakeUnique<TestDelegatingOutputSurface>( + compositor_context_provider, std::move(worker_context_provider), + CreateDisplayOutputSurface(compositor_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + RendererSettings(), ImplThreadTaskRunner(), synchronous_composite, + force_disable_reclaim_resources); + delegating_output_surface->display()->SetEnlargePassTextureAmountForTesting( + enlarge_texture_amount_); + return delegating_output_surface; +} + +std::unique_ptr<OutputSurface> LayerTreePixelTest::CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) { + // Always test Webview shenanigans. + gfx::Size surface_expansion_size(40, 60); + + std::unique_ptr<PixelTestOutputSurface> display_output_surface; + if (test_type_ == PIXEL_TEST_GL) { bool flipped_output_surface = false; display_output_surface = base::MakeUnique<PixelTestOutputSurface>( - std::move(display_context_provider), nullptr, flipped_output_surface); + // Pixel tests use a separate context for the Display to more closely + // mimic texture transport from the renderer process to the Display + // compositor. + make_scoped_refptr(new TestInProcessContextProvider(nullptr)), nullptr, + flipped_output_surface); } else { std::unique_ptr<PixelTestSoftwareOutputDevice> software_output_device( new PixelTestSoftwareOutputDevice); @@ -66,20 +88,7 @@ std::move(software_output_device)); } display_output_surface->set_surface_expansion_size(surface_expansion_size); - - auto* task_runner = ImplThreadTaskRunner(); - bool synchronous_composite = - !HasImplThread() && - !layer_tree_host()->settings().single_thread_proxy_scheduler; - auto delegating_output_surface = - base::MakeUnique<TestDelegatingOutputSurface>( - std::move(compositor_context_provider), - std::move(worker_context_provider), std::move(display_output_surface), - shared_bitmap_manager(), gpu_memory_buffer_manager(), - RendererSettings(), task_runner, synchronous_composite); - delegating_output_surface->display()->SetEnlargePassTextureAmountForTesting( - enlarge_texture_amount_); - return std::move(delegating_output_surface); + return std::move(display_output_surface); } std::unique_ptr<CopyOutputRequest>
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h index 3ab75b4..3e266cb2 100644 --- a/cc/test/layer_tree_pixel_test.h +++ b/cc/test/layer_tree_pixel_test.h
@@ -41,8 +41,11 @@ ~LayerTreePixelTest() override; // LayerTreeTest overrides. - void InitializeSettings(LayerTreeSettings* settings) override; - std::unique_ptr<OutputSurface> CreateOutputSurface() override; + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override; + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override; virtual std::unique_ptr<CopyOutputRequest> CreateCopyOutputRequest();
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 49d4a70..5f64fc2c 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -28,9 +28,8 @@ #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_output_surface.h" #include "cc/test/test_context_provider.h" -#include "cc/test/test_gpu_memory_buffer_manager.h" +#include "cc/test/test_delegating_output_surface.h" #include "cc/test/test_shared_bitmap_manager.h" -#include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_host_single_thread_client.h" @@ -183,15 +182,6 @@ test_hooks_->DrawLayersOnThread(this); } - void DidSwapBuffersComplete() override { - LayerTreeHostImpl::DidSwapBuffersComplete(); - test_hooks_->SwapBuffersCompleteOnThread(); - } - - void ReclaimResources(const ReturnedResourceArray& resources) override { - LayerTreeHostImpl::ReclaimResources(resources); - } - void NotifyReadyToActivate() override { if (block_notify_ready_to_activate_for_testing_) { notify_ready_to_activate_was_blocked_ = true; @@ -441,19 +431,34 @@ bool test_started_; }; +class LayerTreeTestDelegatingOutputSurfaceClient + : public TestDelegatingOutputSurfaceClient { + public: + explicit LayerTreeTestDelegatingOutputSurfaceClient(TestHooks* hooks) + : hooks_(hooks) {} + + // TestDelegatingOutputSurfaceClient implementation. + void DisplayReceivedCompositorFrame(const CompositorFrame& frame) override { + hooks_->DisplayReceivedCompositorFrameOnThread(frame); + } + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) override { + hooks_->DisplayWillDrawAndSwapOnThread(will_draw_and_swap, render_passes); + } + void DisplayDidDrawAndSwap() override { + hooks_->DisplayDidDrawAndSwapOnThread(); + } + + private: + TestHooks* hooks_; +}; + LayerTreeTest::LayerTreeTest() - : external_begin_frame_source_(nullptr), - remote_proto_channel_bridge_(this), + : remote_proto_channel_bridge_(this), image_serialization_processor_( base::WrapUnique(new FakeImageSerializationProcessor)), - beginning_(false), - end_when_begin_returns_(false), - timed_out_(false), - scheduled_(false), - started_(false), - ended_(false), - delegating_renderer_(false), - timeout_seconds_(0), + delegating_output_surface_client_( + new LayerTreeTestDelegatingOutputSurfaceClient(this)), weak_factory_(this) { main_thread_weak_ptr_ = weak_factory_.GetWeakPtr(); @@ -600,16 +605,6 @@ main_thread_weak_ptr_)); } -void LayerTreeTest::SetOutputSurfaceOnLayerTreeHost( - std::unique_ptr<OutputSurface> output_surface) { - if (IsRemoteTest()) { - DCHECK(remote_client_layer_tree_host_); - remote_client_layer_tree_host_->SetOutputSurface(std::move(output_surface)); - } else { - layer_tree_host_->SetOutputSurface(std::move(output_surface)); - } -} - std::unique_ptr<OutputSurface> LayerTreeTest::ReleaseOutputSurfaceOnLayerTreeHost() { if (IsRemoteTest()) { @@ -635,14 +630,6 @@ void LayerTreeTest::DoBeginTest() { client_ = LayerTreeHostClientForTesting::Create(this); - std::unique_ptr<FakeExternalBeginFrameSource> external_begin_frame_source; - if (settings_.use_external_begin_frame_source) { - DCHECK(!IsRemoteTest()); - external_begin_frame_source.reset(new FakeExternalBeginFrameSource( - settings_.renderer_settings.refresh_rate, true)); - external_begin_frame_source_ = external_begin_frame_source.get(); - } - DCHECK(!impl_thread_ || impl_thread_->task_runner().get()); if (IsRemoteTest()) { @@ -650,8 +637,7 @@ layer_tree_host_ = LayerTreeHostForTesting::Create( this, mode_, client_.get(), &remote_proto_channel_bridge_.channel_main, nullptr, nullptr, task_graph_runner_.get(), settings_, - base::ThreadTaskRunnerHandle::Get(), nullptr, - std::move(external_begin_frame_source), + base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, image_serialization_processor_.get()); DCHECK(remote_proto_channel_bridge_.channel_main.HasReceiver()); } else { @@ -659,8 +645,7 @@ this, mode_, client_.get(), nullptr, shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), task_graph_runner_.get(), settings_, base::ThreadTaskRunnerHandle::Get(), - impl_thread_ ? impl_thread_->task_runner() : NULL, - std::move(external_begin_frame_source), + impl_thread_ ? impl_thread_->task_runner() : nullptr, nullptr, image_serialization_processor_.get()); } @@ -828,7 +813,11 @@ settings_.verify_transform_tree_calculations = true; settings_.renderer_settings.buffer_to_texture_target_map = DefaultBufferToTextureTargetMapForTesting(); + // The TestDelegatingOutputSurface will provide a BeginFrameSource. + settings_.use_output_surface_begin_frame_source = true; InitializeSettings(&settings_); + DCHECK(settings_.use_output_surface_begin_frame_source); + DCHECK(!settings_.use_external_begin_frame_source); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -849,22 +838,46 @@ } void LayerTreeTest::RequestNewOutputSurface() { - if (settings_.use_external_begin_frame_source && - settings_.wait_for_beginframe_interval) { - DCHECK(external_begin_frame_source_); + scoped_refptr<TestContextProvider> shared_context_provider = + TestContextProvider::Create(); + scoped_refptr<TestContextProvider> worker_context_provider = + TestContextProvider::CreateWorker(); + + auto delegating_output_surface = CreateDelegatingOutputSurface( + std::move(shared_context_provider), std::move(worker_context_provider)); + delegating_output_surface->SetClient(delegating_output_surface_client_.get()); + + if (IsRemoteTest()) { + DCHECK(remote_client_layer_tree_host_); + remote_client_layer_tree_host_->SetOutputSurface( + std::move(delegating_output_surface)); + } else { + layer_tree_host_->SetOutputSurface(std::move(delegating_output_surface)); } - SetOutputSurfaceOnLayerTreeHost(CreateOutputSurface()); } -std::unique_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() { - if (delegating_renderer_) - return FakeOutputSurface::CreateDelegating3d(); +std::unique_ptr<TestDelegatingOutputSurface> +LayerTreeTest::CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) { + bool synchronous_composite = + !HasImplThread() && + !layer_tree_host()->settings().single_thread_proxy_scheduler; + // Disable reclaim resources by default to act like the Display lives + // out-of-process. + bool force_disable_reclaim_resources = true; + return base::MakeUnique<TestDelegatingOutputSurface>( + compositor_context_provider, std::move(worker_context_provider), + CreateDisplayOutputSurface(compositor_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + layer_tree_host()->settings().renderer_settings, ImplThreadTaskRunner(), + synchronous_composite, force_disable_reclaim_resources); +} - // Make a worker context in a non-delegating OutputSurface. This is an - // exceptional situation for these tests as they put a non-delegating - // OutputSurface into the LayerTreeHost. - return FakeOutputSurface::Create3d(TestContextProvider::Create(), - TestContextProvider::CreateWorker()); +std::unique_ptr<OutputSurface> LayerTreeTest::CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) { + // By default the Display shares a context with the LayerTreeHostImpl. + return FakeOutputSurface::Create3d(std::move(compositor_context_provider)); } void LayerTreeTest::DestroyLayerTreeHost() { @@ -909,10 +922,6 @@ DCHECK(task_runner_provider()->HasImplThread()); } -TaskGraphRunner* LayerTreeTest::task_graph_runner() const { - return task_graph_runner_.get(); -} - TaskRunnerProvider* LayerTreeTest::task_runner_provider() const { // All LayerTreeTests can use the task runner provider to access the impl // thread. In the remote mode, the impl thread of the compositor lives on
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 678b5d7..d682495 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h
@@ -9,14 +9,15 @@ #include "base/threading/thread.h" #include "cc/animation/animation_delegate.h" #include "cc/test/remote_proto_channel_bridge.h" +#include "cc/test/test_gpu_memory_buffer_manager.h" #include "cc/test/test_hooks.h" +#include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_impl.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { class AnimationPlayer; -class FakeExternalBeginFrameSource; class FakeLayerTreeHostClient; class FakeOutputSurface; class LayerImpl; @@ -24,10 +25,12 @@ class LayerTreeHostForTesting; class LayerTreeHostClient; class LayerTreeHostImpl; +class LayerTreeTestDelegatingOutputSurfaceClient; class ProxyImpl; class ProxyMain; class RemoteChannelImplForTest; class TestContextProvider; +class TestDelegatingOutputSurface; class TestGpuMemoryBufferManager; class TestTaskGraphRunner; class TestWebGraphicsContext3D; @@ -113,8 +116,6 @@ void DispatchCompositeImmediately(); void DispatchNextCommitWaitsForActivation(); - void SetOutputSurfaceOnLayerTreeHost( - std::unique_ptr<OutputSurface> output_surface); std::unique_ptr<OutputSurface> ReleaseOutputSurfaceOnLayerTreeHost(); void SetVisibleOnLayerTreeHost(bool visible); @@ -137,7 +138,9 @@ } Proxy* remote_client_proxy() const; TaskRunnerProvider* task_runner_provider() const; - TaskGraphRunner* task_graph_runner() const; + TaskGraphRunner* task_graph_runner() const { + return task_graph_runner_.get(); + } bool TestEnded() const { return ended_; } LayerTreeHost* layer_tree_host(); @@ -146,7 +149,7 @@ SharedBitmapManager* shared_bitmap_manager() const { return shared_bitmap_manager_.get(); } - TestGpuMemoryBufferManager* gpu_memory_buffer_manager() { + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() { return gpu_memory_buffer_manager_.get(); } @@ -158,9 +161,20 @@ // By default, output surface recreation is synchronous. void RequestNewOutputSurface() override; - // Override this for pixel tests, where you need a real output surface, or - // if you want to control the output surface used for drawing. - virtual std::unique_ptr<OutputSurface> CreateOutputSurface(); + // Override this and call the base class to change what ContextProviders will + // be used (such as for pixel tests). Or override it and create your own + // TestDelegatingOutputSurface to control how it is created. + virtual std::unique_ptr<TestDelegatingOutputSurface> + CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider); + // Override this and call the base class to change what ContextProvider will + // be used, such as to prevent sharing the context with the delegating + // OutputSurface. Or override it and create your own OutputSurface to change + // what type of OutputSurface is used, such as a real OutputSurface for pixel + // tests or a software-compositing OutputSurface. + virtual std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider); bool IsRemoteTest() const; @@ -177,21 +191,22 @@ // The LayerTreeHost created by the cc embedder on the client in remote mode. std::unique_ptr<LayerTreeHostForTesting> remote_client_layer_tree_host_; - FakeExternalBeginFrameSource* external_begin_frame_source_; RemoteProtoChannelBridge remote_proto_channel_bridge_; std::unique_ptr<ImageSerializationProcessor> image_serialization_processor_; - bool beginning_; - bool end_when_begin_returns_; - bool timed_out_; - bool scheduled_; - bool started_; - bool ended_; - bool delegating_renderer_; + bool beginning_ = false; + bool end_when_begin_returns_ = false; + bool timed_out_ = false; + bool scheduled_ = false; + bool started_ = false; + bool ended_ = false; + bool delegating_renderer_ = false; - int timeout_seconds_; + int timeout_seconds_ = false; + std::unique_ptr<LayerTreeTestDelegatingOutputSurfaceClient> + delegating_output_surface_client_; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; std::unique_ptr<base::Thread> impl_thread_;
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc index 31ef12e9..2634aff 100644 --- a/cc/test/test_context_provider.cc +++ b/cc/test/test_context_provider.cc
@@ -23,13 +23,17 @@ // static scoped_refptr<TestContextProvider> TestContextProvider::Create() { - return Create(TestWebGraphicsContext3D::Create()); + return new TestContextProvider(base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2Interface>(), + TestWebGraphicsContext3D::Create()); } // static scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker() { - scoped_refptr<TestContextProvider> worker_context_provider = - Create(TestWebGraphicsContext3D::Create()); + scoped_refptr<TestContextProvider> worker_context_provider( + new TestContextProvider(base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2Interface>(), + TestWebGraphicsContext3D::Create())); // Worker contexts are bound to the thread they are created on. if (!worker_context_provider->BindToCurrentThread()) return nullptr; @@ -40,7 +44,8 @@ scoped_refptr<TestContextProvider> TestContextProvider::Create( std::unique_ptr<TestWebGraphicsContext3D> context) { DCHECK(context); - return new TestContextProvider(base::MakeUnique<TestGLES2Interface>(), + return new TestContextProvider(base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2Interface>(), std::move(context)); } @@ -48,23 +53,36 @@ scoped_refptr<TestContextProvider> TestContextProvider::Create( std::unique_ptr<TestGLES2Interface> gl) { DCHECK(gl); - return new TestContextProvider(std::move(gl), + return new TestContextProvider(base::MakeUnique<TestContextSupport>(), + std::move(gl), TestWebGraphicsContext3D::Create()); } +// static +scoped_refptr<TestContextProvider> TestContextProvider::Create( + std::unique_ptr<TestWebGraphicsContext3D> context, + std::unique_ptr<TestContextSupport> support) { + DCHECK(context); + DCHECK(support); + return new TestContextProvider(std::move(support), + base::MakeUnique<TestGLES2Interface>(), + std::move(context)); +} + TestContextProvider::TestContextProvider( + std::unique_ptr<TestContextSupport> support, std::unique_ptr<TestGLES2Interface> gl, std::unique_ptr<TestWebGraphicsContext3D> context) - : context3d_(std::move(context)), + : support_(std::move(support)), + context3d_(std::move(context)), context_gl_(std::move(gl)), - bound_(false), weak_ptr_factory_(this) { DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK(context3d_); DCHECK(context_gl_); context_thread_checker_.DetachFromThread(); context_gl_->set_test_context(context3d_.get()); - context3d_->set_test_support(&support_); + context3d_->set_test_support(support_.get()); } TestContextProvider::~TestContextProvider() { @@ -110,7 +128,7 @@ } gpu::ContextSupport* TestContextProvider::ContextSupport() { - return &support_; + return support(); } class GrContext* TestContextProvider::GrContext() {
diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h index 97c7abc..d7c5627f 100644 --- a/cc/test/test_context_provider.h +++ b/cc/test/test_context_provider.h
@@ -36,6 +36,9 @@ static scoped_refptr<TestContextProvider> Create( std::unique_ptr<TestWebGraphicsContext3D> context); static scoped_refptr<TestContextProvider> Create( + std::unique_ptr<TestWebGraphicsContext3D> context, + std::unique_ptr<TestContextSupport> support); + static scoped_refptr<TestContextProvider> Create( std::unique_ptr<TestGLES2Interface> gl); bool BindToCurrentThread() override; @@ -57,10 +60,11 @@ // InitializeOnCurrentThread on the context returned from this method. TestWebGraphicsContext3D* UnboundTestContext3d(); - TestContextSupport* support() { return &support_; } + TestContextSupport* support() { return support_.get(); } protected: explicit TestContextProvider( + std::unique_ptr<TestContextSupport> support, std::unique_ptr<TestGLES2Interface> gl, std::unique_ptr<TestWebGraphicsContext3D> context); ~TestContextProvider() override; @@ -68,11 +72,10 @@ private: void OnLostContext(); - TestContextSupport support_; - + std::unique_ptr<TestContextSupport> support_; std::unique_ptr<TestWebGraphicsContext3D> context3d_; std::unique_ptr<TestGLES2Interface> context_gl_; - bool bound_; + bool bound_ = false; base::ThreadChecker main_thread_checker_; base::ThreadChecker context_thread_checker_;
diff --git a/cc/test/test_delegating_output_surface.cc b/cc/test/test_delegating_output_surface.cc index 8f586cf..9f980c3 100644 --- a/cc/test/test_delegating_output_surface.cc +++ b/cc/test/test_delegating_output_surface.cc
@@ -24,7 +24,8 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& renderer_settings, base::SingleThreadTaskRunner* task_runner, - bool synchronous_composite) + bool synchronous_composite, + bool force_disable_reclaim_resources) : OutputSurface(std::move(compositor_context_provider), std::move(worker_context_provider), nullptr), @@ -35,8 +36,16 @@ std::unique_ptr<SyntheticBeginFrameSource> begin_frame_source; std::unique_ptr<DisplayScheduler> scheduler; if (!synchronous_composite) { - begin_frame_source.reset(new DelayBasedBeginFrameSource( - base::MakeUnique<DelayBasedTimeSource>(task_runner))); + if (renderer_settings.disable_display_vsync) { + begin_frame_source.reset(new BackToBackBeginFrameSource( + base::MakeUnique<DelayBasedTimeSource>(task_runner))); + } else { + begin_frame_source.reset(new DelayBasedBeginFrameSource( + base::MakeUnique<DelayBasedTimeSource>(task_runner))); + begin_frame_source->SetAuthoritativeVSyncInterval( + base::TimeDelta::FromMilliseconds(1000.f / + renderer_settings.refresh_rate)); + } scheduler.reset(new DisplayScheduler( begin_frame_source.get(), task_runner, display_output_surface->capabilities().max_frames_pending)); @@ -52,8 +61,9 @@ capabilities_.delegated_rendering = true; // Since this OutputSurface and the Display are tightly coupled and in the // same process/thread, the LayerTreeHostImpl can reclaim resources from - // the Display. - capabilities_.can_force_reclaim_resources = true; + // the Display. But we allow tests to disable this to mimic an out-of-process + // Display. + capabilities_.can_force_reclaim_resources = !force_disable_reclaim_resources; capabilities_.delegated_sync_points_required = !context_shared_with_compositor; } @@ -107,6 +117,9 @@ } void TestDelegatingOutputSurface::SwapBuffers(CompositorFrame frame) { + if (test_client_) + test_client_->DisplayReceivedCompositorFrame(frame); + if (delegated_surface_id_.is_null()) { delegated_surface_id_ = surface_id_allocator_->GenerateId(); surface_factory_->Create(delegated_surface_id_); @@ -122,7 +135,7 @@ surface_factory_->SubmitCompositorFrame( delegated_surface_id_, std::move(frame), - base::Bind(&TestDelegatingOutputSurface::DrawCallback, + base::Bind(&TestDelegatingOutputSurface::DidDrawCallback, weak_ptrs_.GetWeakPtr(), synchronous)); for (std::unique_ptr<CopyOutputRequest>& copy_request : copy_requests_) @@ -130,11 +143,11 @@ std::move(copy_request)); copy_requests_.clear(); - if (!display_->has_scheduler()) + if (synchronous) display_->DrawAndSwap(); } -void TestDelegatingOutputSurface::DrawCallback(bool synchronous) { +void TestDelegatingOutputSurface::DidDrawCallback(bool synchronous) { // This is the frame ack to unthrottle the next frame, not actually a notice // that drawing is done. if (synchronous) { @@ -186,4 +199,16 @@ SetMemoryPolicy(policy); } +void TestDelegatingOutputSurface::DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const RenderPassList& render_passes) { + if (test_client_) + test_client_->DisplayWillDrawAndSwap(will_draw_and_swap, render_passes); +} + +void TestDelegatingOutputSurface::DisplayDidDrawAndSwap() { + if (test_client_) + test_client_->DisplayDidDrawAndSwap(); +} + } // namespace cc
diff --git a/cc/test/test_delegating_output_surface.h b/cc/test/test_delegating_output_surface.h index 25ccb123..f5ac294 100644 --- a/cc/test/test_delegating_output_surface.h +++ b/cc/test/test_delegating_output_surface.h
@@ -17,13 +17,24 @@ #include "cc/surfaces/surface_manager.h" namespace cc { - class CopyOutputRequest; +class TestDelegatingOutputSurfaceClient { + public: + virtual ~TestDelegatingOutputSurfaceClient() {} + + virtual void DisplayReceivedCompositorFrame(const CompositorFrame& frame) = 0; + virtual void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) = 0; + virtual void DisplayDidDrawAndSwap() = 0; +}; + class TestDelegatingOutputSurface : public OutputSurface, public SurfaceFactoryClient, public DisplayClient { public: + // Pass true for |force_disable_reclaim_resources| to act like the Display + // is out-of-process and can't return resources synchronously. TestDelegatingOutputSurface( scoped_refptr<ContextProvider> compositor_context_provider, scoped_refptr<ContextProvider> worker_context_provider, @@ -32,9 +43,14 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& renderer_settings, base::SingleThreadTaskRunner* task_runner, - bool synchronous_composite); + bool synchronous_composite, + bool force_disable_reclaim_resources); ~TestDelegatingOutputSurface() override; + void SetClient(TestDelegatingOutputSurfaceClient* client) { + test_client_ = client; + } + Display* display() const { return display_.get(); } // Will be submitted with the next SwapBuffers. @@ -55,9 +71,12 @@ // DisplayClient implementation. void DisplayOutputSurfaceLost() override; void DisplaySetMemoryPolicy(const ManagedMemoryPolicy& policy) override; + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) override; + void DisplayDidDrawAndSwap() override; private: - void DrawCallback(bool synchronous); + void DidDrawCallback(bool synchronous); // TODO(danakj): These don't to be stored in unique_ptrs when OutputSurface // is owned/destroyed on the compositor thread. @@ -72,6 +91,7 @@ std::unique_ptr<Display> display_; bool bound_ = false; + TestDelegatingOutputSurfaceClient* test_client_ = nullptr; std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests_;
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h index f386091d..ff0737f 100644 --- a/cc/test/test_hooks.h +++ b/cc/test/test_hooks.h
@@ -22,6 +22,7 @@ TestHooks(); ~TestHooks() override; + // Compositor thread hooks. virtual void CreateResourceAndRasterBufferProvider( LayerTreeHostImpl* host_impl, std::unique_ptr<RasterBufferProvider>* raster_buffer_provider, @@ -45,22 +46,33 @@ LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result); virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {} - // Note that this is called asynchronously from the LayerTreeHostImpl - // performing its draw, so you should record state you want to use here - // in DrawLayersOnThread() instead. For that reason this method does not - // receive a LayerTreeHostImpl pointer. - virtual void SwapBuffersCompleteOnThread() {} virtual void NotifyReadyToActivateOnThread(LayerTreeHostImpl* host_impl) {} virtual void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) {} virtual void NotifyAllTileTasksCompleted(LayerTreeHostImpl* host_impl) {} virtual void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, const Tile* tile) {} + virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, + bool visible) {} virtual void AnimateLayers(LayerTreeHostImpl* host_impl, base::TimeTicks monotonic_time) {} virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl, bool has_unfinished_animation) {} virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, base::TimeTicks monotonic_time) {} + + // Asynchronous compositor thread hooks. + // These are called asynchronously from the LayerTreeHostImpl performing its + // draw, so you should record state you want to use here in + // DrawLayersOnThread() instead. For that reason these methods do not receive + // a LayerTreeHostImpl pointer. + virtual void DisplayReceivedCompositorFrameOnThread( + const CompositorFrame& frame) {} + virtual void DisplayWillDrawAndSwapOnThread( + bool will_draw_and_swap, + const RenderPassList& render_passes) {} + virtual void DisplayDidDrawAndSwapOnThread() {} + + // Main thread hooks. virtual void ApplyViewportDeltas( const gfx::Vector2dF& inner_delta, const gfx::Vector2dF& outer_delta, @@ -79,8 +91,6 @@ virtual void DidCommit() {} virtual void DidCommitAndDrawFrame() {} virtual void DidCompleteSwapBuffers() {} - virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, - bool visible) {} virtual void ScheduleComposite() {} virtual void DidActivateSyncTree() {}
diff --git a/cc/test/test_web_graphics_context_3d.cc b/cc/test/test_web_graphics_context_3d.cc index 2641c90..4f0e3e61 100644 --- a/cc/test/test_web_graphics_context_3d.cc +++ b/cc/test/test_web_graphics_context_3d.cc
@@ -74,6 +74,7 @@ weak_ptr_factory_(this) { CreateNamespace(); set_support_image(true); + set_have_extension_egl_image(true); // For stream textures. } TestWebGraphicsContext3D::~TestWebGraphicsContext3D() {
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index b32ed4e..243e81da 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -797,11 +797,12 @@ !root_surface->layer_list().empty(); bool hud_wants_to_draw_ = active_tree_->hud_layer() && active_tree_->hud_layer()->IsAnimatingHUDContents(); + bool resources_must_be_resent = + output_surface_->capabilities().can_force_reclaim_resources; if (root_surface_has_contributing_layers && root_surface_has_no_visible_damage && !active_tree_->property_trees()->effect_tree.HasCopyRequests() && - !output_surface_->capabilities().can_force_reclaim_resources && - !hud_wants_to_draw_) { + !resources_must_be_resent && !hud_wants_to_draw_) { TRACE_EVENT0("cc", "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); frame->has_no_damage = true;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 862ef2f8..087ecd0a 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -7854,7 +7854,8 @@ context_provider, TestContextProvider::CreateWorker(), FakeOutputSurface::Create3d(context_provider), nullptr, nullptr, RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), - true /* synchronous_composite */)); + true /* synchronous_composite */, + false /* force_disable_reclaim_resources */)); SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc index 9923f24..e288f52 100644 --- a/cc/trees/layer_tree_host_perftest.cc +++ b/cc/trees/layer_tree_host_perftest.cc
@@ -73,21 +73,21 @@ } } - void DrawLayersOnThread(LayerTreeHostImpl* impl) override { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { if (TestEnded() || CleanUpStarted()) return; draw_timer_.NextLap(); if (draw_timer_.HasTimeLimitExpired()) { - CleanUpAndEndTest(impl); + CleanUpAndEndTest(); return; } if (!begin_frame_driven_drawing_) - impl->SetNeedsRedraw(); + host_impl->SetNeedsRedraw(); if (full_damage_each_frame_) - impl->SetFullRootLayerDamage(); + host_impl->SetFullRootLayerDamage(); } - virtual void CleanUpAndEndTest(LayerTreeHostImpl* host_impl) { EndTest(); } + virtual void CleanUpAndEndTest() { EndTest(); } virtual bool CleanUpStarted() { return false; } @@ -253,17 +253,11 @@ RunTest(CompositorMode::THREADED, false); } -static void EmptyReleaseCallback(const gpu::SyncToken& sync_token, - bool lost_resource) {} - // Simulates main-thread scrolling on each frame. class BrowserCompositorInvalidateLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader { public: - BrowserCompositorInvalidateLayerTreePerfTest() - : LayerTreeHostPerfTestJsonReader(), - next_fence_sync_(1), - clean_up_started_(false) {} + BrowserCompositorInvalidateLayerTreePerfTest() = default; void BuildTree() override { LayerTreeHostPerfTestJsonReader::BuildTree(); @@ -285,7 +279,9 @@ gpu_mailbox.SetName( reinterpret_cast<const int8_t*>(name_stream.str().c_str())); std::unique_ptr<SingleReleaseCallback> callback = - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); + SingleReleaseCallback::Create(base::Bind( + &BrowserCompositorInvalidateLayerTreePerfTest::ReleaseMailbox, + base::Unretained(this))); gpu::SyncToken next_sync_token(gpu::CommandBufferNamespace::GPU_IO, 0, gpu::CommandBufferId::FromUnsafeValue(1), @@ -295,6 +291,8 @@ next_fence_sync_++; tab_contents_->SetTextureMailbox(mailbox, std::move(callback)); + ++sent_mailboxes_count_; + tab_contents_->SetNeedsDisplay(); } void DidCommit() override { @@ -303,7 +301,7 @@ layer_tree_host()->SetNeedsCommit(); } - void CleanUpAndEndTest(LayerTreeHostImpl* host_impl) override { + void CleanUpAndEndTest() override { clean_up_started_ = true; MainThreadTaskRunner()->PostTask( FROM_HERE, @@ -314,15 +312,25 @@ void CleanUpAndEndTestOnMainThread() { tab_contents_->SetTextureMailbox(TextureMailbox(), nullptr); - EndTest(); + // ReleaseMailbox will end the test when we get the last mailbox back. + } + + void ReleaseMailbox(const gpu::SyncToken& sync_token, bool lost_resource) { + ++released_mailboxes_count_; + if (released_mailboxes_count_ == sent_mailboxes_count_) { + DCHECK(CleanUpStarted()); + EndTest(); + } } bool CleanUpStarted() override { return clean_up_started_; } private: scoped_refptr<TextureLayer> tab_contents_; - uint64_t next_fence_sync_; - bool clean_up_started_; + uint64_t next_fence_sync_ = 1; + bool clean_up_started_ = false; + int sent_mailboxes_count_ = 0; + int released_mailboxes_count_ = 0; }; TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) {
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 4fb8e69..27f4ab21 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -47,6 +47,7 @@ #include "cc/test/layer_internals_for_test.h" #include "cc/test/layer_tree_test.h" #include "cc/test/skia_common.h" +#include "cc/test/test_delegating_output_surface.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/effect_node.h" @@ -432,25 +433,37 @@ class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest { public: - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - auto output_surface = base::WrapUnique( - new testing::StrictMock< - MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface>( - delegating_renderer())); + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + auto mock_worker_context_support_owned = + base::MakeUnique<MockContextSupport>(); + auto* mock_worker_context_support = mock_worker_context_support_owned.get(); + + auto mock_worker_context_provider = make_scoped_refptr( + new MockContextProvider(std::move(mock_worker_context_support_owned))); + + // Workers are bound on the main thread. + mock_worker_context_provider->BindToCurrentThread(); // At init, we expect one call to set visibility to true. testing::Expectation visibility_true = - EXPECT_CALL(*output_surface, - SetWorkerContextShouldAggressivelyFreeResources(false)) + EXPECT_CALL(*mock_worker_context_support, + SetAggressivelyFreeResources(false)) .Times(1); // After running, we should get exactly one call to - // FreeWorkerContextGpuResources. - EXPECT_CALL(*output_surface, - SetWorkerContextShouldAggressivelyFreeResources(true)) + // DeleteCachedResources, along with SetAggressivelyFreeResources. + EXPECT_CALL(*mock_worker_context_provider, DeleteCachedResources()) + .After(visibility_true); + EXPECT_CALL(*mock_worker_context_support, + SetAggressivelyFreeResources(true)) .After(visibility_true) .WillOnce(testing::Invoke([this](bool is_visible) { EndTest(); })); - return std::move(output_surface); + + return LayerTreeHostTest::CreateDelegatingOutputSurface( + std::move(compositor_context_provider), + std::move(mock_worker_context_provider)); } void InitializeSettings(LayerTreeSettings* settings) override { @@ -458,27 +471,27 @@ settings->gpu_rasterization_forced = true; } - void BeginTest() override { - // Logic is handled in InitializedRendererOnThread to ensure that our - // LTHI is fully set up. - } - - void AfterTest() override { - // Expectations handled via mock. - } + void BeginTest() override {} + void AfterTest() override {} private: - class MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface - : public FakeOutputSurface { + class MockContextProvider : public TestContextProvider { public: - ~MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface() {} - explicit MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface( - bool delegated_rendering) - : FakeOutputSurface(TestContextProvider::Create(), - TestContextProvider::CreateWorker(), - delegated_rendering) {} - MOCK_METHOD1(SetWorkerContextShouldAggressivelyFreeResources, - void(bool is_visible)); + explicit MockContextProvider(std::unique_ptr<TestContextSupport> support) + : TestContextProvider(std::move(support), + base::MakeUnique<TestGLES2Interface>(), + TestWebGraphicsContext3D::Create()) {} + + MOCK_METHOD0(DeleteCachedResources, void()); + + private: + ~MockContextProvider() = default; + }; + + class MockContextSupport : public TestContextSupport { + public: + MOCK_METHOD1(SetAggressivelyFreeResources, + void(bool aggressively_free_resources)); }; }; @@ -520,7 +533,6 @@ public: void InitializeSettings(LayerTreeSettings* settings) override { LayerTreeHostFreeWorkerContextResourcesTest::InitializeSettings(settings); - settings->use_external_begin_frame_source = true; settings->using_synchronous_renderer_compositor = true; } }; @@ -2562,39 +2574,10 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDChange); -// Verify that the BeginFrame notification is used to initiate rendering. -class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { - public: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_external_begin_frame_source = true; - } - - void BeginTest() override { - // This will trigger a SetNeedsBeginFrame which will trigger a - // BeginFrame. - PostSetNeedsCommitToMainThread(); - } - - DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) override { - EndTest(); - return DRAW_SUCCESS; - } - - void AfterTest() override {} - - private: - base::TimeTicks frame_time_; -}; - -MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); - class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled : public LayerTreeHostTest { public: void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_external_begin_frame_source = true; settings->using_synchronous_renderer_compositor = true; } @@ -2605,8 +2588,7 @@ // once we return. End test while it's enabled. ImplThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest, - base::Unretained(this))); + base::Bind(&LayerTreeHostTest::EndTest, base::Unretained(this))); } void AfterTest() override {} @@ -2620,10 +2602,6 @@ LayerTreeHostTestAbortedCommitDoesntStall() : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {} - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_external_begin_frame_source = true; - } - void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DidCommit() override { @@ -2664,35 +2642,41 @@ int commit_complete_count_; }; -class OnDrawOutputSurface : public OutputSurface { +class OnDrawOutputSurface : public TestDelegatingOutputSurface { public: - explicit OnDrawOutputSurface(base::Closure invalidate_callback) - : OutputSurface(TestContextProvider::Create(), - TestContextProvider::CreateWorker(), - nullptr), - invalidate_callback_(std::move(invalidate_callback)) { - capabilities_.delegated_rendering = true; - } + explicit OnDrawOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider, + std::unique_ptr<OutputSurface> display_output_surface, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const RendererSettings& renderer_settings, + base::SingleThreadTaskRunner* task_runner, + bool synchronous_composite, + bool force_disable_reclaim_resources, + base::Closure invalidate_callback) + : TestDelegatingOutputSurface(std::move(compositor_context_provider), + std::move(worker_context_provider), + std::move(display_output_surface), + shared_bitmap_manager, + gpu_memory_buffer_manager, + renderer_settings, + task_runner, + synchronous_composite, + force_disable_reclaim_resources), + invalidate_callback_(std::move(invalidate_callback)) {} - // OutputSurface implementation. - void SwapBuffers(CompositorFrame frame) override { did_swap_ = true; } - uint32_t GetFramebufferCopyTextureFormat() override { return 0; } + // TestDelegatingOutputSurface overrides. void Invalidate() override { invalidate_callback_.Run(); } void OnDraw(bool resourceless_software_draw) { gfx::Transform identity; gfx::Rect empty_rect; - // SwapBuffers happens inside of OnDraw. client_->OnDraw(identity, empty_rect, resourceless_software_draw); - if (did_swap_) { - did_swap_ = false; - client_->DidSwapBuffersComplete(); - } } private: - bool did_swap_ = false; - base::Closure invalidate_callback_; + const base::Closure invalidate_callback_; }; class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor @@ -2703,11 +2687,21 @@ settings->using_synchronous_renderer_compositor = true; } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - auto output_surface = base::MakeUnique<OnDrawOutputSurface>(base::Bind( + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + auto on_draw_callback = base::Bind( &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor:: CallOnDraw, - base::Unretained(this))); + base::Unretained(this)); + auto output_surface = base::MakeUnique<OnDrawOutputSurface>( + compositor_context_provider, std::move(worker_context_provider), + CreateDisplayOutputSurface(compositor_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + layer_tree_host()->settings().renderer_settings, ImplThreadTaskRunner(), + false /* synchronous_composite */, + false /* force_disable_reclaim_resources */, + std::move(on_draw_callback)); output_surface_ = output_surface.get(); return std::move(output_surface); } @@ -2843,10 +2837,20 @@ client_.set_bounds(root_layer_->bounds()); } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - auto output_surface = base::MakeUnique<OnDrawOutputSurface>( + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + auto on_draw_callback = base::Bind(&LayerTreeHostTestResourcelessSoftwareDraw::CallOnDraw, - base::Unretained(this))); + base::Unretained(this)); + auto output_surface = base::MakeUnique<OnDrawOutputSurface>( + compositor_context_provider, std::move(worker_context_provider), + CreateDisplayOutputSurface(compositor_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + layer_tree_host()->settings().renderer_settings, ImplThreadTaskRunner(), + false /* synchronous_composite */, + false /* force_disable_reclaim_resources */, + std::move(on_draw_callback)); output_surface_ = output_surface.get(); return std::move(output_surface); } @@ -4376,22 +4380,19 @@ : first_output_surface_memory_limit_(4321234), second_output_surface_memory_limit_(1234321) {} - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - if (!first_context_provider_.get()) { + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { + if (!first_context_provider_) { first_context_provider_ = TestContextProvider::Create(); + compositor_context_provider = first_context_provider_; } else { - EXPECT_FALSE(second_context_provider_.get()); + EXPECT_FALSE(second_context_provider_); second_context_provider_ = TestContextProvider::Create(); + compositor_context_provider = second_context_provider_; } - scoped_refptr<TestContextProvider> provider(second_context_provider_.get() - ? second_context_provider_ - : first_context_provider_); - std::unique_ptr<FakeOutputSurface> output_surface; - if (delegating_renderer()) - output_surface = FakeOutputSurface::CreateDelegating3d(provider); - else - output_surface = FakeOutputSurface::Create3d(provider); + auto output_surface = + FakeOutputSurface::Create3d(std::move(compositor_context_provider)); output_surface->SetMemoryPolicyToSetAtBind( base::WrapUnique(new ManagedMemoryPolicy( second_context_provider_.get() ? second_output_surface_memory_limit_ @@ -4527,7 +4528,7 @@ } } - void SwapBuffersCompleteOnThread() override { EndTest(); } + void DisplayDidDrawAndSwapOnThread() override { EndTest(); } void AfterTest() override { // The pending swap promise should activate and swap. @@ -4719,7 +4720,7 @@ : base::Closure()); } - void SwapBuffersCompleteOnThread() override { + void DisplayDidDrawAndSwapOnThread() override { if (num_swaps_++ >= 1) { // The commit changes layers so it should cause a swap. base::AutoLock lock(swap_promise_result_.lock); @@ -5463,13 +5464,29 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise : public LayerTreeHostTest { public: - LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {} + LayerTreeHostTestSynchronousCompositeSwapPromise() = default; void InitializeSettings(LayerTreeSettings* settings) override { settings->single_thread_proxy_scheduler = false; settings->use_zero_copy = true; } + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + bool synchronous_composite = + !HasImplThread() && + !layer_tree_host()->settings().single_thread_proxy_scheduler; + // Relaiming resources is parameterized for this test. + bool force_disable_reclaim_resources = !reclaim_resources_; + return base::MakeUnique<TestDelegatingOutputSurface>( + compositor_context_provider, std::move(worker_context_provider), + CreateDisplayOutputSurface(compositor_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + layer_tree_host()->settings().renderer_settings, ImplThreadTaskRunner(), + synchronous_composite, force_disable_reclaim_resources); + } + void BeginTest() override { // Successful composite. std::unique_ptr<SwapPromise> swap_promise0( @@ -5477,7 +5494,7 @@ layer_tree_host()->QueueSwapPromise(std::move(swap_promise0)); layer_tree_host()->Composite(base::TimeTicks::Now()); - // Fail to swap (no damage). + // Fail to swap (no damage) if not reclaiming resources from the Display. std::unique_ptr<SwapPromise> swap_promise1( new TestSwapPromise(&swap_promise_result_[1])); layer_tree_host()->QueueSwapPromise(std::move(swap_promise1)); @@ -5511,13 +5528,19 @@ EXPECT_TRUE(swap_promise_result_[0].dtor_called); } - // Second swap promise fails to swap. + // Second swap promise fails to swap if not reclaiming resources from the + // Display. { base::AutoLock lock(swap_promise_result_[1].lock); EXPECT_TRUE(swap_promise_result_[1].did_activate_called); - EXPECT_FALSE(swap_promise_result_[1].did_swap_called); - EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); - EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); + if (!reclaim_resources_) { + EXPECT_FALSE(swap_promise_result_[1].did_swap_called); + EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); + EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); + } else { + EXPECT_TRUE(swap_promise_result_[1].did_swap_called); + EXPECT_FALSE(swap_promise_result_[1].did_not_swap_called); + } EXPECT_TRUE(swap_promise_result_[1].dtor_called); } @@ -5532,11 +5555,20 @@ } } - int commit_count_; + bool reclaim_resources_; + int commit_count_ = 0; TestSwapPromiseResult swap_promise_result_[3]; }; -SINGLE_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); +TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise, NoReclaim) { + reclaim_resources_ = false; + RunTest(CompositorMode::SINGLE_THREADED, true); +} + +TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise, Reclaim) { + reclaim_resources_ = true; + RunTest(CompositorMode::SINGLE_THREADED, true); +} // Make sure page scale and top control deltas are applied to the client even // when the LayerTreeHost doesn't have a root layer. @@ -5774,19 +5806,18 @@ class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy : public LayerTreeHostTestCrispUpAfterPinchEnds { protected: - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - std::unique_ptr<TestWebGraphicsContext3D> context3d = - TestWebGraphicsContext3D::Create(); - context3d->set_support_image(true); + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<TestContextProvider> display_context_provider = + TestContextProvider::Create(); + TestWebGraphicsContext3D* context3d = + display_context_provider->UnboundTestContext3d(); context3d->set_support_sync_query(true); #if defined(OS_MACOSX) context3d->set_support_texture_rectangle(true); #endif - - if (delegating_renderer()) - return FakeOutputSurface::CreateDelegating3d(std::move(context3d)); - else - return FakeOutputSurface::Create3d(std::move(context3d)); + return LayerTreeTest::CreateDisplayOutputSurface( + std::move(display_context_provider)); } }; @@ -6826,14 +6857,6 @@ // frame's metadata. class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest { protected: - LayerTreeHostTestPaintedDeviceScaleFactor() = default; - - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - auto ret = FakeOutputSurface::CreateDelegating3d(); - fake_output_surface_ = ret.get(); - return std::move(ret); - } - void BeginTest() override { layer_tree_host()->SetPaintedDeviceScaleFactor(2.0f); EXPECT_EQ(1.0f, layer_tree_host()->device_scale_factor()); @@ -6845,16 +6868,13 @@ EXPECT_EQ(1.0f, host_impl->active_tree()->device_scale_factor()); } - void SwapBuffersCompleteOnThread() override { - EXPECT_EQ( - 2.0f, - fake_output_surface_->last_sent_frame()->metadata.device_scale_factor); + void DisplayReceivedCompositorFrameOnThread( + const CompositorFrame& frame) override { + EXPECT_EQ(2.0f, frame.metadata.device_scale_factor); EndTest(); } void AfterTest() override {} - - FakeOutputSurface* fake_output_surface_ = nullptr; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor);
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index c9a0291..23d344fd 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -16,7 +16,6 @@ #include "cc/layers/video_layer_impl.h" #include "cc/output/filter_operations.h" #include "cc/resources/single_release_callback.h" -#include "cc/test/failure_output_surface.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_output_surface.h" @@ -31,6 +30,7 @@ #include "cc/test/layer_tree_test.h" #include "cc/test/render_pass_test_utils.h" #include "cc/test/test_context_provider.h" +#include "cc/test/test_delegating_output_surface.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/layer_tree_host.h" @@ -80,24 +80,35 @@ return TestWebGraphicsContext3D::Create(); } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { if (times_to_fail_create_) { --times_to_fail_create_; ExpectCreateToFail(); - return base::WrapUnique(new FailureOutputSurface(delegating_renderer())); + auto test_compositor_context_provider = TestContextProvider::Create(); + test_compositor_context_provider->UnboundTestContext3d() + ->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + compositor_context_provider = std::move(test_compositor_context_provider); + } + return LayerTreeTest::CreateDelegatingOutputSurface( + std::move(compositor_context_provider), + std::move(worker_context_provider)); + } + + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { + std::unique_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); + if (context_should_support_io_surface_) { + context3d->set_have_extension_io_surface(true); + context3d->set_have_extension_egl_image(true); } - std::unique_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); base::AutoLock lock(context3d_lock_); context3d_ = context3d.get(); - - if (context_should_support_io_surface_) { - context3d_->set_have_extension_io_surface(true); - context3d_->set_have_extension_egl_image(true); - } - - DCHECK(delegating_renderer()); - return FakeOutputSurface::CreateDelegating3d(std::move(context3d)); + return LayerTreeTest::CreateDisplayOutputSurface( + TestContextProvider::Create(std::move(context3d))); } DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, @@ -178,18 +189,15 @@ if (async_output_surface_creation_) { MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&LayerTreeHostContextTestLostContextSucceeds:: - CreateAndSetOutputSurface, + AsyncRequestNewOutputSurface, base::Unretained(this))); } else { - CreateAndSetOutputSurface(); + AsyncRequestNewOutputSurface(); } } - void CreateAndSetOutputSurface() { - std::unique_ptr<OutputSurface> surface( - LayerTreeHostContextTest::CreateOutputSurface()); - CHECK(surface); - layer_tree_host()->SetOutputSurface(std::move(surface)); + void AsyncRequestNewOutputSurface() { + LayerTreeHostContextTest::RequestNewOutputSurface(); } void DidInitializeOutputSurface() override { @@ -365,9 +373,8 @@ EndTest(); } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - EXPECT_TRUE(false); - return nullptr; + void RequestNewOutputSurface() override { + ADD_FAILURE() << "RequestNewOutputSurface() should not be called"; } void DidInitializeOutputSurface() override { EXPECT_TRUE(false); } @@ -394,16 +401,10 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } void RequestNewOutputSurface() override { - if (layer_tree_host()->visible()) - CreateAndSetOutputSurface(); - } - - void CreateAndSetOutputSurface() { - std::unique_ptr<OutputSurface> surface = - LayerTreeHostContextTest::CreateOutputSurface(); - CHECK(surface); - setos_counter_++; - layer_tree_host()->SetOutputSurface(std::move(surface)); + if (layer_tree_host()->visible()) { + setos_counter_++; + LayerTreeHostContextTest::RequestNewOutputSurface(); + } } void HideAndReleaseOutputSurface() { @@ -463,11 +464,6 @@ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(2)); } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - EXPECT_TRUE(false); - return nullptr; - } - void DidInitializeOutputSurface() override { EXPECT_TRUE(false); } void AfterTest() override {} @@ -500,9 +496,20 @@ EXPECT_LE(num_requests_, 2); if (num_requests_ > 1) return; + LayerTreeHostContextTest::RequestNewOutputSurface(); + } + + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { ExpectCreateToFail(); - layer_tree_host()->SetOutputSurface( - base::WrapUnique(new FailureOutputSurface(false))); + auto test_compositor_context_provider = TestContextProvider::Create(); + test_compositor_context_provider->UnboundTestContext3d() + ->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + return LayerTreeTest::CreateDelegatingOutputSurface( + std::move(test_compositor_context_provider), + std::move(worker_context_provider)); } void BeginTest() override { @@ -555,8 +562,7 @@ void CreateAndSetOutputSurface() { creating_output_ = true; - layer_tree_host()->SetOutputSurface( - LayerTreeHostContextTest::CreateOutputSurface()); + LayerTreeHostContextTest::RequestNewOutputSurface(); } void BeginTest() override { @@ -588,8 +594,7 @@ } void RequestNewOutputSurface() override { - layer_tree_host()->SetOutputSurface( - LayerTreeHostContextTest::CreateOutputSurface()); + LayerTreeHostContextTest::RequestNewOutputSurface(); EndTest(); } @@ -1036,14 +1041,14 @@ return draw_result; } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { + void RequestNewOutputSurface() override { // This will get called twice: // First when we create the initial output surface... if (layer_tree_host()->source_frame_number() > 0) { // ... and then again after we forced the context to be lost. lost_context_ = true; } - return LayerTreeHostContextTest::CreateOutputSurface(); + LayerTreeHostContextTest::RequestNewOutputSurface(); } void DidCommitAndDrawFrame() override {
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc index 623d403..7177580c 100644 --- a/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -11,10 +11,13 @@ #include "cc/layers/layer_iterator.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" +#include "cc/output/direct_renderer.h" +#include "cc/surfaces/display.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_test.h" +#include "cc/test/test_delegating_output_surface.h" #include "cc/trees/layer_tree_impl.h" #include "gpu/GLES2/gl2extchromium.h" @@ -126,19 +129,19 @@ void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); } - std::unique_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { if (!use_gl_renderer_) { return FakeOutputSurface::CreateSoftware( base::WrapUnique(new SoftwareOutputDevice)); } - std::unique_ptr<FakeOutputSurface> output_surface = - FakeOutputSurface::Create3d(TestContextProvider::Create(), - TestContextProvider::CreateWorker()); - TestContextSupport* context_support = static_cast<TestContextSupport*>( - output_surface->context_provider()->ContextSupport()); + scoped_refptr<TestContextProvider> display_context_provider = + TestContextProvider::Create(); + TestContextSupport* context_support = display_context_provider->support(); context_support->set_out_of_order_callbacks(out_of_order_callbacks_); - return std::move(output_surface); + + return FakeOutputSurface::Create3d(std::move(display_context_provider)); } bool use_gl_renderer_; @@ -463,8 +466,17 @@ client_.set_bounds(root_->bounds()); } + std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + auto surface = LayerTreeHostCopyRequestTest::CreateDelegatingOutputSurface( + std::move(compositor_context_provider), + std::move(worker_context_provider)); + display_ = surface->display(); + return surface; + } + void BeginTest() override { - did_draw_ = false; PostSetNeedsCommitToMainThread(); copy_layer_->RequestCopyOfOutput( @@ -480,37 +492,53 @@ EndTest(); } - void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - Renderer* renderer = host_impl->renderer(); + void DisplayWillDrawAndSwapOnThread( + bool will_draw_and_swap, + const RenderPassList& render_passes) override { + EXPECT_TRUE(will_draw_and_swap) << did_swap_; + if (did_swap_) { + // TODO(crbug.com/564832): Ignore the extra frame that occurs due to copy + // completion. This can be removed when the extra commit is removed. + EXPECT_EQ(1u, render_passes.size()); + return; + } - LayerImpl* parent = - host_impl->active_tree()->LayerById(parent_layer_->id()); - LayerImpl* copy_layer = - host_impl->active_tree()->LayerById(copy_layer_->id()); + EXPECT_EQ(2u, render_passes.size()); + // The root pass is the back of the list. + copy_layer_render_pass_id = render_passes[0]->id; + parent_render_pass_id = render_passes[1]->id; + } + + void DisplayDidDrawAndSwapOnThread() override { + DirectRenderer* renderer = display_->renderer_for_testing(); // |parent| owns a surface, but it was hidden and not part of the copy // request so it should not allocate any resource. - EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting( - parent->render_surface()->GetRenderPassId())); + EXPECT_FALSE( + renderer->HasAllocatedResourcesForTesting(parent_render_pass_id)); - // |copy_layer| should have been rendered to a texture since it was needed - // for a copy request. - if (did_draw_) { - // TODO(crbug.com/564832): Ignore the extra frame that occurs due to copy - // completion. This can be removed when the extra commit is removed. - EXPECT_FALSE(copy_layer->render_surface()); + // TODO(crbug.com/564832): Ignore the extra frame that occurs due to copy + // completion. This can be removed when the extra commit is removed. + if (did_swap_) { + EXPECT_FALSE( + renderer->HasAllocatedResourcesForTesting(copy_layer_render_pass_id)); } else { - EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting( - copy_layer->render_surface()->GetRenderPassId())); + // |copy_layer| should have been rendered to a texture since it was needed + // for a copy request. + EXPECT_TRUE( + renderer->HasAllocatedResourcesForTesting(copy_layer_render_pass_id)); } - did_draw_ = true; + did_swap_ = true; } - void AfterTest() override { EXPECT_TRUE(did_draw_); } + void AfterTest() override { EXPECT_TRUE(did_swap_); } + RenderPassId parent_render_pass_id; + RenderPassId copy_layer_render_pass_id; + Display* display_ = nullptr; + bool did_swap_ = false; FakeContentLayerClient client_; - bool did_draw_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> grand_parent_layer_; scoped_refptr<FakePictureLayer> parent_layer_; @@ -707,18 +735,13 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( LayerTreeHostTestAsyncTwoReadbacksWithoutDraw); -class LayerTreeHostCopyRequestTestLostOutputSurface +class LayerTreeHostCopyRequestTestDeleteTexture : public LayerTreeHostCopyRequestTest { protected: - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - if (!first_context_provider_) { - first_context_provider_ = TestContextProvider::Create(); - return FakeOutputSurface::Create3d(first_context_provider_); - } - - EXPECT_FALSE(second_context_provider_); - second_context_provider_ = TestContextProvider::Create(); - return FakeOutputSurface::Create3d(second_context_provider_); + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { + display_context_provider_ = TestContextProvider::Create(); + return FakeOutputSurface::Create3d(display_context_provider_); } void SetupTree() override { @@ -752,7 +775,7 @@ void InsertCopyRequest() { copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface:: + base::Bind(&LayerTreeHostCopyRequestTestDeleteTexture:: ReceiveCopyRequestOutputAndCommit, base::Unretained(this)))); } @@ -762,78 +785,59 @@ result_ = nullptr; ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface:: + FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestDeleteTexture:: CheckNumTexturesAfterReadbackDestroyed, base::Unretained(this))); } void CheckNumTexturesAfterReadbackDestroyed() { - // After the loss we had |num_textures_after_loss_| many textures, but - // releasing the copy output request will cause the texture in the request - // to be released, so we should have 1 less by now. - EXPECT_EQ(num_textures_after_loss_ - 1, - first_context_provider_->TestContext3d()->NumTextures()); + // After the copy we had |num_textures_after_readback_| many textures, but + // releasing the copy output request should cause the texture in the request + // to be destroyed by the compositor, so we should have 1 less by now. + EXPECT_EQ(num_textures_after_readback_ - 1, + display_context_provider_->TestContext3d()->NumTextures()); EndTest(); } - void SwapBuffersCompleteOnThread() override { + void DisplayDidDrawAndSwapOnThread() override { switch (num_swaps_++) { case 0: - // The layers have been drawn, so their textures have been allocated. + // The layers have been drawn, so any textures required for drawing have + // been allocated. EXPECT_FALSE(result_); num_textures_without_readback_ = - first_context_provider_->TestContext3d()->NumTextures(); + display_context_provider_->TestContext3d()->NumTextures(); // Request a copy of the layer. This will use another texture. MainThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface:: - InsertCopyRequest, - base::Unretained(this))); + base::Bind( + &LayerTreeHostCopyRequestTestDeleteTexture::InsertCopyRequest, + base::Unretained(this))); break; case 1: // We did a readback, so there will be a readback texture around now. - EXPECT_LT(num_textures_without_readback_, - first_context_provider_->TestContext3d()->NumTextures()); - - // The copy request will be serviced and the result sent to - // ReceiveCopyRequestOutputAndCommit, which posts a new commit causing - // the test to advance to the next case. - break; - case 2: - // The readback texture is collected. - EXPECT_TRUE(result_); - - // Lose the output surface. - first_context_provider_->TestContext3d()->loseContextCHROMIUM( - GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); - break; - case 3: - // The output surface has been recreated. - EXPECT_TRUE(second_context_provider_); - - num_textures_after_loss_ = - first_context_provider_->TestContext3d()->NumTextures(); + num_textures_after_readback_ = + display_context_provider_->TestContext3d()->NumTextures(); + EXPECT_LT(num_textures_without_readback_, num_textures_after_readback_); // Now destroy the CopyOutputResult, releasing the texture inside back // to the compositor. Then check the resulting number of allocated // textures. MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface:: - DestroyCopyResultAndCheckNumTextures, - base::Unretained(this))); + FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestDeleteTexture:: + DestroyCopyResultAndCheckNumTextures, + base::Unretained(this))); break; } } void AfterTest() override {} - scoped_refptr<TestContextProvider> first_context_provider_; - scoped_refptr<TestContextProvider> second_context_provider_; + scoped_refptr<TestContextProvider> display_context_provider_; int num_swaps_ = 0; size_t num_textures_without_readback_ = 0; - size_t num_textures_after_loss_ = 0; + size_t num_textures_after_readback_ = 0; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> copy_layer_; @@ -841,29 +845,47 @@ }; SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( - LayerTreeHostCopyRequestTestLostOutputSurface); + LayerTreeHostCopyRequestTestDeleteTexture); class LayerTreeHostCopyRequestTestCountTextures : public LayerTreeHostCopyRequestTest { protected: - std::unique_ptr<OutputSurface> CreateOutputSurface() override { - context_provider_ = TestContextProvider::Create(); - return FakeOutputSurface::Create3d(context_provider_); + void InitializeSettings(LayerTreeSettings* settings) override { + // Always allocate only a single texture at a time through ResourceProvider. + settings->renderer_settings.texture_id_allocation_chunk_size = 1; + } + + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { + // These tests expect the LayerTreeHostImpl to share a context with + // the Display so that sync points are not needed and the texture counts + // are visible together. + // Since this test does not override CreateDelegatingOutputSurface, the + // |compositor_context_provider| will be a TestContextProvider. + display_context_provider_ = + static_cast<TestContextProvider*>(compositor_context_provider.get()); + return FakeOutputSurface::Create3d(std::move(compositor_context_provider)); } void SetupTree() override { - client_.set_fill_with_nonsolid_color(true); + // The layers in this test have solid color content, so they don't + // actually allocate any textures, making counting easier. - root_ = FakePictureLayer::Create(&client_); + root_ = FakePictureLayer::Create(&root_client_); root_->SetBounds(gfx::Size(20, 20)); + root_client_.set_bounds(root_->bounds()); - copy_layer_ = FakePictureLayer::Create(&client_); + copy_layer_ = FakePictureLayer::Create(©_client_); copy_layer_->SetBounds(gfx::Size(10, 10)); + copy_client_.set_bounds(copy_layer_->bounds()); + // Doing a copy makes the layer have a render surface which can cause + // texture allocations. So get those allocations out of the way in the + // first frame by forcing it to have a render surface. + copy_layer_->SetForceRenderSurfaceForTesting(true); root_->AddChild(copy_layer_); layer_tree_host()->SetRootLayer(root_); LayerTreeHostCopyRequestTest::SetupTree(); - client_.set_bounds(root_->bounds()); } void BeginTest() override { @@ -876,27 +898,31 @@ void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: - // The layers have been pushed to the impl side. The layer textures have - // been allocated. + // The layers have been pushed to the impl side and drawn. Any textures + // that are created in that process will have been allocated. RequestCopy(copy_layer_.get()); break; } } - void SwapBuffersCompleteOnThread() override { + void DisplayDidDrawAndSwapOnThread() override { switch (num_swaps_++) { case 0: - // The layers have been drawn, so their textures have been allocated. + // The first frame has been drawn, so textures for drawing have been + // allocated. num_textures_without_readback_ = - context_provider_->TestContext3d()->NumTextures(); + display_context_provider_->TestContext3d()->NumTextures(); break; case 1: // We did a readback, so there will be a readback texture around now. num_textures_with_readback_ = - context_provider_->TestContext3d()->NumTextures(); + display_context_provider_->TestContext3d()->NumTextures(); waited_sync_token_after_readback_ = - context_provider_->TestContext3d()->last_waited_sync_token(); + display_context_provider_->TestContext3d() + ->last_waited_sync_token(); + // End the test after main thread has a chance to hear about the + // readback. MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest, @@ -907,12 +933,13 @@ virtual void DoEndTest() { EndTest(); } - scoped_refptr<TestContextProvider> context_provider_; + scoped_refptr<TestContextProvider> display_context_provider_; int num_swaps_ = 0; size_t num_textures_without_readback_ = 0; size_t num_textures_with_readback_ = 0; gpu::SyncToken waited_sync_token_after_readback_; - FakeContentLayerClient client_; + FakeContentLayerClient root_client_; + FakeContentLayerClient copy_client_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> copy_layer_; };
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc index 405d837..d8bde90 100644 --- a/cc/trees/layer_tree_host_unittest_damage.cc +++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -197,7 +197,7 @@ return draw_result; } - void SwapBuffersCompleteOnThread() override { + void DisplayDidDrawAndSwapOnThread() override { ++did_swap_; EXPECT_EQ(expect_swap_, did_swap_); }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 22f6ce17..0490b4a4 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -148,6 +148,7 @@ "//base:base_java", "//chrome/android/webapk/libs/client:client_java", "//chrome/android/webapk/libs/common:common_java", + "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", "//components/safe_json/android:safe_json_java", "//components/variations/android:variations_java", "//components/web_contents_delegate_android:web_contents_delegate_android_java", @@ -360,6 +361,7 @@ "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/android/webapk/libs/common:common_java", + "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", "//chrome/test/android:chrome_java_test_support", "//components/bookmarks/common/android:bookmarks_java", "//components/dom_distiller/android:dom_distiller_core_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java index cf00f5c..1bff649 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java
@@ -4,8 +4,10 @@ package org.chromium.chrome.browser.compositor.bottombar.readermode; +import android.app.Activity; import android.content.Context; +import org.chromium.base.ActivityState; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.LayerTitleCache; import org.chromium.chrome.browser.compositor.bottombar.OverlayContentDelegate; @@ -326,6 +328,13 @@ return -getToolbarHeight(); } + @Override + public void onActivityStateChange(Activity activity, int newState) { + // If the activity is only resuming, don't do anything. + if (newState == ActivityState.RESUMED) return; + super.onActivityStateChange(activity, newState); + } + // ============================================================================================ // ReaderModeBarControl // ============================================================================================
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java new file mode 100644 index 0000000..b34ca865 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java
@@ -0,0 +1,84 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.infobar; + +import android.graphics.Bitmap; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.ResourceId; + +import java.util.ArrayList; +import java.util.List; + +/** + * An infobar for assisted credit card filling. + */ +public class AutofillCreditCardFillingInfoBar extends ConfirmInfoBar { + private final List<CardDetail> mCardDetails = new ArrayList<>(); + + /** + * Creates a new instance of the infobar. + * + * @param nativeAutofillCreditCardFillingInfoBar The pointer to the native object for callbacks. + * @param enumeratedIconId ID corresponding to the icon that will be shown for the InfoBar. + * The ID must have been mapped using the ResourceMapper class before + * passing it to this function. + * @param iconBitmap Bitmap to use if there is no equivalent Java resource for enumeratedIconId. + * @param message Message to display to the user indicating what the InfoBar is for. + * @param buttonOk String to display on the OK button. + * @param buttonCancel String to display on the Cancel button. + */ + private AutofillCreditCardFillingInfoBar(long nativeAutofillCreditCardFillingInfoBar, + int enumeratedIconId, Bitmap iconBitmap, String message, String buttonOk, + String buttonCancel) { + super(ResourceId.mapToDrawableId(enumeratedIconId), iconBitmap, message, null, buttonOk, + buttonCancel); + } + + /** + * Creates an infobar for assisted credit card filling. + * + * @param nativeAutofillCreditCardFillingInfoBar The pointer to the native object for callbacks. + * @param enumeratedIconId ID corresponding to the icon that will be shown for the InfoBar. + * The ID must have been mapped using the ResourceMapper class before + * passing it to this function. + * @param iconBitmap Bitmap to use if there is no equivalent Java resource for enumeratedIconId. + * @param message Message to display to the user indicating what the InfoBar is for. + * @param buttonOk String to display on the OK button. + * @param buttonCancel String to display on the Cancel button. + * @return A new instance of the infobar. + */ + @CalledByNative + private static AutofillCreditCardFillingInfoBar create( + long nativeAutofillCreditCardFillingInfoBar, int enumeratedIconId, Bitmap iconBitmap, + String message, String buttonOk, String buttonCancel) { + return new AutofillCreditCardFillingInfoBar(nativeAutofillCreditCardFillingInfoBar, + enumeratedIconId, iconBitmap, message, buttonOk, buttonCancel); + } + + /** + * Adds information to the infobar about the credit card that will be proposed for the assist. + * + * @param enumeratedIconId ID corresponding to the icon that will be shown for this credit card. + * The ID must have been mapped using the ResourceMapper class before + * passing it to this function. + * @param label The credit card label, for example "***1234". + * @param subLabel The credit card sub-label, for example "Exp: 06/17". + */ + @CalledByNative + private void addDetail(int enumeratedIconId, String label, String subLabel) { + mCardDetails.add(new CardDetail(enumeratedIconId, label, subLabel)); + } + + @Override + public void createContent(InfoBarLayout layout) { + super.createContent(layout); + InfoBarControlLayout control = layout.addControlLayout(); + for (int i = 0; i < mCardDetails.size(); i++) { + CardDetail detail = mCardDetails.get(i); + control.addIcon(detail.issuerIconDrawableId, 0, detail.label, detail.subLabel); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java index d4d09b5..151a58d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java
@@ -13,6 +13,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.browser.ResourceId; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -21,41 +22,6 @@ */ public class AutofillSaveCardInfoBar extends ConfirmInfoBar { /** - * Detailed card information to show in the infobar. - */ - public static class CardDetail { - /** - * The identifier of the drawable of the card issuer icon. - */ - public int issuerIconDrawableId; - - /** - * The label for the card. - */ - public String label; - - /** - * The sub-label for the card. - */ - public String subLabel; - - /** - * Creates a new instance of the detailed card information. - * - * @param enumeratedIconId ID corresponding to the icon that will be shown for this credit - * card. The ID must have been mapped using the ResourceMapper class - * before passing it to this function. - * @param label The credit card label, for example "***1234". - * @param subLabel The credit card sub-label, for example "Exp: 06/17". - */ - public CardDetail(int enumeratedIconId, String label, String subLabel) { - this.issuerIconDrawableId = ResourceId.mapToDrawableId(enumeratedIconId); - this.label = label; - this.subLabel = subLabel; - } - } - - /** * Legal message line with links to show in the infobar. */ public static class LegalMessageLine { @@ -113,7 +79,7 @@ } private final long mNativeAutofillSaveCardInfoBar; - private final List<CardDetail> mCardDetails = new LinkedList<CardDetail>(); + private final List<CardDetail> mCardDetails = new ArrayList<>(); private final LinkedList<LegalMessageLine> mLegalMessageLines = new LinkedList<LegalMessageLine>(); @@ -200,7 +166,8 @@ public void createContent(InfoBarLayout layout) { super.createContent(layout); InfoBarControlLayout control = layout.addControlLayout(); - for (CardDetail detail : mCardDetails) { + for (int i = 0; i < mCardDetails.size(); i++) { + CardDetail detail = mCardDetails.get(i); control.addIcon(detail.issuerIconDrawableId, 0, detail.label, detail.subLabel); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/CardDetail.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/CardDetail.java new file mode 100644 index 0000000..4a20552c --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/CardDetail.java
@@ -0,0 +1,42 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.infobar; + +import org.chromium.chrome.browser.ResourceId; + +/** + * Detailed card information to show in the various Autofill infobars. + */ +public class CardDetail { + /** + * The identifier of the drawable of the card issuer icon. + */ + public int issuerIconDrawableId; + + /** + * The label for the card. + */ + public String label; + + /** + * The sub-label for the card. + */ + public String subLabel; + + /** + * Creates a new instance of the detailed card information. + * + * @param enumeratedIconId ID corresponding to the icon that will be shown for this credit + * card. The ID must have been mapped using the ResourceMapper class + * before passing it to this function. + * @param label The credit card label, for example "***1234". + * @param subLabel The credit card sub-label, for example "Exp: 06/17". + */ + public CardDetail(int enumeratedIconId, String label, String subLabel) { + this.issuerIconDrawableId = ResourceId.mapToDrawableId(enumeratedIconId); + this.label = label; + this.subLabel = subLabel; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java index c5632d1f..2bd35ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java
@@ -96,16 +96,7 @@ // Loop through the metadata for each url. for (int i = 0; i < metadata.length(); i++) { try { - JSONObject obj = metadata.getJSONObject(i); - JSONObject pageInfo = obj.getJSONObject("pageInfo"); - String scannedUrl = obj.getString("scannedUrl"); - String resolvedUrl = obj.getString("resolvedUrl"); - String iconUrl = pageInfo.optString("icon", null); - String title = pageInfo.optString("title", ""); - String description = pageInfo.optString("description", null); - String groupId = pageInfo.optString("groupId", null); - pwsResults.add(new PwsResult( - scannedUrl, resolvedUrl, iconUrl, title, description, groupId)); + pwsResults.add(PwsResult.jsonDeserialize(metadata.getJSONObject(i))); } catch (JSONException e) { Log.e(TAG, "PWS returned invalid data", e); continue;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java index 87d7fc5..8db0ade1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java
@@ -5,6 +5,9 @@ import org.chromium.base.Log; +import org.json.JSONException; +import org.json.JSONObject; + import java.net.MalformedURLException; import java.net.URL; @@ -17,6 +20,13 @@ */ class PwsResult { private static final String TAG = "PhysicalWeb"; + private static final String PAGE_INFO_KEY = "pageInfo"; + private static final String REQUEST_URL_KEY = "scannedUrl"; + private static final String SITE_URL_KEY = "resolvedUrl"; + private static final String ICON_KEY = "icon"; + private static final String TITLE_KEY = "title"; + private static final String DESCRIPTION_KEY = "description"; + private static final String GROUP_ID_KEY = "groupId"; /** * The URL that was set in the request to the PWS. @@ -72,4 +82,37 @@ } this.groupId = groupIdToSet; } + + /** + * Creates a JSON object that represents this data structure. + * @return a JSON serialization of this data structure. + * @throws JSONException if the values cannot be deserialized. + */ + public JSONObject jsonSerialize() throws JSONException { + return new JSONObject() + .put(REQUEST_URL_KEY, requestUrl) + .put(SITE_URL_KEY, siteUrl) + .put(PAGE_INFO_KEY, new JSONObject() + .put(ICON_KEY, iconUrl) + .put(TITLE_KEY, title) + .put(DESCRIPTION_KEY, description) + .put(GROUP_ID_KEY, groupId)); + } + + /** + * Populates a PwsResult with data from a given JSON object. + * @param jsonObject a serialized PwsResult. + * @return The PwsResult represented by the serialized object. + * @throws JSONException if the values cannot be serialized. + */ + public static PwsResult jsonDeserialize(JSONObject jsonObject) throws JSONException { + JSONObject pageInfo = jsonObject.getJSONObject(PAGE_INFO_KEY); + return new PwsResult( + jsonObject.getString(REQUEST_URL_KEY), + jsonObject.getString(SITE_URL_KEY), + pageInfo.optString(ICON_KEY, null), + pageInfo.optString(TITLE_KEY, ""), + pageInfo.optString(DESCRIPTION_KEY, null), + pageInfo.optString(GROUP_ID_KEY, null)); + } }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 6f8c6db..f945f167 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -383,7 +383,9 @@ "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java", "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java", "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java", + "java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java", "java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java", + "java/src/org/chromium/chrome/browser/infobar/CardDetail.java", "java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java", "java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBar.java", "java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBarDelegate.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java new file mode 100644 index 0000000..a3547a0e --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java
@@ -0,0 +1,58 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.physicalweb; + +import android.test.suitebuilder.annotation.SmallTest; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Tests for {@link PwsResult}. + */ +public class PwsResultTest extends TestCase { + PwsResult mReferencePwsResult = null; + JSONObject mReferenceJsonObject = null; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mReferencePwsResult = new PwsResult( + "https://shorturl.com", + "https://longurl.com", + "https://longurl.com/favicon.ico", + "This is a page", + "Pages are the best", + "group1"); + // Because we can't print JSON sorted by keys, the order is important here. + mReferenceJsonObject = new JSONObject("{" + + " \"scannedUrl\": \"https://shorturl.com\"," + + " \"resolvedUrl\": \"https://longurl.com\"," + + " \"icon\": \"https://longurl.com/favicon.ico\"," + + " \"title\": \"This is a page\"," + + " \"description\": \"Pages are the best\"," + + " \"group\": \"group1\"" + + "}"); + } + + @SmallTest + public void testJsonSerializeWorks() throws JSONException { + assertEquals(mReferenceJsonObject.toString(), + mReferencePwsResult.jsonSerialize().toString()); + } + + @SmallTest + public void testJsonDeserializeWorks() throws JSONException { + PwsResult pwsResult = PwsResult.jsonDeserialize(mReferenceJsonObject); + assertEquals(mReferencePwsResult.requestUrl, pwsResult.requestUrl); + assertEquals(mReferencePwsResult.responseUrl, pwsResult.responseUrl); + assertEquals(mReferencePwsResult.iconUrl, pwsResult.iconUrl); + assertEquals(mReferencePwsResult.title, pwsResult.title); + assertEquals(mReferencePwsResult.description, pwsResult.description); + assertEquals(mReferencePwsResult.group, pwsResult.group); + } +}
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn index 57d4a97..b0b7cd9 100644 --- a/chrome/android/webapk/libs/client/BUILD.gn +++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -14,11 +14,9 @@ ] deps = [ "//chrome/android/webapk/libs/common:common_java", + "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", ] - srcjar_deps = [ - ":runtime_library_version_java", - "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl", - ] + srcjar_deps = [ ":runtime_library_version_java" ] } java_cpp_template("runtime_library_version_java") { @@ -37,5 +35,6 @@ deps = [ ":client_java", "//base:base_junit_test_support", + "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", ] }
diff --git a/chrome/android/webapk/libs/runtime_library/BUILD.gn b/chrome/android/webapk/libs/runtime_library/BUILD.gn index ef80ff21..30beb23 100644 --- a/chrome/android/webapk/libs/runtime_library/BUILD.gn +++ b/chrome/android/webapk/libs/runtime_library/BUILD.gn
@@ -21,6 +21,12 @@ ] } +# A standalone jar for the aidl's generated java files so that multiple places +# can depend on the aidl. +android_library("webapk_service_aidl_java") { + srcjar_deps = [ ":webapk_service_aidl" ] +} + # runtime_library_from_assets_java cannot be used as a dependency of another # library because the dx tool expects files ending in .dex.jar android_library("runtime_library_for_assets_java") { @@ -29,8 +35,8 @@ "src/org/chromium/webapk/lib/runtime_library/HostBrowserLauncher.java", "src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java", ] - srcjar_deps = [ ":webapk_service_aidl" ] deps = [ + ":webapk_service_aidl_java", "//chrome/android/webapk/libs/common:common_java", ] } @@ -39,7 +45,9 @@ android_library("runtime_library_for_tests_java") { java_files = [ "src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java" ] - srcjar_deps = [ ":webapk_service_aidl" ] + deps = [ + ":webapk_service_aidl_java", + ] } android_assets("runtime_library_assets") { @@ -61,6 +69,7 @@ java_files = [ "javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java" ] deps = [ ":runtime_library_for_tests_java", + ":webapk_service_aidl_java", "//base:base_java_test_support", "//chrome/test/android:chrome_java_test_support", "//content/public/test/android:content_java_test_support",
diff --git a/chrome/android/webapk/libs/runtime_library/javatests/DEPS b/chrome/android/webapk/libs/runtime_library/javatests/DEPS index 7528863..185d7a0 100644 --- a/chrome/android/webapk/libs/runtime_library/javatests/DEPS +++ b/chrome/android/webapk/libs/runtime_library/javatests/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+base", "+chrome/test", "+content/public/test", ]
diff --git a/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java b/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java index 110a931e..916c9b22 100644 --- a/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java +++ b/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java
@@ -12,8 +12,8 @@ import android.content.pm.PackageManager; import android.os.IBinder; import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.test.webapk.TestWebApkServiceImplWrapper; import org.chromium.content.browser.test.util.CallbackHelper; @@ -62,8 +62,11 @@ /** * Test that an application which is not allowed to use the WebAPK service actually cannot. + * + * @SmallTest + * crbug.com/634390 */ - @SmallTest + @DisabledTest public void testApiFailsIfNoPermission() throws Exception { IWebApkApi api = bindService(mContext, mTargetUid + 1, SMALL_ICON_ID); try { @@ -76,8 +79,11 @@ /** * Test that an application which is allowed to use the WebAPK service actually can. + * + * @SmallTest + * crbug.com/634390 */ - @SmallTest + @DisabledTest public void testApiWorksIfHasPermission() throws Exception { IWebApkApi api = bindService(mContext, mTargetUid, SMALL_ICON_ID); try {
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index f9f0561..0cbfdfe9 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -2497,14 +2497,65 @@ <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION" desc="In the settings tab, the text next to the checkbox to highlight the focused object to make it easier to see."> Highlight the object with keyboard focus when it changes </message> - <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION" desc="In the settings tab, the text next to the checkbox to enable an option to hold a key and click to speak any on-screen text out loud."> - Select-to-speak: Hold down Search and click or drag to speak anything + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE" desc="In the settings tab, the text next to the checkbox to enable an option to hold a key and click to speak any on-screen text out loud."> + Select-to-speak + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION" desc="In the settings tab, the description of an option to hold a key and click to speak any on-screen text out loud."> + Hold down Search and click or drag to speak anything </message> <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION" desc="In the settings tab, the text next to the checkbox to enable switch access (for users with limited motor control)."> Switch access (control the computer with just one or two switches) </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES" desc="In the settings tab, the title of a link that opens a screen allowing the user to change accessibility features."> + Manage accessibility features + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING" desc="In the settings tab, the heading for accessibility features that enable the computer to speak text from the computer screen."> + Text-to-Speech + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DISPLAY_HEADING" desc="In the settings tab, the heading for accessibility features related to the computer's display."> + Display + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_TITLE" desc="In the settings tab, the title of a link to open display settings."> + Open display device settings + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_DESCRIPTION" desc="In the settings tab, an explanation that the display settings have options to adjust the screen resolution."> + Allows you to adjust your screen resolution + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_TITLE" desc="In the settings tab, the title of a link to open appearance settings."> + Open appearance settings + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_DESCRIPTION" desc="In the settings tab, an explanation that the appearance settings allows you to change the size of text on the screen."> + Customize your text size + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_KEYBOARD_HEADING" desc="In the settings tab, the heading above settings related to the keyboard."> + Keyboard + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_TITLE" desc="In the settings tab, the title of a link to open keyboard settings."> + Open keyboard device settings + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_DESCRIPTION" desc="In the settings tab, an explanation that the keyboard settings let you adjust the rate at which keys automatically repeat when held down, automatic prediction of words, and more."> + Allows you to adjust your keyboard repeat rate, word prediction, and more + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MOUSE_AND_TOUCHPAD_HEADING" desc="In the settings tab, the heading for the section on mouse and touchpad settings."> + Mouse and touchpad + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_TITLE" desc="In the settings tab, the title of a link to open mouse and touchpad settings."> + Open mouse and touchpad device settings + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_DESCRIPTION" desc="In the settings tab, an explanation that the mouse and touchpad settings allows you to turn the tap-to-click feature on and off."> + Allows you to enable/disable tap-to-click + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUDIO_HEADING" desc="In the settings tab, the heading for the section on audio / sound settings."> + Audio + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_TITLE" desc="In the settings tab, the title of a link that adds additional accessibility features not found in the built-in settings."> + Add additional features + </message> + <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_DESCRIPTION" desc="In the settings tab, an explanation that additional accessibility features are found on the Chrome Web Store."> + Choose from the Chrome Web Store + </message> <message name="IDS_FLAGS_EXPERIMENTAL_ACCESSIBILITY_FEATURES_NAME" desc="Name of the about:flag option for experimental accessibility features."> - Experimental acecssibility features + Experimental accessibility features </message> <message name="IDS_FLAGS_EXPERIMENTAL_ACCESSIBILITY_FEATURES_DESCRIPTION" desc="Description of the about:flag option for experimental accessibility features."> Enable additional accessibility features in the Settings page.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 54438e4..919656a 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5373,6 +5373,12 @@ <message name="IDS_FLAGS_COMPOSITED_LAYER_BORDERS_DESCRIPTION" desc="Description of the 'Composited layer borders' lab."> Renders a border around composited Render Layers to help debug and study layer compositing. </message> + <message name="IDS_FLAGS_GL_COMPOSITED_TEXTURE_QUAD_BORDERS" desc="Name of the 'Composited layer borders' lab."> + GL composited texture quad borders + </message> + <message name="IDS_FLAGS_GL_COMPOSITED_TEXTURE_QUAD_BORDERS_DESCRIPTION" desc="Description of the 'Composited layer borders' lab."> + Renders a border around GL composited texture quads to help debug and study overlay support. + </message> <message name="IDS_FLAGS_DEBUG_SHORTCUTS_NAME" desc="Name of the 'Debugging keyboard shortcuts' lab."> Debugging keyboard shortcuts </message> @@ -13522,6 +13528,14 @@ </message> </if> + <!-- Strings for controlling credit card assist feature in about:flags. --> + <message name="IDS_FLAGS_CREDIT_CARD_ASSIST_NAME" desc="The name of about:flags option to enable the credit card assisted filling."> + Credit Card Assisted Filling + </message> + <message name="IDS_FLAGS_CREDIT_CARD_ASSIST_DESCRIPTION" desc="The description of about:flags option to enable the credit card assisted filling.."> + Enable assisted credit card filling on certain sites. + </message> + <!-- Strings for controlling credit card scanning feature in about:flags. --> <message name="IDS_FLAGS_CREDIT_CARD_SCAN_NAME" desc="The name of about:flags option to enable scanning of credit cards using device camera."> Credit card scanning
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 190012e32..414ab0c7 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -723,6 +723,36 @@ <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS" desc="In Printing Settings, the title of the CUPS printers setting section."> Printers </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER" desc="In CUPS printing settings subpage, text for the link adding a new CUPS printer."> + Add Printer + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_DETAILS" desc="Text for the drop down menu which allows the user to see the printer details."> + Details + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE" desc="Text for the drop down menu which allows the user to remove the selected printer."> + Remove + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL" desc="The placeholder text in the printer search field."> + printer name + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_TITLE" desc="Text for the title of the Add Printer dialog."> + Add Printer + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE" desc="Text for the title of the Printer Details subpage."> + Printer details + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME" desc="Lable for the CUPS printer name in the printer details page."> + Name + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL" desc="Lable for the CUPS printer model in the printer details page."> + Model + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_CANCEL" desc="Text for the button which cancels adding a CUPS printer."> + Cancel + </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_ADD" desc="Text for the button which allows the user to add a CUPS printer."> + Add + </message> </if> <message name="IDS_SETTINGS_PRINTING_CLOUD_PRINTERS" desc="In Printing Settings, the title of the google cloud printers setting section."> Google Cloud Print @@ -1104,9 +1134,6 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_CATEGORY" desc="Name of the settings page which allows users to modify a specific category under site settings."> Permission Category </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_DETAILS" desc="Name of the settings page which allows users to modify details about a particular site."> - Site Details - </message> <message name="IDS_SETTINGS_SITE_SETTINGS_ALL_SITES" desc="Label for the all sites site settings."> All sites </message> @@ -1294,7 +1321,7 @@ Permissions </message> <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_BUTTON" desc="The Clear and Reset button, used to clear all permissions and storage for a given site."> - Clear & Reset + Clear and reset </message> <message name="IDS_SETTINGS_SITE_SETTINGS_DELETE" desc="Label for the trashcan icon used to delete storage on the Site Details page."> Delete
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5ce5565..f31f319 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -620,7 +620,6 @@ "//ui/compositor", "//ui/views/mus", ] - defines += [ "MOJO_SHELL_CLIENT" ] } if (ui_compositor_image_transport) { deps += [ "//ui/gl" ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index f7887bb..dd8e952 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -707,6 +707,10 @@ {"composited-layer-borders", IDS_FLAGS_COMPOSITED_LAYER_BORDERS, IDS_FLAGS_COMPOSITED_LAYER_BORDERS_DESCRIPTION, kOsAll, SINGLE_VALUE_TYPE(cc::switches::kShowCompositedLayerBorders)}, + {"gl-composited-texture-quad-borders", + IDS_FLAGS_GL_COMPOSITED_TEXTURE_QUAD_BORDERS, + IDS_FLAGS_GL_COMPOSITED_TEXTURE_QUAD_BORDERS_DESCRIPTION, kOsAll, + SINGLE_VALUE_TYPE(cc::switches::kGlCompositedTextureQuadBorder)}, #if defined(ENABLE_WEBRTC) {"disable-webrtc-hw-decoding", IDS_FLAGS_WEBRTC_HW_DECODING_NAME, IDS_FLAGS_WEBRTC_HW_DECODING_DESCRIPTION, kOsAndroid | kOsCrOS, @@ -1499,6 +1503,13 @@ {"disable-new-zip-unpacker", IDS_FLAGS_NEW_ZIP_UNPACKER_NAME, IDS_FLAGS_NEW_ZIP_UNPACKER_DESCRIPTION, kOsCrOS, SINGLE_DISABLE_VALUE_TYPE(chromeos::switches::kDisableNewZIPUnpacker)}, +#endif // defined(OS_CHROMEOS) +#if defined(OS_ANDROID) + {"enable-credit-card-assist", IDS_FLAGS_CREDIT_CARD_ASSIST_NAME, + IDS_FLAGS_CREDIT_CARD_ASSIST_DESCRIPTION, kOsAndroid, + FEATURE_VALUE_TYPE(autofill::kAutofillCreditCardAssist)}, +#endif // defined(OS_ANDROID) +#if defined(OS_CHROMEOS) {"disable-captive-portal-bypass-proxy", IDS_FLAGS_CAPTIVE_PORTAL_BYPASS_PROXY_NAME, IDS_FLAGS_CAPTIVE_PORTAL_BYPASS_PROXY_DESCRIPTION, kOsCrOS,
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index b0d717c..c93b323 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -134,6 +134,7 @@ #include "chrome/browser/ui/android/chrome_http_auth_handler.h" #include "chrome/browser/ui/android/connection_info_popup_android.h" #include "chrome/browser/ui/android/context_menu_helper.h" +#include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h" #include "chrome/browser/ui/android/infobars/autofill_save_card_infobar.h" #include "chrome/browser/ui/android/infobars/grouped_permission_infobar.h" #include "chrome/browser/ui/android/infobars/infobar_android.h"
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner.cc b/chrome/browser/android/offline_pages/prerendering_offliner.cc index 9579bed..e86f3cb 100644 --- a/chrome/browser/android/offline_pages/prerendering_offliner.cc +++ b/chrome/browser/android/offline_pages/prerendering_offliner.cc
@@ -107,6 +107,8 @@ bool PrerenderingOffliner::LoadAndSave(const SavePageRequest& request, const CompletionCallback& callback) { + DCHECK(!pending_request_.get()); + if (pending_request_) { DVLOG(1) << "Already have pending request"; return false;
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index 8061733..4a6b524 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -203,14 +203,14 @@ void AutocompleteControllerAndroid::Stop(JNIEnv* env, const JavaParamRef<jobject>& obj, bool clear_results) { - if (autocomplete_controller_ != NULL) + if (autocomplete_controller_ != nullptr) autocomplete_controller_->Stop(clear_results); } void AutocompleteControllerAndroid::ResetSession( JNIEnv* env, const JavaParamRef<jobject>& obj) { - if (autocomplete_controller_ != NULL) + if (autocomplete_controller_ != nullptr) autocomplete_controller_->ResetSession(); } @@ -566,8 +566,8 @@ obj, j_text, -1, - NULL, - NULL, + nullptr, + nullptr, prevent_inline_autocomplete, false, false, @@ -608,7 +608,7 @@ false, OmniboxEventProto::INVALID_SPEC, &match, - NULL); + nullptr); if (!match.destination_url.is_valid()) return ScopedJavaLocalRef<jstring>();
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc index ddbee41..d27dd7b 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.cc +++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -112,7 +112,7 @@ void TabWebContentsDelegateAndroid::LoadingStateChanged( WebContents* source, bool to_different_document) { - bool has_stopped = source == NULL || !source->IsLoading(); + bool has_stopped = source == nullptr || !source->IsLoading(); WebContentsDelegateAndroid::LoadingStateChanged( source, to_different_document); LoadProgressChanged(source, has_stopped ? 1 : 0); @@ -279,7 +279,7 @@ const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) { MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest( - web_contents, request, callback, NULL); + web_contents, request, callback, nullptr); } bool TabWebContentsDelegateAndroid::CheckMediaAccessPermission( @@ -346,7 +346,7 @@ switches::kDisablePopupBlocking)) { if (popup_blocker_helper->MaybeBlockPopup(nav_params, blink::WebWindowFeatures())) { - return NULL; + return nullptr; } } @@ -407,7 +407,7 @@ jsource.obj(), jnew_contents.obj(), static_cast<jint>(disposition), - NULL, + nullptr, user_gesture); }
diff --git a/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc b/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc new file mode 100644 index 0000000..a3eabe1 --- /dev/null +++ b/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc
@@ -0,0 +1,113 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h" + +#include <memory> + +#include "base/macros.h" +#include "base/test/histogram_tester.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/infobars/core/confirm_infobar_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +class AutofillCreditCardFillingInfoBarDelegateMobileTest + : public ChromeRenderViewHostTestHarness { + public: + AutofillCreditCardFillingInfoBarDelegateMobileTest() + : infobar_callback_has_run_(false) {} + ~AutofillCreditCardFillingInfoBarDelegateMobileTest() override {} + + protected: + std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> + CreateDelegate(); + + void AcceptInfoBarCallback() { infobar_callback_has_run_ = true; } + + bool infobar_callback_has_run_; + + private: + DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardFillingInfoBarDelegateMobileTest); +}; + +std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> +AutofillCreditCardFillingInfoBarDelegateMobileTest::CreateDelegate() { + infobar_callback_has_run_ = false; + CreditCard credit_card; + std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> delegate( + new AutofillCreditCardFillingInfoBarDelegateMobile( + credit_card, + base::Bind(&AutofillCreditCardFillingInfoBarDelegateMobileTest:: + AcceptInfoBarCallback, + base::Unretained(this)))); + delegate->set_was_shown(); + return delegate; +} + +// Test that credit card infobar metrics are logged correctly. +TEST_F(AutofillCreditCardFillingInfoBarDelegateMobileTest, Metrics) { + // Accept the infobar. + { + std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar( + CreateDelegate()); + + base::HistogramTester histogram_tester; + EXPECT_TRUE(infobar->Accept()); + EXPECT_TRUE(infobar_callback_has_run_); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_ACCEPTED, 1); + infobar.reset(); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_SHOWN, 1); + } + + // Cancel the infobar. + { + std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar( + CreateDelegate()); + + base::HistogramTester histogram_tester; + EXPECT_TRUE(infobar->Cancel()); + EXPECT_FALSE(infobar_callback_has_run_); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_DENIED, 1); + infobar.reset(); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_SHOWN, 1); + } + + // Dismiss the infobar. + { + std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar( + CreateDelegate()); + + base::HistogramTester histogram_tester; + infobar->InfoBarDismissed(); + EXPECT_FALSE(infobar_callback_has_run_); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_DENIED, 1); + infobar.reset(); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_SHOWN, 1); + } + + // Ignore the infobar. + { + std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar( + CreateDelegate()); + + base::HistogramTester histogram_tester; + infobar.reset(); + EXPECT_FALSE(infobar_callback_has_run_); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_SHOWN, 1); + histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar", + AutofillMetrics::INFOBAR_IGNORED, 1); + } +} + +} // namespace autofill
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index c7e82fe..d1a7a6e3 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -268,7 +268,7 @@ #include "chrome/browser/usb/web_usb_detector.h" #endif -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) #include "chrome/browser/lifetime/application_lifetime.h" #include "content/public/common/mojo_shell_connection.h" #include "services/shell/runner/common/client_util.h" @@ -1224,7 +1224,7 @@ } void ChromeBrowserMainParts::PreMainMessageLoopRun() { -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) if (content::MojoShellConnection::GetForProcess() && shell::ShellIsRemote()) { content::MojoShellConnection::GetForProcess()->SetConnectionLostClosure( base::Bind(&chrome::SessionEnding));
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c00b4891..4f0bf8e 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -191,6 +191,7 @@ #include "chrome/browser/chromeos/arc/arc_navigation_throttle.h" #include "chrome/browser/chromeos/attestation/platform_verification_impl.h" #include "chrome/browser/chromeos/chrome_browser_main_chromeos.h" +#include "chrome/browser/chromeos/chrome_interface_factory.h" #include "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h" #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.h" @@ -201,15 +202,12 @@ #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/system/input_device_settings.h" +#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chromeos/chromeos_switches.h" #include "components/arc/arc_service_manager.h" #include "components/arc/intent_helper/local_activity_resolver.h" #include "components/user_manager/user_manager.h" -#if defined(MOJO_SHELL_CLIENT) -#include "chrome/browser/chromeos/chrome_interface_factory.h" -#include "chrome/browser/ui/ash/ash_util.h" -#endif // MOJO_SHELL_CLIENT #elif defined(OS_LINUX) #include "chrome/browser/chrome_browser_main_linux.h" #elif defined(OS_ANDROID) @@ -2846,12 +2844,10 @@ apps->insert(std::make_pair("mojo:media", app_info)); #endif #if defined(OS_CHROMEOS) -#if defined(MOJO_SHELL_CLIENT) if (chrome::IsRunningInMash()) { content::MojoShellConnection::GetForProcess()->AddConnectionFilter( base::MakeUnique<chromeos::ChromeInterfaceFactory>()); } -#endif // MOJO_SHELL_CLIENT #endif // OS_CHROMEOS }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index a686f5a0..a4bfb97 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -133,8 +133,6 @@ "//v8", ] - defines = [ "MOJO_SHELL_CLIENT" ] - sources = rebase_path(gypi_values.browser_chromeos_sources, ".", "//chrome") + rebase_path(gypi_values.browser_chromeos_extension_sources, ".", @@ -169,7 +167,7 @@ } if (use_cras) { - defines += [ "USE_CRAS" ] + defines = [ "USE_CRAS" ] } if (ui_compositor_image_transport) {
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 8dee3337..30f50be 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -227,7 +227,9 @@ render_view_host->GetRoutingID(), done_cb); } - extension_service->component_loader()->AddChromeVoxExtension(done_cb); + + extension_service->component_loader()->AddComponentFromDir( + GetChromeVoxPath(), extension_misc::kChromeVoxExtensionId, done_cb); } void InjectChromeVoxContentScript(
diff --git a/chrome/browser/chromeos/arc/arc_auth_service.cc b/chrome/browser/chromeos/arc/arc_auth_service.cc index 3aaffd8..105058e7 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service.cc +++ b/chrome/browser/chromeos/arc/arc_auth_service.cc
@@ -153,9 +153,9 @@ // static void ArcAuthService::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - // TODO(dspaid): Add a syncable default preference so that new - // devices get the last opt-in preference. - registry->RegisterBooleanPref(prefs::kArcEnabled, false); + registry->RegisterBooleanPref( + prefs::kArcEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref(prefs::kArcSignedIn, false); registry->RegisterBooleanPref(prefs::kArcBackupRestoreEnabled, true); registry->RegisterBooleanPref(prefs::kArcLocationServiceEnabled, true);
diff --git a/chrome/browser/chromeos/hats/hats_notification_controller.cc b/chrome/browser/chromeos/hats/hats_notification_controller.cc index 26941c1..70efb15 100644 --- a/chrome/browser/chromeos/hats/hats_notification_controller.cc +++ b/chrome/browser/chromeos/hats/hats_notification_controller.cc
@@ -35,6 +35,17 @@ const float kScale_1x = 1.0f; const float kScale_2x = 2.0f; +// Minimum amount of time before the notification is displayed again after a +// user has interacted with it. +const int kHatsThresholdDays = 90; + +// The threshold for a googler is less. +const int kHatsGooglerThresholdDays = 30; + +// Minimum amount of time after initial login or oobe after which we can show +// the HaTS notification. +const int kHatsNewDeviceThresholdDays = 7; + // Returns true if the given |profile| interacted with HaTS by either // dismissing the notification or taking the survey within a given threshold // days |threshold_days|. @@ -86,12 +97,6 @@ const char HatsNotificationController::kGoogleIcon2xUrl[] = "https://www.gstatic.com/images/branding/product/2x/googleg_48dp.png"; -// static -const int HatsNotificationController::kHatsThresholdDays = 90; - -// static -const int HatsNotificationController::kHatsNewDeviceThresholdDays = 7; - HatsNotificationController::HatsNotificationController( Profile* profile, image_fetcher::ImageFetcher* image_fetcher) @@ -146,9 +151,12 @@ return false; } + int threshold_days = IsGoogleUser(profile->GetProfileUserName()) + ? kHatsGooglerThresholdDays + : kHatsThresholdDays; // Do not show survey to user if user has interacted with HaTS within the past // |kHatsThresholdTime| time delta. - if (DidShowSurveyToProfileRecently(profile, kHatsThresholdDays)) + if (DidShowSurveyToProfileRecently(profile, threshold_days)) return false; return true;
diff --git a/chrome/browser/chromeos/hats/hats_notification_controller.h b/chrome/browser/chromeos/hats/hats_notification_controller.h index bab57b4f..8f856d2 100644 --- a/chrome/browser/chromeos/hats/hats_notification_controller.h +++ b/chrome/browser/chromeos/hats/hats_notification_controller.h
@@ -31,12 +31,6 @@ class HatsNotificationController : public NotificationDelegate, public NetworkPortalDetector::Observer { public: - // Minimum amount of time before the notification is displayed again after a - // user has interacted with it. - static const int kHatsThresholdDays; - // Minimum amount of time after initial login or oobe after which we can show - // the HaTS notification. - static const int kHatsNewDeviceThresholdDays; static const char kDelegateId[]; static const char kNotificationId[]; static const char kImageFetcher1xId[];
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc index ff7c536..afd4e68 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/common/chrome_features.h" +#include "components/user_manager/user_manager.h" namespace chromeos { @@ -27,6 +28,12 @@ return false; } + // TODO(jdufault): Disable PIN for supervised users until we allow the owner + // to set the PIN. See crbug.com/632797. + user_manager::User* user = user_manager::UserManager::Get()->GetActiveUser(); + if (user && user->IsSupervised()) + return false; + // Enable quick unlock only if the switch is present. return base::FeatureList::IsEnabled(features::kQuickUnlockPin); }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc index ebcb944..c549694e 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -11,6 +11,7 @@ #include "ash/common/wm_shell.h" #include "ash/desktop_background/desktop_background_controller.h" #include "ash/desktop_background/user_wallpaper_delegate.h" +#include "ash/public/interfaces/container.mojom.h" #include "ash/shell.h" #include "base/bind.h" #include "base/command_line.h" @@ -87,6 +88,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "media/audio/sounds/sounds_manager.h" +#include "services/ui/public/cpp/property_type_converters.h" #include "ui/aura/window.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/input_method_manager.h" @@ -107,11 +109,6 @@ #include "ui/views/widget/widget_delegate.h" #include "url/gurl.h" -#if defined(MOJO_SHELL_CLIENT) -#include "ash/public/interfaces/container.mojom.h" -#include "services/ui/public/cpp/property_type_converters.h" -#endif - namespace { // Maximum delay for startup sound after 'loginPromptVisible' signal. @@ -1141,13 +1138,9 @@ ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), ash::kShellWindowId_LockScreenContainer); } else { -#if defined(MOJO_SHELL_CLIENT) params.mus_properties[ash::mojom::kWindowContainer_Property] = mojo::ConvertTo<std::vector<uint8_t>>( static_cast<int32_t>(ash::mojom::Container::LOGIN_WINDOWS)); -#else - NOTREACHED(); -#endif } login_window_ = new views::Widget; params.delegate = new LoginWidgetDelegate(login_window_);
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc index 764531d6..44b02c8 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -13,6 +13,7 @@ #include "ash/common/ash_switches.h" #include "ash/desktop_background/desktop_background_controller.h" #include "ash/shell.h" +#include "ash/sysui/public/interfaces/wallpaper.mojom.h" #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_enumerator.h" @@ -66,10 +67,6 @@ #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/skia_util.h" -#if defined(MOJO_SHELL_CLIENT) -#include "ash/sysui/public/interfaces/wallpaper.mojom.h" -#endif - using content::BrowserThread; using wallpaper::WallpaperManagerBase; using wallpaper::WallpaperInfo; @@ -180,7 +177,6 @@ wallpaper_files_id.id()); } -#if defined(MOJO_SHELL_CLIENT) ash::sysui::mojom::WallpaperLayout WallpaperLayoutToMojo( wallpaper::WallpaperLayout layout) { switch (layout) { @@ -199,12 +195,10 @@ NOTREACHED(); return ash::sysui::mojom::WallpaperLayout::CENTER; } -#endif // A helper to set the wallpaper image for Ash and Mash. void SetWallpaper(const gfx::ImageSkia& image, wallpaper::WallpaperLayout layout) { -#if defined(MOJO_SHELL_CLIENT) if (chrome::IsRunningInMash()) { shell::Connector* connector = content::MojoShellConnection::GetForProcess()->GetConnector(); @@ -214,7 +208,6 @@ WallpaperLayoutToMojo(layout)); return; } -#endif // Avoid loading unnecessary wallpapers in tests without a shell instance. if (ash::Shell::HasInstance()) { ash::Shell::GetInstance()
diff --git a/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc b/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc index 2151480..10808ff3 100644 --- a/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc +++ b/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc
@@ -8,13 +8,10 @@ #include "base/sys_info.h" #include "chrome/browser/chromeos/system/fake_input_device_settings.h" #include "content/public/browser/browser_thread.h" +#include "services/shell/runner/common/client_util.h" #include "ui/ozone/public/input_controller.h" #include "ui/ozone/public/ozone_platform.h" -#if defined(MOJO_SHELL_CLIENT) -#include "services/shell/runner/common/client_util.h" -#endif - namespace chromeos { namespace system { @@ -23,11 +20,7 @@ InputDeviceSettings* g_instance = nullptr; std::unique_ptr<ui::InputController> CreateStubInputControllerIfNecessary() { -#if defined(MOJO_SHELL_CLIENT) return shell::ShellIsRemote() ? ui::CreateStubInputController() : nullptr; -#else - return nullptr; -#endif } // InputDeviceSettings for Linux without X11 (a.k.a. Ozone).
diff --git a/chrome/browser/extensions/api/processes/processes_apitest.cc b/chrome/browser/extensions/api/processes/processes_apitest.cc index 074d1eb..626e6a3 100644 --- a/chrome/browser/extensions/api/processes/processes_apitest.cc +++ b/chrome/browser/extensions/api/processes/processes_apitest.cc
@@ -27,13 +27,8 @@ }; -// This test is flaky on Win7 Tests (dbg)(1). https://crbug.com/598445 -#if defined(OS_WIN) -#define MAYBE_Processes DISABLED_Processes -#else -#define MAYBE_Processes Processes -#endif -IN_PROC_BROWSER_TEST_F(ProcessesApiTest, MAYBE_Processes) { +// This test is flaky. https://crbug.com/598445 +IN_PROC_BROWSER_TEST_F(ProcessesApiTest, DISABLED_Processes) { ASSERT_TRUE(RunExtensionTest("processes/api")) << message_; }
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index c6289573..a85f217c 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -56,7 +56,6 @@ #endif #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chromeos/chromeos_switches.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/storage_partition.h" @@ -377,30 +376,8 @@ } #if defined(OS_CHROMEOS) -void ComponentLoader::AddChromeVoxExtension( - const base::Closure& done_cb) { - base::FilePath resources_path; - CHECK(PathService::Get(chrome::DIR_RESOURCES, &resources_path)); - - base::FilePath chromevox_path = - resources_path.Append(extension_misc::kChromeVoxExtensionPath); - - const base::FilePath::CharType* manifest_filename = - IsNormalSession() ? extensions::kManifestFilename - : extension_misc::kGuestManifestFilename; - AddWithManifestFile( - manifest_filename, - chromevox_path, - extension_misc::kChromeVoxExtensionId, - done_cb); -} - void ComponentLoader::AddChromeOsSpeechSynthesisExtension() { - const base::FilePath::CharType* manifest_filename = - IsNormalSession() ? extensions::kManifestFilename - : extension_misc::kGuestManifestFilename; - AddWithManifestFile( - manifest_filename, + AddComponentFromDir( base::FilePath(extension_misc::kSpeechSynthesisExtensionPath), extension_misc::kSpeechSynthesisExtensionId, base::Bind(&ComponentLoader::EnableFileSystemInGuestMode, @@ -625,12 +602,6 @@ Add(IDR_ARC_SUPPORT_MANIFEST, base::FilePath(FILE_PATH_LITERAL("chromeos/arc_support"))); } - - // Load ChromeVox extension now if spoken feedback is enabled. - if (chromeos::AccessibilityManager::Get() && - chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) { - AddChromeVoxExtension(base::Closure()); - } #endif // defined(OS_CHROMEOS) #if defined(GOOGLE_CHROME_BUILD) @@ -689,24 +660,26 @@ } #if defined(OS_CHROMEOS) -void ComponentLoader::AddWithManifestFile( - const base::FilePath::CharType* manifest_filename, +void ComponentLoader::AddComponentFromDir( const base::FilePath& root_directory, const char* extension_id, const base::Closure& done_cb) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + const base::FilePath::CharType* manifest_filename = + IsNormalSession() ? extensions::kManifestFilename + : extension_misc::kGuestManifestFilename; BrowserThread::PostTaskAndReplyWithResult( BrowserThread::FILE, FROM_HERE, base::Bind(&LoadManifestOnFileThread, root_directory, manifest_filename), - base::Bind(&ComponentLoader::FinishAddWithManifestFile, + base::Bind(&ComponentLoader::FinishAddComponentFromDir, weak_factory_.GetWeakPtr(), root_directory, extension_id, done_cb)); } -void ComponentLoader::FinishAddWithManifestFile( +void ComponentLoader::FinishAddComponentFromDir( const base::FilePath& root_directory, const char* extension_id, const base::Closure& done_cb,
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h index c9d8f654..d71d360 100644 --- a/chrome/browser/extensions/component_loader.h +++ b/chrome/browser/extensions/component_loader.h
@@ -99,10 +99,15 @@ void Reload(const std::string& extension_id); #if defined(OS_CHROMEOS) - // Calls |done_cb|, if not a null callback, on success. - // NOTE: |done_cb| is not called if the component loader is shut down - // during loading. - void AddChromeVoxExtension(const base::Closure& done_cb); + // Add a component extension from a specific directory. Assumes that the + // extension uses a different manifest file when this is a guest session. + // Calls |done_cb| on success, unless the component loader is + // shut down during loading. + void AddComponentFromDir( + const base::FilePath& root_directory, + const char* extension_id, + const base::Closure& done_cb); + void AddChromeOsSpeechSynthesisExtension(); #endif @@ -175,18 +180,10 @@ void EnableFileSystemInGuestMode(const std::string& id); #if defined(OS_CHROMEOS) - // Adds an extension where the manifest file is stored on the file system. - // |manifest_filename| can be relative to the |root_directory|. - void AddWithManifestFile( - const base::FilePath::CharType* manifest_filename, - const base::FilePath& root_directory, - const char* extension_id, - const base::Closure& done_cb); - - // Used as a reply callback by |AddWithManifestFile|. + // Used as a reply callback by |AddComponentFromDir|. // Called with a |root_directory| and parsed |manifest| and invokes // |done_cb| after adding the extension. - void FinishAddWithManifestFile( + void FinishAddComponentFromDir( const base::FilePath& root_directory, const char* extension_id, const base::Closure& done_cb,
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index e738185..53de0608 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -1106,7 +1106,7 @@ content::Source<Profile>(profile_), content::Details<UnloadedExtensionInfo>(&details)); - renderer_helper_->OnExtensionUnloaded(extension->id()); + renderer_helper_->OnExtensionUnloaded(*extension); system_->UnregisterExtensionWithRequestContexts(extension->id(), reason);
diff --git a/chrome/browser/extensions/extension_system_impl.cc b/chrome/browser/extensions/extension_system_impl.cc index fa7596f..7ad271f 100644 --- a/chrome/browser/extensions/extension_system_impl.cc +++ b/chrome/browser/extensions/extension_system_impl.cc
@@ -275,8 +275,9 @@ t(path_list, FILE_PATH_LITERAL(",")); while (t.GetNext()) { std::string extension_id; - UnpackedInstaller::Create(extension_service_.get())-> - LoadFromCommandLine(base::FilePath(t.token()), &extension_id); + UnpackedInstaller::Create(extension_service_.get()) + ->LoadFromCommandLine(base::FilePath(t.token()), &extension_id, + false /* only_allow_apps */); } } }
diff --git a/chrome/browser/extensions/renderer_initialization_browsertest.cc b/chrome/browser/extensions/renderer_initialization_browsertest.cc index 4664435..63fbe88 100644 --- a/chrome/browser/extensions/renderer_initialization_browsertest.cc +++ b/chrome/browser/extensions/renderer_initialization_browsertest.cc
@@ -37,4 +37,22 @@ ASSERT_FALSE(web_contents->IsCrashed()); } +// Tests that loading a file from a theme in a tab doesn't crash anything. +// Another part of crbug.com/528026 and related. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, + TestRendererInitializationWithThemesTab) { + const Extension* extension = LoadExtensionWithFlags( + test_data_dir_.AppendASCII("theme"), kFlagAllowOldManifestVersions); + ASSERT_TRUE(extension); + ASSERT_TRUE(extension->is_theme()); + GURL url = extension->GetResourceURL("manifest.json"); + ui_test_utils::NavigateToURL(browser(), url); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + // Wait for the web contents to stop loading. + content::WaitForLoadStop(web_contents); + EXPECT_EQ(url, web_contents->GetLastCommittedURL()); + ASSERT_FALSE(web_contents->IsCrashed()); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc index c00bad4..1808fa7 100644 --- a/chrome/browser/extensions/unpacked_installer.cc +++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -130,7 +130,8 @@ } bool UnpackedInstaller::LoadFromCommandLine(const base::FilePath& path_in, - std::string* extension_id) { + std::string* extension_id, + bool only_allow_apps) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(extension_path_.empty()); @@ -152,6 +153,20 @@ file_util::LoadExtension( extension_path_, Manifest::COMMAND_LINE, GetFlags(), &error).get()); + if (only_allow_apps && !extension()->is_platform_app()) { +#if defined(GOOGLE_CHROME_BUILD) + // Avoid crashing for users with hijacked shortcuts. + return true; +#else + // Defined here to avoid unused variable errors in official builds. + const char extension_instead_of_app_error[] = + "App loading flags cannot be used to load extensions. Please use " + "--load-extension instead."; + ReportExtensionLoadError(extension_instead_of_app_error); + return false; +#endif + } + if (!extension() || !extension_l10n_util::ValidateExtensionLocales( extension_path_, extension()->manifest()->value(), &error)) {
diff --git a/chrome/browser/extensions/unpacked_installer.h b/chrome/browser/extensions/unpacked_installer.h index 2bdc85e..c0416a2 100644 --- a/chrome/browser/extensions/unpacked_installer.h +++ b/chrome/browser/extensions/unpacked_installer.h
@@ -50,8 +50,10 @@ // |extension_path| synchronously. // The return value indicates whether the installation has begun successfully. // The id of the extension being loaded is returned in |extension_id|. + // |only_allow_apps| is used to avoid side-loading of non-app extensions. bool LoadFromCommandLine(const base::FilePath& extension_path, - std::string* extension_id); + std::string* extension_id, + bool only_allow_apps); // Allows prompting for plugins to be disabled; intended for testing only. bool prompt_for_plugins() { return prompt_for_plugins_; }
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.cc b/chrome/browser/media/android/remote/remote_media_player_bridge.cc index fa30672..4bcd1cff 100644 --- a/chrome/browser/media/android/remote/remote_media_player_bridge.cc +++ b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
@@ -321,7 +321,8 @@ CHECK(env); if (bitmaps.empty()) { - Java_RemoteMediaPlayerBridge_setPosterBitmap(env, java_bridge_.obj(), NULL); + Java_RemoteMediaPlayerBridge_setPosterBitmap(env, java_bridge_.obj(), + nullptr); } else { ScopedJavaLocalRef<jobject> j_poster_bitmap; j_poster_bitmap = gfx::ConvertToJavaBitmap(&(bitmaps[0]));
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc index dbb7721..f34a995 100644 --- a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc +++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
@@ -191,6 +191,9 @@ // TODO(csharrison): Add a case for client side redirects, which is what JS // initiated window.location / window.history navigations get set to. UserAbortType AbortTypeForPageTransition(ui::PageTransition transition) { + if (transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT) { + return ABORT_CLIENT_REDIRECT; + } if (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD)) return ABORT_RELOAD; if (transition & ui::PAGE_TRANSITION_FORWARD_BACK) @@ -334,6 +337,12 @@ UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeForwardBack, aborted_chain_size_); return; + // TODO(csharrison): Refactor this code so it is based on the WillStart* + // code path instead of the committed load code path. Then, for every abort + // chain, log a histogram of the counts of each of these metrics. For now, + // merge client redirects with new navigations, which was (basically) the + // previous behavior. + case ABORT_CLIENT_REDIRECT: case ABORT_NEW_NAVIGATION: UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeNewNavigation, aborted_chain_size_);
diff --git a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc index 28e31d0..f6c32ab 100644 --- a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc
@@ -10,6 +10,8 @@ namespace internal { +const char kHistogramAbortClientRedirectBeforeCommit[] = + "PageLoad.AbortTiming.ClientRedirect.BeforeCommit"; const char kHistogramAbortForwardBackBeforeCommit[] = "PageLoad.AbortTiming.ForwardBackNavigation.BeforeCommit"; const char kHistogramAbortReloadBeforeCommit[] = @@ -23,6 +25,8 @@ const char kHistogramAbortOtherBeforeCommit[] = "PageLoad.AbortTiming.Other.BeforeCommit"; +const char kHistogramAbortClientRedirectBeforePaint[] = + "PageLoad.AbortTiming.ClientRedirect.AfterCommit.BeforePaint"; const char kHistogramAbortForwardBackBeforePaint[] = "PageLoad.AbortTiming.ForwardBackNavigation.AfterCommit.BeforePaint"; const char kHistogramAbortReloadBeforePaint[] = @@ -34,6 +38,8 @@ const char kHistogramAbortCloseBeforePaint[] = "PageLoad.AbortTiming.Close.AfterCommit.BeforePaint"; +const char kHistogramAbortClientRedirectDuringParse[] = + "PageLoad.AbortTiming.ClientRedirect.DuringParse"; const char kHistogramAbortForwardBackDuringParse[] = "PageLoad.AbortTiming.ForwardBackNavigation.DuringParse"; const char kHistogramAbortReloadDuringParse[] = @@ -60,6 +66,10 @@ PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortForwardBackBeforeCommit, time_to_abort); return; + case UserAbortType::ABORT_CLIENT_REDIRECT: + PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortClientRedirectBeforeCommit, + time_to_abort); + return; case UserAbortType::ABORT_NEW_NAVIGATION: PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortNewNavigationBeforeCommit, time_to_abort); @@ -95,6 +105,10 @@ PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortForwardBackBeforePaint, time_to_abort); return; + case UserAbortType::ABORT_CLIENT_REDIRECT: + PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortClientRedirectBeforePaint, + time_to_abort); + return; case UserAbortType::ABORT_NEW_NAVIGATION: PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortNewNavigationBeforePaint, time_to_abort); @@ -129,6 +143,10 @@ PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortForwardBackDuringParse, time_to_abort); return; + case UserAbortType::ABORT_CLIENT_REDIRECT: + PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortClientRedirectDuringParse, + time_to_abort); + return; case UserAbortType::ABORT_NEW_NAVIGATION: PAGE_LOAD_HISTOGRAM(internal::kHistogramAbortNewNavigationDuringParse, time_to_abort);
diff --git a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h index 2132d336..6d18d481 100644 --- a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h
@@ -13,6 +13,7 @@ extern const char kHistogramAbortForwardBackBeforeCommit[]; extern const char kHistogramAbortReloadBeforeCommit[]; extern const char kHistogramAbortNewNavigationBeforeCommit[]; +extern const char kHistogramAbortClientRedirectBeforeCommit[]; extern const char kHistogramAbortStopBeforeCommit[]; extern const char kHistogramAbortCloseBeforeCommit[]; extern const char kHistogramAbortOtherBeforeCommit[];
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc index 4cdc73f..cc5c8d9 100644 --- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" #include "components/rappor/rappor_service.h" #include "components/rappor/rappor_utils.h" +#include "net/http/http_response_headers.h" #include "ui/base/page_transition_types.h" namespace { @@ -120,6 +121,9 @@ "PageLoad.ParseTiming.ParseBlockedOnScriptLoadFromDocumentWrite." "Background"; +const char kHistogramFirstContentfulPaintNoStore[] = + "PageLoad.PaintTiming.NavigationToFirstContentfulPaint.NoStore"; + const char kHistogramLoadTypeFirstContentfulPaintReload[] = "PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType." "Reload"; @@ -129,6 +133,9 @@ const char kHistogramLoadTypeFirstContentfulPaintForwardBack[] = "PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType." "ForwardBackNavigation"; +const char kHistogramLoadTypeFirstContentfulPaintForwardBackNoStore[] = + "PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType." + "ForwardBackNavigation.NoStore"; const char kHistogramLoadTypeFirstContentfulPaintNewNavigation[] = "PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType." "NewNavigation"; @@ -138,6 +145,9 @@ const char kHistogramLoadTypeParseStartForwardBack[] = "PageLoad.ParseTiming.NavigationToParseStart.LoadType." "ForwardBackNavigation"; +const char kHistogramLoadTypeParseStartForwardBackNoStore[] = + "PageLoad.ParseTiming.NavigationToParseStart.LoadType." + "ForwardBackNavigation.NoStore"; const char kHistogramLoadTypeParseStartNewNavigation[] = "PageLoad.ParseTiming.NavigationToParseStart.LoadType.NewNavigation"; @@ -165,7 +175,8 @@ CorePageLoadMetricsObserver::CorePageLoadMetricsObserver() : transition_(ui::PAGE_TRANSITION_LINK), - initiated_by_user_gesture_(false) {} + initiated_by_user_gesture_(false), + was_no_store_main_resource_(false) {} CorePageLoadMetricsObserver::~CorePageLoadMetricsObserver() {} @@ -173,6 +184,12 @@ content::NavigationHandle* navigation_handle) { transition_ = navigation_handle->GetPageTransition(); initiated_by_user_gesture_ = navigation_handle->HasUserGesture(); + const net::HttpResponseHeaders* headers = + navigation_handle->GetResponseHeaders(); + if (headers) { + was_no_store_main_resource_ = + headers->HasHeaderValue("cache-control", "no-store"); + } } void CorePageLoadMetricsObserver::OnDomContentLoadedEventStart( @@ -277,6 +294,11 @@ internal::kHistogramParseStartToFirstContentfulPaint, timing.first_contentful_paint.value() - timing.parse_start.value()); + if (was_no_store_main_resource_) { + PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstContentfulPaintNoStore, + timing.first_contentful_paint.value()); + } + switch (GetPageLoadType(transition_)) { case LOAD_TYPE_RELOAD: PAGE_LOAD_HISTOGRAM( @@ -292,6 +314,12 @@ PAGE_LOAD_HISTOGRAM( internal::kHistogramLoadTypeFirstContentfulPaintForwardBack, timing.first_contentful_paint.value()); + if (was_no_store_main_resource_) { + PAGE_LOAD_HISTOGRAM( + internal:: + kHistogramLoadTypeFirstContentfulPaintForwardBackNoStore, + timing.first_contentful_paint.value()); + } break; case LOAD_TYPE_NEW_NAVIGATION: PAGE_LOAD_HISTOGRAM( @@ -327,6 +355,11 @@ case LOAD_TYPE_FORWARD_BACK: PAGE_LOAD_HISTOGRAM(internal::kHistogramLoadTypeParseStartForwardBack, timing.parse_start.value()); + if (was_no_store_main_resource_) { + PAGE_LOAD_HISTOGRAM( + internal::kHistogramLoadTypeParseStartForwardBackNoStore, + timing.parse_start.value()); + } break; case LOAD_TYPE_NEW_NAVIGATION: PAGE_LOAD_HISTOGRAM(internal::kHistogramLoadTypeParseStartNewNavigation,
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h index b33bc568..a7d06d5 100644 --- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
@@ -97,6 +97,7 @@ ui::PageTransition transition_; bool initiated_by_user_gesture_; + bool was_no_store_main_resource_; DISALLOW_COPY_AND_ASSIGN(CorePageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 4773621..6f6a801 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -348,3 +348,32 @@ histogram_tester_.ExpectTotalCount( internal::kHistogramAbortNewNavigationBeforeCommit, 2); } + +IN_PROC_BROWSER_TEST_F(MetricsWebContentsObserverBrowserTest, + AbortClientRedirect) { + ASSERT_TRUE(embedded_test_server()->Start()); + + GURL first_url(embedded_test_server()->GetURL("/title1.html")); + ui_test_utils::NavigateToURL(browser(), first_url); + + GURL second_url(embedded_test_server()->GetURL("/title2.html")); + chrome::NavigateParams params(browser(), second_url, + ui::PAGE_TRANSITION_LINK); + content::TestNavigationManager manager( + browser()->tab_strip_model()->GetActiveWebContents(), second_url); + chrome::Navigate(¶ms); + EXPECT_TRUE(manager.WaitForWillStartRequest()); + + { + content::TestNavigationManager reload_manager( + browser()->tab_strip_model()->GetActiveWebContents(), first_url); + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + "window.location.reload();")); + } + + manager.WaitForNavigationFinished(); + + histogram_tester_.ExpectTotalCount( + internal::kHistogramAbortClientRedirectBeforeCommit, 1); +}
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_observer.h b/chrome/browser/page_load_metrics/page_load_metrics_observer.h index f8268d7d..52e28264 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/page_load_metrics_observer.h
@@ -27,6 +27,11 @@ // The user presses the back/forward button. ABORT_FORWARD_BACK, + // The navigation is replaced with a navigation with the qualifier + // ui::PAGE_TRANSITION_CLIENT_REDIRECT, which is caused by Javascript, or the + // meta refresh tag. + ABORT_CLIENT_REDIRECT, + // If the navigation is replaced by a new navigation. This includes link // clicks, typing in the omnibox (not a reload), and form submissions. ABORT_NEW_NAVIGATION,
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc index d785f95..c045356f 100644 --- a/chrome/browser/plugins/chrome_plugin_service_filter.cc +++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -112,7 +112,11 @@ // Check whether the plugin is disabled. ResourceContextMap::iterator prefs_it = plugin_prefs_.find(context); - DCHECK(prefs_it != plugin_prefs_.end()); + // The context might not be found because RenderFrameMessageFilter might + // outlive the Profile (the context is unregistered during the Profile + // destructor). + if (prefs_it == plugin_prefs_.end()) + return false; if (!prefs_it->second.get()->IsPluginEnabled(*plugin)) return false;
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 1c992d4..becbbe8 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -6,6 +6,7 @@ #include <stdint.h> +#include <map> #include <set> #include <string> @@ -130,9 +131,18 @@ namespace { -// Profiles that should be deleted on shutdown. -std::vector<base::FilePath>& ProfilesToDelete() { - CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ()); +// Profile deletion can pass through two stages: +enum class ProfileDeletionStage { + // At SCHEDULED stage will be performed necessary activity prior to + // profile deletion. Such as new profile creation, if none is left, or load + // fallback profile for Macs, if it not loaded yet. + SCHEDULED, + // At MARKED stage profile can be safely removed from disk. + MARKED +}; +using ProfileDeletionMap = std::map<base::FilePath, ProfileDeletionStage>; +ProfileDeletionMap& ProfilesToDelete() { + CR_DEFINE_STATIC_LOCAL(ProfileDeletionMap, profiles_to_delete, ()); return profiles_to_delete; } @@ -201,14 +211,26 @@ } #if !defined(OS_ANDROID) -void QueueProfileDirectoryForDeletion(const base::FilePath& path) { - ProfilesToDelete().push_back(path); +// Schedule a profile for deletion if it isn't already scheduled. +// Returns whether the profile has been newly scheduled. +bool ScheduleProfileDirectoryForDeletion(const base::FilePath& path) { + if (ContainsKey(ProfilesToDelete(), path)) + return false; + ProfilesToDelete()[path] = ProfileDeletionStage::SCHEDULED; + return true; +} + +void MarkProfileDirectoryForDeletion(const base::FilePath& path) { + DCHECK(!ContainsKey(ProfilesToDelete(), path) || + ProfilesToDelete()[path] == ProfileDeletionStage::SCHEDULED); + ProfilesToDelete()[path] = ProfileDeletionStage::MARKED; } #endif -bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) { - return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), - profile_path) != ProfilesToDelete().end(); +bool IsProfileDirectoryMarkedForDeletion(const base::FilePath& profile_path) { + auto it = ProfilesToDelete().find(profile_path); + return it != ProfilesToDelete().end() && + it->second == ProfileDeletionStage::MARKED; } // Physically remove deleted profile directories from disk. @@ -333,11 +355,9 @@ // static void ProfileManager::NukeDeletedProfilesFromDisk() { - for (std::vector<base::FilePath>::iterator it = - ProfilesToDelete().begin(); - it != ProfilesToDelete().end(); - ++it) { - NukeProfileFromDisk(*it); + for (const auto& item : ProfilesToDelete()) { + if (item.second == ProfileDeletionStage::MARKED) + NukeProfileFromDisk(item.first); } ProfilesToDelete().clear(); } @@ -467,7 +487,7 @@ profile_path.AsUTF8Unsafe()); // Make sure that this profile is not pending deletion. - if (IsProfileMarkedForDeletion(profile_path)) { + if (IsProfileDirectoryMarkedForDeletion(profile_path)) { if (!callback.is_null()) callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); return; @@ -735,7 +755,7 @@ const base::FilePath& profile_dir, const CreateCallback& callback, ProfileMetrics::ProfileDelete deletion_source) { - if (IsProfileMarkedForDeletion(profile_dir)) + if (!ScheduleProfileDirectoryForDeletion(profile_dir)) return false; ScheduleProfileForDeletion(profile_dir, callback); ProfileMetrics::LogProfileDeleteUser(deletion_source); @@ -746,7 +766,7 @@ const base::FilePath& profile_dir, const CreateCallback& callback) { DCHECK(profiles::IsMultipleProfilesEnabled()); - DCHECK(!IsProfileMarkedForDeletion(profile_dir)); + DCHECK(!IsProfileDirectoryMarkedForDeletion(profile_dir)); // Cancel all in-progress downloads before deleting the profile to prevent a // "Do you want to exit Google Chrome and cancel the downloads?" prompt @@ -770,7 +790,7 @@ // legacy-supervised. if (cur_path != profile_dir && !entry->IsLegacySupervised() && - !IsProfileMarkedForDeletion(cur_path)) { + !IsProfileDirectoryMarkedForDeletion(cur_path)) { last_non_supervised_profile_path = cur_path; break; } @@ -1403,7 +1423,7 @@ // Queue even a profile that was nuked so it will be MarkedForDeletion and so // CreateProfileAsync can't create it. - QueueProfileDirectoryForDeletion(profile_dir); + MarkProfileDirectoryForDeletion(profile_dir); storage.RemoveProfile(profile_dir); ProfileMetrics::UpdateReportedProfilesStatistics(this); } @@ -1566,7 +1586,7 @@ } base::FilePath path = profile->GetPath(); - if (IsProfileMarkedForDeletion(path)) { + if (IsProfileDirectoryMarkedForDeletion(path)) { // Do nothing if the profile is already being deleted. } else if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) { // Delete if the profile is an ephemeral profile. @@ -1617,7 +1637,7 @@ if (status != Profile::CREATE_STATUS_INITIALIZED) return; - if (IsProfileMarkedForDeletion(new_active_profile_path)) { + if (IsProfileDirectoryMarkedForDeletion(new_active_profile_path)) { // If the profile we tried to load as the next active profile has been // deleted, then retry deleting this profile to redo the logic to load // the next available profile.
diff --git a/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/chromevox/BUILD.gn index 717722b..ca38116 100644 --- a/chrome/browser/resources/chromeos/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/chromevox/BUILD.gn
@@ -340,6 +340,8 @@ "//chrome/test:test_support", "//chrome/test:test_support_ui", "//content/test:test_support", + "//services/shell/background:lib", + "//services/shell/background/tests:test_support", "//testing/gmock", "//testing/gtest", "//ui/keyboard:resources",
diff --git a/chrome/browser/resources/chromeos/keyboard_overlay.js b/chrome/browser/resources/chromeos/keyboard_overlay.js index fca7f74c..1d4c9b9 100644 --- a/chrome/browser/resources/chromeos/keyboard_overlay.js +++ b/chrome/browser/resources/chromeos/keyboard_overlay.js
@@ -555,6 +555,15 @@ classes.push('keyboard-overlay-key-background'); + if ((shortcutId == 'keyboardOverlayGoBack' || + shortcutId == 'keyboardOverlayGoForward') && + !loadTimeData.getBoolean('backspaceGoesBackFeatureEnabled')) { + // If the "backspace key goes back" experiment is not enabled, then we + // clear the shortcuts for Backspace and Shift+Backspace to go back or + // forward respectively. + shortcutId = null; + } + if (shortcutId) { classes.push('is-shortcut'); classes.push('keyboard-overlay-shortcut-key-background');
diff --git a/chrome/browser/resources/md_downloads/vulcanized.html b/chrome/browser/resources/md_downloads/vulcanized.html index 02e96c2..894990a9 100644 --- a/chrome/browser/resources/md_downloads/vulcanized.html +++ b/chrome/browser/resources/md_downloads/vulcanized.html
@@ -1635,6 +1635,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +<if expr="not chromeos"> @font-face { font-family: 'Roboto'; font-style: normal; @@ -1658,6 +1659,7 @@ src: local('Roboto Bold'), local('Roboto-Bold'), url("chrome://resources/roboto/roboto-bold.woff2") format('woff2'); } +</if> </style> <style is="custom-style"> @@ -2781,4 +2783,4 @@ <command id="find-command" shortcut="Ctrl|f"></command> </if> <link rel="import" href="chrome://resources/html/polymer.html"> - <script src="crisper.js"></script></body></html> \ No newline at end of file + <script src="crisper.js"></script></body></html>
diff --git a/chrome/browser/resources/md_extensions/manager.js b/chrome/browser/resources/md_extensions/manager.js index 4f0596e..bce1c2c 100644 --- a/chrome/browser/resources/md_extensions/manager.js +++ b/chrome/browser/resources/md_extensions/manager.js
@@ -92,6 +92,14 @@ this.readyPromiseResolver.resolve(); }, + get keyboardShortcuts() { + return this.$['keyboard-shortcuts']; + }, + + get packDialog() { + return this.$['pack-dialog']; + }, + /** * @param {!CustomEvent} event * @private @@ -273,7 +281,7 @@ break; } - this.manager_.$['items-list'].set('items', assert(items)); + this.manager_.$/* hack */ ['items-list'].set('items', assert(items)); this.manager_.changePage(Page.ITEM_LIST); }, @@ -284,7 +292,7 @@ /** @override */ showPackDialog: function() { - this.manager_.$['pack-dialog'].show(); + this.manager_.packDialog.show(); } };
diff --git a/chrome/browser/resources/md_extensions/service.js b/chrome/browser/resources/md_extensions/service.js index 4f1f35c..0482a57 100644 --- a/chrome/browser/resources/md_extensions/service.js +++ b/chrome/browser/resources/md_extensions/service.js
@@ -23,8 +23,8 @@ this.manager_ = manager; this.manager_.sidebar.setDelegate(this); this.manager_.set('itemDelegate', this); - this.manager_.$['pack-dialog'].set('delegate', this); - var keyboardShortcuts = this.manager_.$['keyboard-shortcuts']; + this.manager_.packDialog.set('delegate', this); + var keyboardShortcuts = this.manager_.keyboardShortcuts; keyboardShortcuts.addEventListener( 'shortcut-updated', this.onExtensionCommandUpdated_.bind(this));
diff --git a/chrome/browser/resources/md_user_manager/create_profile.html b/chrome/browser/resources/md_user_manager/create_profile.html index af41dde6..b483d019 100644 --- a/chrome/browser/resources/md_user_manager/create_profile.html +++ b/chrome/browser/resources/md_user_manager/create_profile.html
@@ -114,15 +114,8 @@ font-size: inherit; min-height: 40px; }; - --paper-item-focused-before: { - background: none; - }; } - #supervised-user-container paper-listbox paper-item:hover { - background: rgba(0, 0, 0, .12); - }; - #supervised-user-container #import-user { -webkit-margin-start: 16px; }
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js index 9bb0912..08a64afc 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -528,6 +528,10 @@ this.userHasTakenInitialAction_ = true; }, + get header() { + return this.$['container-header']; + }, + /** * Checks that the currently selected cast mode is still in the * updated list of available cast modes. If not, then update the selected @@ -2317,7 +2321,7 @@ updateElementPositioning_: function() { // Ensures that conditionally templated elements have finished stamping. this.async(function() { - var headerHeight = this.$$('#container-header').offsetHeight; + var headerHeight = this.header.offsetHeight; var firstRunFlowHeight = this.$$('#first-run-flow') && this.$$('#first-run-flow').style.display != 'none' ? this.$$('#first-run-flow').offsetHeight : 0; @@ -2330,7 +2334,7 @@ var searchPadding = hasSearch ? this.computeElementVerticalPadding_(search) : 0; - this.$['container-header'].style.marginTop = firstRunFlowHeight + 'px'; + this.header.style.marginTop = firstRunFlowHeight + 'px'; this.$['content'].style.marginTop = firstRunFlowHeight + headerHeight + 'px';
diff --git a/chrome/browser/resources/media_router/media_router.js b/chrome/browser/resources/media_router/media_router.js index afcee951..b0110d0c 100644 --- a/chrome/browser/resources/media_router/media_router.js +++ b/chrome/browser/resources/media_router/media_router.js
@@ -28,8 +28,7 @@ ($('media-router-container')); media_router.ui.setElements(container, - /** @type {!MediaRouterHeaderElement} */ - (container.$['container-header'])); + /** @type {!MediaRouterHeaderElement} */(container.header)); container.addEventListener('acknowledge-first-run-flow', onAcknowledgeFirstRunFlow);
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html index 5fce820..543fd0f 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -1,95 +1,55 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<if expr="chromeos"> -<link rel="import" href="/controls/settings_checkbox.html"> -</if> -<link rel="import" href="/settings_shared_css.html"> <link rel="import" href="/i18n_setup.html"> +<link rel="import" href="/settings_shared_css.html"> + +<if expr="chromeos"> +<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> +<link rel="import" href="/a11y_page/manage_a11y_page.html"> +<link rel="import" href="/settings_page/settings_animated_pages.html"> +<link rel="import" href="/settings_page/settings_subpage.html"> +</if> <dom-module id="settings-a11y-page"> <template> <style include="settings-shared"></style> <if expr="chromeos"> - <div class="settings-box row first"> - <span> - $i18n{a11yExplanation} - <a href="$i18nRaw{a11yLearnMoreUrl}" target="_blank"> - $i18n{learnMore} - </a> - </span> - </div> - - <div class="settings-box block"> - <settings-checkbox label="$i18n{optionsInMenuLabel}" - pref="{{prefs.settings.a11y.enable_menu}}"> - </settings-checkbox> - <settings-checkbox label="$i18n{largeMouseCursorLabel}" - pref="{{prefs.settings.a11y.large_cursor_enabled}}"> - </settings-checkbox> - <settings-checkbox label="$i18n{highContrastLabel}" - pref="{{prefs.settings.a11y.high_contrast_enabled}}"> - </settings-checkbox> - <settings-checkbox - pref="{{prefs.settings.a11y.sticky_keys_enabled}}" - label="$i18n{stickyKeysLabel}"> - </settings-checkbox> - <settings-checkbox pref="{{prefs.settings.accessibility}}" - label="$i18n{chromeVoxLabel}"> - </settings-checkbox> - <settings-checkbox label="$i18n{screenMagnifierLabel}" - pref="{{prefs.settings.a11y.screen_magnifier}}"> - </settings-checkbox> - <settings-checkbox label="$i18n{tapDraggingLabel}" - pref="{{prefs.settings.touchpad.enable_tap_dragging}}"> - </settings-checkbox> - <settings-checkbox label="$i18n{clickOnStopLabel}" - pref="{{prefs.settings.a11y.autoclick}}"> - </settings-checkbox> - - <div class="list-item settings-checkbox-spacer"> - <div>$i18n{delayBeforeClickLabel}</div> - <settings-dropdown-menu - pref="{{prefs.settings.a11y.autoclick_delay_ms}}" - menu-options="[[autoClickDelayOptions_]]" no-label-float> - </settings-dropdown-menu> - </div> - - <settings-checkbox pref="{{prefs.settings.a11y.virtual_keyboard}}" - label="$i18n{onScreenKeyboardLabel}"> - </settings-checkbox> - <settings-checkbox pref="{{prefs.settings.a11y.mono_audio}}" - label="$i18n{monoAudioLabel}"> - </settings-checkbox> - <settings-checkbox pref="{{prefs.settings.a11y.caret_highlight}}" - label="$i18n{caretHighlightLabel}"> - </settings-checkbox> - <settings-checkbox pref="{{prefs.settings.a11y.cursor_highlight}}" - label="$i18n{cursorHighlightLabel}"> - </settings-checkbox> - <settings-checkbox pref="{{prefs.settings.a11y.focus_highlight}}" - label="$i18n{focusHighlightLabel}"> - </settings-checkbox> - <template is="dom-if" if="[[showExperimentalFeatures_]]"> - <settings-checkbox pref="{{prefs.settings.a11y.select_to_speak}}" - label="$i18n{selectToSpeakLabel}"> - </settings-checkbox> - <settings-checkbox pref="{{prefs.settings.a11y.switch_access}}" - label="$i18n{switchAccessLabel}"> - </settings-checkbox> + <settings-animated-pages id="pages" current-route="{{currentRoute}}" + section="a11y"> + <neon-animatable id="main"> + <div class="settings-box first"> + <div class="start"> + $i18n{optionsInMenuLabel} + </div> + <paper-toggle-button id="optionsInMenuToggle" + checked="{{prefs.settings.a11y.enable_menu.value}}"> + </paper-toggle-button> + </div> + <div class="settings-box"> + <paper-button class="primary-button" + on-tap="onManageAccessibilityFeaturesTap_"> + $i18n{manageAccessibilityFeatures} + </paper-button> + </div> + </neon-animatable> + <template is="dom-if" name="manage-a11y"> + <settings-subpage page-title="$i18n{manageAccessibilityFeatures}"> + <settings-manage-a11y-page prefs="{{prefs}}"> + </settings-manage-a11y-page> + </settings-subpage> </template> - </div> + </settings-animated-pages> </if> -<if expr="chromeos"> - <div class="settings-box"> -</if> <if expr="not chromeos"> <div class="settings-box first"> -</if> <paper-button class="primary-button" on-tap="onMoreFeaturesTap_"> $i18n{moreFeaturesLink} </paper-button> </div> +</if> + </template> <script src="a11y_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chrome/browser/resources/settings/a11y_page/a11y_page.js index 2ee16f1..365655e 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.js +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -4,60 +4,37 @@ /** * @fileoverview - * 'settings-a11y-page' is the settings page containing accessibility - * settings. - * - * Example: - * - * <iron-animated-pages> - * <settings-a11y-page prefs="{{prefs}}"></settings-a11y-page> - * ... other pages ... - * </iron-animated-pages> + * 'settings-a11y-page' is the small section of advanced settings with + * a link to the web store accessibility page on most platforms, and + * a subpage with lots of other settings on Chrome OS. */ Polymer({ is: 'settings-a11y-page', properties: { /** + * The current active route. + */ + currentRoute: { + type: Object, + notify: true, + }, + + /** * Preferences state. */ prefs: { type: Object, notify: true, }, + }, <if expr="chromeos"> - autoClickDelayOptions_: { - readOnly: true, - type: Array, - value: function() { - return [ - {value: 600, - name: loadTimeData.getString('delayBeforeClickExtremelyShort')}, - {value: 800, - name: loadTimeData.getString('delayBeforeClickVeryShort')}, - {value: 1000, - name: loadTimeData.getString('delayBeforeClickShort')}, - {value: 2000, - name: loadTimeData.getString('delayBeforeClickLong')}, - {value: 4000, - name: loadTimeData.getString('delayBeforeClickVeryLong')}, - ]; - }, - }, - - /** - * Whether to show experimental accessibility features. - * @private {boolean} - */ - showExperimentalFeatures_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('showExperimentalA11yFeatures'); - }, - } -</if> + /** @private */ + onManageAccessibilityFeaturesTap_: function() { + settings.navigateTo(settings.Route.MANAGE_ACCESSIBILITY); }, +</if> /** @private */ onMoreFeaturesTap_: function() {
diff --git a/chrome/browser/resources/settings/a11y_page/compiled_resources2.gyp b/chrome/browser/resources/settings/a11y_page/compiled_resources2.gyp index 5802b23..bbc7a563 100644 --- a/chrome/browser/resources/settings/a11y_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/a11y_page/compiled_resources2.gyp
@@ -6,7 +6,17 @@ { 'target_name': 'a11y_page', 'dependencies': [ + '../compiled_resources2.gyp:route', + '../settings_page/compiled_resources2.gyp:settings_animated_pages', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'manage_a11y_page', + 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(EXTERNS_GYP):settings_private', + '../compiled_resources2.gyp:route', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], },
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html new file mode 100644 index 0000000..f55d53a --- /dev/null +++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
@@ -0,0 +1,162 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="/controls/settings_checkbox.html"> +<link rel="import" href="/i18n_setup.html"> +<link rel="import" href="/route.html"> +<link rel="import" href="/settings_shared_css.html"> +<link rel="import" href="/settings_vars_css.html"> + +<dom-module id="settings-manage-a11y-page"> + <template> + <style include="settings-shared"> + .indented { + -webkit-margin-start: 20px; + } + + .no-top-border { + border-top: none; + } + + h3 { + color: var(--settings-nav-grey); + font-weight: 500; + } + + .settings-box iron-icon { + -webkit-margin-end: var(--iron-icon-spacing); + } + + .settings-box settings-checkbox { + flex-grow: 1; + } + </style> + <div class="settings-box row first"> + <span> + $i18n{a11yExplanation} + <a href="$i18nRaw{a11yLearnMoreUrl}" target="_blank"> + $i18n{learnMore} + </a> + </span> + </div> + + <div class="settings-box block"> + <h3>$i18n{textToSpeechHeading}</h3> + <div class="settings-box first indented"> + <settings-checkbox pref="{{prefs.settings.accessibility}}" + label="$i18n{chromeVoxLabel}"> + </settings-checkbox> + <paper-icon-button icon="cr:settings" on-tap="onChromeVoxSettingsTap_"> + </paper-icon-button> + </div> + <template is="dom-if" if="[[showExperimentalFeatures_]]"> + <div class="settings-box no-top-border indented"> + <settings-checkbox pref="{{prefs.settings.a11y.select_to_speak}}" + label="$i18n{selectToSpeakTitle}" + sub-label="$i18n{selectToSpeakDescription}"> + </settings-checkbox> + </div> + </template> + + <h3>$i18n{displayHeading}</h3> + <div class="settings-box block first indented"> + <settings-checkbox label="$i18n{highContrastLabel}" + pref="{{prefs.settings.a11y.high_contrast_enabled}}"> + </settings-checkbox> + <settings-checkbox label="$i18n{screenMagnifierLabel}" + pref="{{prefs.settings.a11y.screen_magnifier}}"> + </settings-checkbox> + </div> + <div class="settings-box two-line indented" on-tap="onDisplayTap_" + actionable> + <iron-icon icon="settings:desktop-windows"></iron-icon> + <div class="start"> + <div>$i18n{displaySettingsTitle}</div> + <div class="secondary">$i18n{displaySettingsDescription}</div> + </div> + </div> + <div class="settings-box two-line indented" on-tap="onAppearanceTap_" + actionable> + <iron-icon icon="settings:text-format"></iron-icon> + <div class="start"> + <div>$i18n{appearanceSettingsTitle}</div> + <div class="secondary">$i18n{appearanceSettingsDescription}</div> + </div> + </div> + + <h3>$i18n{keyboardHeading}</h3> + <div class="settings-box block first indented"> + <settings-checkbox + pref="{{prefs.settings.a11y.sticky_keys_enabled}}" + label="$i18n{stickyKeysLabel}"> + </settings-checkbox> + <settings-checkbox pref="{{prefs.settings.a11y.virtual_keyboard}}" + label="$i18n{onScreenKeyboardLabel}"> + </settings-checkbox> + <settings-checkbox pref="{{prefs.settings.a11y.focus_highlight}}" + label="$i18n{focusHighlightLabel}"> + </settings-checkbox> + <settings-checkbox pref="{{prefs.settings.a11y.caret_highlight}}" + label="$i18n{caretHighlightLabel}"> + </settings-checkbox> + <template is="dom-if" if="[[showExperimentalFeatures_]]"> + <settings-checkbox pref="{{prefs.settings.a11y.switch_access}}" + label="$i18n{switchAccessLabel}"> + </settings-checkbox> + </template> + </div> + <div class="settings-box two-line indented" on-tap="onKeyboardTap_" + actionable> + <iron-icon icon="settings:keyboard"></iron-icon> + <div class="start"> + <div>$i18n{keyboardSettingsTitle}</div> + <div class="secondary">$i18n{keyboardSettingsDescription}</div> + </div> + </div> + + <h3>$i18n{mouseAndTouchpadHeading}</h3> + <div class="settings-box block first indented"> + <settings-checkbox label="$i18n{clickOnStopLabel}" + pref="{{prefs.settings.a11y.autoclick}}"> + </settings-checkbox> + <div class="list-item settings-checkbox-spacer"> + <div>$i18n{delayBeforeClickLabel}</div> + <settings-dropdown-menu + pref="{{prefs.settings.a11y.autoclick_delay_ms}}" + menu-options="[[autoClickDelayOptions_]]" no-label-float> + </settings-dropdown-menu> + </div> + <settings-checkbox label="$i18n{tapDraggingLabel}" + pref="{{prefs.settings.touchpad.enable_tap_dragging}}"> + </settings-checkbox> + <settings-checkbox label="$i18n{largeMouseCursorLabel}" + pref="{{prefs.settings.a11y.large_cursor_enabled}}"> + </settings-checkbox> + <settings-checkbox pref="{{prefs.settings.a11y.cursor_highlight}}" + label="$i18n{cursorHighlightLabel}"> + </settings-checkbox> + </div> + <div class="settings-box two-line indented" on-tap="onMouseTap_" + actionable> + <iron-icon icon="settings:mouse"></iron-icon> + <div class="start"> + <div>$i18n{mouseSettingsTitle}</div> + <div class="secondary">$i18n{mouseSettingsDescription}</div> + </div> + </div> + + <h3>$i18n{audioHeading}</h3> + <div class="settings-box block first indented"> + <settings-checkbox pref="{{prefs.settings.a11y.mono_audio}}" + label="$i18n{monoAudioLabel}"> + </settings-checkbox> + </div> + </div> + + <div class="settings-box two-line" on-tap="onMoreFeaturesTap_" actionable> + <div class="start"> + <div>$i18n{additionalFeaturesTitle}</div> + <div class="secondary">$i18n{additionalFeaturesDescription}</div> + </div> + </div> + </template> + <script src="manage_a11y_page.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js new file mode 100644 index 0000000..c8c2437d --- /dev/null +++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js
@@ -0,0 +1,83 @@ +// 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. + +/** + * @fileoverview + * 'settings-manage-a11y-page' is the subpage with the accessibility + * settings. + */ +Polymer({ + is: 'settings-manage-a11y-page', + + properties: { + /** + * Preferences state. + */ + prefs: { + type: Object, + notify: true, + }, + + autoClickDelayOptions_: { + readOnly: true, + type: Array, + value: function() { + return [ + {value: 600, + name: loadTimeData.getString('delayBeforeClickExtremelyShort')}, + {value: 800, + name: loadTimeData.getString('delayBeforeClickVeryShort')}, + {value: 1000, + name: loadTimeData.getString('delayBeforeClickShort')}, + {value: 2000, + name: loadTimeData.getString('delayBeforeClickLong')}, + {value: 4000, + name: loadTimeData.getString('delayBeforeClickVeryLong')}, + ]; + }, + }, + + /** + * Whether to show experimental accessibility features. + * @private {boolean} + */ + showExperimentalFeatures_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('showExperimentalA11yFeatures'); + }, + }, + }, + + /** @private */ + onChromeVoxSettingsTap_: function() { + chrome.send('showChromeVoxSettings'); + }, + + /** @private */ + onDisplayTap_: function() { + settings.navigateTo(settings.Route.DISPLAY); + }, + + /** @private */ + onAppearanceTap_: function() { + settings.navigateTo(settings.Route.APPEARANCE); + }, + + /** @private */ + onKeyboardTap_: function() { + settings.navigateTo(settings.Route.KEYBOARD); + }, + + /** @private */ + onMouseTap_: function() { + settings.navigateTo(settings.Route.POINTERS); + }, + + /** @private */ + onMoreFeaturesTap_: function() { + window.open( + 'https://chrome.google.com/webstore/category/collection/accessibility'); + }, +});
diff --git a/chrome/browser/resources/settings/about_page/about_page.js b/chrome/browser/resources/settings/about_page/about_page.js index 50861b9..07d8eaa 100644 --- a/chrome/browser/resources/settings/about_page/about_page.js +++ b/chrome/browser/resources/settings/about_page/about_page.js
@@ -55,13 +55,6 @@ /** @private {?settings.LifetimeBrowserProxy} */ lifetimeBrowserProxy_: null, - /** - * @type {string} Selector to get the sections. - * TODO(michaelpg): replace duplicate docs with @override once b/24294625 - * is fixed. - */ - sectionSelector: 'settings-section', - /** @override */ attached: function() { this.aboutBrowserProxy_ = settings.AboutPageBrowserProxyImpl.getInstance();
diff --git a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html index 3ca6fc2..a04b0f5ab 100644 --- a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html +++ b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
@@ -13,6 +13,9 @@ <dialog is="cr-dialog" id="dialog"> <div class="title">$i18n{aboutChangeChannel}</div> <div class="body"> + <!-- TODO(dbeam): this can be policy-controlled. Show this in the UI. + https://www.chromium.org/administrators/policy-list-3#ChromeOsReleaseChannel + --> <paper-radio-group on-paper-radio-group-changed="onChannelSelectionChanged_"> <paper-radio-button name="[[browserChannelEnum_.STABLE]]">
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.html b/chrome/browser/resources/settings/advanced_page/advanced_page.html index b2c83a19..c65c24a 100644 --- a/chrome/browser/resources/settings/advanced_page/advanced_page.html +++ b/chrome/browser/resources/settings/advanced_page/advanced_page.html
@@ -93,7 +93,9 @@ <template is="dom-if" if="[[showPage(pageVisibility.a11y)]]" restamp> <settings-section page-title="$i18n{a11yPageTitle}" current-route="[[currentRoute]]" section="a11y"> - <settings-a11y-page prefs="{{prefs}}"></settings-a11y-page> + <settings-a11y-page prefs="{{prefs}}" + current-route="{{currentRoute}}"> + </settings-a11y-page> </settings-section> </template> <if expr="not chromeos">
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.js b/chrome/browser/resources/settings/advanced_page/advanced_page.js index def015b..18e7c81 100644 --- a/chrome/browser/resources/settings/advanced_page/advanced_page.js +++ b/chrome/browser/resources/settings/advanced_page/advanced_page.js
@@ -30,11 +30,4 @@ notify: true, }, }, - - /** - * @type {string} Selector to get the sections. - * TODO(michaelpg): replace duplicate docs with @override once b/24294625 - * is fixed. - */ - sectionSelector: 'settings-section', });
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html index 195d3578..0936c41 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_page.html +++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -4,8 +4,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> <link rel="import" href="/appearance_page/appearance_browser_proxy.html"> +<link rel="import" href="/controls/controlled_radio_button.html"> <link rel="import" href="/controls/settings_dropdown_menu.html"> <link rel="import" href="/controls/settings_input.html"> <link rel="import" href="/controls/settings_radio_group.html"> @@ -72,16 +72,21 @@ <div class="list-frame" hidden="[[!pageVisibility.homeButton]]"> <settings-radio-group pref="{{prefs.homepage_is_newtabpage}}"> - <paper-radio-button class="list-item" name="true"> + <controlled-radio-button class="list-item" name="true" + pref="[[prefs.homepage_is_newtabpage]]"> $i18n{homePageNtp} - </paper-radio-button> - <paper-radio-button class="list-item" name="false"> + </controlled-radio-button> + <controlled-radio-button class="list-item" name="false" + pref="[[prefs.homepage_is_newtabpage]]"> $i18n{other} + <!-- TODO(dbeam): this can show double indicators when both + homepage and whether to use the NTP as the homepage are + managed. --> <settings-input no-label-float pref="{{prefs.homepage}}" label="$i18n{exampleDotCom}" stop-keyboard-event-propagation> </settings-input> - </paper-radio-button> + </controlled-radio-button> </settings-radio-group> </div> </template>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index 450c3b6..abb32bf 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -75,7 +75,6 @@ <template is="dom-if" if="[[showPage(pageVisibility.defaultBrowser)]]" restamp> <settings-section page-title="$i18n{defaultBrowser}" - expand-container="{{expandContainer}}" current-route="[[currentRoute]]" section="defaultBrowser"> <settings-default-browser-page> </settings-default-browser-page>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js index 4fa3a0a..8db640c 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -42,13 +42,6 @@ }, - /** - * @type {string} Selector to get the sections. - * TODO(michaelpg): replace duplicate docs with @override once b/24294625 - * is fixed. - */ - sectionSelector: 'settings-section', - onResetDone_: function() { this.showResetProfileBanner_ = false; },
diff --git a/chrome/browser/resources/settings/controls/compiled_resources2.gyp b/chrome/browser/resources/settings/controls/compiled_resources2.gyp index 72fe9d2..4552cf1 100644 --- a/chrome/browser/resources/settings/controls/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/controls/compiled_resources2.gyp
@@ -4,6 +4,15 @@ { 'targets': [ { + 'target_name': 'controlled_button', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_pref_behavior', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', + 'pref_control_behavior', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'pref_control_behavior', 'dependencies': [ '../prefs/compiled_resources2.gyp:prefs_types',
diff --git a/chrome/browser/resources/settings/controls/controlled_button.html b/chrome/browser/resources/settings/controls/controlled_button.html index 5c02834..9868ce0 100644 --- a/chrome/browser/resources/settings/controls/controlled_button.html +++ b/chrome/browser/resources/settings/controls/controlled_button.html
@@ -1,3 +1,4 @@ +<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html">
diff --git a/chrome/browser/resources/settings/controls/controlled_button.js b/chrome/browser/resources/settings/controls/controlled_button.js index a072e37d..36392db 100644 --- a/chrome/browser/resources/settings/controls/controlled_button.js +++ b/chrome/browser/resources/settings/controls/controlled_button.js
@@ -11,18 +11,17 @@ /** @private */ controlled_: { type: Boolean, - computed: 'computeControlled_(pref)', + computed: 'computeControlled_(pref.*)', reflectToAttribute: true, }, }, /** - * @param {!chrome.settingsPrivate.PrefObject} pref * @return {boolean} Whether the button is disabled. * @private */ - computeControlled_: function(pref) { - return this.isPrefPolicyControlled(pref); + computeControlled_: function() { + return this.isPrefPolicyControlled(assert(this.pref)); }, /**
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.html b/chrome/browser/resources/settings/controls/controlled_radio_button.html new file mode 100644 index 0000000..09073ce --- /dev/null +++ b/chrome/browser/resources/settings/controls/controlled_radio_button.html
@@ -0,0 +1,43 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> +<link rel="import" href="/controls/pref_control_behavior.html"> +<link rel="import" href="/prefs/pref_util.html"> +<link rel="import" href="/settings_shared_css.html"> + +<dom-module id="controlled-radio-button"> + <template> + <style include="settings-shared"> + :host { + align-items: center; + display: flex; + } + + :host([controlled_]) { + /* Disable pointer events for this whole element, as outer on-tap gets + * triggered when clicking/tapping anywhere in :host. */ + pointer-events: none; + } + + cr-policy-pref-indicator { + -webkit-margin-start: var(--checkbox-spacing); + /* Enable pointer events for the indicator so :hover works. Disable + * clicks/taps via onIndicatorTap_ so outer on-tap doesn't trigger. */ + pointer-events: all; + } + </style> + + <paper-radio-button name="{{name}}" disabled="[[controlled_]]" + checked="{{checked}}"> + <content></content> + </paper-radio-button> + + <template is="dom-if" if="[[showIndicator_(controlled_, name, pref)]]"> + <cr-policy-pref-indicator pref="[[pref]]" on-tap="onIndicatorTap_"> + </cr-policy-pref-indicator> + </template> + + </template> + <script src="/controls/controlled_radio_button.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.js b/chrome/browser/resources/settings/controls/controlled_radio_button.js new file mode 100644 index 0000000..dd758323 --- /dev/null +++ b/chrome/browser/resources/settings/controls/controlled_radio_button.js
@@ -0,0 +1,54 @@ +// 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. + +Polymer({ + is: 'controlled-radio-button', + + behaviors: [CrPolicyPrefBehavior, PrefControlBehavior], + + properties: { + name: { + type: String, + notify: true, + }, + + /** @private */ + controlled_: { + type: Boolean, + computed: 'computeControlled_(pref)', + reflectToAttribute: true, + }, + }, + + /** + * @param {chrome.settingsPrivate.PrefObject} pref + * @return {boolean} Whether the button is disabled. + * @private + */ + computeControlled_: function(pref) { + var pref = /** @type {!chrome.settingsPrivate.PrefObject} */(this.pref); + return this.isPrefPolicyControlled(pref); + }, + + /** + * @param {boolean} controlled + * @param {string} name + * @param {chrome.settingsPrivate.PrefObject} pref + * @return {boolean} + * @private + */ + showIndicator_: function(controlled, name, pref) { + return controlled && name == Settings.PrefUtil.prefToString(pref); + }, + + /** + * @param {!Event} e + * @private + */ + onIndicatorTap_: function(e) { + // Disallow <controlled-radio-button on-tap="..."> when controlled. + e.preventDefault(); + e.stopPropagation(); + }, +});
diff --git a/chrome/browser/resources/settings/controls/settings_radio_group.html b/chrome/browser/resources/settings/controls/settings_radio_group.html index 665c531..3b1d8772 100644 --- a/chrome/browser/resources/settings/controls/settings_radio_group.html +++ b/chrome/browser/resources/settings/controls/settings_radio_group.html
@@ -1,5 +1,4 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> <link rel="import" href="/controls/pref_control_behavior.html"> @@ -10,7 +9,8 @@ <style include="settings-shared"></style> <template> <div>[[label]]</div> - <paper-radio-group selected="{{selected}}"> + <paper-radio-group selected="{{selected}}" + selectable="paper-radio-button, controlled-radio-button"> <content></content> </paper-radio-group> </template>
diff --git a/chrome/browser/resources/settings/controls/settings_radio_group.js b/chrome/browser/resources/settings/controls/settings_radio_group.js index 389ebcd..f0bedec 100644 --- a/chrome/browser/resources/settings/controls/settings_radio_group.js +++ b/chrome/browser/resources/settings/controls/settings_radio_group.js
@@ -15,15 +15,9 @@ Polymer({ is: 'settings-radio-group', - behaviors: [CrPolicyPrefBehavior, PrefControlBehavior], + behaviors: [PrefControlBehavior], properties: { - disabled_: { - observer: 'disabledChanged_', - type: Boolean, - value: false, - }, - /** * IronSelectableBehavior selected attribute. */ @@ -41,19 +35,10 @@ /** @private */ prefChanged_: function() { var pref = /** @type {!chrome.settingsPrivate.PrefObject} */(this.pref); - this.disabled_ = this.isPrefPolicyControlled(pref); this.selected = Settings.PrefUtil.prefToString(pref); }, /** @private */ - disabledChanged_: function() { - var radioButtons = this.queryAllEffectiveChildren('paper-radio-button'); - for (var i = 0; i < radioButtons.length; ++i) { - radioButtons[i].disabled = this.disabled_; - } - }, - - /** @private */ selectedChanged_: function(selected) { if (!this.pref) return;
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html index 7279594..18d6350 100644 --- a/chrome/browser/resources/settings/icons.html +++ b/chrome/browser/resources/settings/icons.html
@@ -102,6 +102,7 @@ <g id="sync-disabled"><path d="M10 6.35V4.26c-.8.21-1.55.54-2.23.96l1.46 1.46c.25-.12.5-.24.77-.33zm-7.14-.94l2.36 2.36C4.45 8.99 4 10.44 4 12c0 2.21.91 4.2 2.36 5.64L4 20h6v-6l-2.24 2.24C6.68 15.15 6 13.66 6 12c0-1 .25-1.94.68-2.77l8.08 8.08c-.25.13-.5.25-.77.34v2.09c.8-.21 1.55-.54 2.23-.96l2.36 2.36 1.27-1.27L4.14 4.14 2.86 5.41zM20 4h-6v6l2.24-2.24C17.32 8.85 18 10.34 18 12c0 1-.25 1.94-.68 2.77l1.46 1.46C19.55 15.01 20 13.56 20 12c0-2.21-.91-4.2-2.36-5.64L20 4z"></path></g> <g id="sync-problem"><path d="M3 12c0 2.21.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24C5.68 15.15 5 13.66 5 12c0-2.61 1.67-4.83 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24C18.32 8.85 19 10.34 19 12c0 2.61-1.67 4.83-4 5.65v2.09c3.45-.89 6-4.01 6-7.74 0-2.21-.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z"></path></g> <if expr="chromeos"> + <g id="text-format"><path d="M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z"></path></g> <g id="touch-app"><path d="M9 11.24V7.5C9 6.12 10.12 5 11.5 5S14 6.12 14 7.5v3.74c1.21-.81 2-2.18 2-3.74C16 5.01 13.99 3 11.5 3S7 5.01 7 7.5c0 1.56.79 2.93 2 3.74zm9.84 4.63l-4.54-2.26c-.17-.07-.35-.11-.54-.11H13v-6c0-.83-.67-1.5-1.5-1.5S10 6.67 10 7.5v10.74l-3.43-.72c-.08-.01-.15-.03-.24-.03-.31 0-.59.13-.79.33l-.79.8 4.94 4.94c.27.27.65.44 1.06.44h6.79c.75 0 1.33-.55 1.44-1.28l.75-5.27c.01-.07.02-.14.02-.2 0-.62-.38-1.16-.91-1.38z"></path></g> </if> <g id="usb"><path d="M15 7v4h1v2h-3V5h2l-3-4-3 4h2v8H8v-2.07c.7-.37 1.2-1.08 1.2-1.93 0-1.21-.99-2.2-2.2-2.2-1.21 0-2.2.99-2.2 2.2 0 .85.5 1.56 1.2 1.93V13c0 1.11.89 2 2 2h3v3.05c-.71.37-1.2 1.1-1.2 1.95 0 1.22.99 2.2 2.2 2.2 1.21 0 2.2-.98 2.2-2.2 0-.85-.49-1.58-1.2-1.95V15h3c1.11 0 2-.89 2-2v-2h1V7h-4z"></path></g>
diff --git a/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp b/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp index 0e312d02..d965d3ae 100644 --- a/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp
@@ -86,6 +86,7 @@ { 'target_name': 'network_siminfo', 'dependencies': [ + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted', '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(INTERFACES_GYP):networking_private_interface',
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.js b/chrome/browser/resources/settings/internet_page/network_siminfo.js index b6977dd..1e69b0f 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.js +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.js
@@ -137,7 +137,7 @@ this.networkingPrivate.setCellularSimState(guid, simState, function() { if (chrome.runtime.lastError) { this.error = ErrorType.INCORRECT_PIN; - this.$.enterPin.$.input.select(); + this.$.enterPin.inputElement.select(); } else { this.error = ErrorType.NONE; this.$.enterPinDialog.close(); @@ -182,7 +182,7 @@ this.networkingPrivate.setCellularSimState(guid, simState, function() { if (chrome.runtime.lastError) { this.error = ErrorType.INCORRECT_PIN; - this.$.changePinOld.$.input.select(); + this.$.changePinOld.inputElement.select(); } else { this.error = ErrorType.NONE; this.$.changePinDialog.close(); @@ -217,7 +217,7 @@ this.networkingPrivate.unlockCellularSim(guid, pin, '', function() { if (chrome.runtime.lastError) { this.error = ErrorType.INCORRECT_PIN; - this.$.unlockPin.$.input.select(); + this.$.unlockPin.inputElement.select(); } else { this.error = ErrorType.NONE; this.$.unlockPinDialog.close(); @@ -258,7 +258,7 @@ this.networkingPrivate.unlockCellularSim(guid, pin, puk, function() { if (chrome.runtime.lastError) { this.error = ErrorType.INCORRECT_PUK; - this.$.unlockPuk.$.input.select(); + this.$.unlockPuk.inputElement.select(); } else { this.error = ErrorType.NONE; this.$.unlockPukDialog.close();
diff --git a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html index f66a6693..841f56b9 100644 --- a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html +++ b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> +<link rel="import" href="/controls/controlled_radio_button.html"> <link rel="import" href="/controls/settings_radio_group.html"> <link rel="import" href="/on_startup_page/startup_urls_page.html"> <link rel="import" href="/settings_shared_css.html"> @@ -11,15 +11,18 @@ <div class="settings-box block first"> <settings-radio-group id="onStartupRadioGroup" pref="{{prefs.session.restore_on_startup}}"> - <paper-radio-button name="[[prefValues_.OPEN_NEW_TAB]]"> + <controlled-radio-button name="[[prefValues_.OPEN_NEW_TAB]]" + pref="[[prefs.session.restore_on_startup]]"> $i18n{onStartupOpenNewTab} - </paper-radio-button> - <paper-radio-button name="[[prefValues_.CONTINUE]]"> + </controlled-radio-button> + <controlled-radio-button name="[[prefValues_.CONTINUE]]" + pref="[[prefs.session.restore_on_startup]]"> $i18n{onStartupContinue} - </paper-radio-button> - <paper-radio-button name="[[prefValues_.OPEN_SPECIFIC]]"> + </controlled-radio-button> + <controlled-radio-button name="[[prefValues_.OPEN_SPECIFIC]]" + pref="[[prefs.session.restore_on_startup]]"> $i18n{onStartupOpenSpecific} - </paper-radio-button> + </controlled-radio-button> </settings-radio-group> </div> <template is="dom-if"
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html index 8dee9a45..1e2ee2ac 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html +++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
@@ -8,10 +8,6 @@ <dom-module id="settings-startup-urls-page"> <template> <style include="settings-shared"> - paper-radio-button { - display: block; - } - .list-button { @apply(--settings-actionable); }
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.js b/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.js index 7159694..7f790c0 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.js +++ b/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.js
@@ -88,33 +88,26 @@ * @private */ updateAddressWrapper_: function() { - var self = this; - // Default to the last country used if no country code is provided. - var countryCode = self.countryCode_ || self.countries_[0].countryCode; - self.countryInfo.getAddressFormat(countryCode).then(function(format) { - self.addressWrapper_ = format.components.map(function(component) { + var countryCode = this.countryCode_ || this.countries_[0].countryCode; + this.countryInfo.getAddressFormat(countryCode).then(function(format) { + this.addressWrapper_ = format.components.map(function(component) { return component.row.map(function(c) { - return new settings.address.AddressComponentUI(self.address, c); - }); - }); + return new settings.address.AddressComponentUI(this.address, c); + }.bind(this)); + }.bind(this)); // Flush dom before resize and savability updates. Polymer.dom.flush(); -/** - * TODO(hcarmona): Fix closure compiler to better understand |SettingsDialog|. - * @suppress {missingProperties} - */ -(function() { - self.updateCanSave_(); + this.updateCanSave_(); - self.fire('on-update-address-wrapper'); // For easier testing. + this.fire('on-update-address-wrapper'); // For easier testing. - if (!self.$.dialog.open) - self.$.dialog.showModal(); -})(); - }); + var dialog = /** @type {HTMLDialogElement} */(this.$.dialog); + if (!dialog.open) + dialog.showModal(); + }.bind(this)); }, updateCanSave_: function() {
diff --git a/chrome/browser/resources/settings/printing_page/cloud_printers.js b/chrome/browser/resources/settings/printing_page/cloud_printers.js index 1f96323b..3537e5d 100644 --- a/chrome/browser/resources/settings/printing_page/cloud_printers.js +++ b/chrome/browser/resources/settings/printing_page/cloud_printers.js
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview 'settings-cloud-printers' is a component for showing Google + * Cloud Printer settings subpage (chrome://md-settings/cloudPrinters). + */ +// TODO(xdai): Rename it to 'settings-cloud-printers-page'. Polymer({ is: 'settings-cloud-printers',
diff --git a/chrome/browser/resources/settings/printing_page/compiled_resources2.gyp b/chrome/browser/resources/settings/printing_page/compiled_resources2.gyp index 331656fb..2058a33 100644 --- a/chrome/browser/resources/settings/printing_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/printing_page/compiled_resources2.gyp
@@ -4,21 +4,53 @@ { 'targets': [ { - 'target_name': 'printing_page', + 'target_name': 'cloud_printers', 'dependencies': [ - '../compiled_resources2.gyp:route', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'cups_add_printer_dialog', + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'cups_printer_details_page', + 'dependencies': [ '../settings_page/compiled_resources2.gyp:settings_animated_pages', + 'cups_printers_browser_proxy', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'cups_printers', + 'dependencies': [ + 'cups_printers_browser_proxy', + ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { - 'target_name': 'cloud_printers', + 'target_name': 'cups_printers_browser_proxy', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'cups_printers_list', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:icon', + 'cups_printers_browser_proxy', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'printing_page', + 'dependencies': [ + '../compiled_resources2.gyp:route', + '../settings_page/compiled_resources2.gyp:settings_animated_pages', + 'cups_printer_details_page', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], },
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html new file mode 100644 index 0000000..a10117cb --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
@@ -0,0 +1,39 @@ +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="/settings_shared_css.html"> + +<dom-module id="settings-cups-add-printer-dialog"> + <template> + <style include="settings-shared"></style> + <style> + #dialog .body { + height: 350px; + } + + #dialog .button-container { + border-top: 1px solid rgba(0, 0, 0, 0.14); + font-size: 15px; + font-weight: bold; + margin-top: 0; + padding-top: 10px; + } + </style> + <dialog is="cr-dialog" id="dialog"> + <div class="title">$i18n{addPrinterTitle}</div> + <div class="body"> + <!--TODO(xdai): Add printer settings go here. --> + (coming soon) Add printer settings go here. + </div> + <div class="button-container"> + <paper-button on-tap="onCancelTap_"> + $i18n{cancelButtonText} + </paper-button> + <paper-button disabled> + $i18n{addPrinterButtonText} + </paper-button> + </div> + </dialog> + </template> + <script src="cups_add_printer_dialog.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js new file mode 100644 index 0000000..24e8f78 --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js
@@ -0,0 +1,21 @@ +// 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. + +/** + * @fileoverview 'settings-cups-add-printer-dialog' is the dialog for setting up + * a new CUPS printer. + */ +Polymer({ + is: 'settings-cups-add-printer-dialog', + + /** Opens the Add printer dialog. */ + open: function() { + this.$.dialog.showModal(); + }, + + /** @private */ + onCancelTap_: function() { + this.$.dialog.close(); + }, +});
diff --git a/chrome/browser/resources/settings/printing_page/cups_printer_details_page.html b/chrome/browser/resources/settings/printing_page/cups_printer_details_page.html new file mode 100644 index 0000000..8745ac1b --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_printer_details_page.html
@@ -0,0 +1,35 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> +<link rel="import" href="/settings_shared_css.html"> + +<dom-module id="settings-cups-printer-details-page"> + <template> + <style include="settings-shared"></style> + <style> + paper-input { + width: 20em; + --paper-input-container-input: { + font-size: inherit; + color: inherit; + }; + } + </style> + <div class="settings-box first two-line"> + <div class="start"> + <div>$i18n{printerName}</div> + <div class="secondary"> + <paper-input no-label-float value="{{printer.printerName}}" + on-blur="onValueChanged_"> + </paper-input> + </div> + </div> + </div> + <div class="settings-box two-line"> + <div class="start"> + <div>$i18n{printerModel}</div> + <div class="secondary">[[printer.printerModel]]</div> + </div> + </div> + </template> + <script src="cups_printer_details_page.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/printing_page/cups_printer_details_page.js b/chrome/browser/resources/settings/printing_page/cups_printer_details_page.js new file mode 100644 index 0000000..61cefab --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_printer_details_page.js
@@ -0,0 +1,36 @@ +// 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. + +/** + * @fileoverview 'settings-cups-printer-details-page' is the subpage for + * viewing the details of a CUPS printer. + */ +Polymer({ + is: 'settings-cups-printer-details-page', + + properties: { + /** @type {!CupsPrinterInfo} */ + printer: { + type: Object, + notify: true, + }, + }, + + /** @private {settings.CupsPrintersBrowserProxy} */ + browserProxy_: null, + + /** @override */ + created: function() { + this.browserProxy_ = settings.CupsPrintersBrowserProxyImpl.getInstance(); + }, + + /** + * Event triggered when the input value changes. + * @private + */ + onValueChanged_: function() { + this.browserProxy_.updateCupsPrinter(this.printer.printerId, + this.printer.printerName); + }, +});
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers.html b/chrome/browser/resources/settings/printing_page/cups_printers.html index 053805eb..abf54e72 100644 --- a/chrome/browser/resources/settings/printing_page/cups_printers.html +++ b/chrome/browser/resources/settings/printing_page/cups_printers.html
@@ -1,13 +1,36 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="/printing_page/cups_add_printer_dialog.html"> +<link rel="import" href="/printing_page/cups_printers_list.html"> <link rel="import" href="/settings_shared_css.html"> <dom-module id="settings-cups-printers"> <template> <style include="settings-shared"></style> - <!--TODO(xdai): Implement the cups printing subpage. --> + <style> + a[is='action-link'] { + display: inline-block; + text-decoration: none; + } + + a[is='action-link']:hover { + color: blue; + text-decoration: underline; + } + </style> + + <!-- TODO(xdai): Implement the search field as seen in the mock. --> + <div class="settings-box first"> - CUPS printers settings go here. + <a is="action-link" on-tap="onAddPrinterTap_" actionable> + $i18n{addCupsPrinter} + </a> </div> + + <settings-cups-add-printer-dialog id="addPrinterDialog"> + </settings-cups-add-printer-dialog> + + <settings-cups-printers-list printers="{{printers}}"> + </settings-cups-printers-list> </template> <script src="cups_printers.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers.js b/chrome/browser/resources/settings/printing_page/cups_printers.js index 7472b1f0..12b11d7 100644 --- a/chrome/browser/resources/settings/printing_page/cups_printers.js +++ b/chrome/browser/resources/settings/printing_page/cups_printers.js
@@ -2,6 +2,40 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview 'settings-cups-printers' is a component for showing CUPS + * Printer settings subpage (chrome://md-settings/cupsPrinters). It is used to + * set up legacy & non-CloudPrint printers on ChromeOS by leveraging CUPS (the + * unix printing system) and the many open source drivers built for CUPS. + */ +// TODO(xdai): Rename it to 'settings-cups-printers-page'. Polymer({ is: 'settings-cups-printers', + + properties: { + /** @type {!Array<!CupsPrinterInfo>} */ + printers: { + type: Array, + notify: true, + }, + }, + + /** @override */ + ready: function() { + settings.CupsPrintersBrowserProxyImpl.getInstance(). + getCupsPrintersList().then(this.printersChanged_.bind(this)); + }, + + /** + * @param {!CupsPrintersList} cupsPrintersList + * @private + */ + printersChanged_: function(cupsPrintersList) { + this.printers = cupsPrintersList.printerList; + }, + + /** @private */ + onAddPrinterTap_: function() { + this.$.addPrinterDialog.open(); + }, });
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.html b/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.html new file mode 100644 index 0000000..1423729 --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.html
@@ -0,0 +1,2 @@ +<link rel="import" href="chrome://resources/html/cr.html"> +<script src="/printing_page/cups_printers_browser_proxy.js"></script>
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js b/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js new file mode 100644 index 0000000..cf80912 --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js
@@ -0,0 +1,83 @@ +// 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. + +/** + * @fileoverview A helper object used from the "CUPS printing" section to + * interact with the browser. + */ + +/** + * @typedef {{ + * printerId: string, + * printerName: string, + * printerDescription: string, + * printerManufacturer: string, + * printerModel: string, + * printerStatus: string, + * printerAddress: string, + * printerProtocol: string, + * }} + */ +var CupsPrinterInfo; + +/** + * @typedef {{ + * printerList: !Array<!CupsPrinterInfo>, + * }} + */ +var CupsPrintersList; + +cr.define('settings', function() { + /** @interface */ + function CupsPrintersBrowserProxy() {} + + CupsPrintersBrowserProxy.prototype = { + + /** + * @return {!Promise<!CupsPrintersList>} + */ + getCupsPrintersList: function() {}, + + /** + * @param {string} printerId + * @param {string} printerName + */ + updateCupsPrinter: function(printerId, printerName) {}, + + /** + * @param {string} printerId + */ + removeCupsPrinter: function(printerId) {}, + + }; + + /** + * @constructor + * @implements {settings.CupsPrintersBrowserProxy} + */ + function CupsPrintersBrowserProxyImpl() {} + cr.addSingletonGetter(CupsPrintersBrowserProxyImpl); + + CupsPrintersBrowserProxyImpl.prototype = { + /** override */ + getCupsPrintersList: function() { + return cr.sendWithPromise('getCupsPrintersList'); + }, + + /** override */ + updateCupsPrinter: function(printerId, printerName) { + chrome.send('updateCupsPrinter', [printerId, printerName]); + }, + + /** override */ + removeCupsPrinter: function(printerId) { + chrome.send('removeCupsPrinter', [printerId]); + }, + }; + + return { + CupsPrintersBrowserProxy: CupsPrintersBrowserProxy, + CupsPrintersBrowserProxyImpl: CupsPrintersBrowserProxyImpl, + }; +});
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers_list.html b/chrome/browser/resources/settings/printing_page/cups_printers_list.html new file mode 100644 index 0000000..e8aec3d --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_printers_list.html
@@ -0,0 +1,57 @@ +<link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-dropdown/iron-dropdown.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> +<link rel="import" href="/printing_page/cups_printers_browser_proxy.html"> +<link rel="import" href="/settings_shared_css.html"> + +<dom-module id="settings-cups-printers-list"> + <template> + <style include="settings-shared"></style> + <style> + #container { + border-top: 1px solid lightgray; + display: flex; + padding: 2px 20px; + } + + .name-column { + flex: 1; + margin: 2px; + } + + .list-item { + min-height: 20px; + } + + iron-dropdown { + width: 120px; + } + </style> + + <template is="dom-repeat" items="{{printers}}"> + <div id="container" class="list-item"> + <div class="name-column"> + <span class="name" id="printer-name">[[item.printerName]]</span> + <!--TODO(xdai): Add icon for enterprise CUPS printer. --> + </div> + <paper-icon-button icon="cr:more-vert" toggles + active="{{item.menuOpened}}"> + </paper-icon-button> + <iron-dropdown opened="{{item.menuOpened}}" horizontal-align="right" + vertical-align="top" horizontal-offset="15" vertical-offset="5"> + <div class="dropdown-content"> + <paper-item on-tap="onDetailsTap_"> + $i18n{cupsPrinterDetails} + </paper-item> + <paper-item on-tap="onRemoveTap_"> + $i18n{removePrinter} + </paper-item> + <div> + </iron-dropdown> + </div> + </template> + </template> + <script src="cups_printers_list.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers_list.js b/chrome/browser/resources/settings/printing_page/cups_printers_list.js new file mode 100644 index 0000000..ffdc535 --- /dev/null +++ b/chrome/browser/resources/settings/printing_page/cups_printers_list.js
@@ -0,0 +1,55 @@ +// 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. + +/** + * @fileoverview 'settings-cups-printers-list' is a component for a list of + * CUPS printers. + */ +Polymer({ + is: 'settings-cups-printers-list', + + properties: { + /** @type {!Array<!CupsPrinterInfo>} */ + printers: { + type: Array, + notify: true, + }, + }, + + /** @private {settings.CupsPrintersBrowserProxy} */ + browserProxy_: null, + + /** @override */ + created: function() { + this.browserProxy_ = settings.CupsPrintersBrowserProxyImpl.getInstance(); + }, + + /** + * @param {{model:Object}} event + * @private + */ + onDetailsTap_: function(event) { + this.closeDropdownMenu_(); + + // Event is caught by 'settings-printing-page'. + this.fire('show-cups-printer-details', event.model.item); + }, + + /** + * @param {{model:Object}} event + * @private + */ + onRemoveTap_: function(event) { + this.closeDropdownMenu_(); + + var index = this.printers.indexOf(event.model.item); + this.splice('printers', index, 1); + this.browserProxy_.removeCupsPrinter(event.model.item.printerId); + }, + + /** @private */ + closeDropdownMenu_: function() { + this.$$('iron-dropdown').close(); + }, +});
diff --git a/chrome/browser/resources/settings/printing_page/printing_page.html b/chrome/browser/resources/settings/printing_page/printing_page.html index bd854609..d905e71 100644 --- a/chrome/browser/resources/settings/printing_page/printing_page.html +++ b/chrome/browser/resources/settings/printing_page/printing_page.html
@@ -3,19 +3,23 @@ <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> <link rel="import" href="/icons.html"> <link rel="import" href="/printing_page/cloud_printers.html"> -<if expr="chromeos"> -<link rel="import" href="/printing_page/cups_printers.html"> -</if> <link rel="import" href="/route.html"> <link rel="import" href="/settings_page/settings_animated_pages.html"> <link rel="import" href="/settings_page/settings_subpage.html"> <link rel="import" href="/settings_shared_css.html"> +<if expr="chromeos"> +<link rel="import" href="/printing_page/cups_printer_details_page.html"> +<link rel="import" href="/printing_page/cups_printers.html"> +</if> <dom-module id="settings-printing-page"> <template> <style include="settings-shared"></style> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="printing"> + <array-selector id="arraySelector" items="{{cupsPrinters}}" + selected="{{detailPrinter_}}"> + </array-selector> <neon-animatable id="main"> <if expr="chromeos"> <div id="cupsPrinters" class="settings-box first" @@ -33,7 +37,14 @@ <if expr="chromeos"> <template is="dom-if" name="cups-printers"> <settings-subpage page-title="$i18n{cupsPrintersTitle}"> - <settings-cups-printers></settings-cups-printers> + <settings-cups-printers printers="{{cupsPrinters}}"> + </settings-cups-printers> + </settings-subpage> + </template> + <template is="dom-if" name="cups-printer-details-page" restamp> + <settings-subpage page-title="$i18n{printerDetailsTitle}"> + <settings-cups-printer-details-page printer="{{detailPrinter_}}"> + </settings-cups-printer-details-page> </settings-subpage> </template> </if>
diff --git a/chrome/browser/resources/settings/printing_page/printing_page.js b/chrome/browser/resources/settings/printing_page/printing_page.js index d6ba00a..4b4598e 100644 --- a/chrome/browser/resources/settings/printing_page/printing_page.js +++ b/chrome/browser/resources/settings/printing_page/printing_page.js
@@ -17,6 +17,16 @@ type: Object, notify: true, }, + + /** @type {!Array<!CupsPrinterInfo>} */ + cupsPrinters: { + type: Array, + notify: true, + }, + }, + + listeners: { + 'show-cups-printer-details': 'onShowCupsPrinterDetailsPage_', }, <if expr="chromeos"> @@ -24,6 +34,12 @@ onTapCupsPrinters_: function() { settings.navigateTo(settings.Route.CUPS_PRINTERS); }, + + /** @private */ + onShowCupsPrinterDetailsPage_: function(event) { + settings.navigateTo(settings.Route.CUPS_PRINTER_DETAIL); + this.$.arraySelector.select(event.detail); + }, </if> /** @private */
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 396235f..c07326f 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -266,7 +266,7 @@ <template is="dom-if" name="site-details"> <settings-subpage - page-title="$i18n{siteSettingsSiteDetailsPageTitle}"> + page-title="[[selectedSite.originForDisplay]]"> <site-details site="[[selectedSite]]"></site-details> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index 806176c4..728caf4 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -243,9 +243,14 @@ r.CLOUD_PRINTERS = r.PRINTING.createChild('/cloudPrinters', 'cloud-printers'); <if expr="chromeos"> r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters', 'cups-printers'); + r.CUPS_PRINTER_DETAIL = r.CUPS_PRINTERS.createChild( + '/cupsPrinterDetails', 'cups-printer-details-page'); </if> r.ACCESSIBILITY = r.ADVANCED.createSection('/accessibility', 'a11y'); + r.MANAGE_ACCESSIBILITY = r.ACCESSIBILITY.createChild( + '/manageAccessibility', 'manage-a11y'); + r.SYSTEM = r.ADVANCED.createSection('/system', 'system'); r.RESET = r.ADVANCED.createSection('/reset', 'reset');
diff --git a/chrome/browser/resources/settings/search_settings.js b/chrome/browser/resources/settings/search_settings.js index f001427..4d195ce 100644 --- a/chrome/browser/resources/settings/search_settings.js +++ b/chrome/browser/resources/settings/search_settings.js
@@ -100,7 +100,7 @@ * ensures that <settings-section> instances become visible if any matches * occurred under their subtree. * - * @param {!SearchRequest} request + * @param {!settings.SearchRequest} request * @param {!Node} root The root of the sub-tree to be searched * @private */ @@ -167,11 +167,11 @@ /** * @constructor * - * @param {!SearchRequest} request + * @param {!settings.SearchRequest} request * @param {!Node} node */ function Task(request, node) { - /** @protected {!SearchRequest} */ + /** @protected {!settings.SearchRequest} */ this.request = request; /** @protected {!Node} */ @@ -193,7 +193,7 @@ * @constructor * @extends {Task} * - * @param {!SearchRequest} request + * @param {!settings.SearchRequest} request * @param {!Node} node */ function RenderTask(request, node) { @@ -227,7 +227,7 @@ * @constructor * @extends {Task} * - * @param {!SearchRequest} request + * @param {!settings.SearchRequest} request * @param {!Node} node */ function SearchAndHighlightTask(request, node) { @@ -247,7 +247,7 @@ * @constructor * @extends {Task} * - * @param {!SearchRequest} request + * @param {!settings.SearchRequest} request * @param {!Node} page */ function TopLevelSearchTask(request, page) { @@ -454,11 +454,25 @@ }, }; + /** @interface */ + var SearchManager = function() {}; + + SearchManager.prototype = { + /** + * @param {string} text The text to search for. + * @param {!Node} page + * @return {!Promise<!settings.SearchRequest>} A signal indicating that + * searching finished. + */ + search: function(text, page) {} + }; + /** * @constructor + * @implements {SearchManager} */ - var SearchManager = function() { - /** @private {?SearchRequest} */ + var SearchManagerImpl = function() { + /** @private {?settings.SearchRequest} */ this.activeRequest_ = null; /** @private {!TaskQueue} */ @@ -469,20 +483,15 @@ this.activeRequest_ = null; }.bind(this)); }; - cr.addSingletonGetter(SearchManager); + cr.addSingletonGetter(SearchManagerImpl); - SearchManager.prototype = { - /** - * @param {string} text The text to search for. - * @param {!Node} page - * @return {!Promise<!SearchRequest>} A signal indicating that searching - * finished. - */ + SearchManagerImpl.prototype = { + /** @override */ search: function(text, page) { // Creating a new request only if the |text| changed. if (!this.activeRequest_ || !this.activeRequest_.isSame(text)) { // Resolving previous search request without marking it as - // 'finisthed', if any, and droping all pending tasks. + // 'finished', if any, and dropping all pending tasks. this.queue_.reset(); if (this.activeRequest_) this.activeRequest_.resolver.resolve(this.activeRequest_); @@ -499,10 +508,20 @@ /** @return {!SearchManager} */ function getSearchManager() { - return SearchManager.getInstance(); + return SearchManagerImpl.getInstance(); + } + + /** + * Sets the SearchManager singleton instance, useful for testing. + * @param {!SearchManager} searchManager + */ + function setSearchManagerForTesting(searchManager) { + SearchManagerImpl.instance_ = searchManager; } return { getSearchManager: getSearchManager, + setSearchManagerForTesting: setSearchManagerForTesting, + SearchRequest: SearchRequest, }; });
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html index e18bfb2..5b4e489 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.html +++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/promise_resolver.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="/about_page/about_page.html"> <link rel="import" href="/advanced_page/advanced_page.html"> @@ -39,20 +40,20 @@ -webkit-margin-start: 16px; } - #no-search-results { + #noSearchResults { align-items: center; display: flex; flex-direction: column; margin-top: 80px; } - #no-search-results div:first-child { + #noSearchResults div:first-child { font-size: 120%; margin-bottom: 10px; } </style> <content select="paper-icon-button"></content> - <div id="no-search-results" hidden$="[[!showNoResultsFound_]]"> + <div id="noSearchResults" hidden$="[[!showNoResultsFound_]]"> <div>$i18n{searchNoResults}</div> <div>$i18nRaw{searchNoResultsHelp}</div> </div>
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index c840fbe..30eb7448 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -206,6 +206,7 @@ /** * @param {string} query + * @return {!Promise} A promise indicating that searching finished. */ searchContents: function(query) { this.ensureInDefaultSearchPage_(); @@ -214,26 +215,30 @@ // Trigger rendering of the basic and advanced pages and search once ready. this.showPages_ = {about: false, basic: true, advanced: true}; - setTimeout(function() { - settings.getSearchManager().search( - query, assert(this.$$('settings-basic-page'))); - }.bind(this), 0); - setTimeout(function() { - settings.getSearchManager().search( - query, assert(this.$$('settings-advanced-page'))).then( - function(request) { - if (!request.finished) { - // Nothing to do here. A previous search request was canceled - // because a new search request was issued before the first one - // completed. - return; - } + return new Promise(function(resolve, reject) { + setTimeout(function() { + var whenSearchDone = settings.getSearchManager().search( + query, assert(this.$$('settings-basic-page'))); + assert( + whenSearchDone === + settings.getSearchManager().search( + query, assert(this.$$('settings-advanced-page')))); - this.toolbarSpinnerActive = false; - this.showNoResultsFound_ = - !request.isSame('') && !request.didFindMatches(); - }.bind(this)); - }.bind(this), 0); + whenSearchDone.then(function(request) { + resolve(); + if (!request.finished) { + // Nothing to do here. A previous search request was canceled + // because a new search request was issued before the first one + // completed. + return; + } + + this.toolbarSpinnerActive = false; + this.showNoResultsFound_ = + !request.isSame('') && !request.didFindMatches(); + }.bind(this)); + }.bind(this), 0); + }.bind(this)); }, /**
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_behavior.js index c6844a9..532418a 100644 --- a/chrome/browser/resources/settings/settings_page/main_page_behavior.js +++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
@@ -30,18 +30,15 @@ * @polymerBehavior Polymer.MainPageBehavior */ var MainPageBehaviorImpl = { - /** - * @type {string} Selector to get the sections. Derived elements - * must override. - */ - sectionSelector: '', - /** @type {?Element} The scrolling container. */ scroller: null, /** @override */ attached: function() { - this.scroller = this.domHost && this.domHost.parentNode.$.mainContainer; + if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL') + this.scroller = this.domHost.parentNode.$.mainContainer; + else + this.scroller = document.body; // Used in unit tests. }, /** @@ -52,7 +49,7 @@ */ toggleOtherSectionsHidden_: function(sectionName, hidden) { var sections = Polymer.dom(this.root).querySelectorAll( - this.sectionSelector); + 'settings-section'); for (var section of sections) section.hidden = hidden && (section.section != sectionName); },
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index b7a50fd..32734a3 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -21,6 +21,14 @@ type="chrome_html" flattenhtml="true" allowexternalscript="true" /> + <if expr="chromeos"> + <structure name="IDR_SETTINGS_MANAGE_A11Y_PAGE_JS" + file="a11y_page/manage_a11y_page.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_MANAGE_A11Y_PAGE_HTML" + file="a11y_page/manage_a11y_page.html" + type="chrome_html" /> + </if> <structure name="IDR_SETTINGS_ABOUT_PAGE_BROWSER_PROXY_HTML" file="about_page/about_page_browser_proxy.html" type="chrome_html" /> @@ -329,6 +337,12 @@ <structure name="IDR_SETTINGS_CONTROLS_CONTROLLED_BUTTON_HTML" file="controls/controlled_button.html" type="chrome_html" /> + <structure name="IDR_SETTINGS_CONTROLS_CONTROLLED_RADIO_BUTTON_JS" + file="controls/controlled_radio_button.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CONTROLS_CONTROLLED_RADIO_BUTTON_HTML" + file="controls/controlled_radio_button.html" + type="chrome_html" /> <structure name="IDR_SETTINGS_CONTROLS_CHECKBOX_HTML" file="controls/settings_checkbox.html" type="chrome_html" /> @@ -664,6 +678,30 @@ <structure name="IDR_SETTINGS_CUPS_PRINTING_PAGE_JS" file="printing_page/cups_printers.js" type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTERS_BROWSER_PROXY_HTML" + file="printing_page/cups_printers_browser_proxy.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTERS_BROWSER_PROXY_JS" + file="printing_page/cups_printers_browser_proxy.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTERS_LIST_HTML" + file="printing_page/cups_printers_list.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTERS_LIST_JS" + file="printing_page/cups_printers_list.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTER_DETAILS_HTML" + file="printing_page/cups_printer_details_page.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTER_DETAILS_JS" + file="printing_page/cups_printer_details_page.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_ADD_PRINTER_DIALOG_HTML" + file="printing_page/cups_add_printer_dialog.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_ADD_PRINTER_DIALOG_JS" + file="printing_page/cups_add_printer_dialog.js" + type="chrome_html" /> </if> <structure name="IDR_SETTINGS_CLOUD_PRINTING_PAGE_HTML" file="printing_page/cloud_printers.html"
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html index 38ff9db..22d9184 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.html +++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -12,50 +12,27 @@ <dom-module id="site-details"> <template> <style include="settings-shared"> - :host { - -webkit-margin-start: 4px; - display: block; - } - - .origin-box { - margin-bottom: 20px; - } - - .origin { - -webkit-margin-start: 10px; - font-weight: 500; - } - - .reset-button { - -webkit-margin-start: 15px; - } - #storage { -webkit-padding-end: 0; } - - .website-icon { - background-repeat: no-repeat; - background-size: contain; - height: 16px; - width: 16px; - } </style> - <div class="settings-box block"> - <div class="horizontal layout origin-box"> - <div class="website-icon" - style$="[[computeSiteIcon(site.originForDisplay)]]"></div> - <div class="origin flex">[[site.originForDisplay]]</div> + <div id="usage" hidden$="[[!storedData_]]"> + <div class="settings-box first"> + <h2>$i18n{siteSettingsUsage}</h2> </div> - <h2 id="usage" hidden$="[[!storedData_]]">$i18n{siteSettingsUsage}</h2> - <paper-item id="storage" hidden$="[[!storedData_]]"> - <div class="flex">[[storedData_]]</div> - <paper-icon-button icon="settings:delete" - on-tap="onClearStorage_" - alt="$i18n{siteSettingsDelete}"></paper-icon-button> - </paper-item> + <div class="list-frame"> + <paper-item id="storage" hidden$="[[!storedData_]]"> + <div class="flex">[[storedData_]]</div> + <paper-icon-button icon="settings:delete" + on-tap="onClearStorage_" + alt="$i18n{siteSettingsDelete}"></paper-icon-button> + </paper-item> + </div> + </div> + <div class="settings-box"> <h2>$i18n{siteSettingsPermissions}</h2> - + </div> + <div class="list-frame"> <site-details-permission site="[[site]]" id="cookies" category="{{ContentSettingsTypes.COOKIES}}"> </site-details-permission> @@ -96,9 +73,9 @@ category="{{ContentSettingsTypes.FULLSCREEN}}"> </site-details-permission> - <paper-button on-tap="onClearAndReset_" raised class="reset-button"> + <div on-tap="onClearAndReset_" raised class="list-item list-button"> $i18n{siteSettingsClearAndReset} - </paper-button> + </div> </div> <website-usage-private-api id="usageApi" website-data-usage="{{storedData_}}"
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.html b/chrome/browser/resources/settings/site_settings/site_details_permission.html index 58fa36d..b69122b3 100644 --- a/chrome/browser/resources/settings/site_settings/site_details_permission.html +++ b/chrome/browser/resources/settings/site_settings/site_details_permission.html
@@ -12,7 +12,7 @@ <template> <style include="settings-shared"> </style> - <div id="details" class="list-frame" hidden> + <div id="details" hidden> <div class="list-item underbar"> <div> <iron-icon icon="[[computeIconForContentCategory(category)]]">
diff --git a/chrome/browser/resources/settings/site_settings/site_list.html b/chrome/browser/resources/settings/site_settings/site_list.html index 57a4323..27f4bee 100644 --- a/chrome/browser/resources/settings/site_settings/site_list.html +++ b/chrome/browser/resources/settings/site_settings/site_list.html
@@ -84,7 +84,7 @@ </div> </template> - <template is="dom-if" if="{{!allSites}}"> + <template is="dom-if" if="[[!allSites]]"> <div class="button-container"> <paper-button on-tap="onAddSiteTap_" class="primary-button no-upper">
diff --git a/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc b/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc index f2661974..25e41f3 100644 --- a/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc +++ b/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc
@@ -83,7 +83,8 @@ bool HasWindow() const override { return wrapped_->HasWindow(); } SessionID::id_type GetSessionId() const override { - return wrapped_->GetSessionId(); + return session_id_override_ >= 0 ? session_id_override_ + : wrapped_->GetSessionId(); } int GetTabCount() const override { return wrapped_->GetTabCount(); } @@ -107,6 +108,8 @@ return wrapped_->GetTabAt(index); } + void OverrideSessionId(SessionID::id_type id) { session_id_override_ = id; } + void OverrideTabAt(int index, SyncedTabDelegate* delegate, SessionID::id_type tab_id) { @@ -130,6 +133,7 @@ std::map<int, SyncedTabDelegate*> tab_overrides_; std::map<int, SessionID::id_type> tab_id_overrides_; const SyncedWindowDelegate* const wrapped_; + SessionID::id_type session_id_override_ = -1; }; class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter { @@ -394,32 +398,34 @@ sync_driver::SyncPrefs* sync_prefs() { return sync_prefs_.get(); } + browser_sync::SyncedWindowDelegatesGetter* get_synced_window_getter() { + return manager()->synced_window_delegates_getter(); + } + void set_synced_window_getter( browser_sync::SyncedWindowDelegatesGetter* synced_window_getter) { sessions_client_shim_->set_synced_window_getter(synced_window_getter); } syncer::SyncChange MakeRemoteChange( - int64_t id, const sync_pb::SessionSpecifics& specifics, SyncChange::SyncChangeType type) const { - return syncer::SyncChange(FROM_HERE, type, CreateRemoteData(specifics, id)); + return syncer::SyncChange(FROM_HERE, type, CreateRemoteData(specifics)); } void AddTabsToChangeList(const std::vector<sync_pb::SessionSpecifics>& batch, SyncChange::SyncChangeType type, syncer::SyncChangeList* change_list) const { for (const auto& specifics : batch) { - change_list->push_back(syncer::SyncChange( - FROM_HERE, type, - CreateRemoteData(specifics, specifics.tab_node_id()))); + change_list->push_back( + syncer::SyncChange(FROM_HERE, type, CreateRemoteData(specifics))); } } void AddToSyncDataList(const sync_pb::SessionSpecifics& specifics, syncer::SyncDataList* list, base::Time mtime) const { - list->push_back(CreateRemoteData(specifics, 1, mtime)); + list->push_back(CreateRemoteData(specifics, mtime)); } void AddTabsToSyncDataList(const std::vector<sync_pb::SessionSpecifics>& tabs, @@ -430,18 +436,17 @@ } syncer::SyncData CreateRemoteData(const sync_pb::SessionSpecifics& specifics, - int64_t id = 1, base::Time mtime = base::Time()) const { sync_pb::EntitySpecifics entity; entity.mutable_session()->CopyFrom(specifics); - return CreateRemoteData(entity, id, mtime); + return CreateRemoteData(entity, mtime); } syncer::SyncData CreateRemoteData(const sync_pb::EntitySpecifics& entity, - int64_t id, - base::Time mtime) const { + base::Time mtime = base::Time()) const { + // The server ID is never relevant to these tests, so just use 1. return SyncData::CreateRemoteData( - id, entity, mtime, syncer::AttachmentIdList(), + 1, entity, mtime, syncer::AttachmentIdList(), syncer::AttachmentServiceProxyForTest::Create(), SessionsSyncManager::TagHashFromSpecifics(entity.session())); } @@ -925,12 +930,7 @@ EXPECT_EQ(0, header_s2.window_size()); // Now take that header node and feed it in as input. - SyncData d(SyncData::CreateRemoteData( - 1, - data.GetSpecifics(), - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + SyncData d = CreateRemoteData(data.GetSpecifics()); syncer::SyncDataList in(&d, &d + 1); out.clear(); SessionsSyncManager manager2(GetSyncSessionsClient(), sync_prefs(), @@ -970,29 +970,13 @@ // * one "normal" fully loaded tab // * one "frozen" tab with no WebContents and a tab_id change // * one "frozen" tab with no WebContents and no tab_id change - SyncData t0(SyncData::CreateRemoteData( - 1, - out[2].sync_data().GetSpecifics(), - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); - sync_pb::EntitySpecifics entity(out[4].sync_data().GetSpecifics()); - entity.mutable_session()->mutable_tab()->set_tab_id(kRestoredTabId); - SyncData t1(SyncData::CreateRemoteData( - 2, - entity, - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); - SyncData t2(SyncData::CreateRemoteData( - 3, - out[6].sync_data().GetSpecifics(), - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); - in.push_back(t0); - in.push_back(t1); - in.push_back(t2); + sync_pb::EntitySpecifics t0_entity = out[2].sync_data().GetSpecifics(); + sync_pb::EntitySpecifics t1_entity = out[4].sync_data().GetSpecifics(); + sync_pb::EntitySpecifics t2_entity = out[6].sync_data().GetSpecifics(); + t1_entity.mutable_session()->mutable_tab()->set_tab_id(kRestoredTabId); + in.push_back(CreateRemoteData(t0_entity)); + in.push_back(CreateRemoteData(t1_entity)); + in.push_back(CreateRemoteData(t2_entity)); out.clear(); manager()->StopSyncing(syncer::SESSIONS); @@ -1005,7 +989,7 @@ SyncedWindowDelegateOverride window_override(*windows.begin()); window_override.OverrideTabAt(1, &t1_override, kNewTabId); window_override.OverrideTabAt(2, &t2_override, - t2.GetSpecifics().session().tab().tab_id()); + t2_entity.session().tab().tab_id()); std::set<const SyncedWindowDelegate*> delegates; delegates.insert(&window_override); std::unique_ptr<TestSyncedWindowDelegatesGetter> getter( @@ -1029,7 +1013,7 @@ // Verify TabLinks. SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_; ASSERT_EQ(3U, tab_map.size()); - int t2_tab_id = t2.GetSpecifics().session().tab().tab_id(); + int t2_tab_id = t2_entity.session().tab().tab_id(); EXPECT_EQ(2, tab_map.find(t2_tab_id)->second->tab_node_id()); EXPECT_EQ(1, tab_map.find(kNewTabId)->second->tab_node_id()); int t0_tab_id = out[0].sync_data().GetSpecifics().session().tab().tab_id(); @@ -1040,6 +1024,59 @@ // (similar to how SessionsSyncManagerTest.OnLocalTabModified works.) } +// Ensure model association updates the window ID for tabs whose window's ID has +// changed. +TEST_F(SessionsSyncManagerTest, WindowIdUpdatedOnRestore) { + const int kNewWindowId = 1337; + syncer::SyncDataList in; + syncer::SyncChangeList out; + + // Set up one tab and start sync with it. + AddTab(browser(), GURL("http://foo1")); + NavigateAndCommitActiveTab(GURL("http://foo2")); + InitWithSyncDataTakeOutput(in, &out); + + // Should be one header add, 1 tab add/update pair, and one header update. + ASSERT_EQ(4U, out.size()); + const sync_pb::EntitySpecifics t0_entity = out[2].sync_data().GetSpecifics(); + + in.push_back(CreateRemoteData(t0_entity)); + out.clear(); + manager()->StopSyncing(syncer::SESSIONS); + + // SyncedTabDelegateFake is a placeholder (no WebContents) by default. + SyncedTabDelegateFake t0_override; + t0_override.SetSyncId(t0_entity.session().tab_node_id()); + + // Set up the window override with the new window ID and placeholder tab. + const std::set<const SyncedWindowDelegate*>& windows = + get_synced_window_getter()->GetSyncedWindowDelegates(); + ASSERT_EQ(1U, windows.size()); + SyncedWindowDelegateOverride window_override(*windows.begin()); + window_override.OverrideSessionId(kNewWindowId); + window_override.OverrideTabAt(0, &t0_override, + t0_entity.session().tab().tab_id()); + + // Inject the window override. + std::set<const SyncedWindowDelegate*> delegates; + delegates.insert(&window_override); + std::unique_ptr<TestSyncedWindowDelegatesGetter> getter( + new TestSyncedWindowDelegatesGetter(delegates)); + set_synced_window_getter(getter.get()); + + syncer::SyncMergeResult result = manager()->MergeDataAndStartSyncing( + syncer::SESSIONS, in, std::unique_ptr<syncer::SyncChangeProcessor>( + new TestSyncProcessorStub(&out)), + std::unique_ptr<syncer::SyncErrorFactory>( + new syncer::SyncErrorFactoryMock())); + + // There should be one change for t0's window ID update. + ASSERT_EQ(1U, FilterOutLocalHeaderChanges(&out)->size()); + EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type()); + EXPECT_EQ(kNewWindowId, + out[0].sync_data().GetSpecifics().session().tab().window_id()); +} + // Tests MergeDataAndStartSyncing with sync data but no local data. TEST_F(SessionsSyncManagerTest, MergeWithInitialForeignSession) { std::string tag = "tag1"; @@ -1063,7 +1100,7 @@ sync_pb::EntitySpecifics entity; helper()->BuildTabSpecifics(tag, 0, tab_list2[i], entity.mutable_session()); - initial_data.push_back(CreateRemoteData(entity, i + 10, base::Time())); + initial_data.push_back(CreateRemoteData(entity)); } syncer::SyncChangeList output; @@ -1192,7 +1229,7 @@ } syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, meta1, SyncChange::ACTION_UPDATE)); + changes.push_back(MakeRemoteChange(meta1, SyncChange::ACTION_UPDATE)); AddTabsToChangeList(tabs2, SyncChange::ACTION_ADD, &changes); manager()->ProcessSyncChanges(FROM_HERE, changes); changes.clear(); @@ -1212,7 +1249,7 @@ std::vector<sync_pb::SessionSpecifics> tag2_tabs; sync_pb::SessionSpecifics meta2(helper()->BuildForeignSession( tag2, tag2_tab_list, &tag2_tabs)); - changes.push_back(MakeRemoteChange(100, meta2, SyncChange::ACTION_ADD)); + changes.push_back(MakeRemoteChange(meta2, SyncChange::ACTION_ADD)); AddTabsToChangeList(tag2_tabs, SyncChange::ACTION_ADD, &changes); manager()->ProcessSyncChanges(FROM_HERE, changes); @@ -1236,7 +1273,7 @@ win->add_tab(*iter); } syncer::SyncChangeList removal; - removal.push_back(MakeRemoteChange(1, meta1, SyncChange::ACTION_UPDATE)); + removal.push_back(MakeRemoteChange(meta1, SyncChange::ACTION_UPDATE)); AddTabsToChangeList(tabs1, SyncChange::ACTION_UPDATE, &removal); manager()->ProcessSyncChanges(FROM_HERE, removal); @@ -1311,7 +1348,7 @@ syncer::SyncChangeList adds; // Add tabs for first window, then the meta node. AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &adds); - adds.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); + adds.push_back(MakeRemoteChange(meta, SyncChange::ACTION_ADD)); manager()->ProcessSyncChanges(FROM_HERE, adds); // Check that the foreign session was associated and retrieve the data. @@ -1347,7 +1384,7 @@ } syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_ADD)); AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes); AddTabsToChangeList(tabs2, SyncChange::ACTION_ADD, &changes); manager()->ProcessSyncChanges(FROM_HERE, changes); @@ -1364,7 +1401,7 @@ // Close the second window. meta.mutable_header()->clear_window(); helper()->AddWindowSpecifics(0, tab_list1, &meta); - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_UPDATE)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_UPDATE)); // Update associator with the session's meta node containing one window. manager()->ProcessSyncChanges(FROM_HERE, changes); @@ -1385,18 +1422,13 @@ InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); ASSERT_EQ(2U, out.size()); sync_pb::EntitySpecifics entity(out[0].sync_data().GetSpecifics()); - SyncData d(SyncData::CreateRemoteData( - 1, - entity, - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + SyncData d = CreateRemoteData(entity); SetSyncData(syncer::SyncDataList(&d, &d + 1)); out.clear(); syncer::SyncChangeList changes; changes.push_back( - MakeRemoteChange(1, entity.session(), SyncChange::ACTION_DELETE)); + MakeRemoteChange(entity.session(), SyncChange::ACTION_DELETE)); manager()->ProcessSyncChanges(FROM_HERE, changes); EXPECT_TRUE(manager()->local_tab_pool_out_of_sync_); EXPECT_TRUE(out.empty()); // ChangeProcessor shouldn't see any activity. @@ -1457,7 +1489,7 @@ "tag1", tab_list, &tabs1)); syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_ADD)); AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes); manager()->ProcessSyncChanges(FROM_HERE, changes); @@ -1467,7 +1499,7 @@ changes.clear(); foreign_sessions.clear(); - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_DELETE)); manager()->ProcessSyncChanges(FROM_HERE, changes); EXPECT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions)); @@ -1516,13 +1548,13 @@ } syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, tabs[2], SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, tabs[4], SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, orphan6, SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_UPDATE)); - changes.push_back(MakeRemoteChange(1, tabs[3], SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, tabs[5], SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, orphan7, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tabs[2], SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tabs[4], SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(orphan6, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_UPDATE)); + changes.push_back(MakeRemoteChange(tabs[3], SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tabs[5], SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(orphan7, SyncChange::ACTION_DELETE)); manager()->ProcessSyncChanges(FROM_HERE, changes); std::vector<const SyncedSession*> foreign_sessions; @@ -1597,9 +1629,9 @@ EXPECT_TRUE(tab_node_ids.find(tab2C.tab_node_id()) != tab_node_ids.end()); syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, tab1A, SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, tab1B, SyncChange::ACTION_DELETE)); - changes.push_back(MakeRemoteChange(1, tab2C, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tab1A, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tab1B, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tab2C, SyncChange::ACTION_DELETE)); manager()->ProcessSyncChanges(FROM_HERE, changes); tab_node_ids.clear(); @@ -1647,7 +1679,7 @@ EXPECT_TRUE(tab_node_ids.find(tab_node_id_unique) != tab_node_ids.end()); syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, tab1A, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(tab1A, SyncChange::ACTION_DELETE)); manager()->ProcessSyncChanges(FROM_HERE, changes); tab_node_ids.clear(); @@ -1674,12 +1706,7 @@ // will be deleted before being added to the tab node pool. sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics()); entity.mutable_session()->mutable_tab()->set_tab_id(1); - SyncData d(SyncData::CreateRemoteData( - 1, - entity, - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + SyncData d = CreateRemoteData(entity); syncer::SyncDataList in(&d, &d + 1); changes.clear(); SessionsSyncManager manager2(GetSyncSessionsClient(), sync_prefs(), @@ -1700,12 +1727,7 @@ std::string local_tag = manager()->current_machine_tag(); int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes); - SyncData d(SyncData::CreateRemoteData( - 1, - changes[0].sync_data().GetSpecifics(), - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + SyncData d = CreateRemoteData(changes[0].sync_data().GetSpecifics()); syncer::SyncDataList in(&d, &d + 1); changes.clear(); TearDown(); @@ -2129,8 +2151,8 @@ base::Time tag2_time = base::Time::Now() - base::TimeDelta::FromDays(5); syncer::SyncDataList foreign_data; - foreign_data.push_back(CreateRemoteData(meta, 1, tag1_time)); - foreign_data.push_back(CreateRemoteData(meta2, 1, tag2_time)); + foreign_data.push_back(CreateRemoteData(meta, tag1_time)); + foreign_data.push_back(CreateRemoteData(meta2, tag2_time)); AddTabsToSyncDataList(tabs1, &foreign_data); AddTabsToSyncDataList(tabs2, &foreign_data); @@ -2239,7 +2261,7 @@ tag1, tab_list1, &tabs1)); syncer::SyncDataList foreign_data; base::Time tag1_time = base::Time::Now() - base::TimeDelta::FromDays(21); - foreign_data.push_back(CreateRemoteData(meta, 1, tag1_time)); + foreign_data.push_back(CreateRemoteData(meta, tag1_time)); AddTabsToSyncDataList(tabs1, &foreign_data); syncer::SyncChangeList output; InitWithSyncDataTakeOutput(foreign_data, &output); @@ -2251,7 +2273,7 @@ syncer::SyncChangeList changes; changes.push_back( syncer::SyncChange(FROM_HERE, SyncChange::ACTION_UPDATE, - CreateRemoteData(tabs1[0], 1, base::Time::Now()))); + CreateRemoteData(tabs1[0], base::Time::Now()))); manager()->ProcessSyncChanges(FROM_HERE, changes); // Check that the foreign session was associated and retrieve the data. @@ -2332,7 +2354,7 @@ "tag1", tab_list, &tabs1)); syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_ADD)); manager()->ProcessSyncChanges(FROM_HERE, changes); EXPECT_TRUE(observer()->notified_of_update()); @@ -2344,7 +2366,7 @@ changes.clear(); observer()->Reset(); - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_DELETE)); manager()->ProcessSyncChanges(FROM_HERE, changes); EXPECT_TRUE(observer()->notified_of_update()); } @@ -2361,7 +2383,7 @@ tag, tab_list, &tabs1)); syncer::SyncChangeList changes; - changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); + changes.push_back(MakeRemoteChange(meta, SyncChange::ACTION_ADD)); manager()->ProcessSyncChanges(FROM_HERE, changes); observer()->Reset(); @@ -2401,12 +2423,7 @@ syncer::SyncDataList initial_data; sync_pb::EntitySpecifics entity; entity.mutable_session()->CopyFrom(meta); - initial_data.push_back(SyncData::CreateRemoteData( - 1, - entity, - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + initial_data.push_back(CreateRemoteData(entity)); AddTabsToSyncDataList(tabs1, &initial_data); syncer::SyncChangeList output; @@ -2435,23 +2452,13 @@ syncer::SyncDataList initial_data; sync_pb::EntitySpecifics entity; entity.mutable_session()->CopyFrom(meta); - initial_data.push_back(SyncData::CreateRemoteData( - 1, - entity, - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + initial_data.push_back(CreateRemoteData(entity)); AddTabsToSyncDataList(tabs1, &initial_data); for (size_t i = 0; i < tab_list2.size(); ++i) { sync_pb::EntitySpecifics entity; helper()->BuildTabSpecifics(tag, 0, tab_list2[i], entity.mutable_session()); - initial_data.push_back(SyncData::CreateRemoteData( - i + 10, - entity, - base::Time(), - syncer::AttachmentIdList(), - syncer::AttachmentServiceProxyForTest::Create())); + initial_data.push_back(CreateRemoteData(entity)); } syncer::SyncChangeList output; @@ -2473,13 +2480,12 @@ syncer::SyncDataList initial_data; initial_data.push_back(CreateRemoteData(meta)); - int node_id = 2; sync_pb::EntitySpecifics entity; for (size_t i = 0; i < tabs1.size(); i++) { entity.mutable_session()->CopyFrom(tabs1[i]); initial_data.push_back( - CreateRemoteData(entity, node_id++, base::Time::FromDoubleT(2000))); + CreateRemoteData(entity, base::Time::FromDoubleT(2000))); } // Add two more tabs with duplicating IDs but with different modification @@ -2491,14 +2497,14 @@ duplicating_tab1.mutable_tab()->set_tab_visual_index(2); entity.mutable_session()->CopyFrom(duplicating_tab1); initial_data.push_back( - CreateRemoteData(entity, node_id++, base::Time::FromDoubleT(1000))); + CreateRemoteData(entity, base::Time::FromDoubleT(1000))); sync_pb::SessionSpecifics duplicating_tab2; helper()->BuildTabSpecifics(tag, 0, 17, &duplicating_tab2); duplicating_tab2.mutable_tab()->set_tab_visual_index(3); entity.mutable_session()->CopyFrom(duplicating_tab2); initial_data.push_back( - CreateRemoteData(entity, node_id++, base::Time::FromDoubleT(3000))); + CreateRemoteData(entity, base::Time::FromDoubleT(3000))); syncer::SyncChangeList output; InitWithSyncDataTakeOutput(initial_data, &output); @@ -2534,10 +2540,10 @@ syncer::SyncDataList initial_data; initial_data.push_back( - CreateRemoteData(meta1, 1, base::Time::FromInternalValue(10))); + CreateRemoteData(meta1, base::Time::FromInternalValue(10))); AddTabsToSyncDataList(tabs1, &initial_data); initial_data.push_back( - CreateRemoteData(meta2, 2, base::Time::FromInternalValue(200))); + CreateRemoteData(meta2, base::Time::FromInternalValue(200))); AddTabsToSyncDataList(tabs2, &initial_data); syncer::SyncChangeList output; @@ -2580,7 +2586,7 @@ // Order the tabs oldest to most ReceiveDuplicateUnassociatedTabs and // left to right visually. initial_data.push_back( - CreateRemoteData(entity, i + 10, base::Time::FromInternalValue(i + 1))); + CreateRemoteData(entity, base::Time::FromInternalValue(i + 1))); } syncer::SyncChangeList output;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index db85b4d..e2b7875 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -385,7 +385,6 @@ "//ui/keyboard:resources", "//ui/wm", ] - defines += [ "MOJO_SHELL_CLIENT" ] if (!is_chromeos) { sources += rebase_path(gypi_values.chrome_browser_ui_aura_non_chromeos, ".",
diff --git a/chrome/browser/ui/android/autofill/credit_card_scanner_view_android.cc b/chrome/browser/ui/android/autofill/credit_card_scanner_view_android.cc index 576f1d0..48b3082 100644 --- a/chrome/browser/ui/android/autofill/credit_card_scanner_view_android.cc +++ b/chrome/browser/ui/android/autofill/credit_card_scanner_view_android.cc
@@ -26,7 +26,7 @@ JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaGlobalRef<jobject> java_object( Java_CreditCardScanner_create( - env, 0, base::android::GetApplicationContext(), 0)); + env, 0, base::android::GetApplicationContext(), nullptr)); return Java_CreditCardScanner_canScan(env, java_object.obj()); }
diff --git a/chrome/browser/ui/android/connection_info_popup_android.cc b/chrome/browser/ui/android/connection_info_popup_android.cc index b0bf613..faea509a 100644 --- a/chrome/browser/ui/android/connection_info_popup_android.cc +++ b/chrome/browser/ui/android/connection_info_popup_android.cc
@@ -89,7 +89,7 @@ // Important to use GetVisibleEntry to match what's showing in the omnibox. content::NavigationEntry* nav_entry = web_contents->GetController().GetVisibleEntry(); - if (nav_entry == NULL) + if (nav_entry == nullptr) return; popup_jobject_.Reset(env, java_website_settings_pop); @@ -176,7 +176,7 @@ ScopedJavaLocalRef<jstring> description = ConvertUTF8ToJavaString( env, identity_info.connection_status_description); Java_ConnectionInfoPopup_addDescriptionSection( - env, popup_jobject_.obj(), icon_id, NULL, description.obj()); + env, popup_jobject_.obj(), icon_id, nullptr, description.obj()); } Java_ConnectionInfoPopup_addMoreInfoLink(
diff --git a/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc new file mode 100644 index 0000000..47c5b27 --- /dev/null +++ b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc
@@ -0,0 +1,61 @@ +// 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. + +#include "chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h" + +#include <utility> + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/android/resource_mapper.h" +#include "chrome/browser/infobars/infobar_service.h" +#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h" +#include "jni/AutofillCreditCardFillingInfoBar_jni.h" +#include "ui/gfx/android/java_bitmap.h" +#include "ui/gfx/image/image.h" +#include "url/gurl.h" + +AutofillCreditCardFillingInfoBar::AutofillCreditCardFillingInfoBar( + std::unique_ptr<autofill::AutofillCreditCardFillingInfoBarDelegateMobile> + delegate) + : ConfirmInfoBar(std::move(delegate)) {} + +AutofillCreditCardFillingInfoBar::~AutofillCreditCardFillingInfoBar() {} + +base::android::ScopedJavaLocalRef<jobject> +AutofillCreditCardFillingInfoBar::CreateRenderInfoBar(JNIEnv* env) { + autofill::AutofillCreditCardFillingInfoBarDelegateMobile* delegate = + static_cast<autofill::AutofillCreditCardFillingInfoBarDelegateMobile*>( + GetDelegate()); + ScopedJavaLocalRef<jobject> java_bitmap; + if (delegate->GetIconId() == infobars::InfoBarDelegate::kNoIconID && + !delegate->GetIcon().IsEmpty()) { + java_bitmap = gfx::ConvertToJavaBitmap(delegate->GetIcon().ToSkBitmap()); + } + + base::android::ScopedJavaLocalRef<jobject> java_delegate = + Java_AutofillCreditCardFillingInfoBar_create( + env, reinterpret_cast<intptr_t>(this), GetEnumeratedIconId(), + java_bitmap.obj(), + base::android::ConvertUTF16ToJavaString( + env, delegate->GetMessageText()) + .obj(), + base::android::ConvertUTF16ToJavaString( + env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK)) + .obj(), + base::android::ConvertUTF16ToJavaString( + env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_CANCEL)) + .obj()); + + Java_AutofillCreditCardFillingInfoBar_addDetail( + env, java_delegate.obj(), + ResourceMapper::MapFromChromiumId(delegate->issuer_icon_id()), + base::android::ConvertUTF16ToJavaString(env, delegate->card_label()) + .obj(), + base::android::ConvertUTF16ToJavaString(env, delegate->card_sub_label()) + .obj()); + + return java_delegate; +}
diff --git a/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h new file mode 100644 index 0000000..8a2a8d3 --- /dev/null +++ b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h
@@ -0,0 +1,38 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_ANDROID_INFOBARS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_H_ +#define CHROME_BROWSER_UI_ANDROID_INFOBARS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_H_ + +#include <jni.h> + +#include <memory> + +#include "base/macros.h" +#include "chrome/browser/ui/android/infobars/confirm_infobar.h" + +namespace autofill { +class AutofillCreditCardFillingInfoBarDelegateMobile; +} + +// Android implementation of the infobar for credit card assisted filling, which +// proposes to autofill user data into the detected credit card form in the +// page. Upon accepting the infobar, the form is filled automatically. If +// the infobar is dismissed, nothing happens. +class AutofillCreditCardFillingInfoBar : public ConfirmInfoBar { + public: + explicit AutofillCreditCardFillingInfoBar( + std::unique_ptr<autofill::AutofillCreditCardFillingInfoBarDelegateMobile> + delegate); + ~AutofillCreditCardFillingInfoBar() override; + + private: + // ConfirmInfoBar: + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + JNIEnv* env) override; + + DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardFillingInfoBar); +}; + +#endif // CHROME_BROWSER_UI_ANDROID_INFOBARS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_H_
diff --git a/chrome/browser/ui/ash/ash_init.cc b/chrome/browser/ui/ash/ash_init.cc index ceca12f..ad74f02 100644 --- a/chrome/browser/ui/ash/ash_init.cc +++ b/chrome/browser/ui/ash/ash_init.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/ash/chrome_shell_content_state.h" #include "chrome/browser/ui/ash/chrome_shell_delegate.h" #include "chrome/browser/ui/ash/ime_controller_chromeos.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.h" #include "chrome/browser/ui/ash/volume_controller_chromeos.h" #include "chrome/common/chrome_switches.h" #include "chromeos/accelerometer/accelerometer_reader.h" @@ -43,10 +44,6 @@ #include "ui/base/x/x11_util.h" #endif -#if defined(MOJO_SHELL_CLIENT) -#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.h" -#endif - namespace chrome { void OpenAsh(gfx::AcceleratedWidget remote_window) { @@ -106,10 +103,8 @@ } void InitializeMash() { -#if defined(MOJO_SHELL_CLIENT) DCHECK(!ash::Shell::HasInstance()); ChromeLauncherControllerMus::CreateInstance()->Init(); -#endif } void CloseAsh() {
diff --git a/chrome/browser/ui/ash/ash_util.cc b/chrome/browser/ui/ash/ash_util.cc index eeb288a..30605b6 100644 --- a/chrome/browser/ui/ash/ash_util.cc +++ b/chrome/browser/ui/ash/ash_util.cc
@@ -8,11 +8,8 @@ #include "ash/common/wm_shell.h" #include "build/build_config.h" #include "chrome/browser/ui/ash/ash_init.h" -#include "ui/aura/window_event_dispatcher.h" - -#if defined(MOJO_SHELL_CLIENT) #include "services/shell/runner/common/client_util.h" -#endif +#include "ui/aura/window_event_dispatcher.h" namespace chrome { @@ -21,11 +18,7 @@ } bool IsRunningInMash() { -#if defined(MOJO_SHELL_CLIENT) return shell::ShellIsRemote(); -#else - return false; -#endif } bool IsAcceleratorDeprecated(const ui::Accelerator& accelerator) {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h index eb963f9..17600d306 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_types.h" #include "extensions/common/constants.h" +class AccountId; class ArcAppDeferredLauncherController; class Browser; class BrowserShortcutLauncherItemController; @@ -234,7 +235,7 @@ // animation predictions. virtual bool ShelfBoundsChangesProbablyWithUser( ash::Shelf* shelf, - const std::string& user_id) const = 0; + const AccountId& account_id) const = 0; // Called when the user profile is fully loaded and ready to switch to. virtual void OnUserProfileReadyToSwitch(Profile* profile) = 0;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc index 676aae2d..c48e651 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc
@@ -824,10 +824,9 @@ bool ChromeLauncherControllerImpl::ShelfBoundsChangesProbablyWithUser( ash::Shelf* shelf, - const std::string& user_id) const { - Profile* other_profile = multi_user_util::GetProfileFromAccountId( - AccountId::FromUserEmail(user_id)); - if (other_profile == profile_) + const AccountId& account_id) const { + Profile* other_profile = multi_user_util::GetProfileFromAccountId(account_id); + if (!other_profile || other_profile == profile_) return false; // Note: The Auto hide state from preferences is not the same as the actual
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h index 17dd0c7..d3007c6 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h
@@ -134,7 +134,7 @@ const ash::ShelfID id) override; bool ShelfBoundsChangesProbablyWithUser( ash::Shelf* shelf, - const std::string& user_id) const override; + const AccountId& account_id) const override; void OnUserProfileReadyToSwitch(Profile* profile) override; ArcAppDeferredLauncherController* GetArcDeferredLauncher() override;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.cc index 3115403f..e98778f 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.cc
@@ -225,7 +225,7 @@ bool ChromeLauncherControllerMus::ShelfBoundsChangesProbablyWithUser( ash::Shelf* shelf, - const std::string& user_id) const { + const AccountId& account_id) const { NOTIMPLEMENTED(); return false; }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.h index 2d7082e..4e4b368 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.h +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_mus.h
@@ -81,7 +81,7 @@ const ash::ShelfID id) override; bool ShelfBoundsChangesProbablyWithUser( ash::Shelf* shelf, - const std::string& user_id) const override; + const AccountId& account_id) const override; void OnUserProfileReadyToSwitch(Profile* profile) override; ArcAppDeferredLauncherController* GetArcDeferredLauncher() override;
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc index d469dbe2..c13ba13 100644 --- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc +++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
@@ -268,7 +268,7 @@ if (GetScreenCover(window) != NO_USER_COVERS_SCREEN && (!chrome_launcher_controller || !chrome_launcher_controller->ShelfBoundsChangesProbablyWithUser( - shelf, new_account_id_.GetUserEmail()))) { + shelf, new_account_id_))) { shelf->shelf_widget()->HideShelfBehindBlackBar(true, duration_override); } else { // This shelf change is only part of the animation and will be updated by
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index e9d8756..b071971 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/autofill/risk_util.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -62,6 +61,9 @@ #if defined(OS_ANDROID) #include "base/android/context_utils.h" #include "chrome/browser/android/signin/signin_promo_util_android.h" +#include "chrome/browser/infobars/infobar_service.h" +#include "chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h" +#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h" #include "components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h" #include "components/autofill/core/browser/autofill_save_card_infobar_mobile.h" #include "components/infobars/core/infobar.h" @@ -211,6 +213,22 @@ #endif } +void ChromeAutofillClient::ConfirmCreditCardFillAssist( + const CreditCard& card, + const base::Closure& callback) { +#if defined(OS_ANDROID) + auto infobar_delegate = + base::MakeUnique<AutofillCreditCardFillingInfoBarDelegateMobile>( + card, callback); + auto* raw_delegate = infobar_delegate.get(); + if (InfoBarService::FromWebContents(web_contents())->AddInfoBar( + base::MakeUnique<AutofillCreditCardFillingInfoBar>( + std::move(infobar_delegate)))) { + raw_delegate->set_was_shown(); + } +#endif +} + void ChromeAutofillClient::LoadRiskData( const base::Callback<void(const std::string&)>& callback) { ::autofill::LoadRiskData(0, web_contents(), callback);
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 81791fc..70fda229 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -58,6 +58,8 @@ const CreditCard& card, std::unique_ptr<base::DictionaryValue> legal_message, const base::Closure& callback) override; + void ConfirmCreditCardFillAssist(const CreditCard& card, + const base::Closure& callback) override; void LoadRiskData( const base::Callback<void(const std::string&)>& callback) override; bool HasCreditCardScanFeature() override;
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index dbfd2ca..6da32e1 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -36,6 +36,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_utils.h" #include "chrome/browser/ui/webui/inspect_ui.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/content_restriction.h" #include "chrome/common/pref_names.h" #include "chrome/common/profiling.h" @@ -115,10 +116,6 @@ namespace chrome { -const base::Feature kBackspaceGoesBackFeature { - "BackspaceGoesBack", base::FEATURE_DISABLED_BY_DEFAULT -}; - /////////////////////////////////////////////////////////////////////////////// // BrowserCommandController, public: @@ -318,7 +315,7 @@ switch (id) { // Navigation commands case IDC_BACKSPACE_BACK: - if (base::FeatureList::IsEnabled(kBackspaceGoesBackFeature)) + if (base::FeatureList::IsEnabled(features::kBackspaceGoesBackFeature)) GoBack(browser_, disposition); else browser_->window()->MaybeShowNewBackShortcutBubble(false); @@ -328,7 +325,7 @@ GoBack(browser_, disposition); break; case IDC_BACKSPACE_FORWARD: - if (base::FeatureList::IsEnabled(kBackspaceGoesBackFeature)) + if (base::FeatureList::IsEnabled(features::kBackspaceGoesBackFeature)) GoForward(browser_, disposition); else browser_->window()->MaybeShowNewBackShortcutBubble(true);
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm index 46bf2f6e..051bd0b 100644 --- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm +++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
@@ -284,7 +284,7 @@ // Cancel button. base::scoped_nsobject<NSButton> cancelButton([SaveCardBubbleViewCocoa - makeButton:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY)]); + makeButton:l10n_util::GetNSString(IDS_NO_THANKS)]); [cancelButton setTarget:self]; [cancelButton setAction:@selector(onCancelButton:)]; [cancelButton setKeyEquivalent:@"\e"];
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index 17f832f..27594c0 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -20,22 +20,19 @@ #include "ash/wm/window_state_aura.h" #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" +#include "services/ui/public/cpp/property_type_converters.h" +#include "services/ui/public/cpp/window.h" +#include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/mus/mus_util.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/base/hit_test.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/gfx/skia_util.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/widget/widget.h" -#if defined(MOJO_SHELL_CLIENT) -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" -#include "ui/aura/mus/mus_util.h" -#include "ui/gfx/skia_util.h" -#endif - using extensions::AppWindow; namespace { @@ -148,11 +145,9 @@ ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), ash::kShellWindowId_ImeWindowParentContainer); } -#if defined(MOJO_SHELL_CLIENT) init_params->mus_properties [ui::mojom::WindowManager::kRemoveStandardFrame_Property] = mojo::ConvertTo<std::vector<uint8_t>>(init_params->remove_standard_frame); -#endif } void ChromeNativeAppWindowViewsAuraAsh::OnBeforePanelWidgetInit( @@ -330,7 +325,6 @@ const std::vector<extensions::DraggableRegion>& regions) { ChromeNativeAppWindowViewsAura::UpdateDraggableRegions(regions); -#if defined(MOJO_SHELL_CLIENT) SkRegion* draggable_region = GetDraggableRegion(); // Set the NativeAppWindow's draggable region on the mus window. if (draggable_region && !draggable_region->isEmpty() && widget() && @@ -349,5 +343,4 @@ GetMusWindow(widget()->GetNativeWindow()) ->SetClientArea(insets, std::move(additional_client_regions)); } -#endif }
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc index 09c8f60..40e964d 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -119,7 +119,7 @@ ui::DialogButton button) const { return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT - : IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY); + : IDS_NO_THANKS); } bool SaveCardBubbleViews::ShouldDefaultButtonBeBlue() const {
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc index d89ed32c..e8e44241 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -9,19 +9,16 @@ #include "components/constrained_window/constrained_window_views.h" #if defined(USE_AURA) -#include "ui/display/screen.h" -#include "ui/views/widget/desktop_aura/desktop_screen.h" -#include "ui/wm/core/wm_state.h" -#endif - -#if defined(USE_AURA) && defined(MOJO_SHELL_CLIENT) #include "content/public/common/mojo_shell_connection.h" #include "services/shell/public/cpp/connector.h" #include "services/shell/runner/common/client_util.h" #include "services/ui/public/cpp/input_devices/input_device_client.h" #include "services/ui/public/interfaces/input_devices/input_device_server.mojom.h" +#include "ui/display/screen.h" #include "ui/views/mus/window_manager_connection.h" -#endif +#include "ui/views/widget/desktop_aura/desktop_screen.h" +#include "ui/wm/core/wm_state.h" +#endif // defined(USE_AURA) ChromeBrowserMainExtraPartsViews::ChromeBrowserMainExtraPartsViews() { } @@ -50,7 +47,7 @@ } void ChromeBrowserMainExtraPartsViews::PreProfileInit() { -#if defined(USE_AURA) && defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) content::MojoShellConnection* mojo_shell_connection = content::MojoShellConnection::GetForProcess(); if (mojo_shell_connection && shell::ShellIsRemote()) { @@ -64,6 +61,6 @@ mojo_shell_connection->GetConnector(), mojo_shell_connection->GetIdentity()); } -#endif // defined(USE_AURA) && defined(MOJO_SHELL_CLIENT) +#endif // defined(USE_AURA) ChromeBrowserMainExtraParts::PreProfileInit(); }
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h index fa6c657..11785f5b 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h
@@ -40,8 +40,6 @@ #if defined(USE_AURA) std::unique_ptr<wm::WMState> wm_state_; -#endif -#if defined(USE_AURA) && defined(MOJO_SHELL_CLIENT) std::unique_ptr<views::WindowManagerConnection> window_manager_connection_; // Subscribes to updates about input-devices.
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_views.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_views.cc index d757f26..e83af33 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_views.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_views.cc
@@ -5,7 +5,7 @@ #include "build/build_config.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.h" #include "services/shell/runner/common/client_util.h" #endif @@ -27,7 +27,7 @@ BrowserNonClientFrameView* CreateBrowserNonClientFrameView( BrowserFrame* frame, BrowserView* browser_view) { -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) if (shell::ShellIsRemote()) { BrowserNonClientFrameViewMus* frame_view = new BrowserNonClientFrameViewMus(frame, browser_view);
diff --git a/chrome/browser/ui/views/frame/native_browser_frame_factory_auralinux.cc b/chrome/browser/ui/views/frame/native_browser_frame_factory_auralinux.cc index cd956bc..7515c03 100644 --- a/chrome/browser/ui/views/frame/native_browser_frame_factory_auralinux.cc +++ b/chrome/browser/ui/views/frame/native_browser_frame_factory_auralinux.cc
@@ -4,19 +4,14 @@ #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" -#include "chrome/browser/ui/views/frame/desktop_browser_frame_auralinux.h" - -#if defined(MOJO_SHELL_CLIENT) #include "chrome/browser/ui/views/frame/browser_frame_mus.h" +#include "chrome/browser/ui/views/frame/desktop_browser_frame_auralinux.h" #include "services/shell/runner/common/client_util.h" -#endif NativeBrowserFrame* NativeBrowserFrameFactory::Create( BrowserFrame* browser_frame, BrowserView* browser_view) { -#if defined(MOJO_SHELL_CLIENT) if (shell::ShellIsRemote()) return new BrowserFrameMus(browser_frame, browser_view); -#endif return new DesktopBrowserFrameAuraLinux(browser_frame, browser_view); }
diff --git a/chrome/browser/ui/views/frame/native_browser_frame_factory_aurawin.cc b/chrome/browser/ui/views/frame/native_browser_frame_factory_aurawin.cc index 24d5620..c29e013 100644 --- a/chrome/browser/ui/views/frame/native_browser_frame_factory_aurawin.cc +++ b/chrome/browser/ui/views/frame/native_browser_frame_factory_aurawin.cc
@@ -4,20 +4,14 @@ #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" -#include "ash/shell.h" -#include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h" - -#if defined(MOJO_SHELL_CLIENT) #include "chrome/browser/ui/views/frame/browser_frame_mus.h" +#include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h" #include "services/shell/runner/common/client_util.h" -#endif NativeBrowserFrame* NativeBrowserFrameFactory::Create( BrowserFrame* browser_frame, BrowserView* browser_view) { -#if defined(MOJO_SHELL_CLIENT) if (shell::ShellIsRemote()) return new BrowserFrameMus(browser_frame, browser_view); -#endif return new DesktopBrowserFrameAura(browser_frame, browser_view); }
diff --git a/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc b/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc index 5bbe5d5..f9b95c7 100644 --- a/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc +++ b/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc
@@ -5,18 +5,13 @@ #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" #include "chrome/browser/ui/views/frame/browser_frame_ash.h" - -#if defined(MOJO_SHELL_CLIENT) #include "chrome/browser/ui/views/frame/browser_frame_mus.h" #include "services/shell/runner/common/client_util.h" -#endif NativeBrowserFrame* NativeBrowserFrameFactory::Create( BrowserFrame* browser_frame, BrowserView* browser_view) { -#if defined(MOJO_SHELL_CLIENT) if (shell::ShellIsRemote()) return new BrowserFrameMus(browser_frame, browser_view); -#endif return new BrowserFrameAsh(browser_frame, browser_view); }
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc index e6fd0ac..036f791a 100644 --- a/chrome/browser/ui/views/status_bubble_views.cc +++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -43,7 +43,7 @@ #include "ash/wm/window_state_aura.h" #endif -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" #endif @@ -597,17 +597,17 @@ views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); #if defined(OS_WIN) - // On Windows use the software compositor to ensure that we don't block - // the UI thread blocking issue during command buffer creation. We can - // revert this change once http://crbug.com/125248 is fixed. - params.force_software_compositing = true; + // On Windows use the software compositor to ensure that we don't block + // the UI thread blocking issue during command buffer creation. We can + // revert this change once http://crbug.com/125248 is fixed. + params.force_software_compositing = true; #endif params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.accept_events = false; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.parent = frame->GetNativeView(); params.context = frame->GetNativeWindow(); -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) params.mus_properties [ui::mojom::WindowManager::kWindowIgnoredByShelf_Property] = mojo::ConvertTo<std::vector<uint8_t>>(true);
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 97e4fc3..10261b5 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -49,15 +49,12 @@ #endif #if defined(USE_AURA) -#include "ui/aura/env.h" -#include "ui/aura/window.h" -#include "ui/wm/core/window_modality_controller.h" -#endif - -#if defined(MOJO_SHELL_CLIENT) #include "chrome/browser/ui/views/tabs/window_finder_mus.h" #include "content/public/common/mojo_shell_connection.h" #include "services/shell/runner/common/client_util.h" +#include "ui/aura/env.h" +#include "ui/aura/window.h" +#include "ui/wm/core/window_modality_controller.h" #endif using base::UserMetricsAction; @@ -231,7 +228,7 @@ weak_factory_(this) { instance_ = this; -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) content::MojoShellConnection* mojo_shell_connection = content::MojoShellConnection::GetForProcess(); if (mojo_shell_connection && shell::ShellIsRemote())
diff --git a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc index 412a39a..60e40df 100644 --- a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc +++ b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
@@ -11,11 +11,13 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" @@ -307,6 +309,9 @@ ash::DisplayManager* display_manager = shell->display_manager(); source->AddBoolean("keyboardOverlayIsDisplayUIScalingEnabled", display_manager->IsDisplayUIScalingEnabled()); + source->AddBoolean( + "backspaceGoesBackFeatureEnabled", + base::FeatureList::IsEnabled(features::kBackspaceGoesBackFeature)); source->SetJsonPath("strings.js"); source->AddResourcePath("keyboard_overlay.js", IDR_KEYBOARD_OVERLAY_JS); source->SetDefaultResource(IDR_KEYBOARD_OVERLAY_HTML);
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc new file mode 100644 index 0000000..b90787d9 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -0,0 +1,46 @@ +// 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. + +#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "chrome/browser/extensions/extension_tab_util.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/common/extensions/extension_constants.h" +#include "content/public/browser/web_ui.h" +#include "extensions/browser/extension_registry.h" + +namespace chromeos { +namespace settings { + +AccessibilityHandler::AccessibilityHandler(content::WebUI* webui) + : profile_(Profile::FromWebUI(webui)) { +} + +AccessibilityHandler::~AccessibilityHandler() {} + +void AccessibilityHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "showChromeVoxSettings", + base::Bind(&AccessibilityHandler::HandleShowChromeVoxSettings, + base::Unretained(this))); +} + +void AccessibilityHandler::HandleShowChromeVoxSettings( + const base::ListValue* args) { + const extensions::Extension* chromevox_extension = + extensions::ExtensionRegistry::Get(profile_)->GetExtensionById( + extension_misc::kChromeVoxExtensionId, + extensions::ExtensionRegistry::ENABLED); + if (!chromevox_extension) + return; + extensions::ExtensionTabUtil::OpenOptionsPage( + chromevox_extension, + chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); +} + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h new file mode 100644 index 0000000..33e1822 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
@@ -0,0 +1,46 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + +namespace base { +class ListValue; +} + +namespace content { +class WebUI; +} + +class Profile; + +namespace chromeos { +namespace settings { + +class AccessibilityHandler : public ::settings::SettingsPageUIHandler { + public: + explicit AccessibilityHandler(content::WebUI* webui); + ~AccessibilityHandler() override; + + // SettingsPageUIHandler implementation. + void RegisterMessages() override; + void OnJavascriptAllowed() override {} + void OnJavascriptDisallowed() override {} + + private: + // Callback for the "showChromeVoxSettings" message. + void HandleShowChromeVoxSettings(const base::ListValue* args); + + Profile* profile_; // Weak pointer. + + DISALLOW_COPY_AND_ASSIGN(AccessibilityHandler); +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc new file mode 100644 index 0000000..c37eec2 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -0,0 +1,102 @@ +// 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. + +#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h" + +#include <memory> + +#include "base/bind.h" +#include "base/memory/ref_counted.h" +#include "base/values.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_ui.h" +#include "printing/backend/print_backend.h" + +namespace { + +// TODO(xdai): Retrieve the CUPS printers list from user preference instead. +void EnumeratePrintersOnBlockingPoolThread(base::ListValue* printers) { + scoped_refptr<printing::PrintBackend> print_backend( + printing::PrintBackend::CreateInstance(nullptr)); + + printing::PrinterList printer_list; + print_backend->EnumeratePrinters(&printer_list); + + for (const printing::PrinterBasicInfo& printer : printer_list) { + std::unique_ptr<base::DictionaryValue> printer_info( + new base::DictionaryValue); + printer_info->SetString("printerName", printer.printer_name); + printer_info->SetString("printerDescription", printer.printer_description); + for (const auto opt_it : printer.options) { + // TODO(xdai): Get "printerAddress" and "printerProtocol" from URI. + if (opt_it.first == "printer-make-and-model") + printer_info->SetString("printerModel", opt_it.second); + } + printers->Append(std::move(printer_info)); + } +} + +} // namespace + +namespace chromeos { +namespace settings { + +CupsPrintersHandler::CupsPrintersHandler() : weak_factory_(this) {} + +CupsPrintersHandler::~CupsPrintersHandler() {} + +void CupsPrintersHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "getCupsPrintersList", + base::Bind(&CupsPrintersHandler::HandleGetCupsPrintersList, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "updateCupsPrinter", + base::Bind(&CupsPrintersHandler::HandleUpdateCupsPrinter, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "removeCupsPrinter", + base::Bind(&CupsPrintersHandler::HandleRemoveCupsPrinter, + base::Unretained(this))); +} + +// TODO(xdai): Retrieve the CUPS printer list from user preference instead after +// the CL https://codereview.chromium.org/2161933003/ is landed. +void CupsPrintersHandler::HandleGetCupsPrintersList( + const base::ListValue* args) { + AllowJavascript(); + + CHECK_EQ(1U, args->GetSize()); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + + base::ListValue* printers_list = new base::ListValue; + content::BrowserThread::PostBlockingPoolTaskAndReply( + FROM_HERE, base::Bind(&EnumeratePrintersOnBlockingPoolThread, + base::Unretained(printers_list)), + base::Bind(&CupsPrintersHandler::OnGetCupsPrintersList, + weak_factory_.GetWeakPtr(), callback_id, + base::Owned(printers_list))); +} + +void CupsPrintersHandler::OnGetCupsPrintersList( + const std::string callback_id, + base::ListValue* printers_list) { + std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue()); + response->Set("printerList", printers_list->DeepCopy()); + ResolveJavascriptCallback(base::StringValue(callback_id), *response); +} + +void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) { + // TODO(xdai): Implement it after https://codereview.chromium.org/2161933003/ + // is landed. +} + +void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) { + // TODO(xdai): Implement it after https://codereview.chromium.org/2161933003/ + // is landed. +} + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h new file mode 100644 index 0000000..375ae715 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -0,0 +1,46 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_ + +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + +namespace base { +class ListValue; +} // namespace base + +namespace chromeos { +namespace settings { + +// Chrome OS CUPS printing settings page UI handler. +class CupsPrintersHandler : public ::settings::SettingsPageUIHandler { + public: + CupsPrintersHandler(); + ~CupsPrintersHandler() override; + + // SettingsPageUIHandler overrides: + void RegisterMessages() override; + void OnJavascriptAllowed() override{}; + void OnJavascriptDisallowed() override{}; + + private: + // Gets all CUPS printers and return it to WebUI. + void HandleGetCupsPrintersList(const base::ListValue* args); + void OnGetCupsPrintersList(const std::string callback_id, + base::ListValue* printers_list); + + void HandleUpdateCupsPrinter(const base::ListValue* args); + void HandleRemoveCupsPrinter(const base::ListValue* args); + + base::WeakPtrFactory<CupsPrintersHandler> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(CupsPrintersHandler); +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index b7ee8352..111a1258f 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -113,10 +113,44 @@ IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION}, {"focusHighlightLabel", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION}, - {"selectToSpeakLabel", + {"selectToSpeakTitle", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE}, + {"selectToSpeakDescription", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION}, {"switchAccessLabel", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION}, + {"manageAccessibilityFeatures", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES}, + {"textToSpeechHeading", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING}, + {"displayHeading", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DISPLAY_HEADING}, + {"displaySettingsTitle", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_TITLE}, + {"displaySettingsDescription", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_DESCRIPTION}, + {"appearanceSettingsTitle", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_TITLE}, + {"appearanceSettingsDescription", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_DESCRIPTION}, + {"keyboardHeading", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_KEYBOARD_HEADING}, + {"keyboardSettingsTitle", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_TITLE}, + {"keyboardSettingsDescription", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_DESCRIPTION}, + {"mouseAndTouchpadHeading", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MOUSE_AND_TOUCHPAD_HEADING}, + {"mouseSettingsTitle", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_TITLE}, + {"mouseSettingsDescription", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_DESCRIPTION}, + {"audioHeading", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUDIO_HEADING}, + {"additionalFeaturesTitle", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_TITLE}, + {"additionalFeaturesDescription", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_DESCRIPTION}, #endif }; AddLocalizedStringsBulk(html_source, localized_strings, @@ -944,6 +978,16 @@ {"cloudPrintersTitle", IDS_SETTINGS_PRINTING_CLOUD_PRINTERS}, #if defined(OS_CHROMEOS) {"cupsPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTERS}, + {"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER}, + {"cupsPrinterDetails", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_DETAILS}, + {"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE}, + {"searchLabel", IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL}, + {"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE}, + {"printerName", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME}, + {"printerModel", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL}, + {"addPrinterTitle", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_TITLE}, + {"cancelButtonText", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_CANCEL}, + {"addPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_ADD}, #endif }; AddLocalizedStringsBulk(html_source, localized_strings, @@ -1116,8 +1160,6 @@ {"siteSettingsCategoryNotifications", IDS_SETTINGS_SITE_SETTINGS_NOTIFICATIONS}, {"siteSettingsCategoryPopups", IDS_SETTINGS_SITE_SETTINGS_POPUPS}, - {"siteSettingsSiteDetailsPageTitle", - IDS_SETTINGS_SITE_SETTINGS_SITE_DETAILS}, {"siteSettingsAllSites", IDS_SETTINGS_SITE_SETTINGS_ALL_SITES}, {"siteSettingsAutomaticDownloads", IDS_SETTINGS_SITE_SETTINGS_AUTOMATIC_DOWNLOADS},
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 7f90eb2..256485f4 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -38,7 +38,9 @@ #if defined(OS_CHROMEOS) #include "ash/common/system/chromeos/palette/palette_utils.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" +#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h" @@ -83,7 +85,10 @@ AddSettingsPageUIHandler(new StartupPagesHandler(web_ui)); #if defined(OS_CHROMEOS) + AddSettingsPageUIHandler(new chromeos::settings::AccessibilityHandler( + web_ui)); AddSettingsPageUIHandler(new chromeos::settings::ChangePictureHandler()); + AddSettingsPageUIHandler(new chromeos::settings::CupsPrintersHandler()); AddSettingsPageUIHandler(new chromeos::settings::KeyboardHandler(web_ui)); AddSettingsPageUIHandler(new chromeos::settings::PointerHandler()); #else
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 450c826..0de83b5 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -2120,6 +2120,7 @@ 'android/java/src/org/chromium/chrome/browser/WebContentsFactory.java', 'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java', 'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java', + 'android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java', 'android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java', 'android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java', 'android/java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBarDelegate.java',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 6908eef..6e6c0ad3 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -429,6 +429,8 @@ 'browser/ui/android/context_menu_helper.h', 'browser/ui/android/infobars/app_banner_infobar_android.cc', 'browser/ui/android/infobars/app_banner_infobar_android.h', + 'browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc', + 'browser/ui/android/infobars/autofill_credit_card_filling_infobar.h', 'browser/ui/android/infobars/autofill_save_card_infobar.cc', 'browser/ui/android/infobars/autofill_save_card_infobar.h', 'browser/ui/android/infobars/confirm_infobar.cc', @@ -2043,8 +2045,12 @@ 'browser/ui/webui/settings/appearance_handler.h', 'browser/ui/webui/settings/browser_lifetime_handler.cc', 'browser/ui/webui/settings/browser_lifetime_handler.h', + 'browser/ui/webui/settings/chromeos/accessibility_handler.cc', + 'browser/ui/webui/settings/chromeos/accessibility_handler.h', 'browser/ui/webui/settings/chromeos/change_picture_handler.cc', 'browser/ui/webui/settings/chromeos/change_picture_handler.h', + 'browser/ui/webui/settings/chromeos/cups_printers_handler.cc', + 'browser/ui/webui/settings/chromeos/cups_printers_handler.h', 'browser/ui/webui/settings/chromeos/device_keyboard_handler.cc', 'browser/ui/webui/settings/chromeos/device_keyboard_handler.h', 'browser/ui/webui/settings/chromeos/device_pointer_handler.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index e6d7f1d..0190250a 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -359,6 +359,7 @@ '../tools/json_schema_compiler/test/simple_api_unittest.cc', ], 'chrome_unit_tests_android_sources': [ + 'browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc', 'browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc', 'browser/password_manager/account_chooser_dialog_android_unittest.cc', 'browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc',
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index c8317f2..eb692fcb 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -28,6 +28,12 @@ "BackgroundModeAllowRestart", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_WIN) || defined(OS_LINUX) +// Enables the Backspace key to navigate back in the browser, as well as +// Shift+Backspace to navigate forward. +const base::Feature kBackspaceGoesBackFeature { + "BackspaceGoesBack", base::FEATURE_DISABLED_BY_DEFAULT +}; + // Experiment to disable small cross-origin content. (http://crbug.com/608886) const base::Feature kBlockSmallContent{"BlockSmallPluginContent", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 3471c2d86..aa7ebdc 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -27,6 +27,8 @@ extern const base::Feature kBackgroundModeAllowRestart; #endif // defined(OS_WIN) || defined(OS_LINUX) +extern const base::Feature kBackspaceGoesBackFeature; + extern const base::Feature kBlockSmallContent; extern const base::Feature kBrowserHangFixesExperiment;
diff --git a/chrome/installer/mini_installer/BUILD.gn b/chrome/installer/mini_installer/BUILD.gn index 530e68c..1e269aa 100644 --- a/chrome/installer/mini_installer/BUILD.gn +++ b/chrome/installer/mini_installer/BUILD.gn
@@ -233,6 +233,7 @@ configs += [ ":mini_installer_compiler_flags", "//build/config/compiler:optimize_no_wpo", + "//build/config/sanitizers:link_executable", "//build/config/win:sdk_link", "//build/config/win:windowed", ]
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 14d3200f..1e99e3a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -900,8 +900,6 @@ "//chrome/app:mojo_manifests", "//mash/session", ] - - defines = [ "MOJO_SHELL_CLIENT" ] } }
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 4a276973..ce1ad49 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -63,6 +63,7 @@ "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/android/webapk/libs/runtime_library:runtime_library_for_tests_java", + "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", "//components/bookmarks/common/android:bookmarks_java", "//components/invalidation/impl:java", "//components/location/android:location_java",
diff --git a/chrome/test/base/browser_tests_main.cc b/chrome/test/base/browser_tests_main.cc index cd12f3b..614091d 100644 --- a/chrome/test/base/browser_tests_main.cc +++ b/chrome/test/base/browser_tests_main.cc
@@ -8,12 +8,12 @@ #include "chrome/test/base/chrome_test_launcher.h" #include "chrome/test/base/chrome_test_suite.h" -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) #include "chrome/test/base/mash_browser_tests_main.h" #endif int main(int argc, char** argv) { -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) int exit_code = 0; if (RunMashBrowserTests(argc, argv, &exit_code)) return exit_code;
diff --git a/chrome/test/data/extensions/theme/manifest.json b/chrome/test/data/extensions/theme/manifest.json index ce99ab9c..48500b81 100644 --- a/chrome/test/data/extensions/theme/manifest.json +++ b/chrome/test/data/extensions/theme/manifest.json
@@ -1,5 +1,6 @@ { "name": "camo theme", + "manifest_version": 2, "theme": { "colors": { "frame": [ 71, 105, 91 ],
diff --git a/chrome/test/data/webui/settings/controlled_button_tests.js b/chrome/test/data/webui/settings/controlled_button_tests.js new file mode 100644 index 0000000..edde16b --- /dev/null +++ b/chrome/test/data/webui/settings/controlled_button_tests.js
@@ -0,0 +1,38 @@ +// 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. + +suite('controlled button', function() { + /** @type {ControlledButtonElement} */ + var button; + + /** @type {!chrome.settingsPrivate.PrefObject} */ + var pref = { + key: 'test', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: true + }; + + setup(function() { + PolymerTest.clearBody(); + button = document.createElement('controlled-button'); + button.pref = pref; + document.body.appendChild(button); + }); + + test('disables when pref is managed', function() { + button.set('pref.policyEnforcement', + chrome.settingsPrivate.PolicyEnforcement.ENFORCED); + Polymer.dom.flush(); + assertTrue(button.$$('paper-button').disabled); + + var indicator = button.$$('cr-policy-pref-indicator'); + assertTrue(!!indicator); + assertGT(indicator.clientHeight, 0); + + button.set('pref.policyEnforcement', undefined); + Polymer.dom.flush(); + assertFalse(button.$$('paper-button').disabled); + assertEquals(0, indicator.clientHeight); + }); +});
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 26f76c0..926d7b8 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -621,28 +621,6 @@ * @constructor * @extends {CrSettingsBrowserTest} */ -function CrSettingsRadioGroupTest() {} - -CrSettingsRadioGroupTest.prototype = { - __proto__: CrSettingsBrowserTest.prototype, - - /** @override */ - browsePreload: 'chrome://md-settings/controls/settings_radio_group.html', - - /** @override */ - extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'radio_group_tests.js', - ]), -}; - -TEST_F('CrSettingsRadioGroupTest', 'All', function() { - mocha.run(); -}); - -/** - * @constructor - * @extends {CrSettingsBrowserTest} - */ function CrSettingsRouteTest() {} CrSettingsRouteTest.prototype = { @@ -663,7 +641,7 @@ /** * @constructor * @extends {SettingsPageBrowserTest} -*/ + */ function CrSettingsNonExistentRouteTest() {} CrSettingsNonExistentRouteTest.prototype = { @@ -724,3 +702,48 @@ }); mocha.run(); }); + +/** + * Test fixture for chrome/browser/resources/settings/settings_main/. + * @constructor + * @extends {CrSettingsBrowserTest} +*/ +function CrSettingsMainPageTest() {} + +CrSettingsMainPageTest.prototype = { + __proto__: CrSettingsBrowserTest.prototype, + + /** @override */ + browsePreload: 'chrome://md-settings/settings_main/settings_main.html', + + /** @override */ + extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + 'settings_main_test.js', + ]), +}; + +TEST_F('CrSettingsMainPageTest', 'All', function() { + settings_main_page.registerTests(); + mocha.run(); +}); + +/** + * @constructor + * @extends {CrSettingsBrowserTest} + */ +function CrControlledButtonTest() {} + +CrControlledButtonTest.prototype = { + __proto__: CrSettingsBrowserTest.prototype, + + /** @override */ + browsePreload: 'chrome://md-settings/controls/controlled_button.html', + + extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + 'controlled_button_tests.js', + ]), +}; + +TEST_F('CrControlledButtonTest', 'All', function() { + mocha.run(); +});
diff --git a/chrome/test/data/webui/settings/radio_group_tests.js b/chrome/test/data/webui/settings/radio_group_tests.js deleted file mode 100644 index 5c8083f..0000000 --- a/chrome/test/data/webui/settings/radio_group_tests.js +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -suite('SettingsRadioGroup', function() { - /** - * Checkbox created before each test. - * @type {SettingsRadioGroup} - */ - var testElement; - - /** - * Pref value used in tests, should reflect checkbox 'checked' attribute. - * @type {PrefObject} - */ - var pref = { - key: 'test', - type: chrome.settingsPrivate.PrefType.BOOLEAN, - value: true - }; - - suiteSetup(function() { - return PolymerTest.importHtml('chrome://resources/polymer/v1_0/' + - 'paper-radio-button/paper-radio-button.html'); - }); - - setup(function() { - PolymerTest.clearBody(); - testElement = document.createElement('settings-radio-group'); - testElement.set('pref', pref); - document.body.appendChild(testElement); - }); - - test('disables paper-radio-buttons when managed', function() { - testElement.appendChild(document.createElement('paper-radio-button')); - - assertEquals('PAPER-RADIO-BUTTON', testElement.firstChild.tagName); - assertFalse(testElement.firstChild.disabled); - - testElement.set('pref.policyEnforcement', - chrome.settingsPrivate.PolicyEnforcement.ENFORCED); - assertTrue(testElement.firstChild.disabled); - - testElement.set('pref.policyEnforcement', undefined); - assertFalse(testElement.firstChild.disabled); - }); -});
diff --git a/chrome/test/data/webui/settings/settings_main_test.js b/chrome/test/data/webui/settings/settings_main_test.js new file mode 100644 index 0000000..e058e921 --- /dev/null +++ b/chrome/test/data/webui/settings/settings_main_test.js
@@ -0,0 +1,104 @@ +// 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('settings_main_page', function() { + /** + * @implements {SearchManager} + */ + var TestSearchManager = function() { + /** @private {boolean} */ + this.matchesFound_ = true; + + /** @private {?settings.SearchRequest} */ + this.searchRequest_ = null; + } + + TestSearchManager.prototype = { + /** + * @param {boolean} matchesFound + */ + setMatchesFound: function(matchesFound) { + this.matchesFound_ = matchesFound; + }, + + /** @override */ + search: function(text, page) { + if (this.searchRequest_ == null || !this.searchRequest_.isSame(text)) { + this.searchRequest_ = new settings.SearchRequest(text); + this.searchRequest_.finished = true; + this.searchRequest_.updateMatches(this.matchesFound_); + this.searchRequest_.resolver.resolve(this.searchRequest_); + } + return this.searchRequest_.resolver.promise; + }, + }; + + function registerTests() { + var settingsPrefs = null; + + suiteSetup(function() { + settingsPrefs = document.createElement('settings-prefs'); + return CrSettingsPrefs.initialized; + }); + + suite('SearchTests', function() { + /** @type {?TestSearchManager} */ + var searchManager = null; + + /** @type {?SettingsMainElement} */ + var settingsMain = null; + + // TODO(tommycli): Remove once settings.navigateTo is no longer a stub. + settings.navigateTo = function(route) { + settingsMain.currentRoute = route; + }; + + setup(function() { + searchManager = new TestSearchManager(); + settings.setSearchManagerForTesting(searchManager); + PolymerTest.clearBody(); + settingsMain = document.createElement('settings-main'); + settingsMain.prefs = settingsPrefs.prefs; + settingsMain.toolbarSpinnerActive = false; + document.body.appendChild(settingsMain); + }); + + teardown(function() { settingsMain.remove(); }); + + test('no results page shows and hides', function() { + var noSearchResults = settingsMain.$.noSearchResults; + assertTrue(!!noSearchResults); + assertTrue(noSearchResults.hidden); + + searchManager.setMatchesFound(false); + return settingsMain.searchContents('Query1').then(function() { + assertFalse(noSearchResults.hidden); + + searchManager.setMatchesFound(true); + return settingsMain.searchContents('Query2'); + }).then(function() { + assertTrue(noSearchResults.hidden); + }); + }); + + // Ensure that when the user clears the search box, the "no results" page + // is hidden. + test('no results page hides on clear', function() { + var noSearchResults = settingsMain.$.noSearchResults; + assertTrue(!!noSearchResults); + assertTrue(noSearchResults.hidden); + searchManager.setMatchesFound(false); + + // Clearing the search box is effectively a search for the empty string. + return settingsMain.searchContents('').then(function() { + assertTrue(noSearchResults.hidden); + }); + }); + }); + } + + return { + registerTests: registerTests, + }; +});
diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index 827e599..f1783d8 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg
@@ -521,11 +521,6 @@ 'buildtype': ['dev', 'official'], 'optional': ['dev', 'official'], }, - { - 'filename': 'sync_unit_tests.exe', - 'buildtype': ['official'], - 'optional': ['official'], - }, # Installer files (official build only): { 'filename': 'setup.exe',
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index 6b817bcb..8e1c18e 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -40,7 +40,6 @@ "//ppapi:ppapi_unittests", "//sandbox/linux:sandbox_linux_unittests", "//sql:sql_unittests", - "//components/sync:sync_unit_tests", "//third_party/cacheinvalidation:cacheinvalidation_unittests", "//ui/base:ui_base_unittests", ] @@ -85,7 +84,6 @@ # SoundsManagerTest.Play # Disable AudioStreamHandlerTest.ConsecutivePlayRequests (b/16539293) "media_unittests --gtest_filter=-AudioOutputControllerTest.PlayDivertSwitchDeviceRevertClose:AudioOutputControllerTest.PlaySwitchDeviceClose:AudioStreamHandlerTest.Play:AudioStreamHandlerTest.ConsecutivePlayRequests:PipelineIntegrationTest.BasicPlayback_MediaSource_VP9_WebM:PipelineIntegrationTest.BasicPlayback_VideoOnly_VP9_WebM:PipelineIntegrationTest.BasicPlayback_VP9*:PipelineIntegrationTest.P444_VP9_WebM:PipelineIntegrationTest.BasicPlayback_VP8A*:OpusAudioDecoderTest/AudioDecoderTest.ProduceAudioSamples/0:SoundsManagerTest.Play", - "sync_unit_tests --gtest_filter=-SyncHttpBridgeTest.*", # DoAppendUTF8Invalid fails because of dcheck_always_on flag in Eng builds "url_unittests --gtest_filter=-URLCanonTest.DoAppendUTF8Invalid",
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index 54eb36a..ab77bca 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -14,11 +14,6 @@ # Denotes the type of Cast product. This is #defined as CAST_PRODUCT_TYPE in # version.h. This is an integer in the range [0-4]. cast_product_type = 0 - - # If true, IS_CAST_DEBUG_BUILD() will evaluate to 1 in version.h. Otherwise, - # it will evaluate to 0. Overriding this when is_debug=false is useful for - # doing engineering builds. - cast_is_debug = is_debug } assert(cast_product_type >= 0 && cast_product_type <= 4)
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni index b327f79d..9e5a6ba 100644 --- a/chromecast/chromecast.gni +++ b/chromecast/chromecast.gni
@@ -17,6 +17,11 @@ # than any value the builder may assign to prevent attempted automatic updates # when the default value is used. cast_build_incremental = "999999" + + # If true, IS_CAST_DEBUG_BUILD() will evaluate to 1 in version.h. Otherwise, + # it will evaluate to 0. Overriding this when is_debug=false is useful for + # doing engineering builds. + cast_is_debug = is_debug } declare_args() {
diff --git a/chromecast/chromecast_tests.gypi b/chromecast/chromecast_tests.gypi index 68e6d47..cac841a 100644 --- a/chromecast/chromecast_tests.gypi +++ b/chromecast/chromecast_tests.gypi
@@ -110,7 +110,6 @@ '../ppapi/ppapi_internal.gyp:ppapi_unittests', '../sandbox/sandbox.gyp:sandbox_linux_unittests', '../sql/sql.gyp:sql_unittests', - '../components/sync.gyp:sync_unit_tests', '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests', '../ui/base/ui_base_tests.gyp:ui_base_unittests', '../url/url.gyp:url_unittests', @@ -153,7 +152,6 @@ # SoundsManagerTest.Play # Disable AudioStreamHandlerTest.ConsecutivePlayRequests (b/16539293) 'media_unittests --gtest_filter=-AudioOutputControllerTest.PlayDivertSwitchDeviceRevertClose:AudioOutputControllerTest.PlaySwitchDeviceClose:AudioStreamHandlerTest.Play:AudioStreamHandlerTest.ConsecutivePlayRequests:PipelineIntegrationTest.BasicPlayback_MediaSource_VP9_WebM:PipelineIntegrationTest.BasicPlayback_VideoOnly_VP9_WebM:PipelineIntegrationTest.BasicPlayback_VP9*:PipelineIntegrationTest.P444_VP9_WebM:PipelineIntegrationTest.BasicPlayback_VP8A*:OpusAudioDecoderTest/AudioDecoderTest.ProduceAudioSamples/0:SoundsManagerTest.Play', - 'sync_unit_tests --gtest_filter=-SyncHttpBridgeTest.*', # DoAppendUTF8Invalid fails because of dcheck_always_on flag in Eng builds 'url_unittests --gtest_filter=-URLCanonTest.DoAppendUTF8Invalid', ], @@ -262,7 +260,6 @@ '../media/midi/midi.gyp:midi_unittests_apk', '../net/net.gyp:net_unittests_apk', '../sql/sql.gyp:sql_unittests_apk', - '../components/sync.gyp:sync_unit_tests_apk', '../ui/events/events_unittests.gyp:events_unittests_apk', '../ui/gfx/gfx_tests.gyp:gfx_unittests_apk', ],
diff --git a/chromecast/media/cma/base/demuxer_stream_for_test.cc b/chromecast/media/cma/base/demuxer_stream_for_test.cc index 3115dcf0..bafaa8d7 100644 --- a/chromecast/media/cma/base/demuxer_stream_for_test.cc +++ b/chromecast/media/cma/base/demuxer_stream_for_test.cc
@@ -86,7 +86,8 @@ NOTIMPLEMENTED(); } -void DemuxerStreamForTest::SetStreamRestartedCB(const StreamRestartedCB& cb) { +void DemuxerStreamForTest::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { NOTIMPLEMENTED(); }
diff --git a/chromecast/media/cma/base/demuxer_stream_for_test.h b/chromecast/media/cma/base/demuxer_stream_for_test.h index c3cc922c..aed460c 100644 --- a/chromecast/media/cma/base/demuxer_stream_for_test.h +++ b/chromecast/media/cma/base/demuxer_stream_for_test.h
@@ -49,7 +49,7 @@ ::media::VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta time) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; bool has_pending_read() const { return has_pending_read_; }
diff --git a/components/BUILD.gn b/components/BUILD.gn index e69e03926..609f3d3 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -127,6 +127,7 @@ "//components/subresource_filter/core/common:unit_tests", "//components/suggestions:unit_tests", "//components/supervised_user_error_page:unit_tests", + "//components/sync:unit_tests", "//components/sync_bookmarks:unit_tests", "//components/sync_driver:unit_tests", "//components/sync_sessions:unit_tests",
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index fb45068..5c20c56 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -176,6 +176,8 @@ "test/fake_arc_bridge_instance.h", "test/fake_arc_bridge_service.cc", "test/fake_arc_bridge_service.h", + "test/fake_bluetooth_instance.cc", + "test/fake_bluetooth_instance.h", "test/fake_notifications_instance.cc", "test/fake_notifications_instance.h", "test/fake_policy_instance.cc", @@ -195,6 +197,8 @@ testonly = true sources = [ "arc_bridge_service_unittest.cc", + "bluetooth/arc_bluetooth_bridge_unittest.cc", + "bluetooth/bluetooth_type_converters_unittest.cc", "ime/arc_ime_service_unittest.cc", "intent_helper/activity_icon_loader_unittest.cc", "intent_helper/arc_intent_helper_bridge_unittest.cc", @@ -209,6 +213,7 @@ ":arc_test_support", "//base", "//chromeos", + "//device/bluetooth", "//mojo/public/cpp/system:system", "//testing/gtest", "//ui/aura",
diff --git a/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc new file mode 100644 index 0000000..7953d1b1 --- /dev/null +++ b/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
@@ -0,0 +1,205 @@ +// 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. + +#include "components/arc/bluetooth/arc_bluetooth_bridge.h" + +#include <string> +#include <utility> +#include <vector> + +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "components/arc/bluetooth/bluetooth_type_converters.h" +#include "components/arc/common/bluetooth.mojom.h" +#include "components/arc/test/fake_arc_bridge_service.h" +#include "components/arc/test/fake_bluetooth_instance.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" +#include "mojo/public/cpp/bindings/array.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { + +class ArcBluetoothBridgeTest : public testing::Test { + protected: + void AddTestDevice() { + bluez::BluezDBusManager* dbus_manager = bluez::BluezDBusManager::Get(); + auto* fake_bluetooth_device_client = + static_cast<bluez::FakeBluetoothDeviceClient*>( + dbus_manager->GetBluetoothDeviceClient()); + auto* fake_bluetooth_gatt_service_client = + static_cast<bluez::FakeBluetoothGattServiceClient*>( + dbus_manager->GetBluetoothGattServiceClient()); + auto* fake_bluetooth_gatt_characteristic_client = + static_cast<bluez::FakeBluetoothGattCharacteristicClient*>( + dbus_manager->GetBluetoothGattCharacteristicClient()); + + fake_bluetooth_device_client->CreateDevice( + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); + fake_bluetooth_gatt_service_client->ExposeHeartRateService( + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); + fake_bluetooth_gatt_characteristic_client->ExposeHeartRateCharacteristics( + fake_bluetooth_gatt_service_client->GetHeartRateServicePath()); + } + + void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter) { + adapter_ = adapter; + get_adapter_run_loop_.Quit(); + } + + void SetUp() override { + std::unique_ptr<bluez::BluezDBusManagerSetter> dbus_setter = + bluez::BluezDBusManager::GetSetterForTesting(); + auto fake_bluetooth_device_client = + base::MakeUnique<bluez::FakeBluetoothDeviceClient>(); + fake_bluetooth_device_client->RemoveAllDevices(); + dbus_setter->SetBluetoothDeviceClient( + std::move(fake_bluetooth_device_client)); + dbus_setter->SetBluetoothGattServiceClient( + base::MakeUnique<bluez::FakeBluetoothGattServiceClient>()); + dbus_setter->SetBluetoothGattCharacteristicClient( + base::MakeUnique<bluez::FakeBluetoothGattCharacteristicClient>()); + dbus_setter->SetBluetoothGattDescriptorClient( + base::MakeUnique<bluez::FakeBluetoothGattDescriptorClient>()); + + fake_arc_bridge_service_.reset(new FakeArcBridgeService()); + fake_bluetooth_instance_.reset(new FakeBluetoothInstance()); + fake_arc_bridge_service_->bluetooth()->SetInstance( + fake_bluetooth_instance_.get(), 2); + arc_bluetooth_bridge_.reset( + new ArcBluetoothBridge(fake_arc_bridge_service_.get())); + + device::BluetoothAdapterFactory::GetAdapter(base::Bind( + &ArcBluetoothBridgeTest::OnAdapterInitialized, base::Unretained(this))); + // We will quit the loop once we get the adapter. + get_adapter_run_loop_.Run(); + } + + std::unique_ptr<FakeArcBridgeService> fake_arc_bridge_service_; + std::unique_ptr<FakeBluetoothInstance> fake_bluetooth_instance_; + std::unique_ptr<ArcBluetoothBridge> arc_bluetooth_bridge_; + scoped_refptr<device::BluetoothAdapter> adapter_; + base::MessageLoop message_loop_; + base::RunLoop get_adapter_run_loop_; +}; + +// When we add device to bluez::FakeBluetoothDeviceClient, ArcBluetoothBridge +// should send new device data to Android. This test will then check +// the correctness of the device properties sent via arc bridge. +TEST_F(ArcBluetoothBridgeTest, DeviceFound) { + EXPECT_EQ(0u, fake_bluetooth_instance_->device_found_data().size()); + AddTestDevice(); + EXPECT_EQ(1u, fake_bluetooth_instance_->device_found_data().size()); + const mojo::Array<mojom::BluetoothPropertyPtr>& prop = + fake_bluetooth_instance_->device_found_data().back(); + + EXPECT_EQ(7u, prop.size()); + EXPECT_TRUE(prop[0]->is_bdname()); + EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyName), + prop[0]->get_bdname()); + EXPECT_TRUE(prop[1]->is_bdaddr()); + EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress), + prop[1]->get_bdaddr()->To<std::string>()); + EXPECT_TRUE(prop[2]->is_uuids()); + EXPECT_EQ(1u, prop[2]->get_uuids().size()); + EXPECT_EQ(bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID, + prop[2]->get_uuids()[0].To<device::BluetoothUUID>().value()); + EXPECT_TRUE(prop[3]->is_device_class()); + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyClass, + prop[3]->get_device_class()); + EXPECT_TRUE(prop[4]->is_device_type()); + // bluez::FakeBluetoothDeviceClient does not return proper device type. + EXPECT_TRUE(prop[5]->is_remote_friendly_name()); + EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyName), + prop[5]->get_remote_friendly_name()); + EXPECT_TRUE(prop[6]->is_remote_rssi()); +} + +// Invoke OnDiscoveryStarted to send cached device to BT instance, +// and check correctness of the Advertising data sent via arc bridge. +TEST_F(ArcBluetoothBridgeTest, LEDeviceFound) { + EXPECT_EQ(0u, fake_bluetooth_instance_->device_found_data().size()); + AddTestDevice(); + EXPECT_EQ(1u, fake_bluetooth_instance_->le_device_found_data().size()); + + const mojom::BluetoothAddressPtr& addr = + fake_bluetooth_instance_->le_device_found_data().back()->addr(); + const mojo::Array<mojom::BluetoothAdvertisingDataPtr>& adv_data = + fake_bluetooth_instance_->le_device_found_data().back()->adv_data(); + + EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress), + addr->To<std::string>()); + EXPECT_EQ(1u, adv_data.size()); + + EXPECT_TRUE(adv_data[0]->is_local_name()); + EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyName), + adv_data[0]->get_local_name().To<std::string>()); +} + +// Invoke GetGattDB and check correctness of the GattDB sent via arc bridge. +TEST_F(ArcBluetoothBridgeTest, GetGattDB) { + AddTestDevice(); + + arc_bluetooth_bridge_->GetGattDB(mojom::BluetoothAddress::From( + std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress))); + EXPECT_EQ(1u, fake_bluetooth_instance_->gatt_db_result().size()); + + const mojom::BluetoothAddressPtr& addr = + fake_bluetooth_instance_->gatt_db_result().back()->remote_addr(); + EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress), + addr->To<std::string>()); + + // HeartRateService in bluez::FakeBluetoothDeviceClient consists of + // Service: HeartRateService + // Characteristic: HeartRateMeasurement + // Descriptor: ClientCharacteristicConfiguration + // Characteristic: BodySensorLocation + // Characteristic: HeartRateControlPoint + const mojo::Array<mojom::BluetoothGattDBElementPtr>& db = + fake_bluetooth_instance_->gatt_db_result().back()->db(); + EXPECT_EQ(5u, db.size()); + + EXPECT_EQ(device::BluetoothUUID( + bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID), + db[0]->uuid.To<device::BluetoothUUID>()); + EXPECT_EQ(mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE, + db[0]->type); + + EXPECT_EQ(device::BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient:: + kHeartRateMeasurementUUID), + db[1]->uuid.To<device::BluetoothUUID>()); + EXPECT_EQ(mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, + db[1]->type); + EXPECT_EQ(device::BluetoothGattCharacteristic::PROPERTY_NOTIFY, + db[1]->properties); + + EXPECT_EQ(device::BluetoothUUID(bluez::FakeBluetoothGattDescriptorClient:: + kClientCharacteristicConfigurationUUID), + db[2]->uuid.To<device::BluetoothUUID>()); + EXPECT_EQ(mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, + db[2]->type); + + EXPECT_EQ(device::BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient:: + kBodySensorLocationUUID), + db[3]->uuid.To<device::BluetoothUUID>()); + EXPECT_EQ(mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, + db[3]->type); + EXPECT_EQ(device::BluetoothGattCharacteristic::PROPERTY_READ, + db[3]->properties); + + EXPECT_EQ(device::BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient:: + kHeartRateControlPointUUID), + db[4]->uuid.To<device::BluetoothUUID>()); + EXPECT_EQ(mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, + db[4]->type); + EXPECT_EQ(device::BluetoothGattCharacteristic::PROPERTY_WRITE, + db[4]->properties); +} + +} // namespace arc
diff --git a/components/arc/bluetooth/bluetooth_type_converters.cc b/components/arc/bluetooth/bluetooth_type_converters.cc index af2e08b33..f91139d 100644 --- a/components/arc/bluetooth/bluetooth_type_converters.cc +++ b/components/arc/bluetooth/bluetooth_type_converters.cc
@@ -19,6 +19,10 @@ namespace { +constexpr size_t kAddressSize = 6; +constexpr size_t kUUIDSize = 16; +constexpr char kInvalidAddress[] = "00:00:00:00:00:00"; + bool IsNonHex(char c) { return !isxdigit(c); } @@ -35,8 +39,6 @@ namespace mojo { -// TODO(smbarber): Add unit tests for Bluetooth type converters. - // static arc::mojom::BluetoothAddressPtr TypeConverter<arc::mojom::BluetoothAddressPtr, std::string>::Convert( @@ -61,6 +63,9 @@ const mojo::Array<uint8_t>& bytes = address.address; + if (address.address.size() != kAddressSize) + return std::string(kInvalidAddress); + for (size_t k = 0; k < bytes.size(); k++) { addr_stream << std::setw(2) << (unsigned int)bytes[k]; addr_stream << ((k == bytes.size() - 1) ? "" : ":"); @@ -90,6 +95,9 @@ const arc::mojom::BluetoothUUIDPtr& uuid) { std::vector<uint8_t> address_bytes = uuid->uuid.To<std::vector<uint8_t>>(); + if (address_bytes.size() != kUUIDSize) + return device::BluetoothUUID(); + // BluetoothUUID expects the format below with the dashes inserted. // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx std::string uuid_str =
diff --git a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc b/components/arc/bluetooth/bluetooth_type_converters_unittest.cc new file mode 100644 index 0000000..57e296d --- /dev/null +++ b/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
@@ -0,0 +1,83 @@ +// 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. + +#include "components/arc/bluetooth/bluetooth_type_converters.h" + +#include <string> +#include <vector> + +#include "device/bluetooth/bluetooth_gatt_service.h" +#include "device/bluetooth/bluetooth_uuid.h" +#include "mojo/public/cpp/bindings/array.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +constexpr char kAddressStr[] = "1A:2B:3C:4D:5E:6F"; +constexpr char kInvalidAddressStr[] = "00:00:00:00:00:00"; +constexpr uint8_t kAddressArray[] = {0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f}; +constexpr size_t kAddressSize = 6; +constexpr char kUuidStr[] = "12345678-1234-5678-9abc-def123456789"; +constexpr uint8_t kUuidArray[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, + 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, + 0x23, 0x45, 0x67, 0x89}; +constexpr size_t kUuidSize = 16; +constexpr uint8_t kFillerByte = 0x79; +} // namespace + +namespace mojo { + +TEST(BluetoothTypeConvertorTest, ConvertMojoBluetoothAddressFromString) { + arc::mojom::BluetoothAddressPtr addressMojo = + arc::mojom::BluetoothAddress::From(std::string(kAddressStr)); + EXPECT_EQ(kAddressSize, addressMojo->address.size()); + for (size_t i = 0; i < kAddressSize; i++) { + EXPECT_EQ(kAddressArray[i], addressMojo->address[i]); + } +} + +TEST(BluetoothTypeConvertorTest, ConvertMojoBluetoothAddressToString) { + arc::mojom::BluetoothAddressPtr addressMojo = + arc::mojom::BluetoothAddress::New(); + for (size_t i = 0; i < kAddressSize - 1; i++) { + addressMojo->address.push_back(kAddressArray[i]); + } + EXPECT_EQ(std::string(kInvalidAddressStr), addressMojo->To<std::string>()); + + addressMojo->address.push_back(kAddressArray[kAddressSize - 1]); + EXPECT_EQ(std::string(kAddressStr), addressMojo->To<std::string>()); + + addressMojo->address.push_back(kFillerByte); + + EXPECT_EQ(std::string(kInvalidAddressStr), addressMojo->To<std::string>()); +} + +TEST(BluetoothTypeConvertorTest, + ConvertMojoBluetoothUUIDFromDeviceBluetoothUUID) { + device::BluetoothUUID uuidDevice((std::string(kUuidStr))); + arc::mojom::BluetoothUUIDPtr uuidMojo = + arc::mojom::BluetoothUUID::From(uuidDevice); + EXPECT_EQ(kUuidSize, uuidMojo->uuid.size()); + for (size_t i = 0; i < kUuidSize; i++) { + EXPECT_EQ(kUuidArray[i], uuidMojo->uuid[i]); + } +} + +TEST(BluetoothTypeConvertorTest, + ConvertMojoBluetoothUUIDToDeviceBluetoothUUID) { + arc::mojom::BluetoothUUIDPtr uuidMojo = arc::mojom::BluetoothUUID::New(); + for (size_t i = 0; i < kUuidSize - 1; i++) { + uuidMojo->uuid.push_back(kUuidArray[i]); + } + EXPECT_FALSE(uuidMojo.To<device::BluetoothUUID>().IsValid()); + + uuidMojo->uuid.push_back(kUuidArray[kUuidSize - 1]); + EXPECT_TRUE(uuidMojo.To<device::BluetoothUUID>().IsValid()); + EXPECT_EQ(std::string(kUuidStr), + uuidMojo.To<device::BluetoothUUID>().canonical_value()); + + uuidMojo->uuid.push_back(kFillerByte); + EXPECT_FALSE(uuidMojo.To<device::BluetoothUUID>().IsValid()); +} + +} // namespace mojo
diff --git a/components/arc/test/fake_bluetooth_instance.cc b/components/arc/test/fake_bluetooth_instance.cc new file mode 100644 index 0000000..4db55a2 --- /dev/null +++ b/components/arc/test/fake_bluetooth_instance.cc
@@ -0,0 +1,111 @@ +// 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. + +#include "components/arc/test/fake_bluetooth_instance.h" + +#include <utility> + +namespace arc { + +FakeBluetoothInstance::FakeBluetoothInstance() = default; +FakeBluetoothInstance::~FakeBluetoothInstance() = default; + +FakeBluetoothInstance::GattDBResult::GattDBResult( + mojom::BluetoothAddressPtr&& remote_addr, + mojo::Array<mojom::BluetoothGattDBElementPtr>&& db) + : remote_addr_(std::move(remote_addr)), db_(std::move(db)) {} + +FakeBluetoothInstance::GattDBResult::~GattDBResult() {} + +FakeBluetoothInstance::LEDeviceFoundData::LEDeviceFoundData( + mojom::BluetoothAddressPtr&& addr, + int32_t rssi, + mojo::Array<mojom::BluetoothAdvertisingDataPtr>&& adv_data) + : addr_(std::move(addr)), rssi_(rssi), adv_data_(std::move(adv_data)) {} + +FakeBluetoothInstance::LEDeviceFoundData::~LEDeviceFoundData() {} + +void FakeBluetoothInstance::Init(mojom::BluetoothHostPtr host_ptr) {} + +void FakeBluetoothInstance::OnAdapterProperties( + mojom::BluetoothStatus status, + mojo::Array<mojom::BluetoothPropertyPtr> properties) {} + +void FakeBluetoothInstance::OnRemoteDeviceProperties( + mojom::BluetoothStatus status, + mojom::BluetoothAddressPtr address, + mojo::Array<mojom::BluetoothPropertyPtr> properties) {} + +void FakeBluetoothInstance::OnDeviceFound( + mojo::Array<mojom::BluetoothPropertyPtr> properties) { + device_found_data_.push_back(std::move(properties)); +} + +void FakeBluetoothInstance::OnDiscoveryStateChanged( + mojom::BluetoothDiscoveryState state) {} + +void FakeBluetoothInstance::OnBondStateChanged( + mojom::BluetoothStatus status, + mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothBondState state) {} + +void FakeBluetoothInstance::OnAclStateChanged( + mojom::BluetoothStatus status, + mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothAclState state) {} + +void FakeBluetoothInstance::OnLEDeviceFound( + mojom::BluetoothAddressPtr addr, + int32_t rssi, + mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data) { + le_device_found_data_.push_back( + new LEDeviceFoundData(std::move(addr), rssi, std::move(adv_data))); +} + +void FakeBluetoothInstance::OnLEConnectionStateChange( + mojom::BluetoothAddressPtr remote_addr, + bool connected) {} + +void FakeBluetoothInstance::OnSearchComplete( + mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothGattStatus status) {} + +void FakeBluetoothInstance::OnGetGattDB( + mojom::BluetoothAddressPtr remote_addr, + mojo::Array<mojom::BluetoothGattDBElementPtr> db) { + gatt_db_result_.push_back( + new GattDBResult(std::move(remote_addr), std::move(db))); +} + +void FakeBluetoothInstance::OnServicesRemoved( + mojom::BluetoothAddressPtr remote_addr, + uint16_t start_handle, + uint16_t end_handle) {} + +void FakeBluetoothInstance::OnServicesAdded( + mojom::BluetoothAddressPtr remote_addr, + mojo::Array<mojom::BluetoothGattDBElementPtr> db) {} + +void FakeBluetoothInstance::OnGattNotify( + mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothGattServiceIDPtr service_id, + mojom::BluetoothGattIDPtr char_id, + bool is_notify, + mojo::Array<uint8_t> value) {} + +void FakeBluetoothInstance::RequestGattRead( + mojom::BluetoothAddressPtr address, + int32_t attribute_handle, + int32_t offset, + bool is_long, + const RequestGattReadCallback& callback) {} + +void FakeBluetoothInstance::RequestGattWrite( + mojom::BluetoothAddressPtr address, + int32_t attribute_handle, + int32_t offset, + mojo::Array<uint8_t> value, + const RequestGattWriteCallback& callback) {} + +} // namespace arc
diff --git a/components/arc/test/fake_bluetooth_instance.h b/components/arc/test/fake_bluetooth_instance.h new file mode 100644 index 0000000..336d0b2 --- /dev/null +++ b/components/arc/test/fake_bluetooth_instance.h
@@ -0,0 +1,143 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ARC_TEST_FAKE_BLUETOOTH_INSTANCE_H_ +#define COMPONENTS_ARC_TEST_FAKE_BLUETOOTH_INSTANCE_H_ + +#include <vector> + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "components/arc/common/bluetooth.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace arc { + +class FakeBluetoothInstance : public mojom::BluetoothInstance { + public: + class GattDBResult { + public: + GattDBResult(mojom::BluetoothAddressPtr&& remote_addr, + mojo::Array<mojom::BluetoothGattDBElementPtr>&& db); + ~GattDBResult(); + + const mojom::BluetoothAddressPtr& remote_addr() const { + return remote_addr_; + } + + const mojo::Array<mojom::BluetoothGattDBElementPtr>& db() const { + return db_; + } + + private: + mojom::BluetoothAddressPtr remote_addr_; + mojo::Array<mojom::BluetoothGattDBElementPtr> db_; + + DISALLOW_COPY_AND_ASSIGN(GattDBResult); + }; + + class LEDeviceFoundData { + public: + LEDeviceFoundData( + mojom::BluetoothAddressPtr&& addr, + int32_t rssi, + mojo::Array<mojom::BluetoothAdvertisingDataPtr>&& adv_data); + ~LEDeviceFoundData(); + + const mojom::BluetoothAddressPtr& addr() const { return addr_; } + + int32_t rssi() const { return rssi_; } + + const mojo::Array<mojom::BluetoothAdvertisingDataPtr>& adv_data() const { + return adv_data_; + } + + private: + mojom::BluetoothAddressPtr addr_; + int32_t rssi_; + mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data_; + + DISALLOW_COPY_AND_ASSIGN(LEDeviceFoundData); + }; + + FakeBluetoothInstance(); + ~FakeBluetoothInstance() override; + + // interface BluetoothInstance + void Init(mojom::BluetoothHostPtr host_ptr) override; + void OnAdapterProperties( + mojom::BluetoothStatus status, + mojo::Array<mojom::BluetoothPropertyPtr> properties) override; + void OnRemoteDeviceProperties( + mojom::BluetoothStatus status, + mojom::BluetoothAddressPtr address, + mojo::Array<mojom::BluetoothPropertyPtr> properties) override; + void OnDeviceFound( + mojo::Array<mojom::BluetoothPropertyPtr> properties) override; + void OnDiscoveryStateChanged(mojom::BluetoothDiscoveryState state) override; + void OnBondStateChanged(mojom::BluetoothStatus status, + mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothBondState state) override; + void OnAclStateChanged(mojom::BluetoothStatus status, + mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothAclState state) override; + void OnLEDeviceFound( + mojom::BluetoothAddressPtr addr, + int32_t rssi, + mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data) override; + void OnLEConnectionStateChange(mojom::BluetoothAddressPtr remote_addr, + bool connected) override; + void OnSearchComplete(mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothGattStatus status) override; + void OnGetGattDB(mojom::BluetoothAddressPtr remote_addr, + mojo::Array<mojom::BluetoothGattDBElementPtr> db) override; + void OnServicesRemoved(mojom::BluetoothAddressPtr remote_addr, + uint16_t start_handle, + uint16_t end_handle) override; + void OnServicesAdded( + mojom::BluetoothAddressPtr remote_addr, + mojo::Array<mojom::BluetoothGattDBElementPtr> db) override; + + void OnGattNotify(mojom::BluetoothAddressPtr remote_addr, + mojom::BluetoothGattServiceIDPtr service_id, + mojom::BluetoothGattIDPtr char_id, + bool is_notify, + mojo::Array<uint8_t> value) override; + + void RequestGattRead(mojom::BluetoothAddressPtr address, + int32_t attribute_handle, + int32_t offset, + bool is_long, + const RequestGattReadCallback& callback) override; + + void RequestGattWrite(mojom::BluetoothAddressPtr address, + int32_t attribute_handle, + int32_t offset, + mojo::Array<uint8_t> value, + const RequestGattWriteCallback& callback) override; + + const std::vector<mojo::Array<mojom::BluetoothPropertyPtr>>& + device_found_data() const { + return device_found_data_; + } + + const std::vector<LEDeviceFoundData*>& le_device_found_data() const { + return le_device_found_data_; + } + + const std::vector<GattDBResult*>& gatt_db_result() const { + return gatt_db_result_; + } + + private: + std::vector<mojo::Array<mojom::BluetoothPropertyPtr>> device_found_data_; + std::vector<LEDeviceFoundData*> le_device_found_data_; + std::vector<GattDBResult*> gatt_db_result_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInstance); +}; + +} // namespace arc + +#endif // COMPONENTS_ARC_TEST_FAKE_BLUETOOTH_INSTANCE_H_
diff --git a/components/autofill.gypi b/components/autofill.gypi index faa823a..860ae23 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi
@@ -252,6 +252,14 @@ 'sources': [ 'autofill/core/browser/keyboard_accessory_metrics_logger.h', 'autofill/core/browser/keyboard_accessory_metrics_logger.mm', + ], + }], + ['OS=="android"', { + 'sources': [ + 'autofill/core/browser/autofill_assistant.cc', + 'autofill/core/browser/autofill_assistant.h', + 'autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc', + 'autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h', ], }], ['OS=="ios" or OS=="android"', { @@ -296,6 +304,7 @@ '../testing/gtest.gyp:gtest', 'autofill_core_common', 'autofill_core_browser', + 'infobars', 'os_crypt', 'pref_registry', 'prefs/prefs.gyp:prefs',
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 9f32ae8..0a17887 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -468,7 +468,7 @@ } void AutofillAgent::FillForm(int32_t id, const FormData& form) { - if (id != autofill_query_id_) + if (id != autofill_query_id_ && id != kNoQueryId) return; was_query_node_autofilled_ = element_.isAutofilled();
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index e9d6016..6643319 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -152,6 +152,15 @@ ] } + if (is_android) { + sources += [ + "autofill_assistant.cc", + "autofill_assistant.h", + "autofill_credit_card_filling_infobar_delegate_mobile.cc", + "autofill_credit_card_filling_infobar_delegate_mobile.h", + ] + } + if (is_ios || is_android) { sources += [ "autofill_save_card_infobar_delegate_mobile.cc", @@ -321,6 +330,10 @@ "webdata/web_data_service_unittest.cc", ] + if (is_android) { + sources += [ "autofill_assistant_unittest.cc" ] + } + deps = [ ":browser", ":test_support",
diff --git a/components/autofill/core/browser/autofill_assistant.cc b/components/autofill/core/browser/autofill_assistant.cc new file mode 100644 index 0000000..c74776f9 --- /dev/null +++ b/components/autofill/core/browser/autofill_assistant.cc
@@ -0,0 +1,60 @@ +// 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. + +#include "components/autofill/core/browser/autofill_assistant.h" + +#include "base/containers/adapters.h" +#include "base/strings/string16.h" +#include "components/autofill/core/browser/autofill_experiments.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/common/autofill_constants.h" + +namespace autofill { + +AutofillAssistant::AutofillAssistant(AutofillManager* autofill_manager) + : credit_card_form_data_(nullptr), + autofill_manager_(autofill_manager), + weak_ptr_factory_(this) {} + +AutofillAssistant::~AutofillAssistant() {} + +void AutofillAssistant::Reset() { + credit_card_form_data_.reset(); +} + +bool AutofillAssistant::CanShowCreditCardAssist( + const std::vector<FormStructure*>& form_structures) { +#if !defined(OS_ANDROID) + return false; +#else + if (!IsAutofillCreditCardAssistEnabled() || credit_card_form_data_) + return false; + + for (FormStructure* cur_form : base::Reversed(form_structures)) { + if (cur_form->IsCompleteCreditCardForm()) { + credit_card_form_data_.reset(new FormData(cur_form->ToFormData())); + break; + } + } + return !!credit_card_form_data_; +#endif +} + +void AutofillAssistant::ShowAssistForCreditCard(const CreditCard& card) { + DCHECK(credit_card_form_data_); + autofill_manager_->client()->ConfirmCreditCardFillAssist( + card, base::Bind(&AutofillAssistant::OnUserDidAcceptCreditCardFill, + weak_ptr_factory_.GetWeakPtr(), card)); +} + +void AutofillAssistant::OnUserDidAcceptCreditCardFill(const CreditCard& card) { + // TODO(crbug.com/630656): Trigger CVC dialog flow for card filling. + autofill_manager_->FillCreditCardForm(kNoQueryId, *credit_card_form_data_, + credit_card_form_data_->fields[0], card, + base::string16()); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_assistant.h b/components/autofill/core/browser/autofill_assistant.h new file mode 100644 index 0000000..1a15b4c7 --- /dev/null +++ b/components/autofill/core/browser/autofill_assistant.h
@@ -0,0 +1,59 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_ASSISTANT_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_ASSISTANT_H_ + +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/autofill/core/common/form_data.h" + +namespace autofill { + +class AutofillManager; +class CreditCard; +class FormStructure; + +// This class encompasses the triggering rules and the logic for the autofill +// assisted filling mechanisms. +class AutofillAssistant { + public: + explicit AutofillAssistant(AutofillManager* autofill_manager); + ~AutofillAssistant(); + + // Should be called at every page navigation to clear state. + void Reset(); + + // Returns whether a credit card assist can be shown. Will go through the + // forms in |form_structures| and extract the credit card form. + bool CanShowCreditCardAssist( + const std::vector<FormStructure*>& form_structures); + + // Will show an assist infobar for the previously extracted form proposing to + // autofill it. Should only be called if CanShowCreditCardAssist() returned + // true. + void ShowAssistForCreditCard(const CreditCard& card); + + private: + // Called by the infobar delegate when the user accepts the infobar. + void OnUserDidAcceptCreditCardFill(const CreditCard& card); + + // Holds the FormData to be filled with a credit card. + std::unique_ptr<FormData> credit_card_form_data_; + + // Weak reference to the AutofillManager that created and maintains this + // AutofillAssistant. + AutofillManager* autofill_manager_; + + base::WeakPtrFactory<AutofillAssistant> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(AutofillAssistant); +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_ASSISTANT_H_
diff --git a/components/autofill/core/browser/autofill_assistant_unittest.cc b/components/autofill/core/browser/autofill_assistant_unittest.cc new file mode 100644 index 0000000..b1a61d8 --- /dev/null +++ b/components/autofill/core/browser/autofill_assistant_unittest.cc
@@ -0,0 +1,159 @@ +// 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. + +#include "components/autofill/core/browser/autofill_assistant.h" + +#include <memory> + +#include "base/callback.h" +#include "base/feature_list.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_driver.h" +#include "components/autofill/core/browser/autofill_experiments.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/browser/test_autofill_client.h" +#include "components/autofill/core/browser/test_autofill_driver.h" +#include "components/autofill/core/common/autofill_constants.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; + +namespace autofill { +namespace { + +class MockAutofillManager : public AutofillManager { + public: + MockAutofillManager(TestAutofillDriver* driver, TestAutofillClient* client) + // Force to use the constructor designated for unit test, but we don't + // really need personal_data in this test so we pass a NULL pointer. + : AutofillManager(driver, client, NULL) {} + virtual ~MockAutofillManager() {} + + MOCK_METHOD5(FillCreditCardForm, + void(int query_id, + const FormData& form, + const FormFieldData& field, + const CreditCard& credit_card, + const base::string16& cvc)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockAutofillManager); +}; + +} // namespace + +class AutofillAssistantTest : public testing::Test { + protected: + AutofillAssistantTest() + : message_loop_(), + autofill_client_(), + autofill_driver_(), + autofill_manager_(&autofill_driver_, &autofill_client_), + autofill_assistant_(&autofill_manager_) {} + + void EnableAutofillCreditCardAssist() { + base::FeatureList::ClearInstanceForTesting(); + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->InitializeFromCommandLine(kAutofillCreditCardAssist.name, + std::string()); + base::FeatureList::SetInstance(std::move(feature_list)); + } + + // Returns an initialized FormStructure with credit card form data. To be + // owned by the caller. + std::unique_ptr<FormStructure> CreateValidCreditCardForm() { + std::unique_ptr<FormStructure> form_structure; + FormData form; + + FormFieldData field; + field.form_control_type = "text"; + + field.label = base::ASCIIToUTF16("Name on Card"); + field.name = base::ASCIIToUTF16("name_on_card"); + form.fields.push_back(field); + + field.label = base::ASCIIToUTF16("Card Number"); + field.name = base::ASCIIToUTF16("card_number"); + form.fields.push_back(field); + + field.label = base::ASCIIToUTF16("Exp Month"); + field.name = base::ASCIIToUTF16("ccmonth"); + form.fields.push_back(field); + + field.label = base::ASCIIToUTF16("Exp Year"); + field.name = base::ASCIIToUTF16("ccyear"); + form.fields.push_back(field); + + field.label = base::ASCIIToUTF16("Verification"); + field.name = base::ASCIIToUTF16("verification"); + form.fields.push_back(field); + + form_structure.reset(new FormStructure(form)); + form_structure->DetermineHeuristicTypes(); + + return form_structure; + } + + base::MessageLoop message_loop_; + TestAutofillClient autofill_client_; + testing::NiceMock<TestAutofillDriver> autofill_driver_; + MockAutofillManager autofill_manager_; + AutofillAssistant autofill_assistant_; +}; + +MATCHER_P(CreditCardMatches, guid, "") { + return arg.guid() == guid; +} + +// If the feature is turned off, CanShowCreditCardAssist() always returns +// false. +TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOff) { + std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm(); + + std::vector<FormStructure*> form_structures{form_structure.get()}; + EXPECT_FALSE(autofill_assistant_.CanShowCreditCardAssist(form_structures)); +} + +// Tests that with the feature enabled and proper input, +// CanShowCreditCardAssist() behaves as expected. +TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn) { + EnableAutofillCreditCardAssist(); + std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm(); + + std::vector<FormStructure*> form_structures; + EXPECT_FALSE(autofill_assistant_.CanShowCreditCardAssist(form_structures)); + + // With valid input, the function extracts the credit card form properly. + form_structures.push_back(form_structure.get()); + EXPECT_TRUE(autofill_assistant_.CanShowCreditCardAssist(form_structures)); +} + +TEST_F(AutofillAssistantTest, ShowAssistForCreditCard_ValidCard) { + EnableAutofillCreditCardAssist(); + std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm(); + + // Will extract the credit card form data. + std::vector<FormStructure*> form_structures{form_structure.get()}; + EXPECT_TRUE(autofill_assistant_.CanShowCreditCardAssist(form_structures)); + + // Create a valid card for the assist. + CreditCard card; + test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999"); + + // FillCreditCardForm ends up being called after user has accepted the + // prompt. + EXPECT_CALL( + autofill_manager_, + FillCreditCardForm(kNoQueryId, _, _, CreditCardMatches(card.guid()), + /* empty cvc */ base::string16())); + + autofill_assistant_.ShowAssistForCreditCard(card); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 354610b..d475691 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -132,6 +132,11 @@ std::unique_ptr<base::DictionaryValue> legal_message, const base::Closure& callback) = 0; + // Will show an infobar to get user consent for Credit Card assistive filling. + // Will run |callback| on success. + virtual void ConfirmCreditCardFillAssist(const CreditCard& card, + const base::Closure& callback) = 0; + // Gathers risk data and provides it to |callback|. virtual void LoadRiskData( const base::Callback<void(const std::string&)>& callback) = 0;
diff --git a/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc new file mode 100644 index 0000000..432bb26 --- /dev/null +++ b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
@@ -0,0 +1,89 @@ +// 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. + +#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h" + +#include "base/memory/ptr_util.h" +#include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/common/autofill_constants.h" +#include "components/infobars/core/infobar_delegate.h" +#include "grit/components_scaled_resources.h" +#include "grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" + +namespace autofill { + +AutofillCreditCardFillingInfoBarDelegateMobile:: + AutofillCreditCardFillingInfoBarDelegateMobile( + const CreditCard& card, + const base::Closure& card_filling_callback) + : ConfirmInfoBarDelegate(), + card_filling_callback_(card_filling_callback), + had_user_interaction_(false), + was_shown_(false), + issuer_icon_id_(CreditCard::IconResourceId(card.type())), + card_label_(base::string16(kMidlineEllipsis) + card.LastFourDigits()), + card_sub_label_(card.AbbreviatedExpirationDateForDisplay()) {} + +AutofillCreditCardFillingInfoBarDelegateMobile:: + ~AutofillCreditCardFillingInfoBarDelegateMobile() { + if (was_shown_) { + AutofillMetrics::LogCreditCardFillingInfoBarMetric( + AutofillMetrics::INFOBAR_SHOWN); + if (!had_user_interaction_) + LogUserAction(AutofillMetrics::INFOBAR_IGNORED); + } +} + +int AutofillCreditCardFillingInfoBarDelegateMobile::GetIconId() const { + return IDR_INFOBAR_AUTOFILL_CC; +} + +base::string16 AutofillCreditCardFillingInfoBarDelegateMobile::GetMessageText() + const { + return l10n_util::GetStringUTF16( + IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_TITLE); +} + +void AutofillCreditCardFillingInfoBarDelegateMobile::InfoBarDismissed() { + LogUserAction(AutofillMetrics::INFOBAR_DENIED); +} + +bool AutofillCreditCardFillingInfoBarDelegateMobile::Accept() { + card_filling_callback_.Run(); + LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED); + return true; +} + +bool AutofillCreditCardFillingInfoBarDelegateMobile::Cancel() { + LogUserAction(AutofillMetrics::INFOBAR_DENIED); + return true; +} + +infobars::InfoBarDelegate::Type +AutofillCreditCardFillingInfoBarDelegateMobile::GetInfoBarType() const { + return PAGE_ACTION_TYPE; +} + +infobars::InfoBarDelegate::InfoBarIdentifier +AutofillCreditCardFillingInfoBarDelegateMobile::GetIdentifier() const { + return AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_ANDROID; +} + +base::string16 AutofillCreditCardFillingInfoBarDelegateMobile::GetButtonLabel( + InfoBarButton button) const { + return l10n_util::GetStringUTF16( + button == BUTTON_OK ? IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_ACCEPT + : IDS_NO_THANKS); +} + +void AutofillCreditCardFillingInfoBarDelegateMobile::LogUserAction( + AutofillMetrics::InfoBarMetric user_action) { + DCHECK(!had_user_interaction_); + + AutofillMetrics::LogCreditCardFillingInfoBarMetric(user_action); + had_user_interaction_ = true; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h new file mode 100644 index 0000000..fe1cc19 --- /dev/null +++ b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h
@@ -0,0 +1,75 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/strings/string16.h" +#include "components/autofill/core/browser/autofill_metrics.h" +#include "components/infobars/core/confirm_infobar_delegate.h" + +namespace infobars { +class InfoBarManager; +} + +namespace autofill { + +class CreditCard; + +// An InfoBarDelegate that enables the user to allow or deny filling credit +// card information on a website form. Only used on mobile. +class AutofillCreditCardFillingInfoBarDelegateMobile + : public ConfirmInfoBarDelegate { + public: + AutofillCreditCardFillingInfoBarDelegateMobile( + const CreditCard& card, + const base::Closure& card_filling_callback); + ~AutofillCreditCardFillingInfoBarDelegateMobile() override; + + int issuer_icon_id() const { return issuer_icon_id_; } + const base::string16& card_label() const { return card_label_; } + const base::string16& card_sub_label() const { return card_sub_label_; } + void set_was_shown() { was_shown_ = true; } + + // ConfirmInfoBarDelegate (publicly exposed): + int GetIconId() const override; + base::string16 GetMessageText() const override; + void InfoBarDismissed() override; + bool Accept() override; + bool Cancel() override; + + private: + // ConfirmInfoBarDelegate (continued): + Type GetInfoBarType() const override; + infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; + base::string16 GetButtonLabel(InfoBarButton button) const override; + + void LogUserAction(AutofillMetrics::InfoBarMetric user_action); + + // The callback after having accepted the infobar; will initiate filling the + // credit card information. + base::Closure card_filling_callback_; + + // Did the user ever explicitly accept or dismiss this infobar? + bool had_user_interaction_; + + // Tracks whether the infobar was shown. + bool was_shown_; + + // The resource ID for the icon that identifies the issuer of the card. + int issuer_icon_id_; + + base::string16 card_label_; + base::string16 card_sub_label_; + + DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardFillingInfoBarDelegateMobile); +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index 6136569..03731e98 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -19,6 +19,8 @@ namespace autofill { +const base::Feature kAutofillCreditCardAssist{ + "AutofillCreditCardAssist", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kAutofillProfileCleanup{"AutofillProfileCleanup", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kAutofillCreditCardSigninPromo{ @@ -43,6 +45,10 @@ return base::FeatureList::IsEnabled(kAutofillCreditCardSigninPromo); } +bool IsAutofillCreditCardAssistEnabled() { + return base::FeatureList::IsEnabled(kAutofillCreditCardAssist); +} + int GetCreditCardSigninPromoImpressionLimit() { int impression_limit; std::string param_value = variations::GetVariationParamValueByFeature(
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h index 70fc201f..700e41ee 100644 --- a/components/autofill/core/browser/autofill_experiments.h +++ b/components/autofill/core/browser/autofill_experiments.h
@@ -19,6 +19,7 @@ namespace autofill { +extern const base::Feature kAutofillCreditCardAssist; extern const base::Feature kAutofillProfileCleanup; extern const base::Feature kAutofillCreditCardSigninPromo; extern const char kCreditCardSigninPromoImpressionLimitParamKey[]; @@ -39,6 +40,9 @@ // Returns whether the Autofill credit card signin promo should be shown. bool IsAutofillCreditCardSigninPromoEnabled(); +// Returns whether the Autofill credit card assist infobar should be shown. +bool IsAutofillCreditCardAssistEnabled(); + // Returns the maximum number of impressions of the credit card signin promo, or // 0 if there are no limits. int GetCreditCardSigninPromoImpressionLimit();
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 3e353ee5..d8c306c 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -208,6 +208,9 @@ user_did_accept_upload_prompt_(false), external_delegate_(NULL), test_delegate_(NULL), +#if defined(OS_ANDROID) + autofill_assistant_(this), +#endif weak_ptr_factory_(this) { if (enable_download_manager == ENABLE_AUTOFILL_DOWNLOAD_MANAGER) { download_manager_.reset(new AutofillDownloadManager(driver, this)); @@ -583,11 +586,12 @@ // If there are no Autofill suggestions, consider showing Autocomplete // suggestions. We will not show Autocomplete suggestions for a field that - // specifies autocomplete=off or a field that we think is a credit card - // expiration, cvc or number. + // specifies autocomplete=off (or an unrecognized type) or a field that we + // think is a credit card expiration, cvc or number. if (suggestions.empty() && field.should_autocomplete && !(autofill_field && (IsCreditCardExpirationType(autofill_field->Type().GetStorableType()) || + autofill_field->Type().html_type() == HTML_TYPE_UNRECOGNIZED || autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER || autofill_field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE))) { @@ -1285,6 +1289,9 @@ new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)); credit_card_form_event_logger_.reset( new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)); +#if defined(OS_ANDROID) + autofill_assistant_.Reset(); +#endif has_logged_autofill_enabled_ = false; has_logged_address_suggestions_count_ = false; did_show_suggestions_ = false; @@ -1324,6 +1331,9 @@ unmasking_query_id_(-1), external_delegate_(NULL), test_delegate_(NULL), +#if defined(OS_ANDROID) + autofill_assistant_(this), +#endif weak_ptr_factory_(this) { DCHECK(driver_); DCHECK(client_); @@ -1772,6 +1782,21 @@ #endif } +#if defined(OS_ANDROID) + // When a credit card form is parsed and conditions are met, show an infobar + // prompt for credit card assisted filling. Upon accepting the infobar, the + // form will automatically be filled with the user's information through this + // class' FillCreditCardForm(). + if (autofill_assistant_.CanShowCreditCardAssist(form_structures_.get())) { + const std::vector<CreditCard*> cards = + personal_data_->GetCreditCardsToSuggest(); + // Expired cards are last in the sorted order, so if the first one is + // expired, they all are. + if (!cards.empty() && !cards.front()->IsExpired(base::Time::Now())) + autofill_assistant_.ShowAssistForCreditCard(*cards.front()); + } +#endif + // For the |non_queryable_forms|, we have all the field type info we're ever // going to get about them. For the other forms, we'll wait until we get a // response from the server.
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 4b906a5..03026c9 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -32,6 +32,10 @@ #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/common/form_data.h" +#if defined(OS_ANDROID) +#include "components/autofill/core/browser/autofill_assistant.h" +#endif + // This define protects some debugging code (see DumpAutofillData). This // is here to make it easier to delete this code when the test is complete, // and to prevent adding the code on mobile where there is no desktop (the @@ -251,7 +255,6 @@ ScopedVector<FormStructure>* form_structures() { return &form_structures_; } - protected: // Exposed for testing. AutofillExternalDelegate* external_delegate() { return external_delegate_; @@ -535,6 +538,10 @@ // Delegate used in test to get notifications on certain events. AutofillManagerTestDelegate* test_delegate_; +#if defined(OS_ANDROID) + AutofillAssistant autofill_assistant_; +#endif + base::WeakPtrFactory<AutofillManager> weak_ptr_factory_; friend class AutofillManagerTest; @@ -574,33 +581,9 @@ UserHappinessFormLoadAndSubmission); FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, UserHappinessFormInteraction); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, - FormSubmittedAutocompleteEnabled); - FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, OnLoadedServerPredictions); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, OnLoadedServerPredictions_ResetManager); - FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, - AutocompleteSuggestions_SomeWhenAutofillDisabled); - FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, - AutocompleteSuggestions_SomeWhenAutofillEmpty); - FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, - AutocompleteSuggestions_NoneWhenAutofillPresent); - FRIEND_TEST_ALL_PREFIXES( - AutofillManagerTest, - AutocompleteSuggestions_CreditCardNameFieldShouldAutocomplete); - FRIEND_TEST_ALL_PREFIXES( - AutofillManagerTest, - AutocompleteSuggestions_CreditCardNumberShouldNotAutocomplete); - FRIEND_TEST_ALL_PREFIXES( - AutofillManagerTest, - AutocompleteSuggestions_AutofillDisabledAndFieldShouldNotAutocomplete); - FRIEND_TEST_ALL_PREFIXES( - AutofillManagerTest, - AutocompleteSuggestions_NoneWhenAutofillEmptyFieldShouldNotAutocomplete); - FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, - AutocompleteOffRespectedForAutocomplete); - FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, - DontSaveCvcInAutocompleteHistory); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, DontOfferToSavePaymentsCard); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, FillInUpdatedExpirationDate); DISALLOW_COPY_AND_ASSIGN(AutofillManager);
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc index a25be3c..fffcb83 100644 --- a/components/autofill/core/browser/autofill_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -701,10 +701,21 @@ suggestion_vector.push_back(suggestion2); CheckSuggestions(expected_page_id, 3, &suggestion_vector[0]); } + // Check that the autofill suggestions were sent, and that they match a page + // but contain no results. void CheckNoSuggestions(int expected_page_id) { - EXPECT_TRUE(on_suggestions_returned_seen()); CheckSuggestions(expected_page_id, 0, nullptr); } + // Check that the autofill suggestions were sent, and that they match a page + // and contain a specific number of suggestions. + void CheckSuggestionCount(int expected_page_id, + size_t expected_num_suggestions) { + // Ensure that these results are from the most recent query. + EXPECT_TRUE(on_suggestions_returned_seen_); + + EXPECT_EQ(expected_page_id, query_id_); + ASSERT_EQ(expected_num_suggestions, suggestions_.size()); + } bool on_query_seen() const { return on_query_seen_; @@ -961,6 +972,16 @@ form->fields[0], *card); } + // Convenience method for using and retrieving a mock autocomplete history + // manager. + MockAutocompleteHistoryManager* RecreateMockAutocompleteHistoryManager() { + MockAutocompleteHistoryManager* manager = new + MockAutocompleteHistoryManager(autofill_driver_.get(), + autofill_manager_->client()); + autofill_manager_->autocomplete_history_manager_.reset(manager); + return manager; + } + // Convenience method to cast the FullCardRequest into a CardUnmaskDelegate. CardUnmaskDelegate* full_card_unmask_delegate() { DCHECK(autofill_manager_->full_card_request_); @@ -1062,9 +1083,10 @@ download_manager_->VerifyLastQueriedForms(forms); } -// Test that no suggestions are returned for a field with an unrecognized -// autocomplete attribute. +// Test that no autofill suggestions are returned for a field with an +// unrecognized autocomplete attribute. TEST_F(AutofillManagerTest, GetProfileSuggestions_UnrecognizedAttribute) { + // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); form.origin = GURL("https://myform.com/form.html"); @@ -1085,21 +1107,26 @@ std::vector<FormData> forms(1, form); FormsSeen(forms); - // Suggestions should be returned for the first two fields - GetAutofillSuggestions(form, form.fields[0]); - EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen()); - GetAutofillSuggestions(form, form.fields[1]); - EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen()); + // Ensure that autocomplete manager is not called for suggestions either. + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); - // Suggestions should not be returned for the third field because of its + // Suggestions should be returned for the first two fields. + GetAutofillSuggestions(form, form.fields[0]); + external_delegate_->CheckSuggestionCount(kDefaultPageID, 2); + GetAutofillSuggestions(form, form.fields[1]); + external_delegate_->CheckSuggestionCount(kDefaultPageID, 2); + + // No suggestions should not be provided for the third field because of its // unrecognized autocomplete attribute. GetAutofillSuggestions(form, form.fields[2]); - EXPECT_FALSE(external_delegate_->on_suggestions_returned_seen()); + external_delegate_->CheckNoSuggestions(kDefaultPageID); } // Test that no suggestions are returned when there are less than three fields // and none of them have an autocomplete attribute. TEST_F(AutofillManagerTest, GetProfileSuggestions_SmallFormNoAutocomplete) { + // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); form.origin = GURL("https://myform.com/form.html"); @@ -1113,6 +1140,10 @@ std::vector<FormData> forms(1, form); FormsSeen(forms); + // Ensure that autocomplete manager is called for both fields. + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(2); + GetAutofillSuggestions(form, form.fields[0]); EXPECT_FALSE(external_delegate_->on_suggestions_returned_seen()); @@ -1124,6 +1155,7 @@ // attribute, suggestions are only made for the one that has the attribute. TEST_F(AutofillManagerTest, GetProfileSuggestions_SmallFormWithOneAutocomplete) { + // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); form.origin = GURL("https://myform.com/form.html"); @@ -1156,6 +1188,7 @@ // suggestions are made for both fields. TEST_F(AutofillManagerTest, GetProfileSuggestions_SmallFormWithTwoAutocomplete) { + // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); form.origin = GURL("https://myform.com/form.html"); @@ -1184,7 +1217,7 @@ // Test that we return all address profile suggestions when all form fields are // empty. -TEST_F(AutofillManagerTest, GetProfileSuggestionsEmptyValue) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_EmptyValue) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -1204,7 +1237,7 @@ // Test that we return only matching address profile suggestions when the // selected form field has been partially filled out. -TEST_F(AutofillManagerTest, GetProfileSuggestionsMatchCharacter) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_MatchCharacter) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -1296,7 +1329,7 @@ } // Test that we return no suggestions when the form has no relevant fields. -TEST_F(AutofillManagerTest, GetProfileSuggestionsUnknownFields) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_UnknownFields) { // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); @@ -1321,7 +1354,7 @@ } // Test that we cull duplicate profile suggestions. -TEST_F(AutofillManagerTest, GetProfileSuggestionsWithDuplicates) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_WithDuplicates) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -1345,7 +1378,7 @@ } // Test that we return no suggestions when autofill is disabled. -TEST_F(AutofillManagerTest, GetProfileSuggestionsAutofillDisabledByUser) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_AutofillDisabledByUser) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -1466,7 +1499,7 @@ // Test that we return only matching credit card profile suggestions when the // selected form field has been partially filled out. -TEST_F(AutofillManagerTest, GetCreditCardSuggestionsMatchCharacter) { +TEST_F(AutofillManagerTest, GetCreditCardSuggestions_MatchCharacter) { // Set up our form data. FormData form; CreateTestCreditCardFormData(&form, true, false); @@ -1487,7 +1520,7 @@ // Test that we return credit card profile suggestions when the selected form // field is not the credit card number field. -TEST_F(AutofillManagerTest, GetCreditCardSuggestionsNonCCNumber) { +TEST_F(AutofillManagerTest, GetCreditCardSuggestions_NonCCNumber) { // Set up our form data. FormData form; CreateTestCreditCardFormData(&form, true, false); @@ -1520,7 +1553,7 @@ // Test that we return a warning explaining that credit card profile suggestions // are unavailable when the form is not secure. -TEST_F(AutofillManagerTest, GetCreditCardSuggestionsNonHTTPS) { +TEST_F(AutofillManagerTest, GetCreditCardSuggestions_NonHTTPS) { // Set up our form data. FormData form; CreateTestCreditCardFormData(&form, false, false); @@ -1546,7 +1579,7 @@ // Test that we return all credit card suggestions in the case that two cards // have the same obfuscated number. -TEST_F(AutofillManagerTest, GetCreditCardSuggestionsRepeatedObfuscatedNumber) { +TEST_F(AutofillManagerTest, GetCreditCardSuggestions_RepeatedObfuscatedNumber) { // Add a credit card with the same obfuscated number as Elvis's. // |credit_card| will be owned by the mock PersonalDataManager. CreditCard* credit_card = new CreditCard; @@ -1727,7 +1760,7 @@ Suggestion("Elvis", "", "", 1)); } -TEST_F(AutofillManagerTest, GetProfileSuggestionsFancyPhone) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_FancyPhone) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -1754,7 +1787,7 @@ Suggestion("12345678901", "3734 Elvis Presley Blvd.", "", 3)); } -TEST_F(AutofillManagerTest, GetProfileSuggestionsForPhonePrefixOrSuffix) { +TEST_F(AutofillManagerTest, GetProfileSuggestions_ForPhonePrefixOrSuffix) { // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); @@ -1870,7 +1903,7 @@ } // Test that we correctly fill a credit card form. -TEST_F(AutofillManagerTest, FillCreditCardForm) { +TEST_F(AutofillManagerTest, FillCreditCardForm_Simple) { // Set up our form data. FormData form; CreateTestCreditCardFormData(&form, true, false); @@ -1888,7 +1921,7 @@ } // Test that whitespace is stripped from the credit card number. -TEST_F(AutofillManagerTest, FillCreditCardFormStripCardNumberWhitespace) { +TEST_F(AutofillManagerTest, FillCreditCardForm_StripCardNumberWhitespace) { // Same as the SetUp(), but generate Elvis card with whitespace in credit // card number. personal_data_.CreateTestCreditCardWithWhitespace(); @@ -1909,7 +1942,7 @@ } // Test that separator characters are stripped from the credit card number. -TEST_F(AutofillManagerTest, FillCreditCardFormStripCardNumberSeparators) { +TEST_F(AutofillManagerTest, FillCreditCardForm_StripCardNumberSeparators) { // Same as the SetUp(), but generate Elvis card with separator characters in // credit card number. personal_data_.CreateTestCreditCardWithSeparators(); @@ -1931,7 +1964,7 @@ // Test that we correctly fill a credit card form with month input type. // 1. year empty, month empty -TEST_F(AutofillManagerTest, FillCreditCardFormNoYearNoMonth) { +TEST_F(AutofillManagerTest, FillCreditCardForm_NoYearNoMonth) { // Same as the SetUp(), but generate 4 credit cards with year month // combination. personal_data_.CreateTestCreditCardsYearAndMonth("", ""); @@ -1954,7 +1987,7 @@ // Test that we correctly fill a credit card form with month input type. // 2. year empty, month non-empty -TEST_F(AutofillManagerTest, FillCreditCardFormNoYearMonth) { +TEST_F(AutofillManagerTest, FillCreditCardForm_NoYearMonth) { // Same as the SetUp(), but generate 4 credit cards with year month // combination. personal_data_.CreateTestCreditCardsYearAndMonth("", "04"); @@ -1976,7 +2009,7 @@ // Test that we correctly fill a credit card form with month input type. // 3. year non-empty, month empty -TEST_F(AutofillManagerTest, FillCreditCardFormYearNoMonth) { +TEST_F(AutofillManagerTest, FillCreditCardForm_YearNoMonth) { // Same as the SetUp(), but generate 4 credit cards with year month // combination. personal_data_.CreateTestCreditCardsYearAndMonth("2999", ""); @@ -1998,7 +2031,7 @@ // Test that we correctly fill a credit card form with month input type. // 4. year non-empty, month empty -TEST_F(AutofillManagerTest, FillCreditCardFormYearMonth) { +TEST_F(AutofillManagerTest, FillCreditCardForm_YearMonth) { // Same as the SetUp(), but generate 4 credit cards with year month // combination. personal_data_.ClearCreditCards(); @@ -2021,7 +2054,7 @@ // Test that we correctly fill a credit card form with first and last cardholder // name. -TEST_F(AutofillManagerTest, FillCreditCardFormSplitName) { +TEST_F(AutofillManagerTest, FillCreditCardForm_SplitName) { // Set up our form data. FormData form; form.name = ASCIIToUTF16("MyForm"); @@ -2966,15 +2999,12 @@ autofill_manager_.reset( new TestAutofillManager(autofill_driver_.get(), &client, NULL)); autofill_manager_->set_autofill_enabled(false); - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), &client)); // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); + + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); EXPECT_CALL(*m, OnWillSubmitForm(_)); FormSubmitted(form); } @@ -2996,13 +3026,8 @@ const FormFieldData& field = form.fields[0]; // Expect Autocomplete manager to be called for suggestions. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), &client)); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*m, - OnGetAutocompleteSuggestions(_, _, _, _)); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)); GetAutofillSuggestions(form, field); } @@ -3026,13 +3051,9 @@ field.should_autocomplete = false; // Autocomplete manager is not called for suggestions. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), &client)); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*m, - OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); + + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); GetAutofillSuggestions(form, field); } @@ -3049,14 +3070,8 @@ const FormFieldData& field = form.fields[0]; // Autocomplete manager is not called for suggestions. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), - autofill_manager_->client())); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*m, - OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); GetAutofillSuggestions(form, field); @@ -3082,14 +3097,8 @@ test::CreateTestFormField("Email", "email", "donkey", "email", &field); // Autocomplete manager is called for suggestions because Autofill is empty. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), - autofill_manager_->client())); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*m, - OnGetAutocompleteSuggestions(_, _, _, _)); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)); GetAutofillSuggestions(form, field); } @@ -3115,12 +3124,7 @@ field.should_autocomplete = true; // Autocomplete manager is not called for suggestions. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), - autofill_manager_->client())); - MockAutocompleteHistoryManager* m = - static_cast<MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)); GetAutofillSuggestions(form, field); @@ -3146,11 +3150,7 @@ field.should_autocomplete = true; // Autocomplete manager is not called for suggestions. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), &client)); - MockAutocompleteHistoryManager* m = - static_cast<MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); GetAutofillSuggestions(form, field); @@ -3173,14 +3173,8 @@ test::CreateTestFormField("Email", "email", "donkey", "email", &field); // Autocomplete manager is not called for suggestions. - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), - autofill_manager_->client())); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*m, - OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); GetAutofillSuggestions(form, field); } @@ -3192,13 +3186,8 @@ autofill_manager_->set_autofill_enabled(false); autofill_manager_->SetExternalDelegate(external_delegate_.get()); - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), &client)); - MockAutocompleteHistoryManager* m = static_cast< - MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*m, - OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnGetAutocompleteSuggestions(_, _, _, _)).Times(0); // Set up our form data. FormData form; @@ -4125,7 +4114,8 @@ // Test to verify suggestions appears for forms having credit card number split // across fields. -TEST_F(AutofillManagerTest, GetCreditCardSuggestionsForNumberSpitAcrossFields) { +TEST_F(AutofillManagerTest, + GetCreditCardSuggestions_ForNumberSpitAcrossFields) { // Set up our form data with credit card number split across fields. FormData form; form.name = ASCIIToUTF16("MyForm"); @@ -4182,15 +4172,9 @@ // Test that inputs detected to be CVC inputs are forced to // !should_autocomplete for AutocompleteHistoryManager::OnWillSubmitForm. TEST_F(AutofillManagerTest, DontSaveCvcInAutocompleteHistory) { - autofill_manager_->autocomplete_history_manager_.reset( - new MockAutocompleteHistoryManager(autofill_driver_.get(), - &autofill_client_)); FormData form_seen_by_ahm; - MockAutocompleteHistoryManager* mock_ahm = - static_cast<MockAutocompleteHistoryManager*>( - autofill_manager_->autocomplete_history_manager_.get()); - EXPECT_CALL(*mock_ahm, OnWillSubmitForm(_)) - .WillOnce(SaveArg<0>(&form_seen_by_ahm)); + MockAutocompleteHistoryManager* m = RecreateMockAutocompleteHistoryManager(); + EXPECT_CALL(*m, OnWillSubmitForm(_)).WillOnce(SaveArg<0>(&form_seen_by_ahm)); FormData form; form.name = ASCIIToUTF16("MyForm");
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc index aed621c..7bcb4517 100644 --- a/components/autofill/core/browser/autofill_metrics.cc +++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -265,6 +265,13 @@ } // static +void AutofillMetrics::LogCreditCardFillingInfoBarMetric(InfoBarMetric metric) { + DCHECK_LT(metric, NUM_INFO_BAR_METRICS); + UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardFillingInfoBar", metric, + NUM_INFO_BAR_METRICS); +} + +// static void AutofillMetrics::LogSaveCardPromptMetric(SaveCardPromptMetric metric, bool is_uploading, bool is_reshow) {
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h index d0fcb7c..8f8b4239 100644 --- a/components/autofill/core/browser/autofill_metrics.h +++ b/components/autofill/core/browser/autofill_metrics.h
@@ -513,6 +513,7 @@ static void LogCardUploadDecisionMetric(CardUploadDecisionMetric metric); static void LogCreditCardInfoBarMetric(InfoBarMetric metric); + static void LogCreditCardFillingInfoBarMetric(InfoBarMetric metric); static void LogSaveCardPromptMetric(SaveCardPromptMetric metric, bool is_uploading, bool is_reshow);
diff --git a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc index 471e0d2f..4343a1f 100644 --- a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc +++ b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -97,7 +97,7 @@ InfoBarButton button) const { return l10n_util::GetStringUTF16(button == BUTTON_OK ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT - : IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY); + : IDS_NO_THANKS); } bool AutofillSaveCardInfoBarDelegateMobile::Accept() {
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 164bd717..5d6815f 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -290,6 +290,14 @@ return out; } +bool IsCreditCardExpirationType(ServerFieldType type) { + return type == CREDIT_CARD_EXP_MONTH || + type == CREDIT_CARD_EXP_2_DIGIT_YEAR || + type == CREDIT_CARD_EXP_4_DIGIT_YEAR || + type == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || + type == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR; +} + } // namespace FormStructure::FormStructure(const FormData& form) @@ -577,6 +585,22 @@ return ShouldBeParsed(); } +bool FormStructure::IsCompleteCreditCardForm() const { + bool found_cc_number = false; + bool found_cc_expiration = false; + for (const AutofillField* field : fields_) { + ServerFieldType type = field->Type().GetStorableType(); + if (!found_cc_expiration && IsCreditCardExpirationType(type)) { + found_cc_expiration = true; + } else if (!found_cc_number && type == CREDIT_CARD_NUMBER) { + found_cc_number = true; + } + if (found_cc_expiration && found_cc_number) + return true; + } + return false; +} + void FormStructure::UpdateAutofillCount() { autofill_count_ = 0; for (const AutofillField* field : *this) {
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index aab2a66..074c229 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -99,6 +99,11 @@ // auto-fillable, like google/yahoo/msn search, etc. bool IsAutofillable() const; + // Returns whether |this| form represents a complete Credit Card form, which + // consists in having at least a credit card number field and an expiration + // field. + bool IsCompleteCreditCardForm() const; + // Resets |autofill_count_| and counts the number of auto-fillable fields. // This is used when we receive server data for form fields. At that time, // we may have more known fields than just the number of fields we matched
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index 0463c67..8d7f6473 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -605,6 +605,129 @@ EXPECT_EQ(ADDRESS_HOME_LINE3, form_structure->field(2)->heuristic_type()); } +TEST_F(FormStructureTest, IsCompleteCreditCardForm_Minimal) { + std::unique_ptr<FormStructure> form_structure; + FormData form; + + FormFieldData field; + field.form_control_type = "text"; + + field.label = ASCIIToUTF16("Card Number"); + field.name = ASCIIToUTF16("card_number"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Expiration"); + field.name = ASCIIToUTF16("cc_exp"); + form.fields.push_back(field); + + // Another field to reach the minimum 3. + field.label = ASCIIToUTF16("Zip"); + field.name = ASCIIToUTF16("zip"); + form.fields.push_back(field); + + form_structure.reset(new FormStructure(form)); + form_structure->DetermineHeuristicTypes(); + + EXPECT_TRUE(form_structure->IsCompleteCreditCardForm()); +} + +TEST_F(FormStructureTest, IsCompleteCreditCardForm_Full) { + std::unique_ptr<FormStructure> form_structure; + FormData form; + + FormFieldData field; + field.form_control_type = "text"; + + field.label = ASCIIToUTF16("Name on Card"); + field.name = ASCIIToUTF16("name_on_card"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Card Number"); + field.name = ASCIIToUTF16("card_number"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Exp Month"); + field.name = ASCIIToUTF16("ccmonth"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Exp Year"); + field.name = ASCIIToUTF16("ccyear"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Verification"); + field.name = ASCIIToUTF16("verification"); + form.fields.push_back(field); + + field.label = base::string16(); + field.name = ASCIIToUTF16("Submit"); + field.form_control_type = "submit"; + form.fields.push_back(field); + + form_structure.reset(new FormStructure(form)); + form_structure->DetermineHeuristicTypes(); + + EXPECT_TRUE(form_structure->IsCompleteCreditCardForm()); +} + +// A form with only the credit card number is not considered sufficient. +TEST_F(FormStructureTest, IsCompleteCreditCardForm_OnlyCCNumber) { + std::unique_ptr<FormStructure> form_structure; + FormData form; + + FormFieldData field; + field.form_control_type = "text"; + + field.label = ASCIIToUTF16("Card Number"); + field.name = ASCIIToUTF16("card_number"); + form.fields.push_back(field); + + form_structure.reset(new FormStructure(form)); + form_structure->DetermineHeuristicTypes(); + + EXPECT_FALSE(form_structure->IsCompleteCreditCardForm()); +} + +// A form with only the credit card number is not considered sufficient. +TEST_F(FormStructureTest, IsCompleteCreditCardForm_AddressForm) { + std::unique_ptr<FormStructure> form_structure; + FormData form; + + FormFieldData field; + field.form_control_type = "text"; + + field.label = ASCIIToUTF16("First Name"); + field.name = base::string16(); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Last Name"); + field.name = base::string16(); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Email"); + field.name = base::string16(); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Phone"); + field.name = base::string16(); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Address"); + field.name = base::string16(); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Address"); + field.name = base::string16(); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Zip code"); + field.name = base::string16(); + form.fields.push_back(field); + form_structure.reset(new FormStructure(form)); + form_structure->DetermineHeuristicTypes(); + + EXPECT_FALSE(form_structure->IsCompleteCreditCardForm()); +} + // Verify that we can correctly process the 'autocomplete' attribute for phone // number types (especially phone prefixes and suffixes). TEST_F(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index 647696c..37ea5b5 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -66,6 +66,12 @@ callback.Run(); } +void TestAutofillClient::ConfirmCreditCardFillAssist( + const CreditCard& card, + const base::Closure& callback) { + callback.Run(); +} + void TestAutofillClient::LoadRiskData( const base::Callback<void(const std::string&)>& callback) { callback.Run("some risk data");
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index ea36a9c..e936e42e 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -43,6 +43,8 @@ const CreditCard& card, std::unique_ptr<base::DictionaryValue> legal_message, const base::Closure& callback) override; + void ConfirmCreditCardFillAssist(const CreditCard& card, + const base::Closure& callback) override; void LoadRiskData( const base::Callback<void(const std::string&)>& callback) override; bool HasCreditCardScanFeature() override;
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h index ab09290..872f6974 100644 --- a/components/autofill/core/common/autofill_constants.h +++ b/components/autofill/core/common/autofill_constants.h
@@ -32,6 +32,10 @@ // upload the form to and request predictions from the Autofill servers. const size_t kRequiredFieldsForFormsWithOnlyPasswordFields = 2; +// Special query id used between the browser and the renderer when the action +// is initiated from the browser. +const int kNoQueryId = -1; + // Options bitmask values for AutofillHostMsg_ShowPasswordSuggestions IPC enum ShowPasswordSuggestionsOptions { SHOW_ALL = 1 << 0 /* show all credentials, not just ones matching username */,
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp index 4b7b57e..1c8fef8a 100644 --- a/components/autofill_strings.grdp +++ b/components/autofill_strings.grdp
@@ -174,13 +174,18 @@ Use password for: </message> + <!-- Autofill Credit Card Assisted Filling Infobar --> + <message name="IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_TITLE" desc="Title text for the Autofill Credit Card Assisted Filling Infobar"> + Do you want to fill in your card info? + </message> + <message name="IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_ACCEPT" desc="Text to show for the Autofill credit card Assisted Filling infobar accept button."> + Fill in + </message> + <!-- Autofill save credit card bubble or infobar prompt --> <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT" desc="Text to show for the Autofill save credit card prompt accept button. The prompt can be either a bubble or an infobar."> Save </message> - <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY" desc="Text to show for the Autofill save credit card prompt deny button. The prompt can be either a bubble or an infobar."> - No thanks - </message> <if expr="_google_chrome"> <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_LOCAL" desc="Title text for the Autofill save card prompt when the card is to be saved locally. The prompt can be either a bubble or an infobar."> Do you want Chrome to save this card?
diff --git a/components/browsing_data/content/storage_partition_http_cache_data_remover.cc b/components/browsing_data/content/storage_partition_http_cache_data_remover.cc index b7126eee..c0f2051 100644 --- a/components/browsing_data/content/storage_partition_http_cache_data_remover.cc +++ b/components/browsing_data/content/storage_partition_http_cache_data_remover.cc
@@ -155,7 +155,7 @@ // Clear QUIC server information from memory and the disk cache. http_cache->GetSession() ->quic_stream_factory() - ->ClearCachedStatesInCryptoConfig(); + ->ClearCachedStatesInCryptoConfig(url_predicate_); // Clear SDCH dictionary state. net::SdchManager* sdch_manager =
diff --git a/components/cast_certificate/cast_cert_validator.cc b/components/cast_certificate/cast_cert_validator.cc index f7c62dd..9dcff2f 100644 --- a/components/cast_certificate/cast_cert_validator.cc +++ b/components/cast_certificate/cast_cert_validator.cc
@@ -251,14 +251,14 @@ return options; } -} // namespace - +// Verifies a cast device certficate given a chain of DER-encoded certificates. bool VerifyDeviceCert(const std::vector<std::string>& certs, const base::Time& time, std::unique_ptr<CertVerificationContext>* context, CastDeviceCertPolicy* policy, const CastCRL* crl, - CRLPolicy crl_policy) { + CRLPolicy crl_policy, + net::TrustStore* trust_store) { if (certs.empty()) return false; @@ -290,7 +290,7 @@ if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) return false; net::CertPathBuilder::Result result; - net::CertPathBuilder path_builder(target_cert.get(), &CastTrustStore::Get(), + net::CertPathBuilder path_builder(target_cert.get(), trust_store, signature_policy.get(), verification_time, &result); path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); @@ -322,6 +322,29 @@ return true; } +} // namespace + +bool VerifyDeviceCert(const std::vector<std::string>& certs, + const base::Time& time, + std::unique_ptr<CertVerificationContext>* context, + CastDeviceCertPolicy* policy, + const CastCRL* crl, + CRLPolicy crl_policy) { + return VerifyDeviceCert(certs, time, context, policy, crl, crl_policy, + &CastTrustStore::Get()); +} + +bool VerifyDeviceCertForTest(const std::vector<std::string>& certs, + const base::Time& time, + std::unique_ptr<CertVerificationContext>* context, + CastDeviceCertPolicy* policy, + const CastCRL* crl, + CRLPolicy crl_policy, + net::TrustStore* trust_store) { + return VerifyDeviceCert(certs, time, context, policy, crl, crl_policy, + trust_store); +} + std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest( const base::StringPiece& spki) { // Use a bogus CommonName, since this is just exposed for testing signature @@ -330,15 +353,4 @@ new CertVerificationContextImpl(net::der::Input(spki), "CommonName")); } -bool SetTrustAnchorForTest(const std::string& cert) { - scoped_refptr<net::ParsedCertificate> anchor( - net::ParsedCertificate::CreateFromCertificateCopy( - cert, GetCertParsingOptions())); - if (!anchor) - return false; - CastTrustStore::Get().Clear(); - CastTrustStore::Get().AddTrustedCertificate(std::move(anchor)); - return true; -} - } // namespace cast_certificate
diff --git a/components/cast_certificate/cast_cert_validator.h b/components/cast_certificate/cast_cert_validator.h index be924be7..a918dd58 100644 --- a/components/cast_certificate/cast_cert_validator.h +++ b/components/cast_certificate/cast_cert_validator.h
@@ -14,6 +14,9 @@ #include "base/strings/string_piece.h" #include "base/time/time.h" +namespace net { +class TrustStore; +} namespace cast_certificate { class CastCRL; @@ -59,7 +62,8 @@ DISALLOW_COPY_AND_ASSIGN(CertVerificationContext); }; -// Verifies a cast device certficate given a chain of DER-encoded certificates. +// Verifies a cast device certficate given a chain of DER-encoded certificates, +// using the built-in Cast trust anchors. // // Inputs: // @@ -95,6 +99,18 @@ const CastCRL* crl, CRLPolicy crl_policy) WARN_UNUSED_RESULT; +// Exposed only for testing, not for use in production code. +// +// This is an overloaded version of VerifyDeviceCert that allows +// the input of a custom TrustStore. +bool VerifyDeviceCertForTest(const std::vector<std::string>& certs, + const base::Time& time, + std::unique_ptr<CertVerificationContext>* context, + CastDeviceCertPolicy* policy, + const CastCRL* crl, + CRLPolicy crl_policy, + net::TrustStore* trust_store) WARN_UNUSED_RESULT; + // Exposed only for unit-tests, not for use in production code. // Production code would get a context from VerifyDeviceCert(). // @@ -103,12 +119,6 @@ std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest( const base::StringPiece& spki); -// Exposed only for testing, not for use in production code. -// -// Replaces trusted root certificates in the CastTrustStore. -// Returns true if successful, false if nothing is changed. -bool SetTrustAnchorForTest(const std::string& cert) WARN_UNUSED_RESULT; - } // namespace cast_certificate #endif // COMPONENTS_CAST_CERTIFICATE_CAST_CERT_VALIDATOR_H_
diff --git a/components/cast_certificate/cast_crl.cc b/components/cast_certificate/cast_crl.cc index 7efd90b..94ecb1a 100644 --- a/components/cast_certificate/cast_crl.cc +++ b/components/cast_certificate/cast_crl.cc
@@ -62,13 +62,12 @@ CastCRLTrustStore() { // Initialize the trust store with the root certificate. - // TODO(ryanchung): Add official Cast CRL Root here - // scoped_refptr<net::ParsedCertificate> root = net::ParsedCertificate:: - // net::ParsedCertificate::CreateFromCertificateData( - // kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), - // net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); - // CHECK(root); - // store_.AddTrustedCertificate(std::move(root)); + scoped_refptr<net::ParsedCertificate> root = + net::ParsedCertificate::CreateFromCertificateData( + kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), + net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); + CHECK(root); + store_.AddTrustedCertificate(std::move(root)); } net::TrustStore store_; @@ -101,6 +100,7 @@ bool VerifyCRL(const Crl& crl, const TbsCrl& tbs_crl, const base::Time& time, + net::TrustStore* trust_store, net::der::GeneralizedTime* overall_not_after) { // Verify the trust of the CRL authority. scoped_refptr<net::ParsedCertificate> parsed_cert = @@ -136,9 +136,9 @@ return false; } net::CertPathBuilder::Result result; - net::CertPathBuilder path_builder( - parsed_cert.get(), &CastCRLTrustStore::Get(), signature_policy.get(), - verification_time, &result); + net::CertPathBuilder path_builder(parsed_cert.get(), trust_store, + signature_policy.get(), verification_time, + &result); net::CompletionStatus rv = path_builder.Run(base::Closure()); DCHECK_EQ(rv, net::CompletionStatus::SYNC); if (!result.is_success() || result.paths.empty() || @@ -298,10 +298,11 @@ return true; } -} // namespace - +// Parses and verifies the CRL used to verify the revocation status of +// Cast device certificates. std::unique_ptr<CastCRL> ParseAndVerifyCRL(const std::string& crl_proto, - const base::Time& time) { + const base::Time& time, + net::TrustStore* trust_store) { CrlBundle crl_bundle; if (!crl_bundle.ParseFromString(crl_proto)) { LOG(ERROR) << "CRL - Binary could not be parsed."; @@ -317,7 +318,7 @@ continue; } net::der::GeneralizedTime overall_not_after; - if (!VerifyCRL(crl, tbs_crl, time, &overall_not_after)) { + if (!VerifyCRL(crl, tbs_crl, time, trust_store, &overall_not_after)) { LOG(ERROR) << "CRL - Verification failed."; return nullptr; } @@ -327,14 +328,18 @@ return nullptr; } -bool SetCRLTrustAnchorForTest(const std::string& cert) { - scoped_refptr<net::ParsedCertificate> anchor( - net::ParsedCertificate::CreateFromCertificateCopy(cert, {})); - if (!anchor) - return false; - CastCRLTrustStore::Get().Clear(); - CastCRLTrustStore::Get().AddTrustedCertificate(std::move(anchor)); - return true; +} // namespace + +std::unique_ptr<CastCRL> ParseAndVerifyCRL(const std::string& crl_proto, + const base::Time& time) { + return ParseAndVerifyCRL(crl_proto, time, &CastCRLTrustStore::Get()); +} + +std::unique_ptr<CastCRL> ParseAndVerifyCRLForTest( + const std::string& crl_proto, + const base::Time& time, + net::TrustStore* trust_store) { + return ParseAndVerifyCRL(crl_proto, time, trust_store); } } // namespace cast_certificate
diff --git a/components/cast_certificate/cast_crl.h b/components/cast_certificate/cast_crl.h index e95faf48..f7d102a9 100644 --- a/components/cast_certificate/cast_crl.h +++ b/components/cast_certificate/cast_crl.h
@@ -14,6 +14,10 @@ #include "base/time/time.h" #include "net/cert/internal/parsed_certificate.h" +namespace net { +class TrustStore; +} + namespace cast_certificate { // This class represents the CRL information parsed from the binary proto. @@ -40,7 +44,7 @@ }; // Parses and verifies the CRL used to verify the revocation status of -// Cast device certificates. +// Cast device certificates, using the built-in Cast CRL trust anchors. // // Inputs: // * |crl_proto| is a serialized cast_certificate.CrlBundle proto. @@ -53,11 +57,11 @@ // Exposed only for testing, not for use in production code. // -// Replaces trusted root certificates into the CastCRLTrustStore. -// -// Output: -// Returns true if successful, false if nothing is changed. -bool SetCRLTrustAnchorForTest(const std::string& cert) WARN_UNUSED_RESULT; +// This is an overloaded version of ParseAndVerifyCRL that allows +// the input of a custom TrustStore. +std::unique_ptr<CastCRL> ParseAndVerifyCRLForTest(const std::string& crl_proto, + const base::Time& time, + net::TrustStore* trust_store); } // namespace cast_certificate
diff --git a/components/cast_certificate/cast_crl_root_ca_cert_der-inc.h b/components/cast_certificate/cast_crl_root_ca_cert_der-inc.h index 5463d19..75380151 100644 --- a/components/cast_certificate/cast_crl_root_ca_cert_der-inc.h +++ b/components/cast_certificate/cast_crl_root_ca_cert_der-inc.h
@@ -2,7 +2,149 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(ryanchung): Add Cast CRL Root here. +// Certificate: +// Data: +// Version: 3 (0x2) +// Serial Number: 153 (0x99) +// Signature Algorithm: sha256WithRSAEncryption +// Issuer: C=US, ST=California, L=Mountain View, O=Google Inc, +// OU=Cast, CN=Cast CRL Root CA +// Validity +// Not Before: Aug 1 21:47:47 2016 GMT +// Not After : Jul 27 21:47:47 2036 GMT +// Subject: C=US, ST=California, L=Mountain View, O=Google Inc, OU=Cast, +// CN=Cast CRL Root CA +// Subject Public Key Info: +// Public Key Algorithm: rsaEncryption +// Public-Key: (2048 bit) +// Modulus: +// 00:c2:7f:c0:09:21:d3:60:89:28:b5:96:6e:fe:a6: +// ad:fe:ae:e0:66:35:bd:99:6e:e8:93:85:29:ba:de: +// 44:5d:a8:6b:fc:e6:cc:37:dd:1d:0f:cf:1e:3a:32: +// 2c:7f:e0:1b:c9:bb:4c:34:a9:1c:97:b5:f8:6d:42: +// 9c:4d:06:6a:a0:2d:95:55:3f:78:1d:5c:ab:e9:3a: +// a6:08:3b:5a:af:f4:ab:53:77:14:9a:6b:b2:37:2e: +// cd:6e:ea:bc:22:5d:56:55:73:fd:bd:03:2f:54:5e: +// 7f:8b:c1:74:36:1a:18:1f:64:de:bf:08:80:4a:12: +// 0c:49:53:b8:c7:3b:db:5f:dc:59:77:2f:b8:3a:05: +// 8a:f6:b7:47:2a:9b:74:63:08:31:12:e6:7b:44:d1: +// c1:7c:c8:87:b8:50:63:6d:9f:d7:ba:36:53:72:47: +// 5f:dc:43:43:eb:d7:2e:11:d1:8a:7a:a4:03:f2:6a: +// d3:88:e6:a7:b8:9d:81:b2:b0:88:24:c8:a1:fa:b0: +// aa:db:08:64:3e:8b:2a:07:5c:5a:82:05:99:c2:d5: +// ca:52:75:21:a7:fa:c5:a1:da:ac:f7:fe:d0:c7:44: +// 76:9a:eb:6b:d3:bd:f4:7a:31:a6:ad:2f:5a:c4:31: +// 3a:6d:f1:dd:7b:44:81:37:cf:13:85:5d:96:ae:7b: +// 96:2b +// Exponent: 65537 (0x10001) +// X509v3 extensions: +// X509v3 Basic Constraints: +// CA:TRUE, pathlen:1 +// X509v3 Subject Key Identifier: +// 1A:65:12:B4:A9:B9:B4:FC:91:0C:9E:67:E0:5B:D9:C9:AD:44:1C:B9 +// X509v3 Authority Key Identifier: +// keyid:1A:65:12:B4:A9:B9:B4:FC:91:0C:9E:67:E0:5B:D9:C9:AD:44 +// :1C:B9 +// +// X509v3 Key Usage: +// Certificate Sign +// Signature Algorithm: sha256WithRSAEncryption +// af:5f:8b:c0:f7:c5:26:88:b9:ac:f7:ec:4d:0f:76:ab:e2:74: +// 9a:44:3c:33:f6:74:3d:04:2a:59:76:a2:05:27:c4:e3:a2:c8: +// c2:af:7e:fd:be:b9:ca:e9:5b:a8:2a:cd:a7:1e:0e:37:f1:6f: +// 84:5e:aa:42:1f:ba:f0:44:ba:db:87:61:68:91:bb:1d:5c:3a: +// f0:8e:02:20:76:aa:47:99:c7:73:0d:90:32:4a:b9:e3:fd:11: +// 8b:5d:bd:22:4d:05:75:17:61:a2:a6:4f:b0:3d:52:8e:aa:c9: +// b4:8d:05:5a:1c:36:c1:7b:87:f7:f8:e4:81:36:27:ec:35:ae: +// b9:ce:15:47:e1:10:c9:16:69:3a:22:8e:63:18:31:cc:3b:56: +// 69:c6:d4:24:dd:95:25:cf:34:e6:00:ae:e1:87:1e:ee:0c:14: +// dc:0d:82:81:31:1f:8f:6d:d2:c0:e1:7c:12:f7:9d:ca:02:e3: +// 76:36:44:53:3a:87:71:7d:ed:32:4c:a4:96:e6:e5:2c:c7:0d: +// b7:96:c0:f3:7d:e5:58:32:f7:25:25:c0:13:76:d0:76:6c:73: +// ab:3d:15:cd:c5:e8:85:15:9a:02:52:e9:61:41:e2:66:01:c5: +// 71:e5:db:c0:a5:b3:4c:1e:ac:93:8a:35:4c:4d:da:57:22:24: +// 1d:3a:f6:bd const unsigned char kCastCRLRootCaDer[] = { - 0x30, + 0x30, 0x82, 0x03, 0xce, 0x30, 0x82, 0x02, 0xb6, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x00, 0x99, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x79, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, + 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x04, 0x43, 0x61, 0x73, 0x74, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x61, 0x73, 0x74, 0x20, + 0x43, 0x52, 0x4c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x30, 0x31, 0x32, 0x31, 0x34, + 0x37, 0x34, 0x37, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x37, 0x32, 0x37, + 0x32, 0x31, 0x34, 0x37, 0x34, 0x37, 0x5a, 0x30, 0x79, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, + 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x20, 0x49, 0x6e, 0x63, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x04, 0x43, 0x61, 0x73, 0x74, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x61, 0x73, 0x74, 0x20, 0x43, + 0x52, 0x4c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc2, 0x7f, 0xc0, 0x09, 0x21, + 0xd3, 0x60, 0x89, 0x28, 0xb5, 0x96, 0x6e, 0xfe, 0xa6, 0xad, 0xfe, 0xae, + 0xe0, 0x66, 0x35, 0xbd, 0x99, 0x6e, 0xe8, 0x93, 0x85, 0x29, 0xba, 0xde, + 0x44, 0x5d, 0xa8, 0x6b, 0xfc, 0xe6, 0xcc, 0x37, 0xdd, 0x1d, 0x0f, 0xcf, + 0x1e, 0x3a, 0x32, 0x2c, 0x7f, 0xe0, 0x1b, 0xc9, 0xbb, 0x4c, 0x34, 0xa9, + 0x1c, 0x97, 0xb5, 0xf8, 0x6d, 0x42, 0x9c, 0x4d, 0x06, 0x6a, 0xa0, 0x2d, + 0x95, 0x55, 0x3f, 0x78, 0x1d, 0x5c, 0xab, 0xe9, 0x3a, 0xa6, 0x08, 0x3b, + 0x5a, 0xaf, 0xf4, 0xab, 0x53, 0x77, 0x14, 0x9a, 0x6b, 0xb2, 0x37, 0x2e, + 0xcd, 0x6e, 0xea, 0xbc, 0x22, 0x5d, 0x56, 0x55, 0x73, 0xfd, 0xbd, 0x03, + 0x2f, 0x54, 0x5e, 0x7f, 0x8b, 0xc1, 0x74, 0x36, 0x1a, 0x18, 0x1f, 0x64, + 0xde, 0xbf, 0x08, 0x80, 0x4a, 0x12, 0x0c, 0x49, 0x53, 0xb8, 0xc7, 0x3b, + 0xdb, 0x5f, 0xdc, 0x59, 0x77, 0x2f, 0xb8, 0x3a, 0x05, 0x8a, 0xf6, 0xb7, + 0x47, 0x2a, 0x9b, 0x74, 0x63, 0x08, 0x31, 0x12, 0xe6, 0x7b, 0x44, 0xd1, + 0xc1, 0x7c, 0xc8, 0x87, 0xb8, 0x50, 0x63, 0x6d, 0x9f, 0xd7, 0xba, 0x36, + 0x53, 0x72, 0x47, 0x5f, 0xdc, 0x43, 0x43, 0xeb, 0xd7, 0x2e, 0x11, 0xd1, + 0x8a, 0x7a, 0xa4, 0x03, 0xf2, 0x6a, 0xd3, 0x88, 0xe6, 0xa7, 0xb8, 0x9d, + 0x81, 0xb2, 0xb0, 0x88, 0x24, 0xc8, 0xa1, 0xfa, 0xb0, 0xaa, 0xdb, 0x08, + 0x64, 0x3e, 0x8b, 0x2a, 0x07, 0x5c, 0x5a, 0x82, 0x05, 0x99, 0xc2, 0xd5, + 0xca, 0x52, 0x75, 0x21, 0xa7, 0xfa, 0xc5, 0xa1, 0xda, 0xac, 0xf7, 0xfe, + 0xd0, 0xc7, 0x44, 0x76, 0x9a, 0xeb, 0x6b, 0xd3, 0xbd, 0xf4, 0x7a, 0x31, + 0xa6, 0xad, 0x2f, 0x5a, 0xc4, 0x31, 0x3a, 0x6d, 0xf1, 0xdd, 0x7b, 0x44, + 0x81, 0x37, 0xcf, 0x13, 0x85, 0x5d, 0x96, 0xae, 0x7b, 0x96, 0x2b, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x1a, 0x65, 0x12, 0xb4, 0xa9, 0xb9, 0xb4, 0xfc, 0x91, 0x0c, 0x9e, 0x67, + 0xe0, 0x5b, 0xd9, 0xc9, 0xad, 0x44, 0x1c, 0xb9, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x1a, 0x65, 0x12, + 0xb4, 0xa9, 0xb9, 0xb4, 0xfc, 0x91, 0x0c, 0x9e, 0x67, 0xe0, 0x5b, 0xd9, + 0xc9, 0xad, 0x44, 0x1c, 0xb9, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0xaf, 0x5f, 0x8b, 0xc0, 0xf7, 0xc5, 0x26, 0x88, 0xb9, 0xac, + 0xf7, 0xec, 0x4d, 0x0f, 0x76, 0xab, 0xe2, 0x74, 0x9a, 0x44, 0x3c, 0x33, + 0xf6, 0x74, 0x3d, 0x04, 0x2a, 0x59, 0x76, 0xa2, 0x05, 0x27, 0xc4, 0xe3, + 0xa2, 0xc8, 0xc2, 0xaf, 0x7e, 0xfd, 0xbe, 0xb9, 0xca, 0xe9, 0x5b, 0xa8, + 0x2a, 0xcd, 0xa7, 0x1e, 0x0e, 0x37, 0xf1, 0x6f, 0x84, 0x5e, 0xaa, 0x42, + 0x1f, 0xba, 0xf0, 0x44, 0xba, 0xdb, 0x87, 0x61, 0x68, 0x91, 0xbb, 0x1d, + 0x5c, 0x3a, 0xf0, 0x8e, 0x02, 0x20, 0x76, 0xaa, 0x47, 0x99, 0xc7, 0x73, + 0x0d, 0x90, 0x32, 0x4a, 0xb9, 0xe3, 0xfd, 0x11, 0x8b, 0x5d, 0xbd, 0x22, + 0x4d, 0x05, 0x75, 0x17, 0x61, 0xa2, 0xa6, 0x4f, 0xb0, 0x3d, 0x52, 0x8e, + 0xaa, 0xc9, 0xb4, 0x8d, 0x05, 0x5a, 0x1c, 0x36, 0xc1, 0x7b, 0x87, 0xf7, + 0xf8, 0xe4, 0x81, 0x36, 0x27, 0xec, 0x35, 0xae, 0xb9, 0xce, 0x15, 0x47, + 0xe1, 0x10, 0xc9, 0x16, 0x69, 0x3a, 0x22, 0x8e, 0x63, 0x18, 0x31, 0xcc, + 0x3b, 0x56, 0x69, 0xc6, 0xd4, 0x24, 0xdd, 0x95, 0x25, 0xcf, 0x34, 0xe6, + 0x00, 0xae, 0xe1, 0x87, 0x1e, 0xee, 0x0c, 0x14, 0xdc, 0x0d, 0x82, 0x81, + 0x31, 0x1f, 0x8f, 0x6d, 0xd2, 0xc0, 0xe1, 0x7c, 0x12, 0xf7, 0x9d, 0xca, + 0x02, 0xe3, 0x76, 0x36, 0x44, 0x53, 0x3a, 0x87, 0x71, 0x7d, 0xed, 0x32, + 0x4c, 0xa4, 0x96, 0xe6, 0xe5, 0x2c, 0xc7, 0x0d, 0xb7, 0x96, 0xc0, 0xf3, + 0x7d, 0xe5, 0x58, 0x32, 0xf7, 0x25, 0x25, 0xc0, 0x13, 0x76, 0xd0, 0x76, + 0x6c, 0x73, 0xab, 0x3d, 0x15, 0xcd, 0xc5, 0xe8, 0x85, 0x15, 0x9a, 0x02, + 0x52, 0xe9, 0x61, 0x41, 0xe2, 0x66, 0x01, 0xc5, 0x71, 0xe5, 0xdb, 0xc0, + 0xa5, 0xb3, 0x4c, 0x1e, 0xac, 0x93, 0x8a, 0x35, 0x4c, 0x4d, 0xda, 0x57, + 0x22, 0x24, 0x1d, 0x3a, 0xf6, 0xbd, };
diff --git a/components/cast_certificate/cast_crl_unittest.cc b/components/cast_certificate/cast_crl_unittest.cc index d65b3a63..5698dbe 100644 --- a/components/cast_certificate/cast_crl_unittest.cc +++ b/components/cast_certificate/cast_crl_unittest.cc
@@ -7,11 +7,27 @@ #include "components/cast_certificate/cast_cert_validator_test_helpers.h" #include "components/cast_certificate/cast_crl.h" #include "components/cast_certificate/proto/test_suite.pb.h" +#include "net/cert/internal/trust_store.h" #include "testing/gtest/include/gtest/gtest.h" namespace cast_certificate { namespace { +// Creates a trust store using the test roots encoded in the PEM file at |path|. +std::unique_ptr<net::TrustStore> CreateTrustStoreFromFile( + const std::string& path) { + std::unique_ptr<net::TrustStore> trust_store(new net::TrustStore()); + const auto trusted_test_roots = + cast_certificate::testing::ReadCertificateChainFromFile(path); + for (const auto& trusted_root : trusted_test_roots) { + scoped_refptr<net::ParsedCertificate> anchor( + net::ParsedCertificate::CreateFromCertificateCopy(trusted_root, {})); + EXPECT_TRUE(anchor); + trust_store->AddTrustedCertificate(std::move(anchor)); + } + return trust_store; +} + // Converts uint64_t unix timestamp in seconds to base::Time. base::Time ConvertUnixTimestampSeconds(uint64_t time) { return base::Time::UnixEpoch() + @@ -28,11 +44,19 @@ // and chains up to a trust anchor. bool TestVerifyCertificate(TestStepResult expected_result, const std::vector<std::string>& certificate_chain, - const base::Time& time) { + const base::Time& time, + net::TrustStore* cast_trust_store) { std::unique_ptr<CertVerificationContext> context; CastDeviceCertPolicy policy; - bool result = VerifyDeviceCert(certificate_chain, time, &context, &policy, - nullptr, CRLPolicy::CRL_OPTIONAL); + int result; + if (cast_trust_store != nullptr) { + result = VerifyDeviceCertForTest(certificate_chain, time, &context, &policy, + nullptr, CRLPolicy::CRL_OPTIONAL, + cast_trust_store); + } else { + result = VerifyDeviceCert(certificate_chain, time, &context, &policy, + nullptr, CRLPolicy::CRL_OPTIONAL); + } if (expected_result != RESULT_SUCCESS) { EXPECT_FALSE(result); return !result; @@ -46,8 +70,14 @@ // The validity of the CRL is also checked at the specified time. bool TestVerifyCRL(TestStepResult expected_result, const std::string& crl_bundle, - const base::Time& time) { - std::unique_ptr<CastCRL> crl = ParseAndVerifyCRL(crl_bundle, time); + const base::Time& time, + net::TrustStore* crl_trust_store) { + std::unique_ptr<CastCRL> crl; + if (crl_trust_store != nullptr) { + crl = ParseAndVerifyCRLForTest(crl_bundle, time, crl_trust_store); + } else { + crl = ParseAndVerifyCRL(crl_bundle, time); + } if (expected_result != RESULT_SUCCESS) { EXPECT_EQ(crl, nullptr); return crl == nullptr; @@ -66,10 +96,16 @@ const std::string& crl_bundle, const base::Time& crl_time, const base::Time& cert_time, - bool crl_required) { + bool crl_required, + net::TrustStore* cast_trust_store, + net::TrustStore* crl_trust_store) { std::unique_ptr<CastCRL> crl; if (!crl_bundle.empty()) { - crl = ParseAndVerifyCRL(crl_bundle, crl_time); + if (crl_trust_store != nullptr) { + crl = ParseAndVerifyCRLForTest(crl_bundle, crl_time, crl_trust_store); + } else { + crl = ParseAndVerifyCRL(crl_bundle, crl_time); + } EXPECT_NE(crl.get(), nullptr); } @@ -78,8 +114,15 @@ CRLPolicy crl_policy = CRLPolicy::CRL_REQUIRED; if (!crl_required) crl_policy = CRLPolicy::CRL_OPTIONAL; - int result = VerifyDeviceCert(certificate_chain, cert_time, &context, &policy, - crl.get(), crl_policy); + int result; + if (cast_trust_store != nullptr) { + result = + VerifyDeviceCertForTest(certificate_chain, cert_time, &context, &policy, + crl.get(), crl_policy, cast_trust_store); + } else { + result = VerifyDeviceCert(certificate_chain, cert_time, &context, &policy, + crl.get(), crl_policy); + } if (expected_result != RESULT_SUCCESS) { EXPECT_FALSE(result); return !result; @@ -90,21 +133,17 @@ // Runs a single test case. bool RunTest(const DeviceCertTest& test_case) { - bool use_test_trust_anchors = test_case.use_test_trust_anchors(); - if (use_test_trust_anchors) { - const auto crl_test_root = - cast_certificate::testing::ReadCertificateChainFromFile( - "certificates/cast_crl_test_root_ca.pem"); - EXPECT_EQ(crl_test_root.size(), 1u); - EXPECT_TRUE(SetCRLTrustAnchorForTest(crl_test_root[0])); - const auto cast_test_root = - cast_certificate::testing::ReadCertificateChainFromFile( - "certificates/cast_test_root_ca.pem"); - EXPECT_EQ(cast_test_root.size(), 1u); - EXPECT_TRUE(SetTrustAnchorForTest(cast_test_root[0])); - } + std::unique_ptr<net::TrustStore> crl_trust_store; + std::unique_ptr<net::TrustStore> cast_trust_store; + if (test_case.use_test_trust_anchors()) { + crl_trust_store = + CreateTrustStoreFromFile("certificates/cast_crl_test_root_ca.pem"); + cast_trust_store = + CreateTrustStoreFromFile("certificates/cast_test_root_ca.pem"); - VerificationResult expected_result = test_case.expected_result(); + EXPECT_TRUE(crl_trust_store.get()); + EXPECT_TRUE(cast_trust_store.get()); + } std::vector<std::string> certificate_chain; for (auto const& cert : test_case.der_cert_path()) { @@ -121,38 +160,49 @@ crl_verification_time = cert_verification_time; std::string crl_bundle = test_case.crl_bundle(); - switch (expected_result) { + switch (test_case.expected_result()) { case PATH_VERIFICATION_FAILED: return TestVerifyCertificate(RESULT_FAIL, certificate_chain, - cert_verification_time); + cert_verification_time, + cast_trust_store.get()); break; case CRL_VERIFICATION_FAILED: - return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time); + return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time, + crl_trust_store.get()); break; case REVOCATION_CHECK_FAILED_WITHOUT_CRL: return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, - cert_verification_time) && - TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time) && + cert_verification_time, + cast_trust_store.get()) && + TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time, + crl_trust_store.get()) && TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, crl_verification_time, cert_verification_time, - true); + true, cast_trust_store.get(), + crl_trust_store.get()); break; case REVOCATION_CHECK_FAILED: return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, - cert_verification_time) && - TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time) && + cert_verification_time, + cast_trust_store.get()) && + TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time, + crl_trust_store.get()) && TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, crl_verification_time, cert_verification_time, - false); + false, cast_trust_store.get(), + crl_trust_store.get()); break; case SUCCESS: - return (crl_bundle.empty() || TestVerifyCRL(RESULT_SUCCESS, crl_bundle, - crl_verification_time)) && + return (crl_bundle.empty() || + TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time, + crl_trust_store.get())) && TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, - cert_verification_time) && + cert_verification_time, + cast_trust_store.get()) && TestVerifyRevocation(RESULT_SUCCESS, certificate_chain, crl_bundle, crl_verification_time, cert_verification_time, - !crl_bundle.empty()); + !crl_bundle.empty(), cast_trust_store.get(), + crl_trust_store.get()); break; case UNSPECIFIED: return false;
diff --git a/components/components_strings.grd b/components/components_strings.grd index bd5901b..8e1adc5 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -227,6 +227,9 @@ <message name="IDS_OK" desc="Used for OK on buttons"> OK </message> + <message name="IDS_NO_THANKS" desc="Used to dismiss various prompts."> + No thanks + </message> <if expr="not use_titlecase"> <message name="IDS_NOT_NOW" desc="Used on a button that avoids taking a suggested action. The action will likely be suggested again or automatically taken later."> Not now
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 333b164..0ebb2f0 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -833,6 +833,90 @@ 'supervised_user_error_page_unittest_sources': [ 'supervised_user_error_page/supervised_user_error_page_unittest.cc', ], + 'sync_unittest_sources': [ + 'sync/api/attachments/attachment_id_unittest.cc', + 'sync/api/attachments/attachment_metadata_unittest.cc', + 'sync/api/attachments/attachment_unittest.cc', + 'sync/api/entity_data_unittest.cc', + 'sync/api/model_type_service_unittest.cc', + 'sync/api/sync_change_unittest.cc', + 'sync/api/sync_data_unittest.cc', + 'sync/api/sync_error_unittest.cc', + 'sync/api/sync_merge_result_unittest.cc', + 'sync/engine_impl/apply_control_data_updates_unittest.cc', + 'sync/engine_impl/backoff_delay_provider_unittest.cc', + 'sync/engine_impl/directory_commit_contribution_unittest.cc', + 'sync/engine_impl/directory_update_handler_unittest.cc', + 'sync/engine_impl/get_updates_processor_unittest.cc', + 'sync/engine_impl/model_type_worker_unittest.cc', + 'sync/engine_impl/sync_scheduler_unittest.cc', + 'sync/engine_impl/syncer_proto_util_unittest.cc', + 'sync/engine_impl/syncer_unittest.cc', + 'sync/engine_impl/syncer_util_unittest.cc', + 'sync/engine_impl/worker_entity_tracker_unittest.cc', + 'sync/core_impl/attachments/attachment_downloader_impl_unittest.cc', + 'sync/core_impl/attachments/attachment_service_impl_unittest.cc', + 'sync/core_impl/attachments/attachment_service_proxy_unittest.cc', + 'sync/core_impl/attachments/attachment_store_frontend_unittest.cc', + 'sync/core_impl/attachments/attachment_store_test_template.h', + 'sync/core_impl/attachments/attachment_uploader_impl_unittest.cc', + 'sync/core_impl/attachments/fake_attachment_downloader_unittest.cc', + 'sync/core_impl/attachments/fake_attachment_uploader_unittest.cc', + 'sync/core_impl/attachments/in_memory_attachment_store_unittest.cc', + 'sync/core_impl/attachments/on_disk_attachment_store_unittest.cc', + 'sync/core_impl/attachments/task_queue_unittest.cc', + 'sync/core_impl/debug_info_event_listener_unittest.cc', + 'sync/core/http_bridge_unittest.cc', + 'sync/core_impl/js_mutation_event_observer_unittest.cc', + 'sync/core_impl/js_sync_encryption_handler_observer_unittest.cc', + 'sync/core_impl/js_sync_manager_observer_unittest.cc', + 'sync/core_impl/model_type_connector_proxy_unittest.cc', + 'sync/core/model_type_store_backend_unittest.cc', + 'sync/core/model_type_store_impl_unittest.cc', + 'sync/core/processor_entity_tracker_unittest.cc', + 'sync/core_impl/protocol_event_buffer_unittest.cc', + 'sync/base/attachment_id_proto_unittest.cc', + 'sync/base/cancelation_signal_unittest.cc', + 'sync/base/enum_set_unittest.cc', + 'sync/base/node_ordinal_unittest.cc', + 'sync/base/ordinal_unittest.cc', + 'sync/base/unique_position_unittest.cc', + 'sync/core/change_record_unittest.cc', + 'sync/core/data_batch_impl_unittest.cc', + 'sync/engine/model_safe_worker_unittest.cc', + 'sync/sessions/sync_session_snapshot_unittest.cc', + 'sync/core/simple_metadata_change_list_unittest.cc', + 'sync/base/immutable_unittest.cc', + 'sync/base/proto_value_ptr_unittest.cc', + 'sync/base/weak_handle_unittest.cc', + 'sync/core/shared_model_type_processor_unittest.cc', + 'sync/core_impl/sync_encryption_handler_impl_unittest.cc', + 'sync/core_impl/sync_manager_impl_unittest.cc', + 'sync/core_impl/syncapi_server_connection_manager_unittest.cc', + 'sync/js/js_event_details_unittest.cc', + 'sync/js/sync_js_controller_unittest.cc', + 'sync/protocol/proto_enum_conversions_unittest.cc', + 'sync/protocol/proto_value_conversions_unittest.cc', + 'sync/sessions_impl/model_type_registry_unittest.cc', + 'sync/sessions_impl/nudge_tracker_unittest.cc', + 'sync/sessions_impl/status_controller_unittest.cc', + 'sync/syncable/directory_backing_store_unittest.cc', + 'sync/syncable/directory_unittest.cc', + 'sync/syncable/directory_unittest.h', + 'sync/syncable/entry_kernel_unittest.cc', + 'sync/syncable/model_type_unittest.cc', + 'sync/syncable/nigori_util_unittest.cc', + 'sync/syncable/parent_child_index_unittest.cc', + 'sync/syncable/syncable_enum_conversions_unittest.cc', + 'sync/syncable/syncable_id_unittest.cc', + 'sync/syncable/syncable_unittest.cc', + 'sync/syncable/syncable_util_unittest.cc', + 'sync/base/cryptographer_unittest.cc', + 'sync/base/data_type_histogram_unittest.cc', + 'sync/base/get_session_name_unittest.cc', + 'sync/base/nigori_unittest.cc', + 'sync/base/protobuf_unittest.cc', + ], 'sync_bookmarks_unittest_sources': [ 'sync_bookmarks/bookmark_data_type_controller_unittest.cc', ], @@ -1103,6 +1187,7 @@ '<@(subresource_filter_core_common_unittest_sources)', '<@(suggestions_unittest_sources)', '<@(supervised_user_error_page_unittest_sources)', + '<@(sync_unittest_sources)', '<@(sync_bookmarks_unittest_sources)', '<@(sync_driver_unittest_sources)', '<@(sync_sessions_unittest_sources)', @@ -1129,8 +1214,6 @@ '../jingle/jingle.gyp:notifier_test_util', '../net/net.gyp:net_test_support', '../sql/sql.gyp:test_support_sql', - '../components/sync.gyp:sync', - '../components/sync.gyp:test_support_sync_api', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', '../third_party/icu/icu.gyp:icui18n', @@ -1277,6 +1360,10 @@ 'mime_util/mime_util.gyp:mime_util', 'prefs/prefs.gyp:prefs', 'prefs/prefs.gyp:prefs_test_support', + 'sync.gyp:sync', + 'sync.gyp:test_support_sync_api', + 'sync.gyp:test_support_sync_core', + 'sync.gyp:test_support_sync_core_impl', 'url_formatter/url_formatter.gyp:url_formatter', ], 'conditions': [ @@ -1444,6 +1531,9 @@ # component directory structure). ['exclude', '^[^/]*/content/'], ], + 'sources!': [ + 'core/http_bridge_unittest.cc', + ], 'mac_bundle_resources': [ '<(PRODUCT_DIR)/ui_test.pak', ], @@ -1500,6 +1590,7 @@ }], ['OS == "android"', { 'sources': [ + 'autofill/core/browser/autofill_assistant_unittest.cc', 'data_usage/android/traffic_stats_amortizer_unittest.cc', 'invalidation/impl/invalidation_logger_unittest.cc', 'invalidation/impl/invalidation_service_android_unittest.cc',
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index 0496f19..3f3ed4b 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -30,12 +30,6 @@ jni_package = "cronet" } -java_cpp_enum("chromium_effective_connection_type_java") { - sources = [ - "//net/nqe/effective_connection_type.h", - ] -} - java_cpp_enum("chromium_url_request_java") { sources = [ "chromium_url_request.h", @@ -280,7 +274,6 @@ "api/src/org/chromium/net/ChunkedWritableByteChannel.java", "api/src/org/chromium/net/CronetEngine.java", "api/src/org/chromium/net/CronetException.java", - "api/src/org/chromium/net/EffectiveConnectionType.java", "api/src/org/chromium/net/HttpUrlConnectionUrlRequest.java", "api/src/org/chromium/net/HttpUrlConnectionUrlRequestFactory.java", "api/src/org/chromium/net/HttpUrlRequest.java", @@ -311,7 +304,6 @@ ] srcjar_deps = [ - ":chromium_effective_connection_type_java", ":cronet_api_version_srcjar", ":http_cache_type_java", ":url_request_error_java",
diff --git a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java index 7a01c44..b7013e2f 100644 --- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java +++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
@@ -958,13 +958,6 @@ public abstract byte[] getGlobalMetricsDeltas(); /** - * Returns the effective connection type computed by the network quality - * estimator. - * @hide as it's a prototype. - */ - public abstract int getEffectiveConnectionType(); - - /** * Configures the network quality estimator for testing. This must be called * before round trip time and throughput listeners are added, and after the * network quality estimator has been enabled.
diff --git a/components/cronet/android/api/src/org/chromium/net/EffectiveConnectionType.java b/components/cronet/android/api/src/org/chromium/net/EffectiveConnectionType.java deleted file mode 100644 index 32fa154ae..0000000 --- a/components/cronet/android/api/src/org/chromium/net/EffectiveConnectionType.java +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.net; - -import android.support.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Different values of the effective connection type as computed by the network - * quality estimator. EffectiveConnectionType is the connection type whose - * typical performance is most similar to the measured performance of the - * network in use. In many cases, the "effective" connection type and the actual - * type of connection in use are the same, but often a network connection - * performs significantly differently, usually worse, from its expected - * capabilities. EffectiveConnectionType of a network is independent of if the - * current connection is metered or not. For example, an unmetered slow - * connection may have EFFECTIVE_CONNECTION_TYPE_SLOW_2G as its effective - * connection type. - * {@hide} as it's a prototype. - */ -public class EffectiveConnectionType { - /** {@hide} */ - @IntDef({ - EFFECTIVE_CONNECTION_TYPE_UNKNOWN, EFFECTIVE_CONNECTION_TYPE_OFFLINE, - EFFECTIVE_CONNECTION_TYPE_SLOW_2G, EFFECTIVE_CONNECTION_TYPE_2G, - EFFECTIVE_CONNECTION_TYPE_3G, EFFECTIVE_CONNECTION_TYPE_4G, - EFFECTIVE_CONNECTION_TYPE_BROADBAND, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface EffectiveConnectionTypeValues {} - - /** - * Effective connection type reported when the network quality is unknown. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0; - - /** - * Effective connection type reported when the Internet is unreachable, - * either because the device does not have a connection or because the - * connection is too slow to be usable. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_OFFLINE = 1; - - /** - * Effective connection type reported when the network has the quality of a - * poor 2G connection. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_SLOW_2G = 2; - - /** - * Effective connection type reported when the network has the quality of a - * faster 2G connection. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_2G = 3; - - /** - * Effective connection type reported when the network has the quality of a - * 3G connection. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_3G = 4; - - /** - * Effective connection type reported when the network has the quality of a - * 4G connection. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_4G = 5; - - /** - * Effective connection type reported when the network has the quality of a - * broadband connection. - */ - public static final int EFFECTIVE_CONNECTION_TYPE_BROADBAND = 6; - - private EffectiveConnectionType() {} - - /** - * Maps the effective connection type enum computed by the network quality - * estimator to {@link EffectiveConnectionType}. - * @param effectiveConnectionType Effective connection type enum computed by - * the network quality estimator. - * @return {@link EffectiveConnectionType} corresponding to the provided enum. - * @hide only used by internal implementation. - */ - @EffectiveConnectionTypeValues - public static int getEffectiveConnectionType(int effectiveConnectionType) { - assert ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_LAST == 7; - switch (effectiveConnectionType) { - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN: - return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_OFFLINE: - return EFFECTIVE_CONNECTION_TYPE_OFFLINE; - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_SLOW_2G: - return EFFECTIVE_CONNECTION_TYPE_SLOW_2G; - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_2G: - return EFFECTIVE_CONNECTION_TYPE_2G; - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_3G: - return EFFECTIVE_CONNECTION_TYPE_3G; - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_4G: - return EFFECTIVE_CONNECTION_TYPE_4G; - case ChromiumEffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_BROADBAND: - return EFFECTIVE_CONNECTION_TYPE_BROADBAND; - } - throw new IllegalStateException( - "Effective connection type has an invalid value of " + effectiveConnectionType); - } -} \ No newline at end of file
diff --git a/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java b/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java index 18de61a..d899a6ac4 100644 --- a/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java +++ b/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java
@@ -104,11 +104,6 @@ } @Override - public int getEffectiveConnectionType() { - return EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN; - } - - @Override public void configureNetworkQualityEstimatorForTesting( boolean useLocalHostRequests, boolean useSmallerResponses) {}
diff --git a/components/cronet/android/chromium_url_request.cc b/components/cronet/android/chromium_url_request.cc index 6f047e6..e52d6f4f 100644 --- a/components/cronet/android/chromium_url_request.cc +++ b/components/cronet/android/chromium_url_request.cc
@@ -165,10 +165,10 @@ DCHECK(request_adapter); SetPostContentType(env, request_adapter, jcontent_type); - if (jcontent != NULL) { + if (jcontent != nullptr) { jsize size = env->GetArrayLength(jcontent); if (size > 0) { - jbyte* content_bytes = env->GetByteArrayElements(jcontent, NULL); + jbyte* content_bytes = env->GetByteArrayElements(jcontent, nullptr); request_adapter->SetUploadContent( reinterpret_cast<const char*>(content_bytes), size); env->ReleaseByteArrayElements(jcontent, content_bytes, 0); @@ -223,7 +223,7 @@ jlong jurl_request_adapter) { URLRequestAdapter* request_adapter = reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter); - if (request_adapter != NULL) + if (request_adapter != nullptr) request_adapter->Start(); } @@ -233,7 +233,7 @@ jlong jurl_request_adapter) { URLRequestAdapter* request_adapter = reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter); - if (request_adapter != NULL) + if (request_adapter != nullptr) request_adapter->Destroy(); } @@ -243,7 +243,7 @@ jlong jurl_request_adapter) { URLRequestAdapter* request_adapter = reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter); - if (request_adapter != NULL) + if (request_adapter != nullptr) request_adapter->Cancel(); } @@ -373,7 +373,7 @@ DCHECK(request_adapter); net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders(); - if (headers == NULL) + if (headers == nullptr) return; size_t iter = 0; @@ -393,7 +393,7 @@ ScopedJavaLocalRef<jstring> status_line = ConvertUTF8ToJavaString(env, headers->GetStatusLine()); Java_ChromiumUrlRequest_onAppendResponseHeader(env, jcaller, jheaders_map, - NULL, status_line.obj()); + nullptr, status_line.obj()); } static ScopedJavaLocalRef<jstring> GetNegotiatedProtocol(
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc index 6fd2e91..55929ef7 100644 --- a/components/cronet/android/cronet_library_loader.cc +++ b/components/cronet/android/cronet_library_loader.cc
@@ -32,9 +32,7 @@ #include "url/url_features.h" #include "url/url_util.h" -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) -#include "url/android/url_jni_registrar.h" // nogncheck -#else +#if !BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) #include "base/i18n/icu_util.h" // nogncheck #endif @@ -53,9 +51,6 @@ {"CronetUrlRequestContextAdapter", CronetUrlRequestContextAdapterRegisterJni}, {"NetAndroid", net::android::RegisterJni}, -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) - {"UrlAndroid", url::android::RegisterJni}, -#endif }; // MessageLoop on the main thread, which is where objects that receive Java
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc index 73f618a..f9908ae 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.cc +++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -51,6 +51,7 @@ #include "net/http/http_server_properties_manager.h" #include "net/log/write_to_file_net_log_observer.h" #include "net/nqe/external_estimate_provider.h" +#include "net/nqe/network_quality_estimator.h" #include "net/proxy/proxy_config_service_android.h" #include "net/proxy/proxy_service.h" #include "net/sdch/sdch_owner.h" @@ -415,7 +416,6 @@ if (network_quality_estimator_) { network_quality_estimator_->RemoveRTTObserver(this); network_quality_estimator_->RemoveThroughputObserver(this); - network_quality_estimator_->RemoveEffectiveConnectionTypeObserver(this); } // Stop |write_to_file_observer_| if there is one. StopNetLogHelper(); @@ -597,23 +597,13 @@ if (config->enable_network_quality_estimator) { DCHECK(!network_quality_estimator_); - std::map<std::string, std::string> variation_params; - // Configure network quality estimator: Specify the algorithm that should - // be used for computing the effective connection type. The algorithm - // is specified using the key-value pairs defined in - // //net/nqe/network_quality_estimator.cc. - // TODO(tbansal): Investigate a more robust way of configuring the network - // quality estimator. - variation_params["effective_connection_type_algorithm"] = - "TransportRTTOrDownstreamThroughput"; network_quality_estimator_.reset(new net::NetworkQualityEstimator( - std::unique_ptr<net::ExternalEstimateProvider>(), variation_params, - false, false)); + std::unique_ptr<net::ExternalEstimateProvider>(), + std::map<std::string, std::string>(), false, false)); // Set the socket performance watcher factory so that network quality // estimator is notified of socket performance metrics from TCP and QUIC. context_builder.set_socket_performance_watcher_factory( network_quality_estimator_->GetSocketPerformanceWatcherFactory()); - network_quality_estimator_->AddEffectiveConnectionTypeObserver(this); } context_ = context_builder.Build(); @@ -832,14 +822,6 @@ return file_thread_.get(); } -void CronetURLRequestContextAdapter::OnEffectiveConnectionTypeChanged( - net::EffectiveConnectionType effective_connection_type) { - DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); - Java_CronetUrlRequestContext_onEffectiveConnectionTypeChanged( - base::android::AttachCurrentThread(), jcronet_url_request_context_.obj(), - effective_connection_type); -} - void CronetURLRequestContextAdapter::OnRTTObservation( int32_t rtt_ms, const base::TimeTicks& timestamp,
diff --git a/components/cronet/android/cronet_url_request_context_adapter.h b/components/cronet/android/cronet_url_request_context_adapter.h index 329b413..42626a3f 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.h +++ b/components/cronet/android/cronet_url_request_context_adapter.h
@@ -18,7 +18,6 @@ #include "base/memory/ref_counted.h" #include "base/threading/thread.h" #include "components/prefs/json_pref_store.h" -#include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator.h" #include "net/nqe/network_quality_observation_source.h" @@ -50,8 +49,7 @@ // Adapter between Java CronetUrlRequestContext and net::URLRequestContext. class CronetURLRequestContextAdapter - : public net::NetworkQualityEstimator::EffectiveConnectionTypeObserver, - public net::NetworkQualityEstimator::RTTObserver, + : public net::NetworkQualityEstimator::RTTObserver, public net::NetworkQualityEstimator::ThroughputObserver { public: explicit CronetURLRequestContextAdapter( @@ -151,11 +149,6 @@ void ProvideRTTObservationsOnNetworkThread(bool should); void ProvideThroughputObservationsOnNetworkThread(bool should); - // net::NetworkQualityEstimator::EffectiveConnectionTypeObserver - // implementation. - void OnEffectiveConnectionTypeChanged( - net::EffectiveConnectionType effective_connection_type) override; - // net::NetworkQualityEstimator::RTTObserver implementation. void OnRTTObservation(int32_t rtt_ms, const base::TimeTicks& timestamp,
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java index 57daa09..47d4345 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
@@ -20,7 +20,6 @@ import org.chromium.base.annotations.UsedByReflection; import org.chromium.net.BidirectionalStream; import org.chromium.net.CronetEngine; -import org.chromium.net.EffectiveConnectionType; import org.chromium.net.NetworkQualityRttListener; import org.chromium.net.NetworkQualityThroughputListener; import org.chromium.net.RequestFinishedInfo; @@ -78,14 +77,6 @@ */ private final Object mFinishedListenerLock = new Object(); - /** - * Current effective connection type as computed by the network quality - * estimator. - */ - @GuardedBy("mNetworkQualityLock") - private int mEffectiveConnectionType = - EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN; - @GuardedBy("mNetworkQualityLock") private final ObserverList<NetworkQualityRttListener> mRttListenerList = new ObserverList<NetworkQualityRttListener>(); @@ -269,17 +260,6 @@ return nativeGetHistogramDeltas(); } - @Override - public int getEffectiveConnectionType() { - if (!mNetworkQualityEstimatorEnabled) { - throw new IllegalStateException("Network quality estimator must be enabled"); - } - synchronized (mNetworkQualityLock) { - checkHaveAdapter(); - return mEffectiveConnectionType; - } - } - @VisibleForTesting @Override public void configureNetworkQualityEstimatorForTesting( @@ -457,17 +437,6 @@ @SuppressWarnings("unused") @CalledByNative - private void onEffectiveConnectionTypeChanged(int effectiveConnectionType) { - synchronized (mNetworkQualityLock) { - // Convert the enum returned by the network quality estimator to an enum of type - // EffectiveConnectionType. - mEffectiveConnectionType = - EffectiveConnectionType.getEffectiveConnectionType(effectiveConnectionType); - } - } - - @SuppressWarnings("unused") - @CalledByNative private void onRttObservation(final int rttMs, final long whenMs, final int source) { synchronized (mNetworkQualityLock) { for (final NetworkQualityRttListener listener : mRttListenerList) {
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java index 227ae12..b08e40a 100644 --- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java +++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java
@@ -402,7 +402,7 @@ // Sockets are assigned to requests according to request priorities // when sockets are connected. This requires requests with the same host, // domain and port to have same timeout. - Log.e(TAG, "setConnectTimeout is not supported by CronetHttpURLConnection"); + Log.d(TAG, "setConnectTimeout is not supported by CronetHttpURLConnection"); } /**
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java index 92204d2..b9eeef9 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -326,11 +326,6 @@ assertEquals(mNetworkQualityThread, rttListener.getThread()); assertEquals(mNetworkQualityThread, throughputListener.getThread()); - // Verify that effective connection type callback is received and - // effective connection type is correctly set. - assertTrue(mTestFramework.mCronetEngine.getEffectiveConnectionType() - != EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN); - mTestFramework.mCronetEngine.shutdown(); }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java index 09811e8c..59e134e2 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -223,11 +223,6 @@ // NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC assertTrue(rttListener.rttObservationCount(2) > 0); - // Verify that effective connection type callback is received and - // effective connection type is correctly set. - assertTrue(mTestFramework.mCronetEngine.getEffectiveConnectionType() - != EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN); - mTestFramework.mCronetEngine.shutdown(); } }
diff --git a/components/dom_distiller/core/experiments.cc b/components/dom_distiller/core/experiments.cc index 168f23e..f3927b8 100644 --- a/components/dom_distiller/core/experiments.cc +++ b/components/dom_distiller/core/experiments.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/metrics/field_trial.h" +#include "base/strings/string_util.h" #include "components/dom_distiller/core/dom_distiller_switches.h" namespace dom_distiller { @@ -31,10 +32,12 @@ } NOTREACHED() << "Invalid value for " << switches::kReaderModeHeuristics; } else { - if (group_name == "AdaBoost") { + if (base::StartsWith(group_name, "AdaBoost", + base::CompareCase::INSENSITIVE_ASCII)) { return DistillerHeuristicsType::ADABOOST_MODEL; } - if (group_name == "OGArticle") { + if (base::StartsWith(group_name, "OGArticle", + base::CompareCase::INSENSITIVE_ASCII)) { return DistillerHeuristicsType::OG_ARTICLE; } }
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index 07d7ce7..7ab41b6 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -132,6 +132,7 @@ // Removed: DESKTOP_SEARCH_REDIRECTION_INFOBAR_DELEGATE = 62, UPDATE_PASSWORD_INFOBAR_DELEGATE = 63, DATA_REDUCTION_PROMO_INFOBAR_DELEGATE_ANDROID = 64, + AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_ANDROID = 65, }; // Describes navigation events, used to decide whether infobars should be
diff --git a/components/offline_pages/background/offliner.h b/components/offline_pages/background/offliner.h index 8bc6468..daa6d18 100644 --- a/components/offline_pages/background/offliner.h +++ b/components/offline_pages/background/offliner.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_OFFLINE_PAGES_BACKGROUND_OFFLINER_H_ #define COMPONENTS_OFFLINE_PAGES_BACKGROUND_OFFLINER_H_ +#include <string> + #include "base/callback.h" namespace offline_pages {
diff --git a/components/offline_pages/background/request_coordinator.cc b/components/offline_pages/background/request_coordinator.cc index b32cfa2f..19906d78 100644 --- a/components/offline_pages/background/request_coordinator.cc +++ b/components/offline_pages/background/request_coordinator.cc
@@ -16,6 +16,7 @@ #include "components/offline_pages/background/request_picker.h" #include "components/offline_pages/background/save_page_request.h" #include "components/offline_pages/offline_page_item.h" +#include "components/offline_pages/offline_page_model.h" namespace offline_pages { @@ -56,6 +57,11 @@ const GURL& url, const ClientId& client_id, bool was_user_requested) { DVLOG(2) << "URL is " << url << " " << __func__; + if (!OfflinePageModel::CanSaveURL(url)) { + DVLOG(1) << "Not able to save page for requested url: " << url; + return false; + } + // TODO(petewil): We need a robust scheme for allocating new IDs. static int64_t id = 0; @@ -99,7 +105,7 @@ void RequestCoordinator::RemoveRequests( const std::vector<ClientId>& client_ids) { queue_->RemoveRequestsByClientId( - client_ids, base::Bind(&RequestCoordinator::UpdateRequestCallback, + client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, weak_ptr_factory_.GetWeakPtr())); } @@ -113,20 +119,34 @@ // Called in response to updating a request in the request queue. void RequestCoordinator::UpdateRequestCallback( + const ClientId& client_id, RequestQueue::UpdateRequestResult result) { // If the request succeeded, nothing to do. If it failed, we can't really do // much, so just log it. if (result != RequestQueue::UpdateRequestResult::SUCCESS) { - // TODO(petewil): Consider adding UMA or showing on offline-internals page. - DLOG(WARNING) << "Failed to update a request retry count. " - << static_cast<int>(result); + DVLOG(1) << "Failed to update request attempt details. " + << static_cast<int>(result); + event_logger_.RecordUpdateRequestFailed(client_id.name_space, result); + } +} + +// Called in response to updating multiple requests in the request queue. +void RequestCoordinator::UpdateMultipleRequestCallback( + RequestQueue::UpdateRequestResult result) { + // If the request succeeded, nothing to do. If it failed, we can't really do + // much, so just log it. + if (result != RequestQueue::UpdateRequestResult::SUCCESS) { + DVLOG(1) << "Failed to update request attempt details. " + << static_cast<int>(result); } } void RequestCoordinator::StopProcessing() { is_canceled_ = true; - if (offliner_ && is_busy_) + if (offliner_ && is_busy_) { + // TODO(dougarnett): Find current request and mark attempt aborted. offliner_->Cancel(); + } // Stopping offliner means it will not call callback. last_offlining_status_ = @@ -210,14 +230,28 @@ DCHECK(!is_busy_); is_busy_ = true; - // Start the load and save process in the offliner (Async). - offliner_->LoadAndSave(request, - base::Bind(&RequestCoordinator::OfflinerDoneCallback, - weak_ptr_factory_.GetWeakPtr())); + // Prepare an updated request to attempt. + SavePageRequest updated_request(request); + updated_request.MarkAttemptStarted(base::Time::Now()); - // Start a watchdog timer to catch pre-renders running too long - watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this, - &RequestCoordinator::StopProcessing); + // Start the load and save process in the offliner (Async). + if (offliner_->LoadAndSave( + updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback, + weak_ptr_factory_.GetWeakPtr()))) { + // Offliner accepted request so update it in the queue. + queue_->UpdateRequest(updated_request, + base::Bind(&RequestCoordinator::UpdateRequestCallback, + weak_ptr_factory_.GetWeakPtr(), + updated_request.client_id())); + + // Start a watchdog timer to catch pre-renders running too long + watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this, + &RequestCoordinator::StopProcessing); + } else { + is_busy_ = false; + DVLOG(0) << "Unable to start LoadAndSave"; + StopProcessing(); + } } void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request, @@ -227,38 +261,42 @@ << ", status: " << static_cast<int>(status) << ", " << __func__; DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); DCHECK_NE(status, Offliner::RequestStatus::LOADED); - event_logger_.RecordSavePageRequestUpdated( - request.client_id().name_space, - "Saved", - request.request_id()); + event_logger_.RecordSavePageRequestUpdated(request.client_id().name_space, + status, request.request_id()); last_offlining_status_ = status; RecordOfflinerResultUMA(last_offlining_status_); watchdog_timer_.Stop(); is_busy_ = false; - int64_t new_attempt_count = request.attempt_count() + 1; - - // Remove the request from the queue if it either succeeded or exceeded the - // max number of retries. - if (status == Offliner::RequestStatus::SAVED - || new_attempt_count > policy_->GetMaxTries()) { - queue_->RemoveRequest(request.request_id(), + if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { + // Update the request for the canceled attempt. + // TODO(dougarnett): See if we can conclusively identify other attempt + // aborted cases to treat this way (eg, for Render Process Killed). + SavePageRequest updated_request(request); + updated_request.MarkAttemptAborted(); + queue_->UpdateRequest(updated_request, base::Bind(&RequestCoordinator::UpdateRequestCallback, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), + updated_request.client_id())); + + } else if (status == Offliner::RequestStatus::SAVED || + request.attempt_count() >= policy_->GetMaxTries()) { + // Remove the request from the queue if it either succeeded or exceeded the + // max number of retries. + queue_->RemoveRequest( + request.request_id(), + base::Bind(&RequestCoordinator::UpdateRequestCallback, + weak_ptr_factory_.GetWeakPtr(), request.client_id())); } else { // If we failed, but are not over the limit, update the request in the // queue. SavePageRequest updated_request(request); - updated_request.set_attempt_count(new_attempt_count); - updated_request.set_last_attempt_time(base::Time::Now()); - RequestQueue::UpdateRequestCallback update_callback = - base::Bind(&RequestCoordinator::UpdateRequestCallback, - weak_ptr_factory_.GetWeakPtr()); - queue_->UpdateRequest( - updated_request, - base::Bind(&RequestCoordinator::UpdateRequestCallback, - weak_ptr_factory_.GetWeakPtr())); + updated_request.MarkAttemptCompleted(); + queue_->UpdateRequest(updated_request, + base::Bind(&RequestCoordinator::UpdateRequestCallback, + weak_ptr_factory_.GetWeakPtr(), + updated_request.client_id())); } // Determine whether we might try another request in this
diff --git a/components/offline_pages/background/request_coordinator.h b/components/offline_pages/background/request_coordinator.h index 1be33930..1e51f18 100644 --- a/components/offline_pages/background/request_coordinator.h +++ b/components/offline_pages/background/request_coordinator.h
@@ -123,7 +123,10 @@ const SavePageRequest& request); // Receives the result of update and delete requests to the request queue. - void UpdateRequestCallback(RequestQueue::UpdateRequestResult result); + void UpdateRequestCallback(const ClientId& client_id, + RequestQueue::UpdateRequestResult result); + + void UpdateMultipleRequestCallback(RequestQueue::UpdateRequestResult result); // Callback from the request picker when it has chosen our next request. void RequestPicked(const SavePageRequest& request);
diff --git a/components/offline_pages/background/request_coordinator_event_logger.cc b/components/offline_pages/background/request_coordinator_event_logger.cc index 12ddf8c2..08702920a7 100644 --- a/components/offline_pages/background/request_coordinator_event_logger.cc +++ b/components/offline_pages/background/request_coordinator_event_logger.cc
@@ -2,19 +2,69 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <string> - #include "components/offline_pages/background/request_coordinator_event_logger.h" namespace offline_pages { +namespace { + +static std::string OfflinerRequestStatusToString( + Offliner::RequestStatus request_status) { + switch (request_status) { + case Offliner::UNKNOWN: + return "UNKNOWN"; + case Offliner::LOADED: + return "LOADED"; + case Offliner::SAVED: + return "SAVED"; + case Offliner::REQUEST_COORDINATOR_CANCELED: + return "REQUEST_COORDINATOR_CANCELED"; + case Offliner::PRERENDERING_CANCELED: + return "PRERENDERING_CANCELED"; + case Offliner::PRERENDERING_FAILED: + return "PRERENDERING_FAILED"; + case Offliner::SAVE_FAILED: + return "SAVE_FAILED"; + case Offliner::FOREGROUND_CANCELED: + return "FOREGROUND_CANCELED"; + default: + DCHECK(false); + return ""; + } +} + +static std::string UpdateRequestResultToString( + RequestQueue::UpdateRequestResult result) { + switch (result) { + case RequestQueue::UpdateRequestResult::SUCCESS: + return "SUCCESS"; + case RequestQueue::UpdateRequestResult::STORE_FAILURE: + return "STORE_FAILURE"; + case RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST: + return "REQUEST_DOES_NOT_EXIST"; + default: + DCHECK(false); + return ""; + } +} + +} // namespace + void RequestCoordinatorEventLogger::RecordSavePageRequestUpdated( const std::string& name_space, - const std::string& new_status, + Offliner::RequestStatus new_status, int64_t id) { RecordActivity("Save page request for ID: " + std::to_string(id) + " and namespace: " + name_space + - " has been updated with status " + new_status); + " has been updated with status " + + OfflinerRequestStatusToString(new_status)); +} + +void RequestCoordinatorEventLogger::RecordUpdateRequestFailed( + const std::string& name_space, + RequestQueue::UpdateRequestResult result) { + RecordActivity("Updating queued request for namespace: " + name_space + + " failed with result: " + UpdateRequestResultToString(result)); } } // namespace offline_pages
diff --git a/components/offline_pages/background/request_coordinator_event_logger.h b/components/offline_pages/background/request_coordinator_event_logger.h index 0e0476435..4ac05e89 100644 --- a/components/offline_pages/background/request_coordinator_event_logger.h +++ b/components/offline_pages/background/request_coordinator_event_logger.h
@@ -6,7 +6,10 @@ #define COMPONENTS_OFFLINE_PAGES_BACKGROUND_REQUEST_COORDINATOR_EVENT_LOGGER_H_ #include <stdint.h> +#include <string> +#include "components/offline_pages/background/offliner.h" +#include "components/offline_pages/background/request_queue.h" #include "components/offline_pages/offline_event_logger.h" namespace offline_pages { @@ -16,8 +19,11 @@ // Records that a background task with SavePageRequest |request_id| // has been updated. void RecordSavePageRequestUpdated(const std::string& name_space, - const std::string& new_status, + Offliner::RequestStatus new_status, int64_t request_id); + + void RecordUpdateRequestFailed(const std::string& name_space, + RequestQueue::UpdateRequestResult result); }; } // namespace offline_pages
diff --git a/components/offline_pages/background/request_coordinator_event_logger_unittest.cc b/components/offline_pages/background/request_coordinator_event_logger_unittest.cc index a8189a95..b04e6b6e 100644 --- a/components/offline_pages/background/request_coordinator_event_logger_unittest.cc +++ b/components/offline_pages/background/request_coordinator_event_logger_unittest.cc
@@ -11,11 +11,17 @@ namespace { const char kNamespace[] = "last_n"; -const char kStatus[] = "pending"; +const Offliner::RequestStatus kStatus = Offliner::SAVED; const int64_t kId = 1234; -const char kLogString[] = +const RequestQueue::UpdateRequestResult kUpdateResult = + RequestQueue::UpdateRequestResult::STORE_FAILURE; + +const char kStatusLogString[] = "Save page request for ID: 1234 and namespace: " - "last_n has been updated with status pending"; + "last_n has been updated with status SAVED"; +const char kUpdateResultLogString[] = + "Updating queued request for namespace: last_n failed with result: " + "STORE_FAILURE"; const int kTimeLength = 21; } // namespace @@ -26,10 +32,12 @@ logger.SetIsLogging(true); logger.RecordSavePageRequestUpdated(kNamespace, kStatus, kId); + logger.RecordUpdateRequestFailed(kNamespace, kUpdateResult); logger.GetLogs(&log); - EXPECT_EQ(1u, log.size()); - EXPECT_EQ(std::string(kLogString), log[0].substr(kTimeLength)); + EXPECT_EQ(2u, log.size()); + EXPECT_EQ(std::string(kUpdateResultLogString), log[0].substr(kTimeLength)); + EXPECT_EQ(std::string(kStatusLogString), log[1].substr(kTimeLength)); } TEST(RequestCoordinatorEventLoggerTest, RecordsWhenLoggingIsOff) {
diff --git a/components/offline_pages/background/request_coordinator_unittest.cc b/components/offline_pages/background/request_coordinator_unittest.cc index 68b9bac..cd81ccc 100644 --- a/components/offline_pages/background/request_coordinator_unittest.cc +++ b/components/offline_pages/background/request_coordinator_unittest.cc
@@ -332,6 +332,7 @@ // Add a request to the queue, wait for callbacks to finish. offline_pages::SavePageRequest request( kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); + request.MarkAttemptStarted(base::Time::Now()); coordinator()->queue()->AddRequest( request, base::Bind(&RequestCoordinatorTest::AddRequestDone, @@ -372,6 +373,7 @@ // Add a request to the queue, wait for callbacks to finish. offline_pages::SavePageRequest request( kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); + request.MarkAttemptStarted(base::Time::Now()); coordinator()->queue()->AddRequest( request, base::Bind(&RequestCoordinatorTest::AddRequestDone, @@ -416,11 +418,48 @@ base::Unretained(this))); PumpLoop(); - // Still two requests in the queue. - EXPECT_EQ(2UL, last_requests().size()); - // Verify retry count was incremented for first request. + // Now just one request in the queue since failed request removed + // (for single attempt policy). + EXPECT_EQ(1UL, last_requests().size()); +} + +TEST_F(RequestCoordinatorTest, OfflinerDoneForegroundCancel) { + // Add a request to the queue, wait for callbacks to finish. + offline_pages::SavePageRequest request( + kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); + request.MarkAttemptStarted(base::Time::Now()); + coordinator()->queue()->AddRequest( + request, base::Bind(&RequestCoordinatorTest::AddRequestDone, + base::Unretained(this))); + PumpLoop(); + + // We need to give a callback to the request. + base::Callback<void(bool)> callback = base::Bind( + &RequestCoordinatorTest::EmptyCallbackFunction, base::Unretained(this)); + coordinator()->SetProcessingCallbackForTest(callback); + + // Set up device conditions for the test. + DeviceConditions device_conditions(false, 75, + net::NetworkChangeNotifier::CONNECTION_3G); + SetDeviceConditionsForTest(device_conditions); + + // Call the OfflinerDoneCallback to simulate the request failed, wait + // for callbacks. + EnableOfflinerCallback(true); + SendOfflinerDoneCallback(request, + Offliner::RequestStatus::FOREGROUND_CANCELED); + PumpLoop(); + + // Verify the request is not removed from the queue, and wait for callbacks. + coordinator()->queue()->GetRequests(base::Bind( + &RequestCoordinatorTest::GetRequestsDone, base::Unretained(this))); + PumpLoop(); + + // Request no longer in the queue (for single attempt policy). + EXPECT_EQ(1UL, last_requests().size()); + // Verify foreground cancel not counted as an attempt after all. const SavePageRequest& found_request = last_requests().front(); - EXPECT_EQ(1L, found_request.attempt_count()); + EXPECT_EQ(0L, found_request.attempt_count()); } // This tests a StopProcessing call before we have actually started the @@ -498,7 +537,7 @@ EXPECT_TRUE(OfflinerWasCanceled()); } -TEST_F(RequestCoordinatorTest, PrerendererTimeout) { +TEST_F(RequestCoordinatorTest, WatchdogTimeout) { // Build a request to use with the pre-renderer, and put it on the queue. offline_pages::SavePageRequest request( kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested);
diff --git a/components/offline_pages/background/request_queue.h b/components/offline_pages/background/request_queue.h index 4c19550d..429c375 100644 --- a/components/offline_pages/background/request_queue.h +++ b/components/offline_pages/background/request_queue.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <string> #include <vector> #include "base/callback.h"
diff --git a/components/offline_pages/background/save_page_request.cc b/components/offline_pages/background/save_page_request.cc index f9372f3..e5424d70 100644 --- a/components/offline_pages/background/save_page_request.cc +++ b/components/offline_pages/background/save_page_request.cc
@@ -78,4 +78,12 @@ last_attempt_time_ = base::Time(); } +void SavePageRequest::MarkAttemptAborted() { + DCHECK_GT(attempt_count_, 0); + last_attempt_time_ = base::Time(); + // TODO(dougarnett): Would be safer if we had two persisted counters + // (attempts_started and attempts_completed) rather just one with decrement. + --attempt_count_; +} + } // namespace offline_pages
diff --git a/components/offline_pages/background/save_page_request.h b/components/offline_pages/background/save_page_request.h index 8c09562..d241dea 100644 --- a/components/offline_pages/background/save_page_request.h +++ b/components/offline_pages/background/save_page_request.h
@@ -50,6 +50,10 @@ // Marks attempt as completed and clears |last_attempt_time_|. void MarkAttemptCompleted(); + // Marks attempt as aborted. Specifically it clears |last_attempt_time_| + // and decrements |attempt_count_|. + void MarkAttemptAborted(); + int64_t request_id() const { return request_id_; } const GURL& url() const { return url_; }
diff --git a/components/offline_pages/background/save_page_request_unittest.cc b/components/offline_pages/background/save_page_request_unittest.cc index 63b970f..68f12fe 100644 --- a/components/offline_pages/background/save_page_request_unittest.cc +++ b/components/offline_pages/background/save_page_request_unittest.cc
@@ -92,10 +92,43 @@ ASSERT_EQ(creation_time, request.creation_time()); ASSERT_EQ(activation_time, request.activation_time()); - // Last attempt time, status and attempt count are updated. + // Last attempt time and status are updated. ASSERT_EQ(base::Time(), request.last_attempt_time()); ASSERT_EQ(1, request.attempt_count()); ASSERT_EQ(SavePageRequest::Status::PENDING, request.GetStatus(start_time)); } -} // offline_pages +TEST_F(SavePageRequestTest, StartAndAbortRequest) { + base::Time creation_time = base::Time::Now(); + SavePageRequest request(kRequestId, kUrl, kClientId, creation_time, + kUserRequested); + int start_attempt_count = 2; + request.set_attempt_count(start_attempt_count); + + base::Time start_time = creation_time + base::TimeDelta::FromHours(3); + request.MarkAttemptStarted(start_time); + + // Most things don't change about the request. + ASSERT_EQ(kRequestId, request.request_id()); + ASSERT_EQ(kUrl, request.url()); + ASSERT_EQ(kClientId, request.client_id()); + ASSERT_EQ(creation_time, request.creation_time()); + + // Attempt time and attempt count will though. + ASSERT_EQ(start_time, request.last_attempt_time()); + ASSERT_EQ(start_attempt_count + 1, request.attempt_count()); + + request.MarkAttemptAborted(); + + // Again, most things don't change about the request. + ASSERT_EQ(kRequestId, request.request_id()); + ASSERT_EQ(kUrl, request.url()); + ASSERT_EQ(kClientId, request.client_id()); + ASSERT_EQ(creation_time, request.creation_time()); + + // Last attempt time is updated and attempt count decremented. + ASSERT_EQ(base::Time(), request.last_attempt_time()); + ASSERT_EQ(start_attempt_count, request.attempt_count()); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/client_namespace_constants.cc b/components/offline_pages/client_namespace_constants.cc index 098ab66..6b391de 100644 --- a/components/offline_pages/client_namespace_constants.cc +++ b/components/offline_pages/client_namespace_constants.cc
@@ -10,6 +10,7 @@ const char kLastNNamespace[] = "last_n"; const char kAsyncNamespace[] = "async_loading"; const char kCCTNamespace[] = "custom_tabs"; +const char kDownloadNamespace[] = "download"; const char kDefaultNamespace[] = "default";
diff --git a/components/offline_pages/client_namespace_constants.h b/components/offline_pages/client_namespace_constants.h index 7dc4ac5..28057d6 100644 --- a/components/offline_pages/client_namespace_constants.h +++ b/components/offline_pages/client_namespace_constants.h
@@ -15,6 +15,7 @@ extern const char kLastNNamespace[]; extern const char kAsyncNamespace[]; extern const char kCCTNamespace[]; +extern const char kDownloadNamespace[]; // Currently used for fallbacks like tests. extern const char kDefaultNamespace[];
diff --git a/components/offline_pages/client_policy_controller.cc b/components/offline_pages/client_policy_controller.cc index 3289eac..2d03bec 100644 --- a/components/offline_pages/client_policy_controller.cc +++ b/components/offline_pages/client_policy_controller.cc
@@ -33,6 +33,13 @@ MakePolicy(kCCTNamespace, LifetimeType::TEMPORARY, base::TimeDelta::FromDays(2), kUnlimitedPages, 1))); + policies_.insert(std::make_pair( + kDownloadNamespace, MakePolicy(kDownloadNamespace, + LifetimeType::PERSISTENT, + base::TimeDelta::FromDays(0), + kUnlimitedPages, + kUnlimitedPages))); + // Fallback policy. policies_.insert(std::make_pair( kDefaultNamespace, MakePolicy(kDefaultNamespace, LifetimeType::TEMPORARY,
diff --git a/components/offline_pages/client_policy_controller_unittest.cc b/components/offline_pages/client_policy_controller_unittest.cc index 08c5d03..735d7a38 100644 --- a/components/offline_pages/client_policy_controller_unittest.cc +++ b/components/offline_pages/client_policy_controller_unittest.cc
@@ -71,4 +71,10 @@ EXPECT_TRUE(isTemporary(policy)); } +TEST_F(ClientPolicyControllerTest, CheckDownloadDefined) { + OfflinePageClientPolicy policy = controller()->GetPolicy(kDownloadNamespace); + EXPECT_EQ(policy.name_space, kDownloadNamespace); + EXPECT_FALSE(isTemporary(policy)); +} + } // namespace offline_pages
diff --git a/components/offline_pages/offline_page_model_impl_unittest.cc b/components/offline_pages/offline_page_model_impl_unittest.cc index 040815a..94902093 100644 --- a/components/offline_pages/offline_page_model_impl_unittest.cc +++ b/components/offline_pages/offline_page_model_impl_unittest.cc
@@ -1068,6 +1068,15 @@ static_cast<int>(SavePageResult::SUCCESS), 1); } +TEST_F(OfflinePageModelImplTest, DownloadNamespace) { + SavePage(kTestUrl, ClientId(kDownloadNamespace, "123")); + std::string histogram_name = "OfflinePages.SavePageResult."; + histogram_name += kDownloadNamespace; + + histograms().ExpectUniqueSample(histogram_name, + static_cast<int>(SavePageResult::SUCCESS), 1); +} + TEST(CommandLineFlagsTest, OfflineBookmarks) { // Disabled by default. EXPECT_FALSE(offline_pages::IsOfflineBookmarksEnabled());
diff --git a/components/safe_browsing_db/v4_rice.cc b/components/safe_browsing_db/v4_rice.cc index b053715..3016fac 100644 --- a/components/safe_browsing_db/v4_rice.cc +++ b/components/safe_browsing_db/v4_rice.cc
@@ -106,10 +106,14 @@ if (result != DECODE_SUCCESS) { return result; } - out->reserve((num_entries + 1) * 4); + + // Cast to unsigned since we don't look at the sign bit as a sign bit. + // first_value should have been an unsigned to begin with but proto don't + // allow that. + uint32_t first_value_unsigned = static_cast<uint32_t>(first_value); + base::CheckedNumeric<uint32_t> last_value(first_value_unsigned); char bytes[4]; - base::CheckedNumeric<uint32_t> last_value(first_value); GetBytesFromUInt32(last_value.ValueOrDie(), bytes); out->append(bytes, 4);
diff --git a/components/safe_browsing_db/v4_store.cc b/components/safe_browsing_db/v4_store.cc index 4e731ae..69d49a2 100644 --- a/components/safe_browsing_db/v4_store.cc +++ b/components/safe_browsing_db/v4_store.cc
@@ -5,9 +5,11 @@ #include "base/base64.h" #include "base/bind.h" #include "base/files/file_util.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/strings/stringprintf.h" +#include "components/safe_browsing_db/v4_rice.h" #include "components/safe_browsing_db/v4_store.h" #include "components/safe_browsing_db/v4_store.pb.h" @@ -40,6 +42,18 @@ APPLY_UPDATE_RESULT_MAX); } +void RecordDecodeAdditionsResult(V4DecodeResult result) { + UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4DecodeAdditionsResult", result, + DECODE_RESULT_MAX); +} + +void RecordDecodeRemovalsResult(V4DecodeResult result) { + UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4DecodeRemovalsResult", result, + DECODE_RESULT_MAX); +} + +// TODO(vakh): Collect and record the metrics for time taken to process updates. + void RecordApplyUpdateResultWhenReadingFromDisk(ApplyUpdateResult result) { UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.V4ApplyUpdateResultWhenReadingFromDisk", result, @@ -99,6 +113,68 @@ return true; } +ApplyUpdateResult V4Store::ProcessFullUpdate( + std::unique_ptr<ListUpdateResponse> response, + const std::unique_ptr<V4Store>& new_store) { + HashPrefixMap hash_prefix_map; + ApplyUpdateResult apply_update_result = + UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); + if (apply_update_result == APPLY_UPDATE_SUCCESS) { + new_store->hash_prefix_map_ = hash_prefix_map; + RecordStoreWriteResult(new_store->WriteToDisk(std::move(response))); + } + return apply_update_result; +} + +ApplyUpdateResult V4Store::ProcessPartialUpdate( + std::unique_ptr<ListUpdateResponse> response, + const std::unique_ptr<V4Store>& new_store) { + // TODO(vakh): + // 1. Done: Merge the old store and the new update in new_store. + // 2. Create a ListUpdateResponse containing RICE encoded hash-prefixes and + // response_type as FULL_UPDATE, and write that to disk. + // 3. Remove this if condition after completing 1. and 2. + + const RepeatedField<int32>* raw_removals = nullptr; + RepeatedField<int32> rice_removals; + size_t removals_size = response->removals_size(); + DCHECK_LE(removals_size, 1u); + if (removals_size == 1) { + const ThreatEntrySet& removal = response->removals().Get(0); + const CompressionType compression_type = removal.compression_type(); + if (compression_type == RAW) { + raw_removals = &removal.raw_indices().indices(); + } else if (compression_type == RICE) { + DCHECK(removal.has_rice_indices()); + + const RiceDeltaEncoding& rice_indices = removal.rice_indices(); + V4DecodeResult decode_result = V4RiceDecoder::DecodeIntegers( + rice_indices.first_value(), rice_indices.rice_parameter(), + rice_indices.num_entries(), rice_indices.encoded_data(), + &rice_removals); + RecordDecodeRemovalsResult(decode_result); + if (decode_result != DECODE_SUCCESS) { + return RICE_DECODING_FAILURE; + } else { + raw_removals = &rice_removals; + } + } else { + NOTREACHED() << "Unexpected compression_type type: " << compression_type; + return UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE; + } + } + + HashPrefixMap hash_prefix_map; + ApplyUpdateResult apply_update_result = + UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); + + if (apply_update_result == APPLY_UPDATE_SUCCESS) { + apply_update_result = + new_store->MergeUpdate(hash_prefix_map_, hash_prefix_map, raw_removals); + } + return apply_update_result; +} + void V4Store::ApplyUpdate( std::unique_ptr<ListUpdateResponse> response, const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, @@ -106,39 +182,12 @@ std::unique_ptr<V4Store> new_store( new V4Store(this->task_runner_, this->store_path_)); new_store->state_ = response->new_client_state(); - // TODO(vakh): - // 1. Done: Merge the old store and the new update in new_store. - // 2. Create a ListUpdateResponse containing RICE encoded hash-prefixes and - // response_type as FULL_UPDATE, and write that to disk. - // 3. Remove this if condition after completing 1. and 2. - HashPrefixMap hash_prefix_map; + ApplyUpdateResult apply_update_result; if (response->response_type() == ListUpdateResponse::PARTIAL_UPDATE) { - const RepeatedField<int32>* raw_removals = nullptr; - size_t removals_size = response->removals_size(); - DCHECK_LE(removals_size, 1u); - if (removals_size == 1) { - const ThreatEntrySet& removal = response->removals().Get(0); - // TODO(vakh): Allow other compression types. - // See: https://bugs.chromium.org/p/chromium/issues/detail?id=624567 - DCHECK_EQ(RAW, removal.compression_type()); - raw_removals = &removal.raw_indices().indices(); - } - - apply_update_result = UpdateHashPrefixMapFromAdditions( - response->additions(), &hash_prefix_map); - if (apply_update_result == APPLY_UPDATE_SUCCESS) { - apply_update_result = new_store->MergeUpdate( - hash_prefix_map_, hash_prefix_map, raw_removals); - } - // TODO(vakh): Generate the updated ListUpdateResponse to write to disk. + apply_update_result = ProcessPartialUpdate(std::move(response), new_store); } else if (response->response_type() == ListUpdateResponse::FULL_UPDATE) { - apply_update_result = UpdateHashPrefixMapFromAdditions( - response->additions(), &hash_prefix_map); - if (apply_update_result == APPLY_UPDATE_SUCCESS) { - new_store->hash_prefix_map_ = hash_prefix_map; - RecordStoreWriteResult(new_store->WriteToDisk(std::move(response))); - } + apply_update_result = ProcessFullUpdate(std::move(response), new_store); } else { apply_update_result = UNEXPECTED_RESPONSE_TYPE_FAILURE; NOTREACHED() << "Unexpected response type: " << response->response_type(); @@ -161,21 +210,46 @@ const RepeatedPtrField<ThreatEntrySet>& additions, HashPrefixMap* additions_map) { for (const auto& addition : additions) { - // TODO(vakh): Allow other compression types. - // See: https://bugs.chromium.org/p/chromium/issues/detail?id=624567 - DCHECK_EQ(RAW, addition.compression_type()); + ApplyUpdateResult apply_update_result = APPLY_UPDATE_SUCCESS; + const CompressionType compression_type = addition.compression_type(); + if (compression_type == RAW) { + DCHECK(addition.has_raw_hashes()); + DCHECK(addition.raw_hashes().has_raw_hashes()); - DCHECK(addition.has_raw_hashes()); - DCHECK(addition.raw_hashes().has_raw_hashes()); + apply_update_result = + AddUnlumpedHashes(addition.raw_hashes().prefix_size(), + addition.raw_hashes().raw_hashes(), additions_map); + } else if (compression_type == RICE) { + DCHECK(addition.has_rice_hashes()); - PrefixSize prefix_size = addition.raw_hashes().prefix_size(); - ApplyUpdateResult result = AddUnlumpedHashes( - prefix_size, addition.raw_hashes().raw_hashes(), additions_map); - if (result != APPLY_UPDATE_SUCCESS) { + const RiceDeltaEncoding& rice_hashes = addition.rice_hashes(); + std::string raw_hashes; + V4DecodeResult decode_result = V4RiceDecoder::DecodeBytes( + rice_hashes.first_value(), rice_hashes.rice_parameter(), + rice_hashes.num_entries(), rice_hashes.encoded_data(), &raw_hashes); + RecordDecodeAdditionsResult(decode_result); + if (decode_result != DECODE_SUCCESS) { + return RICE_DECODING_FAILURE; + } else { + // Rice-Golomb encoding is used to send compressed compressed 4-byte + // hash prefixes. Hash prefixes longer than 4 bytes will not be + // compressed, and will be served in raw format instead. + // Source: https://developers.google.com/safe-browsing/v4/compression + const PrefixSize kPrefixSize = 4; + apply_update_result = + AddUnlumpedHashes(kPrefixSize, raw_hashes, additions_map); + } + } else { + NOTREACHED() << "Unexpected compression_type type: " << compression_type; + return UNEXPECTED_COMPRESSION_TYPE_ADDITIONS_FAILURE; + } + + if (apply_update_result != APPLY_UPDATE_SUCCESS) { // If there was an error in updating the map, discard the update entirely. - return result; + return apply_update_result; } } + return APPLY_UPDATE_SUCCESS; } @@ -337,7 +411,7 @@ return (!raw_removals || removals_iter == raw_removals->end()) ? APPLY_UPDATE_SUCCESS - : REMOVALS_INDEX_TOO_LARGE; + : REMOVALS_INDEX_TOO_LARGE_FAILURE; } StoreReadResult V4Store::ReadFromDisk() { @@ -418,7 +492,6 @@ DCHECK_EQ(file_format_string.size(), written); if (!base::Move(new_filename, store_path_)) { - DVLOG(1) << "store_path_: " << store_path_.value(); return UNABLE_TO_RENAME_FAILURE; }
diff --git a/components/safe_browsing_db/v4_store.h b/components/safe_browsing_db/v4_store.h index 310004d..94621e5 100644 --- a/components/safe_browsing_db/v4_store.h +++ b/components/safe_browsing_db/v4_store.h
@@ -133,7 +133,16 @@ // One of more index(es) in removals field of the response is greater than // the number of hash prefixes currently in the (old) store. - REMOVALS_INDEX_TOO_LARGE = 7, + REMOVALS_INDEX_TOO_LARGE_FAILURE = 7, + + // Failed to decode the Rice-encoded additions/removals field. + RICE_DECODING_FAILURE = 8, + + // Compression type other than RAW and RICE for additions. + UNEXPECTED_COMPRESSION_TYPE_ADDITIONS_FAILURE = 9, + + // Compression type other than RAW and RICE for removals. + UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE = 10, // Memory space for histograms is determined by the max. ALWAYS // ADD NEW VALUES BEFORE THIS ONE. @@ -238,6 +247,11 @@ TestHashPrefixExistsInMapWithDifferentSizes); FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestHashPrefixDoesNotExistInMapWithDifferentSizes); + FRIEND_TEST_ALL_PREFIXES(V4StoreTest, + TestAdditionsWithRiceEncodingFailsWithInvalidInput); + FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestAdditionsWithRiceEncodingSucceeds); + FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestRemovalsWithRiceEncodingSucceeds); + friend class V4StoreTest; // If |prefix_size| is within expected range, and |raw_hashes| is not invalid, // then it sets |raw_hashes| as the value at key |prefix_size| in @@ -287,6 +301,20 @@ const ::google::protobuf::RepeatedField< ::google::protobuf::int32>* raw_removals); + // Processes the FULL_UPDATE |response| from the server and updates the + // V4Store in |new_store| and writes it to disk. If processing the |response| + // succeeds, it returns APPLY_UPDATE_SUCCESS. + ApplyUpdateResult ProcessFullUpdate( + std::unique_ptr<ListUpdateResponse> response, + const std::unique_ptr<V4Store>& new_store); + + // Processes the PARTIAL_UPDATE |response| from the server and updates the + // V4Store in |new_store|. If processing the |response| succeeds, it returns + // APPLY_UPDATE_SUCCESS. + ApplyUpdateResult ProcessPartialUpdate( + std::unique_ptr<ListUpdateResponse> response, + const std::unique_ptr<V4Store>& new_store); + // Reads the state of the store from the file on disk and returns the reason // for the failure or reports success. StoreReadResult ReadFromDisk();
diff --git a/components/safe_browsing_db/v4_store_unittest.cc b/components/safe_browsing_db/v4_store_unittest.cc index 59d2ebb..f9bd1ba 100644 --- a/components/safe_browsing_db/v4_store_unittest.cc +++ b/components/safe_browsing_db/v4_store_unittest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/bind.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/ptr_util.h" @@ -16,6 +17,7 @@ namespace safe_browsing { using ::google::protobuf::RepeatedField; +using ::google::protobuf::RepeatedPtrField; using ::google::protobuf::int32; class V4StoreTest : public PlatformTest { @@ -53,6 +55,14 @@ file_format_string.size()); } + void UpdatedStoreReadyAfterRiceRemovals(bool* called_back, + std::unique_ptr<V4Store> new_store) { + *called_back = true; + EXPECT_EQ(2u, new_store->hash_prefix_map_.size()); + EXPECT_EQ("22222", new_store->hash_prefix_map_[5]); + EXPECT_EQ("abcd", new_store->hash_prefix_map_[4]); + } + base::ScopedTempDir temp_dir_; base::FilePath store_path_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; @@ -339,7 +349,7 @@ // old_store: ["2222"] raw_removals.Add(1); EXPECT_EQ( - REMOVALS_INDEX_TOO_LARGE, + REMOVALS_INDEX_TOO_LARGE_FAILURE, store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); } @@ -613,4 +623,79 @@ EXPECT_TRUE(store.GetMatchingHashPrefix(full_hash).empty()); } +#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) +// This test hits a NOTREACHED so it is a release mode only test. +TEST_F(V4StoreTest, TestAdditionsWithRiceEncodingFailsWithInvalidInput) { + RepeatedPtrField<ThreatEntrySet> additions; + ThreatEntrySet* addition = additions.Add(); + addition->set_compression_type(RICE); + addition->mutable_rice_hashes()->set_num_entries(-1); + HashPrefixMap additions_map; + EXPECT_EQ(RICE_DECODING_FAILURE, V4Store::UpdateHashPrefixMapFromAdditions( + additions, &additions_map)); +} +#endif + +TEST_F(V4StoreTest, TestAdditionsWithRiceEncodingSucceeds) { + RepeatedPtrField<ThreatEntrySet> additions; + ThreatEntrySet* addition = additions.Add(); + addition->set_compression_type(RICE); + RiceDeltaEncoding* rice_hashes = addition->mutable_rice_hashes(); + rice_hashes->set_first_value(5); + rice_hashes->set_num_entries(3); + rice_hashes->set_rice_parameter(28); + // The following value is hand-crafted by getting inspiration from: + // https://goto.google.com/testlargenumbersriceencoded + // The value listed at that place fails the "integer overflow" check so I + // modified it until the decoder parsed it successfully. + rice_hashes->set_encoded_data( + "\xbf\xa8\x3f\xfb\xf\xf\x5e\x27\xe6\xc3\x1d\xc6\x38"); + HashPrefixMap additions_map; + EXPECT_EQ(APPLY_UPDATE_SUCCESS, V4Store::UpdateHashPrefixMapFromAdditions( + additions, &additions_map)); + EXPECT_EQ(1u, additions_map.size()); + EXPECT_EQ(std::string("\x5\0\0\0V\x7F\xF6o\xCEo1\x81\fL\x93\xAD", 16), + additions_map[4]); +} + +TEST_F(V4StoreTest, TestRemovalsWithRiceEncodingSucceeds) { + HashPrefixMap prefix_map_old; + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + V4Store::AddUnlumpedHashes(4, "1111abcdefgh", &prefix_map_old)); + HashPrefixMap prefix_map_additions; + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + V4Store::AddUnlumpedHashes(5, "22222bcdef", &prefix_map_additions)); + + V4Store store(task_runner_, store_path_); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + + // At this point, the store map looks like this: + // 4: 1111abcdefgh + // 5: 22222bcdef + // sorted: 1111, 22222, abcd, bcdef, efgh + // We'll now try to delete hashes at indexes 0, 3 and 4 in the sorted list. + + std::unique_ptr<ListUpdateResponse> lur(new ListUpdateResponse); + lur->set_response_type(ListUpdateResponse::PARTIAL_UPDATE); + ThreatEntrySet* removal = lur->add_removals(); + removal->set_compression_type(RICE); + RiceDeltaEncoding* rice_indices = removal->mutable_rice_indices(); + rice_indices->set_first_value(0); + rice_indices->set_num_entries(2); + rice_indices->set_rice_parameter(2); + rice_indices->set_encoded_data("\x16"); + + bool called_back = false; + UpdatedStoreReadyCallback store_ready_callback = + base::Bind(&V4StoreTest::UpdatedStoreReadyAfterRiceRemovals, + base::Unretained(this), &called_back); + store.ApplyUpdate(std::move(lur), task_runner_, store_ready_callback); + task_runner_->RunPendingTasks(); + base::RunLoop().RunUntilIdle(); + + // This ensures that the callback was called. + EXPECT_TRUE(called_back); +} + } // namespace safe_browsing
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 0ed9652..0cc8cce68 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -609,8 +609,22 @@ ] } -# GYP version: sync/sync_tests.gypi:sync_unit_tests +# TODO(maxbogue): Remove this dummy target once bots are updated. test("sync_unit_tests") { + testonly = true + sources = [ + "base/immutable_unittest.cc", + ] + deps = [ + ":sync", + "//base", + "//base/test:run_all_unittests", + "//testing/gtest", + ] +} + +source_set("unit_tests") { + testonly = true sources = [ "api/attachments/attachment_id_unittest.cc", "api/attachments/attachment_metadata_unittest.cc", @@ -712,7 +726,6 @@ ":test_support_sync_core", ":test_support_sync_core_impl", "//base", - "//base/test:run_all_unittests", "//components/sync", "//components/sync/protocol", "//google_apis",
diff --git a/components/sync/sync_tests.gypi b/components/sync/sync_tests.gypi index 6fdc321a..7a3ad9d 100644 --- a/components/sync/sync_tests.gypi +++ b/components/sync/sync_tests.gypi
@@ -242,141 +242,6 @@ 'api/sync_error_factory_mock.h', ], }, - - # The unit test executable for sync tests. - # GN version: //components/sync:sync_unit_tests - { - 'target_name': 'sync_unit_tests', - 'type': '<(gtest_target_type)', - # Typed-parametrized tests generate exit-time destructors. - 'variables': { 'enable_wexit_time_destructors': 0, }, - 'defines': [ - 'SYNC_TEST', - ], - 'dependencies': [ - '../base/base.gyp:base', - '../base/base.gyp:run_all_unittests', - '../google_apis/google_apis.gyp:google_apis', - '../google_apis/google_apis.gyp:google_apis_test_support', - '../net/net.gyp:net', - '../net/net.gyp:net_test_support', - '../sql/sql.gyp:sql', - '../sql/sql.gyp:test_support_sql', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase', - '../third_party/protobuf/protobuf.gyp:protobuf_lite', - 'sync', - 'test_support_sync_api', - 'test_support_sync_core', - 'test_support_sync_core_impl', - ], - 'include_dirs': [ - '..', - ], - 'sources': [ - 'api/attachments/attachment_id_unittest.cc', - 'api/attachments/attachment_metadata_unittest.cc', - 'api/attachments/attachment_unittest.cc', - 'api/entity_data_unittest.cc', - 'api/model_type_service_unittest.cc', - 'api/sync_change_unittest.cc', - 'api/sync_data_unittest.cc', - 'api/sync_error_unittest.cc', - 'api/sync_merge_result_unittest.cc', - 'engine_impl/apply_control_data_updates_unittest.cc', - 'engine_impl/backoff_delay_provider_unittest.cc', - 'engine_impl/directory_commit_contribution_unittest.cc', - 'engine_impl/directory_update_handler_unittest.cc', - 'engine_impl/get_updates_processor_unittest.cc', - 'engine_impl/model_type_worker_unittest.cc', - 'engine_impl/sync_scheduler_unittest.cc', - 'engine_impl/syncer_proto_util_unittest.cc', - 'engine_impl/syncer_unittest.cc', - 'engine_impl/syncer_util_unittest.cc', - 'engine_impl/worker_entity_tracker_unittest.cc', - 'core_impl/attachments/attachment_downloader_impl_unittest.cc', - 'core_impl/attachments/attachment_service_impl_unittest.cc', - 'core_impl/attachments/attachment_service_proxy_unittest.cc', - 'core_impl/attachments/attachment_store_frontend_unittest.cc', - 'core_impl/attachments/attachment_store_test_template.h', - 'core_impl/attachments/attachment_uploader_impl_unittest.cc', - 'core_impl/attachments/fake_attachment_downloader_unittest.cc', - 'core_impl/attachments/fake_attachment_uploader_unittest.cc', - 'core_impl/attachments/in_memory_attachment_store_unittest.cc', - 'core_impl/attachments/on_disk_attachment_store_unittest.cc', - 'core_impl/attachments/task_queue_unittest.cc', - 'core_impl/debug_info_event_listener_unittest.cc', - 'core/http_bridge_unittest.cc', - 'core_impl/js_mutation_event_observer_unittest.cc', - 'core_impl/js_sync_encryption_handler_observer_unittest.cc', - 'core_impl/js_sync_manager_observer_unittest.cc', - 'core_impl/model_type_connector_proxy_unittest.cc', - 'core/model_type_store_backend_unittest.cc', - 'core/model_type_store_impl_unittest.cc', - 'core/processor_entity_tracker_unittest.cc', - 'core_impl/protocol_event_buffer_unittest.cc', - 'base/attachment_id_proto_unittest.cc', - 'base/cancelation_signal_unittest.cc', - 'base/enum_set_unittest.cc', - 'base/node_ordinal_unittest.cc', - 'base/ordinal_unittest.cc', - 'base/unique_position_unittest.cc', - 'core/change_record_unittest.cc', - 'core/data_batch_impl_unittest.cc', - 'engine/model_safe_worker_unittest.cc', - 'sessions/sync_session_snapshot_unittest.cc', - 'core/simple_metadata_change_list_unittest.cc', - 'base/immutable_unittest.cc', - 'base/proto_value_ptr_unittest.cc', - 'base/weak_handle_unittest.cc', - 'core/shared_model_type_processor_unittest.cc', - 'core_impl/sync_encryption_handler_impl_unittest.cc', - 'core_impl/sync_manager_impl_unittest.cc', - 'core_impl/syncapi_server_connection_manager_unittest.cc', - 'js/js_event_details_unittest.cc', - 'js/sync_js_controller_unittest.cc', - 'protocol/proto_enum_conversions_unittest.cc', - 'protocol/proto_value_conversions_unittest.cc', - 'sessions_impl/model_type_registry_unittest.cc', - 'sessions_impl/nudge_tracker_unittest.cc', - 'sessions_impl/status_controller_unittest.cc', - 'syncable/directory_backing_store_unittest.cc', - 'syncable/directory_unittest.cc', - 'syncable/directory_unittest.h', - 'syncable/entry_kernel_unittest.cc', - 'syncable/model_type_unittest.cc', - 'syncable/nigori_util_unittest.cc', - 'syncable/parent_child_index_unittest.cc', - 'syncable/syncable_enum_conversions_unittest.cc', - 'syncable/syncable_id_unittest.cc', - 'syncable/syncable_unittest.cc', - 'syncable/syncable_util_unittest.cc', - 'base/cryptographer_unittest.cc', - 'base/data_type_histogram_unittest.cc', - 'base/get_session_name_unittest.cc', - 'base/nigori_unittest.cc', - 'base/protobuf_unittest.cc', - ], - 'conditions': [ - ['OS == "android"', { - 'dependencies': [ - '../testing/android/native_test.gyp:native_test_native_code', - ], - }], - ['OS=="linux" and chromeos==1', { - # Required by get_session_name_unittest.cc on Chrome OS. - 'dependencies': [ - '../chromeos/chromeos.gyp:chromeos', - ], - }], - ['OS == "ios"', { - 'sources!': [ - 'core/http_bridge_unittest.cc', - ], - }], - ], - }, ], 'conditions': [ ['OS != "ios"', { @@ -494,55 +359,6 @@ 'test/fake_server/android/fake_server_helper_android.h', ], }, - { - # GN: //components/sync:sync_unit_tests_apk - 'target_name': 'sync_unit_tests_apk', - 'type': 'none', - 'dependencies': [ - 'sync_unit_tests', - ], - 'variables': { - 'test_suite_name': 'sync_unit_tests', - 'isolate_file': '../sync_unit_tests.isolate', - }, - 'includes': [ '../../build/apk_test.gypi' ], - }, - ], - 'conditions': [ - ['test_isolation_mode != "noop"', { - 'targets': [ - { - 'target_name': 'sync_unit_tests_apk_run', - 'type': 'none', - 'dependencies': [ - 'sync_unit_tests_apk', - ], - 'includes': [ - '../../build/isolate.gypi', - ], - 'sources': [ - 'sync_unit_tests_apk.isolate', - ], - }, - ], - }], - ], - }], - ['test_isolation_mode != "noop"', { - 'targets': [ - { - 'target_name': 'sync_unit_tests_run', - 'type': 'none', - 'dependencies': [ - 'sync_unit_tests', - ], - 'includes': [ - '../../build/isolate.gypi', - ], - 'sources': [ - '../sync_unit_tests.isolate', - ], - }, ], }], ],
diff --git a/components/sync/sync_unit_tests_apk.isolate b/components/sync/sync_unit_tests_apk.isolate deleted file mode 100644 index dbd6410..0000000 --- a/components/sync/sync_unit_tests_apk.isolate +++ /dev/null
@@ -1,24 +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. -{ - 'includes': [ - '../../build/android/android.isolate', - 'sync_unit_tests.isolate', - ], - 'variables': { - 'command': [ - '<(PRODUCT_DIR)/bin/run_sync_unit_tests', - '--logcat-output-dir', '${ISOLATED_OUTDIR}/logcats', - ], - 'files': [ - '../../base/base.isolate', - '../../build/config/', - '../../third_party/icu/icu.isolate', - '../../third_party/instrumented_libraries/instrumented_libraries.isolate', - '<(PRODUCT_DIR)/bin/run_sync_unit_tests', - '<(PRODUCT_DIR)/sync_unit_tests_apk/', - 'sync_unit_tests.isolate', - ] - }, -}
diff --git a/components/sync_sessions/sessions_sync_manager.cc b/components/sync_sessions/sessions_sync_manager.cc index 4d9505d1..516999d 100644 --- a/components/sync_sessions/sessions_sync_manager.cc +++ b/components/sync_sessions/sessions_sync_manager.cc
@@ -238,15 +238,15 @@ continue; if (synced_tab->IsPlaceholderTab()) { - // For tabs without WebContents update the |tab_id|, as it could have - // changed after a session restore. + // For tabs without WebContents update the |tab_id| and |window_id|, + // as it could have changed after a session restore. // Note: We cannot check if a tab is valid if it has no WebContents. // We assume any such tab is valid and leave the contents of // corresponding sync node unchanged. if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID && tab_id > TabNodePool::kInvalidTabID) { - AssociateRestoredPlaceholderTab(*synced_tab, tab_id, restored_tabs, - change_output); + AssociateRestoredPlaceholderTab(*synced_tab, tab_id, window_id, + restored_tabs, change_output); found_tabs = true; window_s.add_tab(tab_id); } @@ -948,6 +948,7 @@ void SessionsSyncManager::AssociateRestoredPlaceholderTab( const SyncedTabDelegate& tab_delegate, SessionID::id_type new_tab_id, + SessionID::id_type new_window_id, const syncer::SyncDataList& restored_tabs, syncer::SyncChangeList* change_output) { DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); @@ -974,11 +975,14 @@ TabLink* tab_link = new TabLink(tab_delegate.GetSyncId(), &tab_delegate); local_tab_map_[new_tab_id] = make_linked_ptr<TabLink>(tab_link); - if (specifics->tab().tab_id() == new_tab_id) + if (specifics->tab().tab_id() == new_tab_id && + specifics->tab().window_id() == new_window_id) return; - // The tab_id changed (e.g due to session restore), so update sync. + // Either the tab_id or window_id changed (e.g due to session restore), so + // update the sync node. specifics->mutable_tab()->set_tab_id(new_tab_id); + specifics->mutable_tab()->set_window_id(new_window_id); syncer::SyncData data = syncer::SyncData::CreateLocalData( TabNodePool::TabIdToTag(current_machine_tag_, specifics->tab_node_id()), current_session_name_, entity);
diff --git a/components/sync_sessions/sessions_sync_manager.h b/components/sync_sessions/sessions_sync_manager.h index 8e0b53ff..e759fdc 100644 --- a/components/sync_sessions/sessions_sync_manager.h +++ b/components/sync_sessions/sessions_sync_manager.h
@@ -289,8 +289,8 @@ // into memory yet (e.g on android) and we don't have a WebContents. In this // case we can't do a full association, but we still want to update tab IDs // as they may have changed after a session was restored. This method - // compares new_tab_id against the previously persisted tab ID (from - // our TabNodePool) and updates it if it differs. + // compares new_tab_id and new_window_id against the previously persisted tab + // ID and window ID (from our TabNodePool) and updates them if either differs. // |restored_tabs| is a filtered tab-only subset of initial sync data, if // available (during MergeDataAndStartSyncing). It can be used to obtain // baseline SessionSpecifics for tabs we can't fully associate any other @@ -300,6 +300,7 @@ void AssociateRestoredPlaceholderTab( const SyncedTabDelegate& tab_delegate, SessionID::id_type new_tab_id, + SessionID::id_type new_window_id, const syncer::SyncDataList& restored_tabs, syncer::SyncChangeList* change_output);
diff --git a/components/sync_unit_tests.isolate b/components/sync_unit_tests.isolate deleted file mode 100644 index b180652..0000000 --- a/components/sync_unit_tests.isolate +++ /dev/null
@@ -1,32 +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. -{ - 'conditions': [ - ['OS=="linux" or OS=="mac" or OS=="win"', { - 'variables': { - 'command': [ - '../../testing/test_env.py', - '<(PRODUCT_DIR)/sync_unit_tests<(EXECUTABLE_SUFFIX)', - '--brave-new-test-launcher', - '--test-launcher-bot-mode', - '--asan=<(asan)', - '--msan=<(msan)', - '--tsan=<(tsan)', - ], - 'files': [ - '../../chrome/test/data/sync/', - '../../net/tools/testserver/', - '../../testing/test_env.py', - '../../third_party/pyftpdlib/', - '../../third_party/pywebsocket/', - '../../third_party/tlslite/', - '<(PRODUCT_DIR)/pyproto/google/', - ], - }, - }], - ], - 'includes': [ - '../../base/base.isolate', - ], -}
diff --git a/components/test/data/cast_certificate/testsuite/testsuite1.pb b/components/test/data/cast_certificate/testsuite/testsuite1.pb index c85079c..3f3b90de 100644 --- a/components/test/data/cast_certificate/testsuite/testsuite1.pb +++ b/components/test/data/cast_certificate/testsuite/testsuite1.pb Binary files differ
diff --git a/components/test/data/cast_certificate/testsuite/testsuite1.pb_text b/components/test/data/cast_certificate/testsuite/testsuite1.pb_text index dcebb0eb..3a4fb31 100644 --- a/components/test/data/cast_certificate/testsuite/testsuite1.pb_text +++ b/components/test/data/cast_certificate/testsuite/testsuite1.pb_text
@@ -217,3 +217,20 @@ cert_verification_time_seconds: 1466642485 crl_verification_time_seconds: 1466642483 } +tests { + description: "Prod: Valid cert, valid path, no revocation checking." + der_cert_path: "0\202\003\2420\202\002\212\240\003\002\001\002\002\004U\aG\3170\r\006\t*\206H\206\367\r\001\001\005\005\0000y1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0310\027\006\003U\004\003\f\020Chromecast ICA 30\036\027\r150316211455Z\027\r350311211455Z0|1\v0\t\006\003U\004\006\023\002US1\r0\v\006\003U\004\v\f\004Cast1\0230\021\006\003U\004\n\f\nGoogle Inc1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0340\032\006\003U\004\003\f\0233ZZAK6 FA8FCA3F0D350\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\341F_q\275\306-\344\002\246\r!\3173\240\350\352\373\210T\241\264\203I\236\236\020\304\335\303Z\376\233\211)\034\316\274;\322g\016\205\341\303\212\036K\375\233\272\227\2248Ct[\r\027\307\277\300\234\331\001\021\361\325\313\224A\254\201\n\373x9\357\303H\346\265\227\276\212\241V\364\237\324\373!\263\247\240\1770\203\036\'\032M\030\252-\361E\0032\252\f6\204\016\267\037i\264\355u\364\321\241\227p+\220\336\371\262\263\v\243\262\030\2665\365\273\004L\356\204RXk\312\226\v\272\314>1]\205gy.\005\005\3120\372*j#\002\002\327\331A\253\257\305\320\273\247d\327\004\335\310\vGh~\022\201\246/\\75$z\177S\304E\035\372\t\251W\030\220>\032&\201<\236\350\b\246U\214\336\034\302\261\233$lPH\357\271\271\232\310M;\263U\220\034\023?\215\031&Z\267\326\0370\213\305\254k\241\bJ\312Y\002\003\001\000\001\243/0-0\t\006\003U\035\023\004\0020\0000\v\006\003U\035\017\004\004\003\002\a\2000\023\006\003U\035%\004\f0\n\006\b+\006\001\005\005\a\003\0020\r\006\t*\206H\206\367\r\001\001\005\005\000\003\202\001\001\000c^\"\317\260\217\210\264d\242w\205)R\206\023\341\210\352t\006Q\376!E=b\335|\t\311\300d\225\231mU\231\3524#\330\037\252\331\275\266\221\031z-\016\\\377c\321\377\242\271\364\275\263\2464\203y\310\002\363g\"\312\251\252\252\365\357{\356}\v\357\362\367\346\351\312\354\305\315\274\030\377\fD\356n\346\tD9\372o\031\260\276_K\256h7\203\002\262\257\376k\005h\227e.y\025\313\221\201X\267\366N\362\357\341\266\223\213\240\242\235\215\351\005\333\334x\t\313\005\260r\263P\331\r\254\302\021\224{\232\026\334A4J\256\264\372\375\020_O\310F3y3n\250\225\326\222}\273\004m\001\231`{\261\331\024\273~\212/Q\344Y\002:R\324\322\322\223\323\363;\256\032lP\237\231P(\242.\341\341`\027\0341\027?\273u\247\274\326\235\fX\251\376i\024\271N\352\324&\362Z\256&\272\377\357C\356\003" + der_cert_path: "0\202\003\3110\202\002\261\240\003\002\001\002\002\001$0\r\006\t*\206H\206\367\r\001\001\v\005\0000u1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0250\023\006\003U\004\003\f\fCast Root CA0\036\027\r150312164439Z\027\r250309164439Z0y1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0310\027\006\003U\004\003\f\020Chromecast ICA 30\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\321\336\373\255\213C\a(\256V-\362s*\037cCvm\215\270\321\324\220)\033\221hJUA\240\325a\264\354\335\256\341\372\247\2668\304\336\031\3413M\232)\361H\342k\247,!\024\"?\207\201\363q,\346C\034\270\324\354\317g/\262\242u\213\020\275\371\347\311\\\336\005\251\264\206\267h}\247v\205\342e\270vQO\271`]~+dH\022f\331\247\273|\327H\210\212\211\371\030\024\212\0252j\033?@d<\200\323\345r\356;o\210\273\223\032\027<5\313\324[\330\364P\006\b\210\n\345\302<\265\215\233\231\202&\243\233\271\345\001\220\267\311\335\377\017\366\317\264\233\370Jp@\003\355\25285\222IJZ g\222^%\250klI(EA\263\225\035\241\255\357\303Z\0225\246/D\364\3736\314\371\377\324l\250`\346\t\027\246\240\023#\t\226o\335>\375\372Z\347\232\006\023\345\a\016}\\\017\321F\205\002\003\001\000\001\243`0^0\017\006\003U\035\023\004\b0\006\001\001\377\002\001\0000\035\006\003U\035\016\004\026\004\024B\326<\203NN\2036\364-\200\022\030\260\372d\355\313\221\3350\037\006\003U\035#\004\0300\026\200\024|\232\036}\337yT\274\327\314^\312\231\206Eyet(\0310\v\006\003U\035\017\004\004\003\002\001\0060\r\006\t*\206H\206\367\r\001\001\v\005\000\003\202\001\001\000L\307wK\tu\204\253\204\f\223\032\243\037\n\002\262(\000\363\353\301\351R\f{8{\002\32421!\321\205\260#B\340&\005\340\021!\374\264\263~=\252JT\251\b\346y\'\374\275\3751\330\322\302\336\226\0166\371\370g\312\363Yz\250\357\242\275\246s\352\350\253]%\005\235r-\377\n,\177\257\227\306\303\277\265v\005\240\000\021\033\203\231L\213\310\270Kvy\003V\313\352\314\362\002\274#\213\032\246\177\177K\235}ji\315\343Px\271\\\255Y>\335\323\214/\n\373\335\003\300w\204\346\251&\027\024$\242{=<\267<\330\b1\244Kh\213\f\203%i\353hB\242\207\240\241\335Z\032J\034\355(\001=\255Q\326\\\357K\200\322~#\374\275\032\0020\320F\270\261\253\017\307(\356\332\272\347\326>\244\251&\354\324sA\305\233h\212\250\306\02593MH~j/K\034m\257#\002m\350/\316\026\270K" + expected_result: SUCCESS + cert_verification_time_seconds: 1470182400 + use_test_trust_anchors: false +} +tests { + description: "Prod: Empty CRL." + der_cert_path: "0\202\003\2420\202\002\212\240\003\002\001\002\002\004U\aG\3170\r\006\t*\206H\206\367\r\001\001\005\005\0000y1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0310\027\006\003U\004\003\f\020Chromecast ICA 30\036\027\r150316211455Z\027\r350311211455Z0|1\v0\t\006\003U\004\006\023\002US1\r0\v\006\003U\004\v\f\004Cast1\0230\021\006\003U\004\n\f\nGoogle Inc1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0340\032\006\003U\004\003\f\0233ZZAK6 FA8FCA3F0D350\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\341F_q\275\306-\344\002\246\r!\3173\240\350\352\373\210T\241\264\203I\236\236\020\304\335\303Z\376\233\211)\034\316\274;\322g\016\205\341\303\212\036K\375\233\272\227\2248Ct[\r\027\307\277\300\234\331\001\021\361\325\313\224A\254\201\n\373x9\357\303H\346\265\227\276\212\241V\364\237\324\373!\263\247\240\1770\203\036\'\032M\030\252-\361E\0032\252\f6\204\016\267\037i\264\355u\364\321\241\227p+\220\336\371\262\263\v\243\262\030\2665\365\273\004L\356\204RXk\312\226\v\272\314>1]\205gy.\005\005\3120\372*j#\002\002\327\331A\253\257\305\320\273\247d\327\004\335\310\vGh~\022\201\246/\\75$z\177S\304E\035\372\t\251W\030\220>\032&\201<\236\350\b\246U\214\336\034\302\261\233$lPH\357\271\271\232\310M;\263U\220\034\023?\215\031&Z\267\326\0370\213\305\254k\241\bJ\312Y\002\003\001\000\001\243/0-0\t\006\003U\035\023\004\0020\0000\v\006\003U\035\017\004\004\003\002\a\2000\023\006\003U\035%\004\f0\n\006\b+\006\001\005\005\a\003\0020\r\006\t*\206H\206\367\r\001\001\005\005\000\003\202\001\001\000c^\"\317\260\217\210\264d\242w\205)R\206\023\341\210\352t\006Q\376!E=b\335|\t\311\300d\225\231mU\231\3524#\330\037\252\331\275\266\221\031z-\016\\\377c\321\377\242\271\364\275\263\2464\203y\310\002\363g\"\312\251\252\252\365\357{\356}\v\357\362\367\346\351\312\354\305\315\274\030\377\fD\356n\346\tD9\372o\031\260\276_K\256h7\203\002\262\257\376k\005h\227e.y\025\313\221\201X\267\366N\362\357\341\266\223\213\240\242\235\215\351\005\333\334x\t\313\005\260r\263P\331\r\254\302\021\224{\232\026\334A4J\256\264\372\375\020_O\310F3y3n\250\225\326\222}\273\004m\001\231`{\261\331\024\273~\212/Q\344Y\002:R\324\322\322\223\323\363;\256\032lP\237\231P(\242.\341\341`\027\0341\027?\273u\247\274\326\235\fX\251\376i\024\271N\352\324&\362Z\256&\272\377\357C\356\003" + der_cert_path: "0\202\003\3110\202\002\261\240\003\002\001\002\002\001$0\r\006\t*\206H\206\367\r\001\001\v\005\0000u1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0250\023\006\003U\004\003\f\fCast Root CA0\036\027\r150312164439Z\027\r250309164439Z0y1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0310\027\006\003U\004\003\f\020Chromecast ICA 30\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\321\336\373\255\213C\a(\256V-\362s*\037cCvm\215\270\321\324\220)\033\221hJUA\240\325a\264\354\335\256\341\372\247\2668\304\336\031\3413M\232)\361H\342k\247,!\024\"?\207\201\363q,\346C\034\270\324\354\317g/\262\242u\213\020\275\371\347\311\\\336\005\251\264\206\267h}\247v\205\342e\270vQO\271`]~+dH\022f\331\247\273|\327H\210\212\211\371\030\024\212\0252j\033?@d<\200\323\345r\356;o\210\273\223\032\027<5\313\324[\330\364P\006\b\210\n\345\302<\265\215\233\231\202&\243\233\271\345\001\220\267\311\335\377\017\366\317\264\233\370Jp@\003\355\25285\222IJZ g\222^%\250klI(EA\263\225\035\241\255\357\303Z\0225\246/D\364\3736\314\371\377\324l\250`\346\t\027\246\240\023#\t\226o\335>\375\372Z\347\232\006\023\345\a\016}\\\017\321F\205\002\003\001\000\001\243`0^0\017\006\003U\035\023\004\b0\006\001\001\377\002\001\0000\035\006\003U\035\016\004\026\004\024B\326<\203NN\2036\364-\200\022\030\260\372d\355\313\221\3350\037\006\003U\035#\004\0300\026\200\024|\232\036}\337yT\274\327\314^\312\231\206Eyet(\0310\v\006\003U\035\017\004\004\003\002\001\0060\r\006\t*\206H\206\367\r\001\001\v\005\000\003\202\001\001\000L\307wK\tu\204\253\204\f\223\032\243\037\n\002\262(\000\363\353\301\351R\f{8{\002\32421!\321\205\260#B\340&\005\340\021!\374\264\263~=\252JT\251\b\346y\'\374\275\3751\330\322\302\336\226\0166\371\370g\312\363Yz\250\357\242\275\246s\352\350\253]%\005\235r-\377\n,\177\257\227\306\303\277\265v\005\240\000\021\033\203\231L\213\310\270Kvy\003V\313\352\314\362\002\274#\213\032\246\177\177K\235}ji\315\343Px\271\\\255Y>\335\323\214/\n\373\335\003\300w\204\346\251&\027\024$\242{=<\267<\330\b1\244Kh\213\f\203%i\353hB\242\207\240\241\335Z\032J\034\355(\001=\255Q\326\\\357K\200\322~#\374\275\032\0020\320F\270\261\253\017\307(\356\332\272\347\326>\244\251&\354\324sA\305\233h\212\250\306\02593MH~j/K\034m\257#\002m\350/\316\026\270K" + crl_bundle: "\n\337\t\n\f\020\270\362\203\275\005\030\270\347\250\275\005\022\313\a0\202\003\3070\202\002\257\240\003\002\001\002\002\002\000\2320\r\006\t*\206H\206\367\r\001\001\v\005\0000y1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0310\027\006\003U\004\003\f\020Cast CRL Root CA0\036\027\r160801234632Z\027\r161109234632Z0x1\v0\t\006\003U\004\006\023\002US1\0230\021\006\003U\004\b\f\nCalifornia1\0260\024\006\003U\004\a\f\rMountain View1\0230\021\006\003U\004\n\f\nGoogle Inc1\r0\v\006\003U\004\v\f\004Cast1\0300\026\006\003U\004\003\f\017Cast CRL Signer0\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\312\323\264p\353\347\253W\266\315k\020`\274\202\034t[\262\245\037\340\265\245E\266\260\267\251\027\275a\367\237\016\307>\347\305X\273\341e-\325\2231d\276\351\271\264\257*\\\023\b\223\377Z\330\266-/\314JY\324\267`\240\370t2\177\247\003;8\321\024\315\022\242@\304;\253\rZ\352\305\232\005\314\245\241-\247n\251\240\021\tk\311\227\334\351h\004+6\231\274\213\n\357lt\0257A\353\200M#\245\317\230\346\211\257\216\312\301\2035!l\252\\\250/i\r\025\342\022D\343\343\375zU\261\265\246:=?\a\230\373\246\275\351\370\304\016#o\035\323\261\233&\315\006\312N\215\030\206\034_\221\204\302b<\336\327\317\006\227m\317K\370\351\301\037\266C\341\305\226s5\177\235:\233\257\032\317\0170\343\212\275\271(\355\213\272\360\fI\211^\264m\330\274\234\036-\250\006\210\353@@\016\"\330\n\a)\032\321\v\336\331\002\003\001\000\001\243Z0X0\t\006\003U\035\023\004\0020\0000\035\006\003U\035\016\004\026\004\024+\220\335<H\234\211#\264\254h\315^B\036^,\324\313\2430\037\006\003U\035#\004\0300\026\200\024\032e\022\264\251\271\264\374\221\f\236g\340[\331\311\255D\034\2710\v\006\003U\035\017\004\004\003\002\a\2000\r\006\t*\206H\206\367\r\001\001\v\005\000\003\202\001\001\000\215M\323\271\237\355\260\336\315\020_\315\3051\363i\365V\307\033\251/;\002\311M\2279.j\373\311\267\034\315\221\360\230\227\"\372\237\231\210\025Uk\b\206\360\236*$\277x+\362\022B\240\005\214\213\272\330\205\325+\346\221\303\r\036\004\357\021\371K\033;8\350\322H7\220\241\244a\234\2051C\333Z\376\316\205\350\320\r\266\201\002\003\250\236\000%\231\302\t6#\310K\305#\246+\346\027\255N\376}S\226s\366\317%-h\235\357Q\230\253Mc;\204\"\202I\230C \261\036^\257\335\374;Qe\001\333\2432\323\277\217Y\004\'q\356\311\210\\\322\244\233*\016\367 &~\3752\373\236\000\261o\260\2036\005\001SB\306g(\202\343\325\370\376\021UA\200UT\030\323\213\325\306\232&\275\377;5[\353\335yY*\372_\346\310\361\360\307\270U\207X\226\260\f!\273\237\206\307]z-\310j4\004\'4\240\032\200\002n\327,\252e\n\211=\224\241Ng\357tc\237-\246\a\226&GR\277\365dc2\342\344\335\311\001M\356A\026\000\247\035A;\\\332\335d\313\\\371xo\032P\361\266\347q\300\271\371E\250\255.VM\325\266\002\305\020\212\375\3721>\251J}M]\216{\205Twp\3208\330\232\271\341n@&a\225\222\205\302\022\226LA\211\343=}\233\340\325\330P\023\027=g\371\372\3162\370\355r\305\f\v\222`r|\266\222\212\327\3360J\310\221\220\316m_K\377I8\333\356\004\234L\340\267\315\270&\272\025\025\323#ed\366{\330\3273\332\326c\300}\000N2xS\255\327\206\224T\336\267\344^\225C\221e\220Wt\264S\022:\023\235ww\207\367=\320\267-\003+\v\265\250\330W\314\261\222>d\240\204\264R\006\316A\344\267#\213\216\005\301\272\375\310\336\210\373\033\341\316U_\324\307D}\311v\343\034" + expected_result: SUCCESS + cert_verification_time_seconds: 1470182400 + use_test_trust_anchors: false +}
diff --git a/components/tracing/BUILD.gn b/components/tracing/BUILD.gn index 0e3c97f..c00cdd2b 100644 --- a/components/tracing/BUILD.gn +++ b/components/tracing/BUILD.gn
@@ -63,7 +63,9 @@ visibility = [ "//components/tracing/*" ] sources = [ - "test/example_messages.proto", + "test/example_proto/library.proto", + "test/example_proto/library_internals/galaxies.proto", + "test/example_proto/test_messages.proto", ] generator_plugin_label = "tools/proto_zero_plugin:proto_zero_plugin"
diff --git a/components/tracing/test/example_proto/library.proto b/components/tracing/test/example_proto/library.proto new file mode 100644 index 0000000..04f019e --- /dev/null +++ b/components/tracing/test/example_proto/library.proto
@@ -0,0 +1,16 @@ +// 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. + +syntax = "proto2"; +package foo.bar; + +import public "library_internals/galaxies.proto"; + +message TransgalacticMessage { + optional Galaxy origin_galaxy = 1; + optional string origin_planet = 2; + optional Galaxy destination_galaxy = 3; + optional string destination_planet = 4; + optional bytes proto_message = 5; +}
diff --git a/components/tracing/test/example_proto/library_internals/galaxies.proto b/components/tracing/test/example_proto/library_internals/galaxies.proto new file mode 100644 index 0000000..21e9019 --- /dev/null +++ b/components/tracing/test/example_proto/library_internals/galaxies.proto
@@ -0,0 +1,12 @@ +// 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. + +syntax = "proto2"; +package foo.bar; + +enum Galaxy { + MILKY_WAY = 1; + ANDROMEDA = 2; + SUNFLOWER = 3; +}
diff --git a/components/tracing/test/example_messages.proto b/components/tracing/test/example_proto/test_messages.proto similarity index 85% rename from components/tracing/test/example_messages.proto rename to components/tracing/test/example_proto/test_messages.proto index c3210b82..588ec84 100644 --- a/components/tracing/test/example_messages.proto +++ b/components/tracing/test/example_proto/test_messages.proto
@@ -5,9 +5,17 @@ syntax = "proto2"; package foo.bar; +import "library.proto"; + // This file contains comprehensive set of supported message structures and // data types. Unit tests depends on the plugin-processed version of this file. +// Tests importing message definition from another proto file. +message TransgalacticParcel { + optional TransgalacticMessage message = 1; + optional string tracking_code = 2; +} + enum SmallEnum { TO_BE = 1; NOT_TO_BE = 0; @@ -63,4 +71,5 @@ optional NestedC value_b = 1; } repeated NestedB repeated_a = 2; + optional NestedB.NestedC super_nested = 3; }
diff --git a/components/tracing/test/proto_zero_generation_unittest.cc b/components/tracing/test/proto_zero_generation_unittest.cc index 31fb8ea..531cadb 100644 --- a/components/tracing/test/proto_zero_generation_unittest.cc +++ b/components/tracing/test/proto_zero_generation_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/tracing/test/example_messages.pbzero.h" +#include "components/tracing/test/example_proto/test_messages.pbzero.h" #include "testing/gtest/include/gtest/gtest.h" namespace tracing {
diff --git a/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc b/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc index 12a32ab3..2165673 100644 --- a/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc +++ b/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
@@ -6,6 +6,7 @@ #include <map> #include <memory> +#include <set> #include <string> #include "third_party/protobuf/src/google/protobuf/descriptor.h" @@ -33,6 +34,10 @@ namespace { +inline std::string ProtoStubName(const FileDescriptor* proto) { + return StripSuffixString(proto->name(), ".proto") + ".pbzero"; +} + class GeneratorJob { public: GeneratorJob(const FileDescriptor *file, @@ -102,14 +107,7 @@ return true; } - void Preprocess() { - // Package name maps to a series of namespaces. - package_ = source_->package(); - namespaces_ = Split(package_, "."); - full_namespace_prefix_ = "::"; - for (const std::string& ns : namespaces_) - full_namespace_prefix_ += ns + "::"; - + void CollectDescriptors() { // Collect message descriptors in DFS order. std::vector<const Descriptor*> stack; for (int i = 0; i < source_->message_type_count(); ++i) @@ -135,6 +133,74 @@ } } + void CollectDependencies() { + // Public import basically means that callers only need to import this + // proto in order to use the stuff publicly imported by this proto. + for (int i = 0; i < source_->public_dependency_count(); ++i) + public_imports_.insert(source_->public_dependency(i)); + + if (source_->weak_dependency_count() > 0) + Abort("Weak imports are not supported."); + + // Sanity check. Collect public imports (of collected imports) in DFS order. + // Visibilty for current proto: + // - all imports listed in current proto, + // - public imports of everything imported (recursive). + std::vector<const FileDescriptor*> stack; + for (int i = 0; i < source_->dependency_count(); ++i) { + const FileDescriptor* import = source_->dependency(i); + stack.push_back(import); + if (public_imports_.count(import) == 0) { + private_imports_.insert(import); + } + } + + while (!stack.empty()) { + const FileDescriptor* import = stack.back(); + stack.pop_back(); + // Having imports under different packages leads to unnecessary + // complexity with namespaces. + if (import->package() != package_) + Abort("Imported proto must be in the same package."); + + for (int i = 0; i < import->public_dependency_count(); ++i) { + stack.push_back(import->public_dependency(i)); + } + } + + // Collect descriptors of messages and enums used in current proto. + // It will be used to generate necessary forward declarations and performed + // sanity check guarantees that everything lays in the same namespace. + for (const Descriptor* message : messages_) { + for (int i = 0; i < message->field_count(); ++i) { + const FieldDescriptor* field = message->field(i); + + if (field->type() == FieldDescriptor::TYPE_MESSAGE) { + if (public_imports_.count(field->message_type()->file()) == 0) { + // Avoid multiple forward declarations since + // public imports have been already included. + referenced_messages_.insert(field->message_type()); + } + } else if (field->type() == FieldDescriptor::TYPE_ENUM) { + if (public_imports_.count(field->enum_type()->file()) == 0) { + referenced_enums_.insert(field->enum_type()); + } + } + } + } + } + + void Preprocess() { + // Package name maps to a series of namespaces. + package_ = source_->package(); + namespaces_ = Split(package_, "."); + full_namespace_prefix_ = "::"; + for (const std::string& ns : namespaces_) + full_namespace_prefix_ += ns + "::"; + CollectDescriptors(); + CollectDependencies(); + } + // Print top header, namespaces and forward declarations. void GeneratePrologue() { std::string greeting = @@ -151,30 +217,65 @@ "#define $guard$\n\n" "#include <stddef.h>\n" "#include <stdint.h>\n\n" - "#include \"components/tracing/core/proto_zero_message.h\"\n\n", + "#include \"components/tracing/core/proto_zero_message.h\"\n", "greeting", greeting, "guard", guard); stub_cc_->Print( "$greeting$\n" - "// This file intentionally left blank.\n", - "greeting", greeting); + "#include \"$name$.h\"\n", + "greeting", greeting, + "name", ProtoStubName(source_)); + + // Print includes for public imports. + for (const FileDescriptor* dependency : public_imports_) { + // Dependency name could contatin slashes but importing from upper-level + // directories is not possible anyway since build system process each + // proto file individually. Hence proto lookup path always equal to the + // directory where particular proto file is located and protoc does not + // allow reference to upper directory (aka ..) in import path. + // + // Laconically said: + // - source_->name() may never have slashes, + // - dependency->name() may have slashes but always reffers to inner path. + stub_h_->Print( + "#include \"$name$.h\"\n", + "name", ProtoStubName(dependency)); + } + stub_h_->Print("\n"); + + // Print includes for private imports to .cc file. + for (const FileDescriptor* dependency : private_imports_) { + stub_cc_->Print( + "#include \"$name$.h\"\n", + "name", ProtoStubName(dependency)); + } + stub_cc_->Print("\n"); // Print namespaces. - for (const std::string& ns : namespaces_) + for (const std::string& ns : namespaces_) { stub_h_->Print("namespace $ns$ {\n", "ns", ns); + stub_cc_->Print("namespace $ns$ {\n", "ns", ns); + } stub_h_->Print("\n"); + stub_cc_->Print("\n"); + // Print forward declarations. - for (const Descriptor* message : messages_) { + for (const Descriptor* message : referenced_messages_) { stub_h_->Print( "class $class$;\n", "class", GetCppClassName(message)); } + for (const EnumDescriptor* enumeration : referenced_enums_) { + stub_h_->Print( + "enum $class$ : int32_t;\n", + "class", GetCppClassName(enumeration)); + } stub_h_->Print("\n"); } void GenerateEnumDescriptor(const EnumDescriptor* enumeration) { stub_h_->Print( - "enum $class$ {\n", + "enum $class$ : int32_t {\n", "class", GetCppClassName(enumeration)); stub_h_->Indent(); @@ -302,14 +403,24 @@ } void GenerateNestedMessageFieldDescriptor(const FieldDescriptor* field) { + std::string action = field->is_repeated() ? "add" : "set"; + std::string inner_class = GetCppClassName(field->message_type()); + std::string outer_class = GetCppClassName(field->containing_type()); + stub_h_->Print( - "$class$* $action$_$name$() {\n" - " return BeginNestedMessage<$class$>($id$);\n" - "}\n", + "$inner_class$* $action$_$name$();\n", + "name", field->name(), + "action", action, + "inner_class", inner_class); + stub_cc_->Print( + "$inner_class$* $outer_class$::$action$_$name$() {\n" + " return BeginNestedMessage<$inner_class$>($id$);\n" + "}\n\n", "id", std::to_string(field->number()), "name", field->name(), - "action", field->is_repeated() ? "add" : "set", - "class", GetCppClassName(field->message_type())); + "action", action, + "inner_class", inner_class, + "outer_class", outer_class); } void GenerateMessageDescriptor(const Descriptor* message) { @@ -373,6 +484,7 @@ void GenerateEpilogue() { for (unsigned i = 0; i < namespaces_.size(); ++i) { stub_h_->Print("} // Namespace.\n"); + stub_cc_->Print("} // Namespace.\n"); } stub_h_->Print("#endif // Include guard.\n"); } @@ -387,6 +499,11 @@ std::string full_namespace_prefix_; std::vector<const Descriptor*> messages_; std::vector<const EnumDescriptor*> enums_; + + std::set<const FileDescriptor*> public_imports_; + std::set<const FileDescriptor*> private_imports_; + std::set<const Descriptor*> referenced_messages_; + std::set<const EnumDescriptor*> referenced_enums_; }; } // namespace @@ -402,13 +519,10 @@ GeneratorContext* context, std::string* error) const { - const std::string proto_stubs_name = - StripSuffixString(file->name(), ".proto") + ".pbzero"; - const std::unique_ptr<ZeroCopyOutputStream> stub_h_file_stream( - context->Open(proto_stubs_name + ".h")); + context->Open(ProtoStubName(file) + ".h")); const std::unique_ptr<ZeroCopyOutputStream> stub_cc_file_stream( - context->Open(proto_stubs_name + ".cc")); + context->Open(ProtoStubName(file) + ".cc")); // Variables are delimited by $. Printer stub_h_printer(stub_h_file_stream.get(), '$');
diff --git a/content/app/BUILD.gn b/content/app/BUILD.gn index 116a1dbe..1c4e913 100644 --- a/content/app/BUILD.gn +++ b/content/app/BUILD.gn
@@ -15,7 +15,6 @@ extra_configs = [ "//build/config/compiler:wexit_time_destructors", "//content:content_implementation", - "//content/public/common:mojo_shell_client", "//v8:external_startup_data", ]
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index ceba43c..e0bc7d1 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -23,7 +23,6 @@ configs += [ "//build/config:precompiled_headers", "//content:content_implementation", - "//content/public/common:mojo_shell_client", "//third_party/WebKit/public:debug_devtools", "//v8:external_startup_data", ]
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 21c29ee..d7a1f39 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -277,7 +277,7 @@ } #endif // defined(USE_GLIB) -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) +#if defined(USE_AURA) void WaitForMojoShellInitialize() { // TODO(rockot): Remove this. http://crbug.com/594852. base::RunLoop wait_loop; @@ -285,7 +285,7 @@ wait_loop.QuitClosure()); wait_loop.Run(); } -#endif // defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) +#endif // defined(USE_AURA) void OnStoppedStartupTracing(const base::FilePath& trace_file) { VLOG(0) << "Completed startup tracing to " << trace_file.value(); @@ -1196,7 +1196,7 @@ ->task_runner())); mojo_shell_context_.reset(new MojoShellContext); -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) +#if defined(USE_AURA) // TODO(rockot): Remove the blocking wait for init. // http://crbug.com/594852. if (shell::ShellIsRemote() && MojoShellConnection::GetForProcess()) { @@ -1243,11 +1243,8 @@ BrowserGpuChannelHostFactory::Initialize(established_gpu_channel); ImageTransportFactory::Initialize(); #if defined(USE_AURA) - bool use_mus_in_renderer = false; -#if defined (MOJO_SHELL_CLIENT) - use_mus_in_renderer = base::CommandLine::ForCurrentProcess()->HasSwitch( + bool use_mus_in_renderer = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseMusInRenderer); -#endif // defined(MOJO_SHELL_CLIENT); if (aura::Env::GetInstance() && !use_mus_in_renderer) { aura::Env::GetInstance()->set_context_factory(GetContextFactory()); }
diff --git a/content/browser/child_process_launcher.h b/content/browser/child_process_launcher.h index 6f51a90a..f400f694 100644 --- a/content/browser/child_process_launcher.h +++ b/content/browser/child_process_launcher.h
@@ -142,15 +142,6 @@ base::Process process, int error_code); -#if defined(MOJO_SHELL_CLIENT) - // When this process is run from an external Mojo shell, this function will - // create a channel and pass one end to the spawned process and register the - // other end with the external shell, allowing the spawned process to bind an - // Application request from the shell. - void CreateMojoShellChannel(base::CommandLine* command_line, - int child_process_id); -#endif - Client* client_; BrowserThread::ID client_thread_id_; base::Process process_;
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 0bc1ceb..7857c963 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -206,7 +206,8 @@ } const net::HttpResponseHeaders* NavigationHandleImpl::GetResponseHeaders() { - return response_headers_.get(); + DCHECK_GE(state_, WILL_REDIRECT_REQUEST); + return response_headers_.get(); } bool NavigationHandleImpl::HasCommitted() {
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index 264bffa..677a167 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -98,6 +98,7 @@ bool IsSamePage() override; bool HasCommitted() override; bool IsErrorPage() override; + const net::HttpResponseHeaders* GetResponseHeaders() override; void Resume() override; void CancelDeferredNavigation( NavigationThrottle::ThrottleCheckResult result) override; @@ -123,12 +124,6 @@ RequestContextType GetRequestContextType() const; - // Returns the response headers for the request or nullptr if there are none. - // This should only be accessed after a redirect was encountered or after the - // navigation is ready to commit. The headers returned should not be modified, - // as modifications will not be reflected in the network stack. - const net::HttpResponseHeaders* GetResponseHeaders(); - // Get the unique id from the NavigationEntry associated with this // NavigationHandle. Note that a synchronous, renderer-initiated navigation // will not have a NavigationEntry associated with it, and this will return 0.
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 4d7367c..7f3ef1a 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -48,10 +48,6 @@ #if defined(OS_WIN) #include "base/win/windows_version.h" #endif // OS_WIN -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) -#include "services/shell/runner/common/client_util.h" // nogncheck -#include "services/ui/common/gpu_service.h" // nogncheck -#endif namespace content {
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index f394db3..a12b1c6 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -62,6 +62,7 @@ #include "mojo/edk/embedder/embedder.h" #include "services/shell/public/cpp/connection.h" #include "services/shell/public/cpp/interface_provider.h" +#include "services/shell/runner/common/client_util.h" #include "ui/base/ui_base_switches.h" #include "ui/events/latency_info.h" #include "ui/gl/gl_switches.h" @@ -90,10 +91,6 @@ #include "content/browser/gpu/gpu_surface_tracker.h" #endif -#if defined(MOJO_SHELL_CLIENT) -#include "services/shell/runner/common/client_util.h" -#endif - namespace content { bool GpuProcessHost::gpu_enabled_ = true; @@ -119,7 +116,6 @@ #endif #if defined(OS_WIN) switches::kEnableAcceleratedVpxDecode, - switches::kEnableMFH264Encoding, #endif switches::kEnableHeapProfiling, switches::kEnableLogging, @@ -316,9 +312,7 @@ // static GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, bool force_create) { -#if defined(MOJO_SHELL_CLIENT) DCHECK(!shell::ShellIsRemote()); -#endif DCHECK_CURRENTLY_ON(BrowserThread::IO); // Don't grant further access to GPU if it is not allowed.
diff --git a/content/browser/media/session/media_session_visibility_browsertest.cc b/content/browser/media/session/media_session_visibility_browsertest.cc index 659b3c1a..70ddbfbf 100644 --- a/content/browser/media/session/media_session_visibility_browsertest.cc +++ b/content/browser/media/session/media_session_visibility_browsertest.cc
@@ -63,7 +63,24 @@ media_session_state_callback_subscription_.reset(); } + void EnableDisableResumingBackgroundVideos(bool enable) { + std::string enabled_features; + std::string disabled_features; + if (enable) + enabled_features = media::kResumeBackgroundVideo.name; + else + disabled_features = media::kResumeBackgroundVideo.name; + + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->InitializeFromCommandLine( + enabled_features, disabled_features); + base::FeatureList::ClearInstanceForTesting(); + base::FeatureList::SetInstance(std::move(feature_list)); + } + void SetUpCommandLine(base::CommandLine* command_line) override { + EnableDisableResumingBackgroundVideos(false); + command_line->AppendSwitch( switches::kDisableGestureRequirementForMediaPlayback); #if !defined(OS_ANDROID) @@ -149,6 +166,24 @@ LOG(INFO) << "Test succeeded"; } + void TestSessionSuspendedWhenHiddenWhilePlaying() { + LoadTestPage(); + + LOG(INFO) << "Starting player"; + ClearMediaSessionStateLoopRunners(); + RunScript(kStartPlayerScript); + LOG(INFO) << "Waiting for Session to be active"; + WaitForMediaSessionState(MediaSession::State::ACTIVE); + + LOG(INFO) << "Hiding the tab"; + ClearMediaSessionStateLoopRunners(); + web_contents_->WasHidden(); + LOG(INFO) << "Waiting for Session to be suspended"; + WaitForMediaSessionState(MediaSession::State::SUSPENDED); + + LOG(INFO) << "Test succeeded"; + } + void TestSessionSuspendedWhenHiddenAfterContentPause() { LoadTestPage(); @@ -239,6 +274,20 @@ MediaSessionVisibilityBrowserTest_UnifiedPipeline_SuspendOnHide, TestSessionInactiveWhenHiddenWhilePlaying) +IN_PROC_BROWSER_TEST_F( + MediaSessionVisibilityBrowserTest_UnifiedPipeline_SuspendOnHide, + TestSessionSuspendedWhenHiddenWhilePlaying) { + EnableDisableResumingBackgroundVideos(true); + TestSessionSuspendedWhenHiddenWhilePlaying(); +} + +IN_PROC_BROWSER_TEST_F( + MediaSessionVisibilityBrowserTest_UnifiedPipeline_SuspendOnHide, + TestSessionSuspendedWhenHiddenAfterContentPause) { + EnableDisableResumingBackgroundVideos(true); + TestSessionSuspendedWhenHiddenAfterContentPause(); +} + // UnifiedPipeline + NosuspendOnHide class MediaSessionVisibilityBrowserTest_UnifiedPipeline_NosuspendOnHide : public MediaSessionVisibilityBrowserTest { @@ -257,6 +306,13 @@ MediaSessionVisibilityBrowserTest_UnifiedPipeline_NosuspendOnHide, TestSessionActiveWhenHiddenWhilePlaying) +IN_PROC_BROWSER_TEST_F( + MediaSessionVisibilityBrowserTest_UnifiedPipeline_NosuspendOnHide, + TestSessionActiveWhenHiddenWhilePlayingWithResume) { + EnableDisableResumingBackgroundVideos(true); + TestSessionActiveWhenHiddenWhilePlaying(); +} + #if defined(OS_ANDROID) // AndroidPipeline + SuspendOnHide class MediaSessionVisibilityBrowserTest_AndroidPipeline_SuspendOnHide :
diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc index a712e54..47a060f 100644 --- a/content/browser/renderer_host/ime_adapter_android.cc +++ b/content/browser/renderer_host/ime_adapter_android.cc
@@ -329,18 +329,6 @@ return true; } -void ImeAdapterAndroid::RequestCursorUpdate( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - bool immediate_request, - bool monitor_request) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - rwhi->Send(new InputMsg_RequestCompositionUpdate( - rwhi->GetRoutingID(), immediate_request, monitor_request)); -} - bool ImeAdapterAndroid::IsImeThreadEnabled( JNIEnv* env, const base::android::JavaParamRef<jobject>&) {
diff --git a/content/browser/renderer_host/ime_adapter_android.h b/content/browser/renderer_host/ime_adapter_android.h index ea88d543..1f559c6 100644 --- a/content/browser/renderer_host/ime_adapter_android.h +++ b/content/browser/renderer_host/ime_adapter_android.h
@@ -78,8 +78,6 @@ int before, int after); void ResetImeAdapter(JNIEnv*, const base::android::JavaParamRef<jobject>&); - void RequestCursorUpdate(JNIEnv*, const base::android::JavaParamRef<jobject>&, - bool immediateRequest, bool monitorRequest); bool RequestTextInputStateUpdate(JNIEnv*, const base::android::JavaParamRef<jobject>&); bool IsImeThreadEnabled(JNIEnv*, const base::android::JavaParamRef<jobject>&);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 119edec2..394217d4 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1642,9 +1642,7 @@ switches::kIpcDumpDirectory, switches::kIpcFuzzerTestcase, #endif -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) switches::kUseMusInRenderer, -#endif }; renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames, arraysize(kSwitchNames));
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 3362aec..7286cec3 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -45,7 +45,6 @@ #include "content/browser/renderer_host/ui_events_helper.h" #include "content/browser/renderer_host/web_input_event_aura.h" #include "content/common/content_switches_internal.h" -#include "content/common/input_messages.h" #include "content/common/site_isolation_policy.h" #include "content/common/text_input_state.h" #include "content/common/view_messages.h" @@ -108,6 +107,7 @@ #endif #if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#include "content/common/input_messages.h" #include "ui/base/ime/linux/text_edit_command_auralinux.h" #include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h" #endif @@ -2996,23 +2996,8 @@ const TextInputState* state = text_input_manager_->GetTextInputState(); if (state && state->show_ime_if_needed && - state->type != ui::TEXT_INPUT_TYPE_NONE) { + state->type != ui::TEXT_INPUT_TYPE_NONE) GetInputMethod()->ShowImeIfNeeded(); - - // Start monitoring the composition information if the focused node is - // editable. - host_->Send(new InputMsg_RequestCompositionUpdate( - host_->GetRoutingID(), - false /* immediate request */, - true /* monitor request */)); - } else { - // Stop monitoring the composition information if the focused node is not - // editable. - host_->Send(new InputMsg_RequestCompositionUpdate( - host_->GetRoutingID(), - false /* immediate request */, - false /* monitor request */)); - } } void RenderWidgetHostViewAura::OnImeCancelComposition(
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc index ee764be..4526ab3 100644 --- a/content/browser/ssl/ssl_manager.cc +++ b/content/browser/ssl/ssl_manager.cc
@@ -15,7 +15,6 @@ #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/ssl/ssl_cert_error_handler.h" #include "content/browser/ssl/ssl_policy.h" -#include "content/browser/ssl/ssl_request_info.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/ssl_status_serialization.h" #include "content/public/browser/browser_context.h" @@ -144,32 +143,16 @@ void SSLManager::DidLoadFromMemoryCache( const LoadFromMemoryCacheDetails& details) { // Simulate loading this resource through the usual path. - // Note that we specify SUB_RESOURCE as the resource type as WebCore only - // caches sub-resources. - // This resource must have been loaded with no filtering because filtered - // resouces aren't cachable. - scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo( - details.url, - RESOURCE_TYPE_SUB_RESOURCE, - details.cert_id, - details.cert_status)); - - // Simulate loading this resource through the usual path. - policy()->OnRequestStarted(info.get()); + policy()->OnRequestStarted(details.url, details.cert_id, details.cert_status); } void SSLManager::DidStartResourceResponse( const ResourceRequestDetails& details) { - scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo( - details.url, - details.resource_type, - details.ssl_cert_id, - details.ssl_cert_status)); - // Notify our policy that we started a resource request. Ideally, the // policy should have the ability to cancel the request, but we can't do // that yet. - policy()->OnRequestStarted(info.get()); + policy()->OnRequestStarted(details.url, details.ssl_cert_id, + details.ssl_cert_status); } void SSLManager::DidReceiveResourceRedirect(
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc index e710e7c..a45e135 100644 --- a/content/browser/ssl/ssl_policy.cc +++ b/content/browser/ssl/ssl_policy.cc
@@ -16,7 +16,6 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/site_instance_impl.h" #include "content/browser/ssl/ssl_cert_error_handler.h" -#include "content/browser/ssl/ssl_request_info.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/web_contents.h" @@ -44,7 +43,7 @@ } void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) { - bool expired_previous_decision; + bool expired_previous_decision = false; // First we check if we know the policy for this error. DCHECK(handler->ssl_info().is_valid()); SSLHostStateDelegate::CertJudgment judgment = @@ -118,9 +117,11 @@ site_instance->GetProcess()->GetID()); } -void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) { - if (info->ssl_cert_id() && info->url().SchemeIsCryptographic() && - !net::IsCertStatusError(info->ssl_cert_status())) { +void SSLPolicy::OnRequestStarted(const GURL& url, + int cert_id, + net::CertStatus cert_status) { + if (cert_id && url.SchemeIsCryptographic() && + !net::IsCertStatusError(cert_status)) { // If the scheme is https: or wss: *and* the security info for the // cert has been set (i.e. the cert id is not 0) and the cert did // not have any errors, revoke any previous decisions that @@ -128,11 +129,11 @@ // isn't known if the connection was actually a valid connection or if it // had a cert error. SSLGoodCertSeenEvent event = NO_PREVIOUS_EXCEPTION; - if (backend_->HasAllowException(info->url().host())) { + if (backend_->HasAllowException(url.host())) { // If there's no certificate error, a good certificate has been seen, so // clear out any exceptions that were made by the user for bad // certificates. - backend_->RevokeUserAllowExceptions(info->url().host()); + backend_->RevokeUserAllowExceptions(url.host()); event = HAD_PREVIOUS_EXCEPTION; } UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.good_cert_seen", event,
diff --git a/content/browser/ssl/ssl_policy.h b/content/browser/ssl/ssl_policy.h index a4644ef..8df01a1 100644 --- a/content/browser/ssl/ssl_policy.h +++ b/content/browser/ssl/ssl_policy.h
@@ -19,7 +19,6 @@ class NavigationEntryImpl; class SSLCertErrorHandler; class SSLPolicyBackend; -class SSLRequestInfo; class WebContents; // SSLPolicy @@ -38,8 +37,11 @@ void DidRunInsecureContent(NavigationEntryImpl* entry, const GURL& security_origin); - // We have started a resource request with the given info. - void OnRequestStarted(SSLRequestInfo* info); + // We have started a resource request for |url| with the given |cert_id| and + // |cert_status|. + void OnRequestStarted(const GURL& url, + int cert_id, + net::CertStatus cert_status); // Update the SSL information in |entry| to match the current state. // |web_contents| is the WebContents associated with this entry.
diff --git a/content/browser/ssl/ssl_request_info.cc b/content/browser/ssl/ssl_request_info.cc deleted file mode 100644 index 4917a0a..0000000 --- a/content/browser/ssl/ssl_request_info.cc +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright (c) 2010 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/ssl/ssl_request_info.h" - -namespace content { - -SSLRequestInfo::SSLRequestInfo(const GURL& url, - ResourceType resource_type, - int ssl_cert_id, - net::CertStatus ssl_cert_status) - : url_(url), - resource_type_(resource_type), - ssl_cert_id_(ssl_cert_id), - ssl_cert_status_(ssl_cert_status) { -} - -SSLRequestInfo::~SSLRequestInfo() {} - -} // namespace content
diff --git a/content/browser/ssl/ssl_request_info.h b/content/browser/ssl/ssl_request_info.h deleted file mode 100644 index f07f0f8..0000000 --- a/content/browser/ssl/ssl_request_info.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_SSL_SSL_REQUEST_INFO_H_ -#define CONTENT_BROWSER_SSL_SSL_REQUEST_INFO_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "content/public/common/resource_type.h" -#include "net/cert/cert_status_flags.h" -#include "url/gurl.h" - -namespace content { - -// SSLRequestInfo wraps up the information SSLPolicy needs about a request in -// order to update our security UI. SSLRequestInfo is RefCounted in case we -// need to deal with the request asynchronously. -class SSLRequestInfo : public base::RefCounted<SSLRequestInfo> { - public: - SSLRequestInfo(const GURL& url, - ResourceType resource_type, - int ssl_cert_id, - net::CertStatus ssl_cert_status); - - const GURL& url() const { return url_; } - ResourceType resource_type() const { return resource_type_; } - int ssl_cert_id() const { return ssl_cert_id_; } - net::CertStatus ssl_cert_status() const { return ssl_cert_status_; } - - private: - friend class base::RefCounted<SSLRequestInfo>; - - virtual ~SSLRequestInfo(); - - GURL url_; - ResourceType resource_type_; - int ssl_cert_id_; - net::CertStatus ssl_cert_status_; - - DISALLOW_COPY_AND_ASSIGN(SSLRequestInfo); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_SSL_SSL_REQUEST_INFO_H_
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 19d9d26..26e6d0a 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -143,7 +143,7 @@ #include "base/mac/foundation_util.h" #endif -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) #include "content/browser/web_contents/web_contents_view_mus.h" #include "content/public/common/mojo_shell_connection.h" #include "ui/aura/mus/mus_util.h" @@ -1545,7 +1545,7 @@ WebContentsViewDelegate* delegate = GetContentClient()->browser()->GetWebContentsViewDelegate(this); -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) if (MojoShellConnection::GetForProcess() && base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseMusInRenderer)) {
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc index 8899bb4b..8d60451 100644 --- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc +++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -598,13 +598,19 @@ ExecuteJavascriptAndReturnResult(gum_with_vga_constraints)); } +#if defined(OS_ANDROID) && defined(NDEBUG) +#define MAYBE_TraceVideoCaptureControllerPerformanceDuringGetUserMedia DISABLED_TraceVideoCaptureControllerPerformanceDuringGetUserMedia +#else +#define MAYBE_TraceVideoCaptureControllerPerformanceDuringGetUserMedia TraceVideoCaptureControllerPerformanceDuringGetUserMedia +#endif + // This test will make a simple getUserMedia page, verify that video is playing // in a simple local <video>, and for a couple of seconds, collect some // performance traces from VideoCaptureController colorspace conversion and // potential resizing. IN_PROC_BROWSER_TEST_F( WebRtcGetUserMediaBrowserTest, - TraceVideoCaptureControllerPerformanceDuringGetUserMedia) { + MAYBE_TraceVideoCaptureControllerPerformanceDuringGetUserMedia) { RunGetUserMediaAndCollectMeasures( 10, "VideoCaptureDeviceClient::OnIncomingCapturedData",
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn index ad151b5..1466965a 100644 --- a/content/child/BUILD.gn +++ b/content/child/BUILD.gn
@@ -34,10 +34,7 @@ ".", "//content") - configs += [ - "//build/config:precompiled_headers", - "//content/public/common:mojo_shell_client", - ] + configs += [ "//build/config:precompiled_headers" ] public_deps = [ "//gpu/ipc/client:client",
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index 5ca7f71..4d3c0ce 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -262,11 +262,6 @@ IPC_MESSAGE_ROUTED0(InputMsg_RequestTextInputStateUpdate) #endif -// Request from browser to update the cursor and composition information. -IPC_MESSAGE_ROUTED2(InputMsg_RequestCompositionUpdate, - bool /* immediate request */, - bool /* monitor request */) - IPC_MESSAGE_ROUTED0(InputMsg_SyntheticGestureCompleted) // -----------------------------------------------------------------------------
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 5f1c0ed..4fd4b67 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi
@@ -1475,8 +1475,6 @@ 'browser/ssl/ssl_policy.h', 'browser/ssl/ssl_policy_backend.cc', 'browser/ssl/ssl_policy_backend.h', - 'browser/ssl/ssl_request_info.cc', - 'browser/ssl/ssl_request_info.h', 'browser/startup_task_runner.cc', 'browser/startup_task_runner.h', 'browser/storage_partition_impl.cc',
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java b/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java index 809f6dd..443e7d2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java
@@ -9,6 +9,7 @@ import android.os.Build; import android.view.View; import android.view.inputmethod.CursorAnchorInfo; +import android.view.inputmethod.InputConnection; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.SuppressFBWarnings; @@ -128,16 +129,14 @@ /** * Sets positional information of composing text as an array of character bounds. * @param compositionCharacterBounds Array of character bounds in local coordinates. - * @param view The attached view. */ - public void setCompositionCharacterBounds(float[] compositionCharacterBounds, View view) { + public void setCompositionCharacterBounds(float[] compositionCharacterBounds) { if (!mIsEditable) return; if (!Arrays.equals(compositionCharacterBounds, mCompositionCharacterBounds)) { mLastCursorAnchorInfo = null; mCompositionCharacterBounds = compositionCharacterBounds; } - updateCursorAnchorInfo(view); } /** @@ -199,6 +198,14 @@ } } + /** + * Resets the current state on update monitoring mode to the default (= do nothing.) + */ + public void resetMonitoringState() { + mMonitorModeEnabled = false; + mHasPendingImmediateRequest = false; + } + public void focusedNodeChanged(boolean isEditable) { mIsEditable = isEditable; mCompositionCharacterBounds = null; @@ -206,18 +213,11 @@ mLastCursorAnchorInfo = null; } - public boolean onRequestCursorUpdates(boolean immediateRequest, boolean monitorRequest, - View view) { + public boolean onRequestCursorUpdates(int cursorUpdateMode, View view) { if (!mIsEditable) return false; - if (mMonitorModeEnabled && !monitorRequest) { - // Invalidate saved cursor anchor info if monitor request is cancelled since no longer - // new values will be arrived from renderer and immediate request may return too old - // position. - invalidateLastCursorAnchorInfo(); - } - mMonitorModeEnabled = monitorRequest; - if (immediateRequest) { + mMonitorModeEnabled = (cursorUpdateMode & InputConnection.CURSOR_UPDATE_MONITOR) != 0; + if ((cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0) { mHasPendingImmediateRequest = true; updateCursorAnchorInfo(view); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java index ade6398b..8c1ae7a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -18,7 +18,6 @@ import android.view.View; import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; @@ -193,15 +192,8 @@ mViewEmbedder.getAttachedView(), this, mTextInputType, mTextInputFlags, mLastSelectionStart, mLastSelectionEnd, outAttrs)); if (DEBUG_LOGS) Log.w(TAG, "onCreateInputConnection: " + mInputConnection); - if (mCursorAnchorInfoController != null) { - mCursorAnchorInfoController.onRequestCursorUpdates( - false /* not an immediate request */, false /* disable monitoring */, - mViewEmbedder.getAttachedView()); - } - if (mNativeImeAdapterAndroid != 0) { - nativeRequestCursorUpdate(mNativeImeAdapterAndroid, - false /* not an immediate request */, false /* disable monitoring */); + mCursorAnchorInfoController.resetMonitoringState(); } return mInputConnection; } @@ -682,16 +674,8 @@ * Notified when IME requested Chrome to change the cursor update mode. */ public boolean onRequestCursorUpdates(int cursorUpdateMode) { - final boolean immediateRequest = - (cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0; - final boolean monitorRequest = - (cursorUpdateMode & InputConnection.CURSOR_UPDATE_MONITOR) != 0; - - if (mNativeImeAdapterAndroid != 0) { - nativeRequestCursorUpdate(mNativeImeAdapterAndroid, immediateRequest, monitorRequest); - } if (mCursorAnchorInfoController == null) return false; - return mCursorAnchorInfoController.onRequestCursorUpdates(immediateRequest, monitorRequest, + return mCursorAnchorInfoController.onRequestCursorUpdates(cursorUpdateMode, mViewEmbedder.getAttachedView()); } @@ -747,8 +731,7 @@ @CalledByNative private void setCharacterBounds(float[] characterBounds) { if (mCursorAnchorInfoController == null) return; - mCursorAnchorInfoController.setCompositionCharacterBounds(characterBounds, - mViewEmbedder.getAttachedView()); + mCursorAnchorInfoController.setCompositionCharacterBounds(characterBounds); } @CalledByNative @@ -780,7 +763,5 @@ int before, int after); private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); private native boolean nativeRequestTextInputStateUpdate(long nativeImeAdapterAndroid); - private native void nativeRequestCursorUpdate(long nativeImeAdapterAndroid, - boolean immediateRequest, boolean monitorRequest); private native boolean nativeIsImeThreadEnabled(long nativeImeAdapterAndroid); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java index 2d488aa..768b6bbf 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java
@@ -13,6 +13,7 @@ import android.text.TextUtils; import android.view.View; import android.view.inputmethod.CursorAnchorInfo; +import android.view.inputmethod.InputConnection; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; @@ -140,11 +141,10 @@ assertFalse( "IC#onRequestCursorUpdates() must be rejected if the focused node is not editable.", - controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); + controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); // Make sure that the focused node is considered to be non-editable by default. - controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}, view); + controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}); composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), true, true, 2.0f, 0.0f, 3.0f, view); @@ -155,7 +155,7 @@ // Make sure that the controller does not crash even if it is called while the focused node // is not editable. - controller.setCompositionCharacterBounds(new float[] {30.0f, 1.0f, 32.0f, 3.0f}, view); + controller.setCompositionCharacterBounds(new float[] {30.0f, 1.0f, 32.0f, 3.0f}); composingTextDelegate.updateTextAndSelection(controller, "1", 0, 1, 0, 1); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 100.0f), true, true, 2.0f, 0.0f, 3.0f, view); @@ -179,9 +179,9 @@ // Make sure that #updateCursorAnchorInfo() is not be called until the matrix info becomes // available with #onUpdateFrameInfo(). - assertTrue(controller.onRequestCursorUpdates( - true /* immediate request */, false /* monitor request */, view)); - controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}, view); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE, + view)); + controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}); composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1); assertEquals(0, immw.getUpdateCursorAnchorInfoCounter()); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), @@ -205,8 +205,8 @@ // Make sure that #onUpdateFrameInfo() is immediately called because the matrix info is // already available. - assertTrue(controller.onRequestCursorUpdates( - true /* immediate request */, false /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE, + view)); assertEquals(2, immw.getUpdateCursorAnchorInfoCounter()); assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo()); assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, @@ -222,7 +222,8 @@ // Make sure that CURSOR_UPDATE_IMMEDIATE and CURSOR_UPDATE_MONITOR can be specified at // the same time. assertTrue(controller.onRequestCursorUpdates( - true /* immediate request*/, true /* monitor request */, view)); + InputConnection.CURSOR_UPDATE_IMMEDIATE | InputConnection.CURSOR_UPDATE_MONITOR, + view)); assertEquals(3, immw.getUpdateCursorAnchorInfoCounter()); assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo()); immw.clearLastCursorAnchorInfo(); @@ -245,8 +246,8 @@ controller.focusedNodeChanged(false); controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - true /* immediate request */, false /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE, + view)); controller.focusedNodeChanged(false); composingTextDelegate.clearTextAndSelection(controller); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 100.0f), @@ -256,8 +257,8 @@ // Make sure that CURSOR_UPDATE_IMMEDIATE can be enabled again. controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - true /* immediate request */, false /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE, + view)); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), true, true, 2.0f, 0.0f, 3.0f, view); assertEquals(5, immw.getUpdateCursorAnchorInfoCounter()); @@ -288,9 +289,8 @@ // Make sure that #updateCursorAnchorInfo() is not be called until the matrix info becomes // available with #onUpdateFrameInfo(). - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); - controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}, view); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); + controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}); composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1); assertEquals(0, immw.getUpdateCursorAnchorInfoCounter()); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), @@ -309,14 +309,14 @@ // Make sure that #updateCursorAnchorInfo() is not be called if any coordinate parameter is // changed for better performance. - controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}, view); + controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), true, true, 2.0f, 0.0f, 3.0f, view); assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); // Make sure that #updateCursorAnchorInfo() is called if #setCompositionCharacterBounds() // is called with a different parameter. - controller.setCompositionCharacterBounds(new float[] {30.0f, 1.0f, 32.0f, 3.0f}, view); + controller.setCompositionCharacterBounds(new float[] {30.0f, 1.0f, 32.0f, 3.0f}); assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), true, true, 2.0f, 0.0f, 3.0f, view); @@ -388,11 +388,10 @@ controller.focusedNodeChanged(false); controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); controller.focusedNodeChanged(false); composingTextDelegate.clearTextAndSelection(controller); - controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}, view); + controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}); composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), true, true, 2.0f, 0.0f, 3.0f, view); @@ -401,9 +400,8 @@ // Make sure that CURSOR_UPDATE_MONITOR can be enabled again. controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); - controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}, view); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); + controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f}); composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1); assertEquals(5, immw.getUpdateCursorAnchorInfoCounter()); viewDelegate.locationX = 0; @@ -438,12 +436,11 @@ controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); composingTextDelegate.updateTextAndSelection(controller, "01234", 1, 3, 1, 1); controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f, - 4.0f, 1.1f, 6.0f, 2.9f}, view); + 4.0f, 1.1f, 6.0f, 2.9f}); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), false, false, Float.NaN, Float.NaN, Float.NaN, view); assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); @@ -478,8 +475,7 @@ controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); composingTextDelegate.updateTextAndSelection(controller, "01234", 3, 3, 1, 1); controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), @@ -511,8 +507,7 @@ controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); // Test no insertion marker. controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), @@ -550,8 +545,7 @@ controller.focusedNodeChanged(true); composingTextDelegate.clearTextAndSelection(controller); - assertTrue(controller.onRequestCursorUpdates( - false /* immediate request */, true /* monitor request */, view)); + assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view)); // Test no transformation viewDelegate.locationX = 0;
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java index 26c51cb5..159d73a5 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java
@@ -58,10 +58,6 @@ }); requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE); waitForUpdateCursorAnchorInfoComposingText("abcd"); - - setComposingText("abcde", 2); - requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE); - waitForUpdateCursorAnchorInfoComposingText("abcde"); } private void requestCursorUpdates(final int cursorUpdateMode) {
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index ff190a7..007cd9d 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -15,6 +15,10 @@ class GURL; +namespace net { +class HttpResponseHeaders; +} // namespace net + namespace content { class NavigationData; class NavigationThrottle; @@ -150,6 +154,12 @@ // Whether the navigation resulted in an error page. virtual bool IsErrorPage() = 0; + // Returns the response headers for the request or nullptr if there are none. + // This should only be accessed after a redirect was encountered or after the + // navigation is ready to commit. The headers returned should not be modified, + // as modifications will not be reflected in the network stack. + virtual const net::HttpResponseHeaders* GetResponseHeaders() = 0; + // Resumes a navigation that was previously deferred by a NavigationThrottle. virtual void Resume() = 0;
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index d3b05edf..2df12fd 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -53,15 +53,6 @@ defines = [ "COMPILE_CONTENT_STATICALLY" ] } -# Set in GN builds, triggering behavior in content when run from an external -# Mojo shell. -config("mojo_shell_client") { - # This configuration has only been tested on these platforms. - if ((is_win || is_linux || is_chromeos) && !is_chromecast) { - defines = [ "MOJO_SHELL_CLIENT" ] - } -} - # This target allows you to use the content_switches constants and statically # link to it, without depending on the rest of content. This is only for use # without content, or you will get multiply defined symbols.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index c1778f7..a25ec7c 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -29,7 +29,6 @@ configs += [ "//content:content_implementation", "//build/config/compiler:no_size_t_to_int_warning", - "//content/public/common:mojo_shell_client", ] defines = []
diff --git a/content/renderer/android/synchronous_compositor_output_surface.h b/content/renderer/android/synchronous_compositor_output_surface.h index 6a8f83a2..de8f1f0f 100644 --- a/content/renderer/android/synchronous_compositor_output_surface.h +++ b/content/renderer/android/synchronous_compositor_output_surface.h
@@ -143,6 +143,10 @@ void DisplayOutputSurfaceLost() override {} void DisplaySetMemoryPolicy( const cc::ManagedMemoryPolicy& policy) override {} + void DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const cc::RenderPassList& render_passes) override {} + void DisplayDidDrawAndSwap() override {} }; // TODO(danakj): These don't to be stored in unique_ptrs when OutputSurface
diff --git a/content/renderer/gpu/render_widget_compositor_unittest.cc b/content/renderer/gpu/render_widget_compositor_unittest.cc index 47c1e21..3246db3 100644 --- a/content/renderer/gpu/render_widget_compositor_unittest.cc +++ b/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -14,14 +14,16 @@ #include "base/threading/thread_task_runner_handle.h" #include "cc/output/begin_frame_args.h" #include "cc/output/copy_output_request.h" -#include "cc/test/failure_output_surface.h" #include "cc/test/fake_external_begin_frame_source.h" +#include "cc/test/fake_output_surface.h" +#include "cc/test/test_context_provider.h" #include "cc/trees/layer_tree_host.h" #include "components/scheduler/renderer/renderer_scheduler.h" #include "content/public/test/mock_render_thread.h" #include "content/renderer/render_widget.h" #include "content/test/fake_compositor_dependencies.h" #include "content/test/fake_renderer_scheduler.h" +#include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" @@ -80,18 +82,20 @@ RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK, fallback); last_create_was_fallback_ = fallback; + bool success = num_failures_ >= num_failures_before_success_; - if (success) { - std::unique_ptr<cc::TestWebGraphicsContext3D> context = - cc::TestWebGraphicsContext3D::Create(); - // Image support required for synchronous compositing. - context->set_support_image(true); - // Create delegating surface so that max_pending_frames = 1. - return cc::FakeOutputSurface::CreateDelegating3d(std::move(context)); + if (!success && use_null_output_surface_) + return nullptr; + + auto context_provider = cc::TestContextProvider::Create(); + if (!success) { + context_provider->UnboundTestContext3d()->loseContextCHROMIUM( + GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); } - return use_null_output_surface_ - ? nullptr - : base::WrapUnique(new cc::FailureOutputSurface(true)); + + // Create delegating surface so that max_pending_frames = 1. + return cc::FakeOutputSurface::CreateDelegating3d( + std::move(context_provider)); } std::unique_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource()
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index 8dd8323..451ba42 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -374,11 +374,16 @@ void WebMediaPlayerAndroid::play() { DCHECK(main_thread_checker_.CalledOnValidThread()); - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableMediaSuspend) && - hasVideo() && player_manager_->render_frame()->IsHidden()) { - is_play_pending_ = true; - return; + if (hasVideo() && player_manager_->render_frame()->IsHidden()) { + bool can_video_play_in_background = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableMediaSuspend) || + (IsBackgroundVideoCandidate() && + delegate_ && delegate_->IsPlayingBackgroundVideo()); + if (!can_video_play_in_background) { + is_play_pending_ = true; + return; + } } is_play_pending_ = false; @@ -1511,6 +1516,13 @@ } void WebMediaPlayerAndroid::OnHidden() { + // Pause audible video preserving its session. + if (hasVideo() && IsBackgroundVideoCandidate() && !paused()) { + Pause(false); + is_play_pending_ = true; + return; + } + OnSuspendRequested(false); } @@ -1528,8 +1540,10 @@ // If we're idle or playing video, pause and release resources; audio only // players are allowed to continue unless indicated otherwise by the call. - if (must_suspend || (paused() && playback_completed_) || hasVideo()) + if (must_suspend || (paused() && playback_completed_) || + (hasVideo() && !IsBackgroundVideoCandidate())) { SuspendAndReleaseResources(); + } } void WebMediaPlayerAndroid::OnPlay() { @@ -1683,4 +1697,16 @@ result, PREDICTION_RESULT_MAX); } +bool WebMediaPlayerAndroid::IsBackgroundVideoCandidate() const { + DCHECK(hasVideo()); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableMediaSuspend)) { + return false; + } + + return base::FeatureList::IsEnabled(media::kResumeBackgroundVideo) && + hasAudio() && !isRemote() && delegate_ && delegate_->IsHidden(); +} + } // namespace content
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index 7eef73e..77e1b7d 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -324,6 +324,9 @@ // |defer_load_cb_| is null this is called immediately. void DoLoad(LoadType load_type, const blink::WebURL& url, CORSMode cors_mode); + // Returns if this video can be resumed in the background. + bool IsBackgroundVideoCandidate() const; + blink::WebFrame* const frame_; blink::WebMediaPlayerClient* const client_;
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc index f3b8125..24dc39d 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -32,6 +32,7 @@ DCHECK(id_map_.Lookup(delegate_id)); id_map_.Remove(delegate_id); RemoveIdleDelegate(delegate_id); + playing_videos_.erase(delegate_id); } void RendererWebMediaPlayerDelegate::DidPlay(int delegate_id, @@ -41,6 +42,10 @@ base::TimeDelta duration) { DCHECK(id_map_.Lookup(delegate_id)); has_played_media_ = true; + if (has_video && !is_remote) + playing_videos_.insert(delegate_id); + else + playing_videos_.erase(delegate_id); RemoveIdleDelegate(delegate_id); Send(new MediaPlayerDelegateHostMsg_OnMediaPlaying( routing_id(), delegate_id, has_video, has_audio, is_remote, duration)); @@ -50,6 +55,8 @@ bool reached_end_of_stream) { DCHECK(id_map_.Lookup(delegate_id)); AddIdleDelegate(delegate_id); + if (reached_end_of_stream) + playing_videos_.erase(delegate_id); Send(new MediaPlayerDelegateHostMsg_OnMediaPaused(routing_id(), delegate_id, reached_end_of_stream)); } @@ -57,6 +64,7 @@ void RendererWebMediaPlayerDelegate::PlayerGone(int delegate_id) { DCHECK(id_map_.Lookup(delegate_id)); RemoveIdleDelegate(delegate_id); + playing_videos_.erase(delegate_id); Send(new MediaPlayerDelegateHostMsg_OnMediaDestroyed(routing_id(), delegate_id)); } @@ -65,12 +73,17 @@ return render_frame()->IsHidden(); } +bool RendererWebMediaPlayerDelegate::IsPlayingBackgroundVideo() { + return is_playing_background_video_; +} + void RendererWebMediaPlayerDelegate::WasHidden() { for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) it.GetCurrentValue()->OnHidden(); } void RendererWebMediaPlayerDelegate::WasShown() { + is_playing_background_video_ = false; for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) it.GetCurrentValue()->OnShown(); } @@ -100,14 +113,20 @@ void RendererWebMediaPlayerDelegate::OnMediaDelegatePause(int delegate_id) { Observer* observer = id_map_.Lookup(delegate_id); - if (observer) + if (observer) { + if (playing_videos_.find(delegate_id) != playing_videos_.end()) + is_playing_background_video_ = false; observer->OnPause(); + } } void RendererWebMediaPlayerDelegate::OnMediaDelegatePlay(int delegate_id) { Observer* observer = id_map_.Lookup(delegate_id); - if (observer) + if (observer) { + if (playing_videos_.find(delegate_id) != playing_videos_.end()) + is_playing_background_video_ = IsHidden(); observer->OnPlay(); + } } void RendererWebMediaPlayerDelegate::OnMediaDelegateSuspendAllMediaPlayers() {
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h index 0e830774..f8c8563d 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.h +++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -7,6 +7,7 @@ #include <map> #include <memory> +#include <set> #include "base/id_map.h" #include "base/macros.h" @@ -48,6 +49,7 @@ void DidPause(int delegate_id, bool reached_end_of_stream) override; void PlayerGone(int delegate_id) override; bool IsHidden() override; + bool IsPlayingBackgroundVideo() override; // content::RenderFrameObserver overrides. void WasHidden() override; @@ -64,6 +66,8 @@ return idle_cleanup_timer_.IsRunning(); } + friend class RendererWebMediaPlayerDelegateTest; + private: void OnMediaDelegatePause(int delegate_id); void OnMediaDelegatePlay(int delegate_id); @@ -101,6 +105,16 @@ std::unique_ptr<base::DefaultTickClock> default_tick_clock_; base::TickClock* tick_clock_; + // If a video is playing in the background. Set when user resumes a video + // allowing it to play and reset when either user pauses it or it goes + // foreground. + bool is_playing_background_video_ = false; + + // The currently playing local videos. Used to determine whether + // OnMediaDelegatePlay() should allow the videos to play in the background or + // not. + std::set<int> playing_videos_; + DISALLOW_COPY_AND_ASSIGN(RendererWebMediaPlayerDelegate); };
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc b/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc index 4fe4fdb..060f391c 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
@@ -61,6 +61,22 @@ protected: IPC::TestSink& test_sink() { return render_thread_->sink(); } + bool HasPlayingVideo(int delegate_id) { + return delegate_manager_->playing_videos_.count(delegate_id); + } + + void SetPlayingBackgroundVideo(bool is_playing) { + delegate_manager_->is_playing_background_video_ = is_playing; + } + + void CallOnMediaDelegatePlay(int delegate_id) { + delegate_manager_->OnMediaDelegatePlay(delegate_id); + } + + void CallOnMediaDelegatePause(int delegate_id) { + delegate_manager_->OnMediaDelegatePause(delegate_id); + } + std::unique_ptr<RendererWebMediaPlayerDelegate> delegate_manager_; private: @@ -271,4 +287,84 @@ delegate_manager_->RemoveObserver(delegate_id_1); } +TEST_F(RendererWebMediaPlayerDelegateTest, PlayingVideosSet) { + MockWebMediaPlayerDelegateObserver observer; + int delegate_id = delegate_manager_->AddObserver(&observer); + EXPECT_FALSE(HasPlayingVideo(delegate_id)); + + // Playing a local video adds it to the set. + delegate_manager_->DidPlay(delegate_id, true, true, false, base::TimeDelta()); + EXPECT_TRUE(HasPlayingVideo(delegate_id)); + + // Pause doesn't remove the video from the set. + delegate_manager_->DidPause(delegate_id, false); + EXPECT_TRUE(HasPlayingVideo(delegate_id)); + + // Reaching the end removes the video from the set. + delegate_manager_->DidPause(delegate_id, true); + EXPECT_FALSE(HasPlayingVideo(delegate_id)); + + // Removing the player removes the video from the set. + delegate_manager_->DidPlay(delegate_id, true, true, false, base::TimeDelta()); + delegate_manager_->PlayerGone(delegate_id); + EXPECT_FALSE(HasPlayingVideo(delegate_id)); + + // Playing a remote video removes it from the set. + delegate_manager_->DidPlay(delegate_id, true, true, false, base::TimeDelta()); + delegate_manager_->DidPlay(delegate_id, true, true, true, base::TimeDelta()); + EXPECT_FALSE(HasPlayingVideo(delegate_id)); + + // Playing a local video without audio adds it to the set (because of WMPA). + delegate_manager_->DidPlay( + delegate_id, true, false, false, base::TimeDelta()); + EXPECT_TRUE(HasPlayingVideo(delegate_id)); + + // Playing a local audio removes it from the set. + delegate_manager_->DidPlay( + delegate_id, false, true, false, base::TimeDelta()); + EXPECT_FALSE(HasPlayingVideo(delegate_id)); + + // Removing the observer also removes the video from the set. + delegate_manager_->DidPlay(delegate_id, true, true, false, base::TimeDelta()); + delegate_manager_->RemoveObserver(delegate_id); + EXPECT_FALSE(HasPlayingVideo(delegate_id)); +} + +TEST_F(RendererWebMediaPlayerDelegateTest, IsPlayingBackgroundVideo) { + MockWebMediaPlayerDelegateObserver observer; + int delegate_id = delegate_manager_->AddObserver(&observer); + EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); + + // Showing the frame always clears the flag. + SetPlayingBackgroundVideo(true); + delegate_manager_->WasShown(); + EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); + + // Pausing anything other than a local playing video doesn't affect the flag. + SetPlayingBackgroundVideo(true); + CallOnMediaDelegatePause(delegate_id); + EXPECT_TRUE(delegate_manager_->IsPlayingBackgroundVideo()); + + // Pausing a currently playing video does clears the flag. + delegate_manager_->DidPlay( + delegate_id, true, true, false, base::TimeDelta()); + CallOnMediaDelegatePause(delegate_id); + EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); + + // TODO(avayvod): this test can't mock IsHidden() method. + // Just test that the value changes or doesn't depending on whether the video + // is currently playing. + bool old_value = !delegate_manager_->IsHidden(); + SetPlayingBackgroundVideo(old_value); + delegate_manager_->DidPause(delegate_id, true); + CallOnMediaDelegatePlay(delegate_id); + EXPECT_EQ(old_value, delegate_manager_->IsPlayingBackgroundVideo()); + + delegate_manager_->DidPlay( + delegate_id, true, true, false, base::TimeDelta()); + CallOnMediaDelegatePlay(delegate_id); + EXPECT_NE(old_value, delegate_manager_->IsPlayingBackgroundVideo()); +} + + } // namespace media
diff --git a/content/renderer/media/webmediaplayer_ms_unittest.cc b/content/renderer/media/webmediaplayer_ms_unittest.cc index 41f76bd..f27ff46 100644 --- a/content/renderer/media/webmediaplayer_ms_unittest.cc +++ b/content/renderer/media/webmediaplayer_ms_unittest.cc
@@ -76,6 +76,8 @@ bool IsHidden() override { return is_hidden_; } + bool IsPlayingBackgroundVideo() override { return false; } + void set_hidden(bool is_hidden) { is_hidden_ = is_hidden; } private:
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index e52952d0..3bd70a5 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1313,8 +1313,7 @@ return; Send(new InputHostMsg_ImeCancelComposition(render_view_->GetRoutingID())); #if defined(OS_MACOSX) || defined(USE_AURA) - GetRenderWidget()->UpdateCompositionInfo( - false /* not an immediate request */); + GetRenderWidget()->UpdateCompositionInfo(true); #endif }
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 3cedbac5..830fd3d6 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -200,7 +200,7 @@ #include "v8/src/third_party/vtune/v8-vtune.h" #endif -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) +#if defined(USE_AURA) #include "content/public/common/mojo_shell_connection.h" #include "content/renderer/mus/render_widget_mus_connection.h" #include "content/renderer/mus/render_widget_window_tree_client_factory.h" @@ -642,9 +642,10 @@ // Register this object as the main thread. ChildProcess::current()->set_main_thread(this); -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) if (IsRunningInMash()) - ui::GpuService::Initialize(GetMojoShellConnection()->GetConnector()); + gpu_service_ = + ui::GpuService::Initialize(GetMojoShellConnection()->GetConnector()); #endif InitializeWebKit(resource_task_queue); @@ -718,7 +719,7 @@ AddFilter((new ServiceWorkerContextMessageFilter())->GetFilter()); -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) +#if defined(USE_AURA) if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseMusInRenderer)) { CreateRenderWidgetWindowTreeClientFactory(GetMojoShellConnection()); @@ -1802,8 +1803,8 @@ ChildProcess::current()->GetShutDownEvent(), gpu_memory_buffer_manager()); } else { -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) - gpu_channel_ = ui::GpuService::GetInstance()->EstablishGpuChannelSync(); +#if defined(USE_AURA) + gpu_channel_ = gpu_service_->EstablishGpuChannelSync(); #else NOTREACHED(); #endif @@ -1822,7 +1823,7 @@ if (command_line.HasSwitch(switches::kDisableGpuCompositing)) use_software = true; -#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA) +#if defined(USE_AURA) if (GetMojoShellConnection() && !use_software && command_line.HasSwitch(switches::kUseMusInRenderer)) { RenderWidgetMusConnection* connection =
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index b8c2371e..ad3e112 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -87,6 +87,10 @@ class WebThreadBase; } +namespace ui { +class GpuService; +} + namespace v8 { class Extension; } @@ -655,6 +659,10 @@ std::unique_ptr<memory_coordinator::ChildMemoryCoordinatorImpl> memory_coordinator_; +#if defined(USE_AURA) + std::unique_ptr<ui::GpuService> gpu_service_; +#endif + scoped_refptr<base::SingleThreadTaskRunner> main_thread_compositor_task_runner_;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index e3382c9..b11681c 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -92,7 +92,7 @@ #include "third_party/skia/include/core/SkPixelRef.h" #endif // defined(OS_POSIX) -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) #include "content/public/common/mojo_shell_connection.h" #include "content/renderer/mus/render_widget_mus_connection.h" #endif @@ -199,7 +199,7 @@ content::RenderWidgetInputHandlerDelegate* GetRenderWidgetInputHandlerDelegate( content::RenderWidget* widget) { -#if defined(MOJO_SHELL_CLIENT) +#if defined(USE_AURA) const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess(); if (content::MojoShellConnection::GetForProcess() && cmdline.HasSwitch(switches::kUseMusInRenderer)) { @@ -247,7 +247,6 @@ text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), text_input_flags_(0), can_compose_inline_(true), - composition_range_(gfx::Range::InvalidRange()), popup_type_(popup_type), pending_window_rect_count_(0), screen_info_(screen_info), @@ -255,7 +254,6 @@ #if defined(OS_ANDROID) text_field_is_dirty_(false), #endif - monitor_composition_info_(false), popup_origin_scale_for_emulation_(0.f), frame_swap_message_queue_(new FrameSwapMessageQueue()), resizing_mode_selector_(new ResizingModeSelector()), @@ -497,8 +495,6 @@ IPC_MESSAGE_HANDLER(ViewMsg_SetSurfaceClientId, OnSetSurfaceClientId) IPC_MESSAGE_HANDLER(ViewMsg_WaitForNextFrameForTests, OnWaitNextFrameForTests) - IPC_MESSAGE_HANDLER(InputMsg_RequestCompositionUpdate, - OnRequestCompositionUpdate) #if defined(OS_ANDROID) IPC_MESSAGE_HANDLER(InputMsg_ImeEventAck, OnImeEventAck) IPC_MESSAGE_HANDLER(InputMsg_RequestTextInputStateUpdate, @@ -1369,7 +1365,7 @@ // sure we are in a consistent state. Send(new InputHostMsg_ImeCancelComposition(routing_id())); } - UpdateCompositionInfo(false /* not an immediate request */); + UpdateCompositionInfo(true); } void RenderWidget::OnImeConfirmComposition(const base::string16& text, @@ -1398,7 +1394,7 @@ else webwidget_->confirmComposition(WebWidget::DoNotKeepSelection); input_handler_->set_handling_input_event(false); - UpdateCompositionInfo(false /* not an immediate request */); + UpdateCompositionInfo(true); } void RenderWidget::OnDeviceScaleFactorChanged() { @@ -1483,26 +1479,19 @@ return ui::TEXT_INPUT_TYPE_NONE; } -void RenderWidget::UpdateCompositionInfo(bool immediate_request) { - if (!monitor_composition_info_ && !immediate_request) - return; // Do not calculate composition info if not requested. - +void RenderWidget::UpdateCompositionInfo(bool should_update_range) { TRACE_EVENT0("renderer", "RenderWidget::UpdateCompositionInfo"); - gfx::Range range; - std::vector<gfx::Rect> character_bounds; - - if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { - // Composition information is only available on editable node. - range = gfx::Range::InvalidRange(); - } else { + gfx::Range range = gfx::Range(); + if (should_update_range) { GetCompositionRange(&range); - GetCompositionCharacterBounds(&character_bounds); + } else { + range = composition_range_; } + std::vector<gfx::Rect> character_bounds; + GetCompositionCharacterBounds(&character_bounds); - if (!immediate_request && - !ShouldUpdateCompositionInfo(range, character_bounds)) { + if (!ShouldUpdateCompositionInfo(range, character_bounds)) return; - } composition_character_bounds_ = character_bounds; composition_range_ = range; Send(new InputHostMsg_ImeCompositionRangeChanged( @@ -1561,14 +1550,6 @@ } #endif -void RenderWidget::OnRequestCompositionUpdate(bool immediate_request, - bool monitor_request) { - monitor_composition_info_ = monitor_request; - if (!immediate_request) - return; - UpdateCompositionInfo(true /* immediate request */); -} - bool RenderWidget::ShouldHandleImeEvent() { #if defined(OS_ANDROID) if (!webwidget_) @@ -1760,7 +1741,7 @@ } } - UpdateCompositionInfo(false /* not an immediate request */); + UpdateCompositionInfo(false); } void RenderWidget::SetDeviceColorProfileForTesting( @@ -1905,7 +1886,7 @@ Send(new InputHostMsg_ImeCancelComposition(routing_id())); } - UpdateCompositionInfo(false /* not an immediate request */); + UpdateCompositionInfo(true); } #if defined(OS_ANDROID)
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index daee7170..c91e0b8 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -352,9 +352,7 @@ // changed. If they are changed, the new value will be sent to the browser // process. This method does nothing when the browser process is not able to // handle composition range and composition character bounds. - // If immediate_request is true, render sends the latest composition info to - // the browser even if the composition info is not changed. - void UpdateCompositionInfo(bool immediate_request); + void UpdateCompositionInfo(bool should_update_range); // Change the device ICC color profile while running a layout test. void SetDeviceColorProfileForTesting(const std::vector<char>& color_profile); @@ -496,10 +494,6 @@ void OnRequestTextInputStateUpdate(); #endif - // Called by the browser process to update the cursor and composition - // information. - void OnRequestCompositionUpdate(bool immediate_request, bool monitor_request); - // Notify the compositor about a change in viewport size. This should be // used only with auto resize mode WebWidgets, as normal WebWidgets should // go through OnResize. @@ -744,9 +738,6 @@ std::deque<blink::WebTextInputInfo> text_input_info_history_; #endif - // True if the IME requests updated composition info. - bool monitor_composition_info_; - std::unique_ptr<RenderWidgetScreenMetricsEmulator> screen_metrics_emulator_; // Popups may be displaced when screen metrics emulation is enabled.
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index d27892c..0caf15c 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -264,7 +264,8 @@ std::move(compositor_context_provider), std::move(worker_context_provider), std::move(display_output_surface), deps->GetSharedBitmapManager(), deps->GetGpuMemoryBufferManager(), - settings.renderer_settings, task_runner, synchronous_composite); + settings.renderer_settings, task_runner, synchronous_composite, + false /* force_disable_reclaim_resources */); output_surfaces_[routing_id] = output_surface.get(); return std::move(output_surface); }
diff --git a/device/geolocation/geolocation.gyp b/device/geolocation/geolocation.gyp index 805ffae..a344ec7a 100644 --- a/device/geolocation/geolocation.gyp +++ b/device/geolocation/geolocation.gyp
@@ -108,6 +108,7 @@ 'conditions': [ ["use_dbus==1", { 'dependencies': [ + '<(DEPTH)/build/linux/system.gyp:dbus', '<(DEPTH)/dbus/dbus.gyp:dbus', ], 'sources!': [
diff --git a/device/serial/serial_io_handler_posix.cc b/device/serial/serial_io_handler_posix.cc index 3685ec8..71b398c8 100644 --- a/device/serial/serial_io_handler_posix.cc +++ b/device/serial/serial_io_handler_posix.cc
@@ -123,8 +123,6 @@ DCHECK(pending_read_buffer()); DCHECK(file().IsValid()); - EnsureWatchingReads(); - // Try to read immediately. This is needed because on some platforms // (e.g., OSX) there may not be a notification from the message loop // when the fd is ready to read immediately after it is opened. There @@ -303,7 +301,7 @@ AttemptRead(false); } -void SerialIoHandlerPosix::AttemptRead(bool within_read) { +bool SerialIoHandlerPosix::AttemptRead(bool within_read) { if (pending_read_buffer()) { int bytes_read = HANDLE_EINTR(read(file().GetPlatformFile(), pending_read_buffer(), @@ -311,7 +309,7 @@ if (bytes_read < 0) { if (errno == EAGAIN) { // The fd does not have data to read yet so continue waiting. - return; + EnsureWatchingReads(); } else if (errno == ENXIO) { RunReadCompleted(within_read, 0, serial::ReceiveError::DEVICE_LOST); } else { @@ -343,6 +341,8 @@ is_watching_reads_ = false; file_read_watcher_.StopWatchingFileDescriptor(); } + + return true; } void SerialIoHandlerPosix::RunReadCompleted(bool within_read,
diff --git a/device/serial/serial_io_handler_posix.h b/device/serial/serial_io_handler_posix.h index 28f10c43..b25f7c87 100644 --- a/device/serial/serial_io_handler_posix.h +++ b/device/serial/serial_io_handler_posix.h
@@ -49,7 +49,7 @@ scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner); ~SerialIoHandlerPosix() override; - void AttemptRead(bool within_read); + bool AttemptRead(bool within_read); void RunReadCompleted(bool within_read, int bytes_read, serial::ReceiveError error);
diff --git a/docs/component_build.md b/docs/component_build.md index fe36579..06341c2 100644 --- a/docs/component_build.md +++ b/docs/component_build.md
@@ -5,17 +5,21 @@ Release builds are “static” builds which compile to one executable and zero-to-two shared libraries (depending on the platform). This is efficient at runtime, but can take a long time to link because so much code goes into a -single binary. When you set the GN build variable +single binary. + +In a component build, many smaller shared libraries will be generated. This +speeds up link times, and means that many changes only require that the local +shared library be linked rather than the full executable, but at the expense of +program load-time performance. + +The component build is currently the default for debug non-iOS builds (it +doesn’t work for iOS). You can force it on for release builds using the +[GN build arg](https://www.chromium.org/developers/gn-build-configuration): ```python is_component_build = true ``` -the build will generate many smaller shared libraries. This speeds up link -times, and means that many changes only require that the local shared library -be linked rather than the full executable, but at the expense of program -load-time performance. - ### How to make a component Defining a component just means using the GN “component” template instead
diff --git a/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc b/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc index ab1b4d0..297effb8 100644 --- a/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc +++ b/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc
@@ -137,13 +137,7 @@ EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } -#if defined(_LIBCPP_VERSION) -// This test fails in libc++ builds, see http://crbug.com/392205. -#define MAYBE_Listen DISABLED_Listen -#else -#define MAYBE_Listen Listen -#endif -IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, MAYBE_Listen) { +IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, Listen) { ResultCatcher catcher; catcher.RestrictToBrowserContext(browser_context());
diff --git a/extensions/browser/extension_web_contents_observer.cc b/extensions/browser/extension_web_contents_observer.cc index 12a2c7e9..52b9041 100644 --- a/extensions/browser/extension_web_contents_observer.cc +++ b/extensions/browser/extension_web_contents_observer.cc
@@ -107,8 +107,7 @@ // Plus, we can delete the concept of activating an extension once site // isolation is turned on. RendererStartupHelperFactory::GetForBrowserContext(browser_context_) - ->ActivateExtensionInProcess(extension->id(), - render_view_host->GetProcess()); + ->ActivateExtensionInProcess(*extension, render_view_host->GetProcess()); } void ExtensionWebContentsObserver::RenderFrameCreated(
diff --git a/extensions/browser/renderer_startup_helper.cc b/extensions/browser/renderer_startup_helper.cc index b3aa205..452c8169 100644 --- a/extensions/browser/renderer_startup_helper.cc +++ b/extensions/browser/renderer_startup_helper.cc
@@ -128,12 +128,18 @@ } void RendererStartupHelper::ActivateExtensionInProcess( - const ExtensionId& id, + const Extension& extension, content::RenderProcessHost* process) { + // Renderers don't need to know about themes. We also don't normally + // "activate" themes, but this could happen if someone tries to open a tab + // to the e.g. theme's manifest. + if (extension.is_theme()) + return; + if (initialized_processes_.count(process)) - process->Send(new ExtensionMsg_ActivateExtension(id)); + process->Send(new ExtensionMsg_ActivateExtension(extension.id())); else - pending_active_extensions_[process].insert(id); + pending_active_extensions_[process].insert(extension.id()); } void RendererStartupHelper::OnExtensionLoaded(const Extension& extension) { @@ -152,11 +158,15 @@ process->Send(new ExtensionMsg_Loaded(params)); } -void RendererStartupHelper::OnExtensionUnloaded(const ExtensionId& id) { +void RendererStartupHelper::OnExtensionUnloaded(const Extension& extension) { + // Renderers don't need to know about themes. + if (extension.is_theme()) + return; + for (content::RenderProcessHost* process : initialized_processes_) - process->Send(new ExtensionMsg_Unloaded(id)); + process->Send(new ExtensionMsg_Unloaded(extension.id())); for (auto& process_extensions_pair : pending_active_extensions_) - process_extensions_pair.second.erase(id); + process_extensions_pair.second.erase(extension.id()); } //////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/browser/renderer_startup_helper.h b/extensions/browser/renderer_startup_helper.h index 9681f29..94ec383 100644 --- a/extensions/browser/renderer_startup_helper.h +++ b/extensions/browser/renderer_startup_helper.h
@@ -48,14 +48,14 @@ // Sends a message to the specified |process| activating the given extension // once the process is initialized. - void ActivateExtensionInProcess(const ExtensionId& id, + void ActivateExtensionInProcess(const Extension& extension, content::RenderProcessHost* process); // Sends a message to all initialized processes to [un]load the given // extension. We have explicit calls for these (rather than using an // ExtensionRegistryObserver) because this needs to happen before other // initialization which might rely on the renderers being notified. - void OnExtensionUnloaded(const ExtensionId& id); + void OnExtensionUnloaded(const Extension& extension); void OnExtensionLoaded(const Extension& extension); private:
diff --git a/extensions/test/data/api_test/bluetooth_socket/listen/runtest.js b/extensions/test/data/api_test/bluetooth_socket/listen/runtest.js index 63a05af..4741167 100644 --- a/extensions/test/data/api_test/bluetooth_socket/listen/runtest.js +++ b/extensions/test/data/api_test/bluetooth_socket/listen/runtest.js
@@ -7,25 +7,32 @@ function testListen() { chrome.test.assertEq(2, sockets.length); + var serverSocket = sockets[0], clientSocket = sockets[1]; + + // In case the sockets don't come back to us in order. + if (sockets[0].socketId != serverSocketId) { + serverSocket = sockets[1]; + clientSocket = sockets[0]; + } // First socket should be the listening one. - chrome.test.assertEq(serverSocketId, sockets[0].socketId); - chrome.test.assertEq(false, sockets[0].persistent); - chrome.test.assertEq('MyServiceName', sockets[0].name); - chrome.test.assertEq(false, sockets[0].paused); - chrome.test.assertEq(false, sockets[0].connected); - chrome.test.assertEq(undefined, sockets[0].address); - chrome.test.assertEq(uuid, sockets[0].uuid); + chrome.test.assertEq(serverSocketId, serverSocket.socketId); + chrome.test.assertEq(false, serverSocket.persistent); + chrome.test.assertEq('MyServiceName', serverSocket.name); + chrome.test.assertEq(false, serverSocket.paused); + chrome.test.assertEq(false, serverSocket.connected); + chrome.test.assertEq(undefined, serverSocket.address); + chrome.test.assertEq(uuid, serverSocket.uuid); // Second socket should be the client one, which unlike the server should // be created paused. - chrome.test.assertEq(clientSocketId, sockets[1].socketId); - chrome.test.assertEq(false, sockets[1].persistent); - chrome.test.assertEq(undefined, sockets[1].name); - chrome.test.assertEq(true, sockets[1].paused); - chrome.test.assertEq(true, sockets[1].connected); - chrome.test.assertEq(clientAddress, sockets[1].address); - chrome.test.assertEq(uuid, sockets[1].uuid); + chrome.test.assertEq(clientSocketId, clientSocket.socketId); + chrome.test.assertEq(false, clientSocket.persistent); + chrome.test.assertEq(undefined, clientSocket.name); + chrome.test.assertEq(true, clientSocket.paused); + chrome.test.assertEq(true, clientSocket.connected); + chrome.test.assertEq(clientAddress, clientSocket.address); + chrome.test.assertEq(uuid, clientSocket.uuid); chrome.test.succeed(); }
diff --git a/gpu/gles2_conform_support/native/egl_native_x11.cc b/gpu/gles2_conform_support/native/egl_native_x11.cc index 7e4c42362..2c1d809 100644 --- a/gpu/gles2_conform_support/native/egl_native_x11.cc +++ b/gpu/gles2_conform_support/native/egl_native_x11.cc
@@ -25,30 +25,23 @@ }; if (format != GL_RGBA && format != GL_RGB) - return static_cast<EGLImageKHR>(NULL); + return static_cast<EGLImageKHR>(nullptr); if (type != GL_UNSIGNED_BYTE) - return static_cast<EGLImageKHR>(NULL); + return static_cast<EGLImageKHR>(nullptr); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, - 0, - format, - width, - height, - 0, - format, - type, - NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, + nullptr); // Disable mip-maps because we do not require it. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if(glGetError() != GL_NO_ERROR) - return static_cast<EGLImageKHR>(NULL); + return static_cast<EGLImageKHR>(nullptr); EGLImageKHR egl_image = egl_create_image_khr_(eglGetCurrentDisplay(), @@ -60,7 +53,7 @@ if (eglGetError() == EGL_SUCCESS) return egl_image; else - return static_cast<EGLImageKHR>(NULL); + return static_cast<EGLImageKHR>(nullptr); } void GTFDestroyEGLImage(EGLImageKHR image) {
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc index 39d226f..1410313 100644 --- a/headless/app/headless_shell.cc +++ b/headless/app/headless_shell.cc
@@ -349,6 +349,7 @@ if (command_line.HasSwitch(headless::switches::kUserDataDir)) { builder.SetUserDataDir( command_line.GetSwitchValuePath(headless::switches::kUserDataDir)); + builder.SetIncognitoMode(false); } return HeadlessBrowserMain(
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc index 458103d..2fb76e6 100644 --- a/headless/lib/browser/headless_browser_context_impl.cc +++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -160,7 +160,7 @@ } bool HeadlessBrowserContextImpl::IsOffTheRecord() const { - return false; + return context_options_->incognito_mode(); } content::ResourceContext* HeadlessBrowserContextImpl::GetResourceContext() { @@ -343,6 +343,12 @@ } HeadlessBrowserContext::Builder& +HeadlessBrowserContext::Builder::SetIncognitoMode(bool incognito_mode) { + options_->incognito_mode_ = incognito_mode; + return *this; +} + +HeadlessBrowserContext::Builder& HeadlessBrowserContext::Builder::AddJsMojoBindings( const std::string& mojom_name, const std::string& js_bindings) {
diff --git a/headless/lib/browser/headless_browser_context_options.cc b/headless/lib/browser/headless_browser_context_options.cc index 6f7a4d8..82e3d51a 100644 --- a/headless/lib/browser/headless_browser_context_options.cc +++ b/headless/lib/browser/headless_browser_context_options.cc
@@ -56,6 +56,11 @@ return ReturnOverriddenValue(user_data_dir_, browser_options_->user_data_dir); } +bool HeadlessBrowserContextOptions::incognito_mode() const { + return ReturnOverriddenValue(incognito_mode_, + browser_options_->incognito_mode); +} + const ProtocolHandlerMap& HeadlessBrowserContextOptions::protocol_handlers() const { return protocol_handlers_;
diff --git a/headless/lib/browser/headless_browser_context_options.h b/headless/lib/browser/headless_browser_context_options.h index a3f97eac..af9b893 100644 --- a/headless/lib/browser/headless_browser_context_options.h +++ b/headless/lib/browser/headless_browser_context_options.h
@@ -38,6 +38,9 @@ // See HeadlessBrowser::Options::user_data_dir. const base::FilePath& user_data_dir() const; + // Set HeadlessBrowser::Options::incognito_mode. + bool incognito_mode() const; + // Custom network protocol handlers. These can be used to override URL // fetching for different network schemes. const ProtocolHandlerMap& protocol_handlers() const; @@ -56,6 +59,7 @@ base::Optional<std::string> host_resolver_rules_; base::Optional<gfx::Size> window_size_; base::Optional<base::FilePath> user_data_dir_; + base::Optional<bool> incognito_mode_; ProtocolHandlerMap protocol_handlers_;
diff --git a/headless/lib/headless_browser_context_browsertest.cc b/headless/lib/headless_browser_context_browsertest.cc index a6ad735..305dce41 100644 --- a/headless/lib/headless_browser_context_browsertest.cc +++ b/headless/lib/headless_browser_context_browsertest.cc
@@ -219,6 +219,7 @@ browser() ->CreateBrowserContextBuilder() .SetUserDataDir(user_data_dir.path()) + .SetIncognitoMode(false) .Build(); HeadlessWebContents* web_contents = @@ -234,4 +235,36 @@ EXPECT_FALSE(base::IsDirectoryEmpty(user_data_dir.path())); } +IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, IncognitoMode) { + // We do not want to bother with posting tasks to create a temp dir. + // Just allow IO from main thread for now. + base::ThreadRestrictions::SetIOAllowed(true); + + EXPECT_TRUE(embedded_test_server()->Start()); + + base::ScopedTempDir user_data_dir; + ASSERT_TRUE(user_data_dir.CreateUniqueTempDir()); + + // Newly created temp directory should be empty. + EXPECT_TRUE(base::IsDirectoryEmpty(user_data_dir.path())); + + HeadlessBrowserContext* browser_context = + browser() + ->CreateBrowserContextBuilder() + .SetUserDataDir(user_data_dir.path()) + .SetIncognitoMode(true) + .Build(); + + HeadlessWebContents* web_contents = + browser_context->CreateWebContentsBuilder() + .SetInitialURL(embedded_test_server()->GetURL("/hello.html")) + .Build(); + + EXPECT_TRUE(WaitForLoad(web_contents)); + + // Similar to test above, but now we are in incognito mode, + // so nothing should be written to this directory. + EXPECT_TRUE(base::IsDirectoryEmpty(user_data_dir.path())); +} + } // namespace headless
diff --git a/headless/public/headless_browser.cc b/headless/public/headless_browser.cc index 3a9e2f23..cbfbc5e 100644 --- a/headless/public/headless_browser.cc +++ b/headless/public/headless_browser.cc
@@ -27,7 +27,8 @@ disable_sandbox(false), gl_implementation("osmesa"), user_agent(content::BuildUserAgentFromProduct(kProductName)), - window_size(kDefaultWindowSize) {} + window_size(kDefaultWindowSize), + incognito_mode(true) {} Options::Options(Options&& options) = default; @@ -91,6 +92,11 @@ return *this; } +Builder& Builder::SetIncognitoMode(bool incognito_mode) { + options_.incognito_mode = incognito_mode; + return *this; +} + Options Builder::Build() { return std::move(options_); }
diff --git a/headless/public/headless_browser.h b/headless/public/headless_browser.h index ccc14369..6c7dfe4 100644 --- a/headless/public/headless_browser.h +++ b/headless/public/headless_browser.h
@@ -131,6 +131,9 @@ // If empty, default directory (where the binary is located) will be used. base::FilePath user_data_dir; + // Run a browser context in an incognito mode. Enabled by default. + bool incognito_mode; + // Reminder: when adding a new field here, do not forget to add it to // HeadlessBrowserContextOptions (where appropriate). private: @@ -160,6 +163,7 @@ Builder& SetHostResolverRules(const std::string& host_resolver_rules); Builder& SetWindowSize(const gfx::Size& window_size); Builder& SetUserDataDir(const base::FilePath& user_data_dir); + Builder& SetIncognitoMode(bool incognito_mode); Options Build();
diff --git a/headless/public/headless_browser_context.h b/headless/public/headless_browser_context.h index 702541e..4cdaf35 100644 --- a/headless/public/headless_browser_context.h +++ b/headless/public/headless_browser_context.h
@@ -101,6 +101,7 @@ Builder& SetHostResolverRules(const std::string& host_resolver_rules); Builder& SetWindowSize(const gfx::Size& window_size); Builder& SetUserDataDir(const base::FilePath& user_data_dir); + Builder& SetIncognitoMode(bool incognito_mode); HeadlessBrowserContext* Build();
diff --git a/ios/build/bots/chromium.mac/ios-simulator-swarming.json b/ios/build/bots/chromium.mac/ios-simulator-swarming.json index 56f9121..4297caa 100644 --- a/ios/build/bots/chromium.mac/ios-simulator-swarming.json +++ b/ios/build/bots/chromium.mac/ios-simulator-swarming.json
@@ -8,7 +8,7 @@ "Tests run on iPhone 5s (64-bit) and iPad Retina (32-bit).", "Build is performed with gn+ninja." ], - "xcode version": "7.0", + "xcode version": "7.3", "GYP_DEFINES": [ "OS=ios", "chromium_ios_signing=0", @@ -31,17 +31,19 @@ "compiler": "ninja", "additional_compile_targets": ["gn_all"], "configuration": "Debug", - "sdk": "iphonesimulator9.0", + "sdk": "iphonesimulator9.3", "tests": [ { "include": "common_tests.json", "device type": "iPhone 5s", - "os": "9.0" + "os": "9.0", + "xcode version": "7.0" }, { "include": "common_tests.json", "device type": "iPad Retina", - "os": "9.0" + "os": "9.0", + "xcode version": "7.0" } ] }
diff --git a/ios/build/bots/tests/common_tests.json b/ios/build/bots/tests/common_tests.json index f5aca97..81f4634 100644 --- a/ios/build/bots/tests/common_tests.json +++ b/ios/build/bots/tests/common_tests.json
@@ -37,9 +37,6 @@ "app": "sql_unittests" }, { - "app": "sync_unit_tests" - }, - { "app": "ui_base_unittests" }, {
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.h b/ios/chrome/browser/ui/autofill/autofill_client_ios.h index 6c5575f..8ce38ae 100644 --- a/ios/chrome/browser/ui/autofill/autofill_client_ios.h +++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.h
@@ -66,6 +66,8 @@ const CreditCard& card, std::unique_ptr<base::DictionaryValue> legal_message, const base::Closure& callback) override; + void ConfirmCreditCardFillAssist(const CreditCard& card, + const base::Closure& callback) override; void LoadRiskData( const base::Callback<void(const std::string&)>& callback) override; bool HasCreditCardScanFeature() override;
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm index c7b6f59..b8a2e7f 100644 --- a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
@@ -109,6 +109,12 @@ true, card, std::move(legal_message), callback)))); } +void AutofillClientIOS::ConfirmCreditCardFillAssist( + const CreditCard& card, + const base::Closure& callback) { + NOTREACHED(); +} + void AutofillClientIOS::LoadRiskData( const base::Callback<void(const std::string&)>& callback) { callback.Run(ios::GetChromeBrowserProvider()->GetRiskData());
diff --git a/ios/net/http_cache_helper.cc b/ios/net/http_cache_helper.cc index e9e185a4..5aa57a1 100644 --- a/ios/net/http_cache_helper.cc +++ b/ios/net/http_cache_helper.cc
@@ -19,6 +19,7 @@ #include "net/quic/chromium/quic_stream_factory.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" +#include "url/gurl.h" namespace { @@ -55,7 +56,7 @@ // Clear QUIC server information from memory and the disk cache. http_cache->GetSession() ->quic_stream_factory() - ->ClearCachedStatesInCryptoConfig(); + ->ClearCachedStatesInCryptoConfig(base::Callback<bool(const GURL&)>()); // Clear SDCH dictionary state. net::SdchManager* sdch_manager =
diff --git a/media/base/demuxer_stream.h b/media/base/demuxer_stream.h index 17f193f..c90de79 100644 --- a/media/base/demuxer_stream.h +++ b/media/base/demuxer_stream.h
@@ -102,9 +102,12 @@ // reading data from a key frame preceeding the |timestamp|. virtual void set_enabled(bool enabled, base::TimeDelta timestamp) = 0; - using StreamRestartedCB = - base::Callback<void(DemuxerStream*, base::TimeDelta)>; - virtual void SetStreamRestartedCB(const StreamRestartedCB& cb) = 0; + // The StreamStatusChangeCB allows DemuxerStream clients to receive + // notifications about the stream being disabled or enabled. + // The first parameter indicates whether the stream is enabled or disabled. + // The second parameter is the playback position when the change occured. + using StreamStatusChangeCB = base::Callback<void(bool, base::TimeDelta)>; + virtual void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) = 0; protected: // Only allow concrete implementations to get deleted.
diff --git a/media/base/fake_demuxer_stream.cc b/media/base/fake_demuxer_stream.cc index beb44f1..731e6b1d 100644 --- a/media/base/fake_demuxer_stream.cc +++ b/media/base/fake_demuxer_stream.cc
@@ -112,7 +112,8 @@ NOTIMPLEMENTED(); } -void FakeDemuxerStream::SetStreamRestartedCB(const StreamRestartedCB& cb) { +void FakeDemuxerStream::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { NOTIMPLEMENTED(); }
diff --git a/media/base/fake_demuxer_stream.h b/media/base/fake_demuxer_stream.h index 95b1fae..385d8243 100644 --- a/media/base/fake_demuxer_stream.h +++ b/media/base/fake_demuxer_stream.h
@@ -37,7 +37,7 @@ VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta timestamp) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; void Initialize();
diff --git a/media/base/fake_text_track_stream.cc b/media/base/fake_text_track_stream.cc index c0a8ae48b..279fe39c 100644 --- a/media/base/fake_text_track_stream.cc +++ b/media/base/fake_text_track_stream.cc
@@ -54,7 +54,8 @@ NOTIMPLEMENTED(); } -void FakeTextTrackStream::SetStreamRestartedCB(const StreamRestartedCB& cb) { +void FakeTextTrackStream::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { NOTIMPLEMENTED(); }
diff --git a/media/base/fake_text_track_stream.h b/media/base/fake_text_track_stream.h index 1e3c0a5..ee8b15c 100644 --- a/media/base/fake_text_track_stream.h +++ b/media/base/fake_text_track_stream.h
@@ -31,7 +31,7 @@ VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta timestamp) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; void SatisfyPendingRead(const base::TimeDelta& start, const base::TimeDelta& duration,
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 16c3355..a292246 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -55,9 +55,6 @@ // for details. const char kEnableExclusiveAudio[] = "enable-exclusive-audio"; -// Enables H264 HW encode acceleration using Media Foundation for Windows. -const char kEnableMFH264Encoding[] = "enable-mf-h264-encoding"; - // Force the use of MediaFoundation for video capture. This is only supported in // Windows 7 and above. Used, like |kForceDirectShowVideoCapture|, to // troubleshoot problems in Windows platforms. @@ -138,6 +135,12 @@ namespace media { +#if defined(OS_WIN) +// Enables H264 HW encode acceleration using Media Foundation for Windows. +const base::Feature kMediaFoundationH264Encoding{ + "MediaFoundationH264Encoding", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // defined(OS_WIN) + #if defined(ENABLE_PLUGINS) // Let flash join and be controlled by media session, only valid when // |kEnableDefaultMediaSession| is on. @@ -149,6 +152,18 @@ const base::Feature kNewAudioRenderingMixingStrategy{ "NewAudioRenderingMixingStrategy", base::FEATURE_DISABLED_BY_DEFAULT}; +// Let videos be resumed via remote controls (for example, the notification) +// when in background. +const base::Feature kResumeBackgroundVideo { + "resume-background-video", +#if defined(OS_ANDROID) + base::FEATURE_ENABLED_BY_DEFAULT +}; +#else + base::FEATURE_DISABLED_BY_DEFAULT +}; +#endif + // Use shared block-based buffering for media. const base::Feature kUseNewMediaCache{"use-new-media-cache", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 77ca1df..8e60f8f1 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -37,7 +37,6 @@ #if defined(OS_WIN) MEDIA_EXPORT extern const char kEnableExclusiveAudio[]; -MEDIA_EXPORT extern const char kEnableMFH264Encoding[]; MEDIA_EXPORT extern const char kForceMediaFoundationVideoCapture[]; MEDIA_EXPORT extern const char kForceWaveAudio[]; MEDIA_EXPORT extern const char kTrySupportedChannelLayouts[]; @@ -78,11 +77,16 @@ // All features in alphabetical order. The features should be documented // alongside the definition of their values in the .cc file. +#if defined(OS_WIN) +MEDIA_EXPORT extern const base::Feature kMediaFoundationH264Encoding; +#endif // defined(OS_WIN) + #if defined(ENABLE_PLUGINS) MEDIA_EXPORT extern const base::Feature kFlashJoinsMediaSession; #endif // defined(ENABLE_PLUGINS) MEDIA_EXPORT extern const base::Feature kNewAudioRenderingMixingStrategy; +MEDIA_EXPORT extern const base::Feature kResumeBackgroundVideo; MEDIA_EXPORT extern const base::Feature kUseNewMediaCache; } // namespace media
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index ecd6848..598860f 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h
@@ -158,7 +158,7 @@ VideoRotation video_rotation() override; MOCK_CONST_METHOD0(enabled, bool()); MOCK_METHOD2(set_enabled, void(bool, base::TimeDelta)); - MOCK_METHOD1(SetStreamRestartedCB, void(const StreamRestartedCB&)); + MOCK_METHOD1(SetStreamStatusChangeCB, void(const StreamStatusChangeCB&)); private: Type type_;
diff --git a/media/blink/webmediaplayer_delegate.h b/media/blink/webmediaplayer_delegate.h index c70b07f3..e33cc70 100644 --- a/media/blink/webmediaplayer_delegate.h +++ b/media/blink/webmediaplayer_delegate.h
@@ -68,6 +68,10 @@ // Returns whether the render frame is currently hidden. virtual bool IsHidden() = 0; + // Returns whether there's a video playing in background within the render + // frame. + virtual bool IsPlayingBackgroundVideo() = 0; + protected: virtual ~WebMediaPlayerDelegate() {} };
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 84dd78f..23a518d82 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -115,6 +115,10 @@ #endif } +bool IsResumeBackgroundVideosEnabled() { + return base::FeatureList::IsEnabled(kResumeBackgroundVideo); +} + bool IsNetworkStateError(blink::WebMediaPlayer::NetworkState state) { bool result = state == blink::WebMediaPlayer::NetworkStateFormatError || state == blink::WebMediaPlayer::NetworkStateNetworkError || @@ -386,7 +390,6 @@ return; } #endif - paused_ = false; is_idle_ = false; pipeline_.SetPlaybackRate(playback_rate_); @@ -1160,6 +1163,7 @@ void WebMediaPlayerImpl::OnHidden() { DCHECK(main_task_runner_->BelongsToCurrentThread()); + UpdatePlayState(); // Schedule suspended playing media to be paused if the user doesn't come back @@ -1171,6 +1175,7 @@ DCHECK(main_task_runner_->BelongsToCurrentThread()); must_suspend_ = false; background_pause_timer_.Stop(); + UpdatePlayState(); } @@ -1605,7 +1610,15 @@ // Background suspend is not enabled for audio-only players unless paused, // though in the case of audio-only the session should be kept. - bool background_suspended = is_backgrounded && have_metadata && hasVideo(); + // Videos are not suspended if the user resumed the playback via the remote + // controls earlier and it's still playing. + bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo(); + bool can_play_backgrounded = is_backgrounded_video && !is_remote && + hasAudio() && IsResumeBackgroundVideosEnabled(); + bool is_background_playing = + delegate_ && delegate_->IsPlayingBackgroundVideo(); + bool background_suspended = is_backgrounded_video && + !(can_play_backgrounded && is_background_playing); // The |paused_| state is not reliable until we |have_future_data|. bool background_pause_suspended = @@ -1650,11 +1663,20 @@ // TODO(sandersd): If Blink told us the paused state sooner, we could create // the media session sooner. bool can_play = !has_error && !is_remote && have_future_data; - bool has_session = can_play && !must_suspend_ && !background_suspended; + bool has_session_playing = + can_play && !must_suspend_ && !background_suspended; + + // |has_session_suspended| means the player is suspended from the media + // element point of view but paused and can be resumed from the delegate point + // of view. Therefore it behaves like |paused_| for the delegate. + bool has_session_suspended = can_play && !must_suspend_ && + background_suspended && can_play_backgrounded; + + bool has_session = has_session_playing || has_session_suspended; if (!has_session) { result.delegate_state = DelegateState::GONE; - } else if (paused_) { + } else if (paused_ || has_session_suspended) { if (seeking() || overlay_enabled_) { result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; } else if (ended_) {
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index edee39b7..9fb661d 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -327,7 +327,7 @@ // - network_state_, ready_state_, // - is_idle_, must_suspend_, // - paused_, ended_, - // - pending_suspend_resume_cycle_. + // - pending_suspend_resume_cycle_, void UpdatePlayState(); // Methods internal to UpdatePlayState().
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index e457440..4f7827c 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -18,6 +19,7 @@ #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "media/base/media_log.h" +#include "media/base/media_switches.h" #include "media/base/test_helpers.h" #include "media/blink/mock_webframeclient.h" #include "media/blink/webmediaplayer_delegate.h" @@ -33,6 +35,10 @@ #include "third_party/WebKit/public/web/WebView.h" #include "url/gurl.h" +using ::testing::InSequence; +using ::testing::Return; +using ::testing::_; + namespace media { int64_t OnAdjustAllocatedMemory(int64_t delta) { @@ -84,6 +90,23 @@ DISALLOW_COPY_AND_ASSIGN(DummyWebMediaPlayerClient); }; +class MockWebMediaPlayerDelegate + : public WebMediaPlayerDelegate, + public base::SupportsWeakPtr<MockWebMediaPlayerDelegate> { + public: + MockWebMediaPlayerDelegate() = default; + ~MockWebMediaPlayerDelegate() = default; + + // WebMediaPlayerDelegate implementation. + MOCK_METHOD1(AddObserver, int(Observer*)); + MOCK_METHOD1(RemoveObserver, void(int)); + MOCK_METHOD5(DidPlay, void(int, bool, bool, bool, base::TimeDelta)); + MOCK_METHOD2(DidPause, void(int, bool)); + MOCK_METHOD1(PlayerGone, void(int)); + MOCK_METHOD0(IsHidden, bool()); + MOCK_METHOD0(IsPlayingBackgroundVideo, bool()); +}; + class WebMediaPlayerImplTest : public testing::Test { public: WebMediaPlayerImplTest() @@ -99,8 +122,7 @@ media_thread_.StartAndWaitForTesting(); wmpi_.reset(new WebMediaPlayerImpl( - web_local_frame_, &client_, nullptr, - base::WeakPtr<WebMediaPlayerDelegate>(), + web_local_frame_, &client_, nullptr, delegate_.AsWeakPtr(), base::WrapUnique(new DefaultRendererFactory( media_log_, nullptr, DefaultRendererFactory::GetGpuFactoriesCB())), url_index_, @@ -181,6 +203,18 @@ return wmpi_->UpdatePlayState_ComputePlayState(false, false, false); } + void SetupForResumingBackgroundVideo() { +#if !defined(OS_ANDROID) + // Need to enable media suspend to test resuming background videos. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableMediaSuspend); +#endif // !defined(OS_ANDROID) + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->InitializeFromCommandLine(kResumeBackgroundVideo.name, ""); + base::FeatureList::ClearInstanceForTesting(); + base::FeatureList::SetInstance(std::move(feature_list)); + } + // "Renderer" thread. base::MessageLoop message_loop_; @@ -203,6 +237,8 @@ // may want a mock or intelligent fake. DummyWebMediaPlayerClient client_; + MockWebMediaPlayerDelegate delegate_; + // The WebMediaPlayerImpl instance under test. std::unique_ptr<WebMediaPlayerImpl> wmpi_; @@ -283,7 +319,11 @@ EXPECT_FALSE(state.is_suspended); state = ComputeBackgroundedPlayState(); - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); + + if (base::FeatureList::IsEnabled(kResumeBackgroundVideo)) + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); + else + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); EXPECT_FALSE(state.is_memory_reporting_enabled); EXPECT_TRUE(state.is_suspended); @@ -311,7 +351,10 @@ EXPECT_FALSE(state.is_suspended); state = ComputeBackgroundedPlayState(); - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); + if (base::FeatureList::IsEnabled(kResumeBackgroundVideo)) + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); + else + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); EXPECT_FALSE(state.is_memory_reporting_enabled); EXPECT_TRUE(state.is_suspended); @@ -337,7 +380,10 @@ // Background suspend should still be possible during underflow. state = ComputeBackgroundedPlayState(); - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); + if (base::FeatureList::IsEnabled(kResumeBackgroundVideo)) + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); + else + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); EXPECT_FALSE(state.is_memory_reporting_enabled); EXPECT_TRUE(state.is_suspended); @@ -502,4 +548,41 @@ ASSERT_EQ(blink::WebSize(1080, 1920), wmpi_->naturalSize()); } +// Audible backgrounded videos are not suspended if delegate_ allows it. +TEST_F(WebMediaPlayerImplTest, ComputePlayState_BackgroundedVideoPlaying) { + WebMediaPlayerImpl::PlayState state; + SetMetadata(true, true); + SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); + + SetupForResumingBackgroundVideo(); + + EXPECT_CALL(delegate_, IsPlayingBackgroundVideo()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(delegate_, IsHidden()).WillRepeatedly(Return(true)); + + SetPaused(false); + state = ComputeBackgroundedPlayState(); + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); + EXPECT_TRUE(state.is_memory_reporting_enabled); + EXPECT_FALSE(state.is_suspended); +} + +// Backgrounding audible videos should suspend them and report as paused, not +// gone. +TEST_F(WebMediaPlayerImplTest, ComputePlayState_BackgroundedVideoPaused) { + WebMediaPlayerImpl::PlayState state; + SetMetadata(true, true); + SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); + + SetupForResumingBackgroundVideo(); + + EXPECT_CALL(delegate_, IsPlayingBackgroundVideo()).WillOnce(Return(false)); + EXPECT_CALL(delegate_, IsHidden()).WillRepeatedly(Return(true)); + + state = ComputeBackgroundedPlayState(); + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); + EXPECT_FALSE(state.is_memory_reporting_enabled); + EXPECT_TRUE(state.is_suspended); +} + } // namespace media
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 31f3de14..526cafee 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc
@@ -300,18 +300,19 @@ if (enabled) { DCHECK(stream_); stream_->Seek(timestamp); - if (!stream_restarted_cb_.is_null()) - stream_restarted_cb_.Run(this, timestamp); } else if (!read_cb_.is_null()) { DVLOG(1) << "Read from disabled stream, returning EOS"; base::ResetAndReturn(&read_cb_).Run(kOk, StreamParserBuffer::CreateEOSBuffer()); } + if (!stream_status_change_cb_.is_null()) + stream_status_change_cb_.Run(is_enabled_, timestamp); } -void ChunkDemuxerStream::SetStreamRestartedCB(const StreamRestartedCB& cb) { +void ChunkDemuxerStream::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { DCHECK(!cb.is_null()); - stream_restarted_cb_ = BindToCurrentLoop(cb); + stream_status_change_cb_ = BindToCurrentLoop(cb); } TextTrackConfig ChunkDemuxerStream::text_track_config() {
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h index 9065829..1e4f357f 100644 --- a/media/filters/chunk_demuxer.h +++ b/media/filters/chunk_demuxer.h
@@ -113,7 +113,7 @@ VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta timestamp) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; // Returns the text track configuration. It is an error to call this method // if type() != TEXT. @@ -158,7 +158,7 @@ bool splice_frames_enabled_; bool partial_append_window_trimming_enabled_; bool is_enabled_; - StreamRestartedCB stream_restarted_cb_; + StreamStatusChangeCB stream_status_change_cb_; DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); };
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index 419c6cd..0d7c9a1 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "base/synchronization/waitable_event.h" #include "media/base/audio_decoder_config.h" #include "media/base/decoder_buffer.h" #include "media/base/decrypt_config.h" @@ -4706,4 +4707,41 @@ CheckExpectedBuffers(video_stream, "71K 81"); } +void OnStreamStatusChanged(base::WaitableEvent* event, + DemuxerStream* stream, + bool enabled, + base::TimeDelta) { + EXPECT_EQ(enabled, stream->enabled()); + event->Signal(); +} + +void CheckStreamStatusNotifications(DemuxerStream* stream) { + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + + ASSERT_TRUE(stream->enabled()); + stream->SetStreamStatusChangeCB(base::Bind(&OnStreamStatusChanged, + base::Unretained(&event), + base::Unretained(stream))); + + stream->set_enabled(false, base::TimeDelta()); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(event.IsSignaled()); + + event.Reset(); + stream->set_enabled(true, base::TimeDelta()); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(event.IsSignaled()); +} + +TEST_F(ChunkDemuxerTest, StreamStatusNotifications) { + ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); + DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); + EXPECT_NE(nullptr, audio_stream); + CheckStreamStatusNotifications(audio_stream); + DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); + EXPECT_NE(nullptr, video_stream); + CheckStreamStatusNotifications(video_stream); +} + } // namespace media
diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc index 293ecdb4..0e31ef4 100644 --- a/media/filters/decrypting_demuxer_stream.cc +++ b/media/filters/decrypting_demuxer_stream.cc
@@ -161,9 +161,9 @@ demuxer_stream_->set_enabled(enabled, timestamp); } -void DecryptingDemuxerStream::SetStreamRestartedCB( - const StreamRestartedCB& cb) { - demuxer_stream_->SetStreamRestartedCB(cb); +void DecryptingDemuxerStream::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { + demuxer_stream_->SetStreamStatusChangeCB(cb); } DecryptingDemuxerStream::~DecryptingDemuxerStream() {
diff --git a/media/filters/decrypting_demuxer_stream.h b/media/filters/decrypting_demuxer_stream.h index 4c1e4be..ceed9e32 100644 --- a/media/filters/decrypting_demuxer_stream.h +++ b/media/filters/decrypting_demuxer_stream.h
@@ -64,7 +64,7 @@ VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta timestamp) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; private: // For a detailed state diagram please see this link: http://goo.gl/8jAok
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 2cf751d..b34d8bc 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -711,19 +711,20 @@ is_enabled_ = enabled; if (is_enabled_) { waiting_for_keyframe_ = true; - if (!stream_restarted_cb_.is_null()) - stream_restarted_cb_.Run(this, timestamp); } if (!is_enabled_ && !read_cb_.is_null()) { DVLOG(1) << "Read from disabled stream, returning EOS"; base::ResetAndReturn(&read_cb_).Run(kOk, DecoderBuffer::CreateEOSBuffer()); return; } + if (!stream_status_change_cb_.is_null()) + stream_status_change_cb_.Run(is_enabled_, timestamp); } -void FFmpegDemuxerStream::SetStreamRestartedCB(const StreamRestartedCB& cb) { +void FFmpegDemuxerStream::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { DCHECK(!cb.is_null()); - stream_restarted_cb_ = cb; + stream_status_change_cb_ = cb; } void FFmpegDemuxerStream::SetLiveness(Liveness liveness) {
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h index 550316f8..1a95e11 100644 --- a/media/filters/ffmpeg_demuxer.h +++ b/media/filters/ffmpeg_demuxer.h
@@ -112,7 +112,7 @@ VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta timestamp) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; void SetLiveness(Liveness liveness); @@ -179,7 +179,7 @@ DecoderBufferQueue buffer_queue_; ReadCB read_cb_; - StreamRestartedCB stream_restarted_cb_; + StreamStatusChangeCB stream_status_change_cb_; #if defined(USE_PROPRIETARY_CODECS) std::unique_ptr<FFmpegBitstreamConverter> bitstream_converter_;
diff --git a/media/gpu/ipc/service/gpu_video_encode_accelerator.cc b/media/gpu/ipc/service/gpu_video_encode_accelerator.cc index 4c48a9f..23ce04e4 100644 --- a/media/gpu/ipc/service/gpu_video_encode_accelerator.cc +++ b/media/gpu/ipc/service/gpu_video_encode_accelerator.cc
@@ -36,6 +36,7 @@ #elif defined(OS_MACOSX) #include "media/gpu/vt_video_encode_accelerator_mac.h" #elif defined(OS_WIN) +#include "base/feature_list.h" #include "media/base/media_switches.h" #include "media/gpu/media_foundation_video_encode_accelerator_win.h" #endif @@ -212,8 +213,7 @@ create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateVTVEA); #endif #if defined(OS_WIN) - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableMFH264Encoding)) { + if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding)) { create_vea_fps.push_back( &GpuVideoEncodeAccelerator::CreateMediaFoundationVEA); }
diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.cc b/media/gpu/media_foundation_video_encode_accelerator_win.cc index bf292724..9e4b194 100644 --- a/media/gpu/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/media_foundation_video_encode_accelerator_win.cc
@@ -81,7 +81,7 @@ MediaFoundationVideoEncodeAccelerator:: ~MediaFoundationVideoEncodeAccelerator() { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(sequence_checker_.CalledOnValidSequence()); DCHECK(!encoder_thread_.IsRunning()); @@ -90,12 +90,17 @@ VideoEncodeAccelerator::SupportedProfiles MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles() { - DVLOG(3) << __FUNCTION__; + TRACE_EVENT0("gpu,startup", + "MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles"); + DVLOG(3) << __func__; DCHECK(sequence_checker_.CalledOnValidSequence()); SupportedProfiles profiles; - if (base::win::GetVersion() < base::win::VERSION_WIN8) { - DLOG(ERROR) << "Windows versions earlier than 8 are not supported."; + const bool rv = CreateHardwareEncoderMFT(); + encoder_.Release(); + if (!rv) { + DVLOG(1) + << "Hardware encode acceleration is not available on this platform."; return profiles; } @@ -116,8 +121,7 @@ VideoCodecProfile output_profile, uint32_t initial_bitrate, Client* client) { - DVLOG(3) << __FUNCTION__ - << ": input_format=" << VideoPixelFormatToString(format) + DVLOG(3) << __func__ << ": input_format=" << VideoPixelFormatToString(format) << ", input_visible_size=" << input_visible_size.ToString() << ", output_profile=" << output_profile << ", initial_bitrate=" << initial_bitrate; @@ -134,13 +138,6 @@ return false; } - for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) { - if (!::GetModuleHandle(mfdll)) { - DLOG(ERROR) << mfdll << " is required for encoding"; - return false; - } - } - encoder_thread_.init_com_with_mta(false); if (!encoder_thread_.Start()) { DLOG(ERROR) << "Failed spawning encoder thread."; @@ -148,25 +145,10 @@ } encoder_thread_task_runner_ = encoder_thread_.task_runner(); - InitializeMediaFoundation(); - - uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; - MFT_REGISTER_TYPE_INFO input_info; - input_info.guidMajorType = MFMediaType_Video; - input_info.guidSubtype = MFVideoFormat_NV12; - MFT_REGISTER_TYPE_INFO output_info; - output_info.guidMajorType = MFMediaType_Video; - output_info.guidSubtype = MFVideoFormat_H264; - - base::win::ScopedCoMem<CLSID> CLSIDs; - uint32_t count = 0; - HRESULT hr = MFTEnum(MFT_CATEGORY_VIDEO_ENCODER, flags, NULL, &output_info, - NULL, &CLSIDs, &count); - RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false); - RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); - DVLOG(3) << "HW encoder(s) found: " << count; - hr = encoder_.CreateInstance(CLSIDs[0]); - RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); + if (!CreateHardwareEncoderMFT()) { + DLOG(ERROR) << "Failed creating a hardware encoder MFT."; + return false; + } client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); client_ = client_ptr_factory_->GetWeakPtr(); @@ -195,7 +177,8 @@ return false; } - hr = encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL); + HRESULT hr = + encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL); RETURN_ON_HR_FAILURE(hr, "Couldn't set ProcessMessage", false); client_task_runner_->PostTask( @@ -208,7 +191,7 @@ void MediaFoundationVideoEncodeAccelerator::Encode( const scoped_refptr<VideoFrame>& frame, bool force_keyframe) { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(sequence_checker_.CalledOnValidSequence()); encoder_thread_task_runner_->PostTask( @@ -219,7 +202,7 @@ void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer( const BitstreamBuffer& buffer) { - DVLOG(3) << __FUNCTION__ << ": buffer size=" << buffer.size(); + DVLOG(3) << __func__ << ": buffer size=" << buffer.size(); DCHECK(sequence_checker_.CalledOnValidSequence()); if (buffer.size() < bitstream_buffer_size_) { @@ -249,7 +232,7 @@ void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChange( uint32_t bitrate, uint32_t framerate) { - DVLOG(3) << __FUNCTION__ << ": bitrate=" << bitrate + DVLOG(3) << __func__ << ": bitrate=" << bitrate << ": framerate=" << framerate; DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -261,7 +244,7 @@ } void MediaFoundationVideoEncodeAccelerator::Destroy() { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(sequence_checker_.CalledOnValidSequence()); // Cancel all callbacks. @@ -284,6 +267,44 @@ ::LoadLibrary(mfdll); } +bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() { + DVLOG(3) << __func__; + DCHECK(sequence_checker_.CalledOnValidSequence()); + + if (base::win::GetVersion() < base::win::VERSION_WIN8) { + DVLOG(ERROR) << "Windows versions earlier than 8 are not supported."; + return false; + } + + for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) { + if (!::GetModuleHandle(mfdll)) { + DVLOG(ERROR) << mfdll << " is required for encoding"; + return false; + } + } + + InitializeMediaFoundation(); + + uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; + MFT_REGISTER_TYPE_INFO input_info; + input_info.guidMajorType = MFMediaType_Video; + input_info.guidSubtype = MFVideoFormat_NV12; + MFT_REGISTER_TYPE_INFO output_info; + output_info.guidMajorType = MFMediaType_Video; + output_info.guidSubtype = MFVideoFormat_H264; + + base::win::ScopedCoMem<CLSID> CLSIDs; + uint32_t count = 0; + HRESULT hr = MFTEnum(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info, + &output_info, NULL, &CLSIDs, &count); + RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false); + RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); + DVLOG(3) << "HW encoder(s) found: " << count; + hr = encoder_.CreateInstance(CLSIDs[0]); + RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); + return true; +} + bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -383,7 +404,7 @@ void MediaFoundationVideoEncodeAccelerator::EncodeTask( const scoped_refptr<VideoFrame>& frame, bool force_keyframe) { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); base::win::ScopedComPtr<IMFMediaBuffer> input_buffer; @@ -430,7 +451,7 @@ } void MediaFoundationVideoEncodeAccelerator::ProcessOutput() { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; @@ -493,7 +514,7 @@ void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBufferTask( std::unique_ptr<BitstreamBufferRef> buffer_ref) { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); // If there is already EncodeOutput waiting, copy its output first. @@ -512,7 +533,7 @@ std::unique_ptr<EncodeOutput> encode_output, std::unique_ptr<MediaFoundationVideoEncodeAccelerator::BitstreamBufferRef> buffer_ref) { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); memcpy(buffer_ref->shm->memory(), encode_output->memory(), @@ -527,7 +548,7 @@ void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChangeTask( uint32_t bitrate, uint32_t framerate) { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); frame_rate_ = framerate ? framerate : 1; @@ -550,7 +571,7 @@ } void MediaFoundationVideoEncodeAccelerator::DestroyTask() { - DVLOG(3) << __FUNCTION__; + DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); // Cancel all encoder thread callbacks.
diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.h b/media/gpu/media_foundation_video_encode_accelerator_win.h index f6b9a0d..d820e9d 100644 --- a/media/gpu/media_foundation_video_encode_accelerator_win.h +++ b/media/gpu/media_foundation_video_encode_accelerator_win.h
@@ -62,6 +62,9 @@ // Holds output buffers coming from the encoder. class EncodeOutput; + // Creates an hardware encoder backed IMFTransform instance on |encoder_|. + bool CreateHardwareEncoderMFT(); + // Initializes and allocates memory for input and output samples. bool InitializeInputOutputSamples();
diff --git a/media/mojo/services/mojo_demuxer_stream_adapter.cc b/media/mojo/services/mojo_demuxer_stream_adapter.cc index 1a5a09f..f302a2ce 100644 --- a/media/mojo/services/mojo_demuxer_stream_adapter.cc +++ b/media/mojo/services/mojo_demuxer_stream_adapter.cc
@@ -79,8 +79,8 @@ NOTIMPLEMENTED(); } -void MojoDemuxerStreamAdapter::SetStreamRestartedCB( - const StreamRestartedCB& cb) { +void MojoDemuxerStreamAdapter::SetStreamStatusChangeCB( + const StreamStatusChangeCB& cb) { NOTIMPLEMENTED(); }
diff --git a/media/mojo/services/mojo_demuxer_stream_adapter.h b/media/mojo/services/mojo_demuxer_stream_adapter.h index 43a97131..a195954 100644 --- a/media/mojo/services/mojo_demuxer_stream_adapter.h +++ b/media/mojo/services/mojo_demuxer_stream_adapter.h
@@ -46,7 +46,7 @@ VideoRotation video_rotation() override; bool enabled() const override; void set_enabled(bool enabled, base::TimeDelta timestamp) override; - void SetStreamRestartedCB(const StreamRestartedCB& cb) override; + void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override; private: void OnStreamReady(mojom::DemuxerStream::Type type,
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index 007b4b0..7381e94e 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc
@@ -134,13 +134,13 @@ DemuxerStream* audio_stream = demuxer_stream_provider->GetStream(DemuxerStream::AUDIO); if (audio_stream) - audio_stream->SetStreamRestartedCB( - base::Bind(&RendererImpl::RestartStreamPlayback, weak_this_)); + audio_stream->SetStreamStatusChangeCB(base::Bind( + &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream)); DemuxerStream* video_stream = demuxer_stream_provider->GetStream(DemuxerStream::VIDEO); if (video_stream) - video_stream->SetStreamRestartedCB( - base::Bind(&RendererImpl::RestartStreamPlayback, weak_this_)); + video_stream->SetStreamStatusChangeCB(base::Bind( + &RendererImpl::RestartStreamPlayback, weak_this_, video_stream)); if (HasEncryptedStream() && !cdm_context_) { state_ = STATE_INIT_PENDING_CDM; @@ -215,9 +215,13 @@ } void RendererImpl::RestartStreamPlayback(DemuxerStream* stream, + bool enabled, base::TimeDelta time) { - DVLOG(1) << __func__ << " stream=" << stream << " time=" << time.InSecondsF(); DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(stream); + bool video = (stream->type() == DemuxerStream::VIDEO); + DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream + << " enabled=" << stream->enabled() << " time=" << time.InSecondsF(); if (state_ != STATE_PLAYING) return; if (stream->type() == DemuxerStream::VIDEO) { @@ -246,24 +250,22 @@ } void RendererImpl::RestartVideoRenderer(base::TimeDelta time) { + DVLOG(3) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); - DVLOG(2) << __func__; + DCHECK(video_renderer_); + DCHECK_EQ(state_, STATE_PLAYING); video_ended_ = false; - if (state_ == STATE_PLAYING) { - DCHECK(video_renderer_); - video_renderer_->StartPlayingFrom(time); - } + video_renderer_->StartPlayingFrom(time); } void RendererImpl::RestartAudioRenderer(base::TimeDelta time) { + DVLOG(3) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); - DVLOG(2) << __func__; + DCHECK_EQ(state_, STATE_PLAYING); + DCHECK(time_source_); + DCHECK(audio_renderer_); audio_ended_ = false; - if (state_ == STATE_PLAYING) { - DCHECK(time_source_); - DCHECK(audio_renderer_); - audio_renderer_->StartPlaying(); - } + audio_renderer_->StartPlaying(); } void RendererImpl::SetPlaybackRate(double playback_rate) {
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h index 76c496a..0752805f 100644 --- a/media/renderers/renderer_impl.h +++ b/media/renderers/renderer_impl.h
@@ -62,7 +62,9 @@ bool HasAudio() final; bool HasVideo() final; - void RestartStreamPlayback(DemuxerStream* stream, base::TimeDelta time); + void RestartStreamPlayback(DemuxerStream* stream, + bool enabled, + base::TimeDelta time); // Helper functions for testing purposes. Must be called before Initialize(). void DisableUnderflowForTesting();
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc index 62d6f85..1a280e1 100644 --- a/media/renderers/renderer_impl_unittest.cc +++ b/media/renderers/renderer_impl_unittest.cc
@@ -87,7 +87,8 @@ DemuxerStream::Type type) { std::unique_ptr<StrictMock<MockDemuxerStream>> stream( new StrictMock<MockDemuxerStream>(type)); - EXPECT_CALL(*stream, SetStreamRestartedCB(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*stream, SetStreamStatusChangeCB(_)) + .Times(testing::AnyNumber()); return stream; } @@ -713,4 +714,31 @@ base::RunLoop().RunUntilIdle(); } +TEST_F(RendererImplTest, StreamStatusNotificationHandling) { + CreateAudioAndVideoStream(); + + DemuxerStream::StreamStatusChangeCB audio_stream_status_change_cb; + DemuxerStream::StreamStatusChangeCB video_stream_status_change_cb; + EXPECT_CALL(*audio_stream_, SetStreamStatusChangeCB(_)) + .WillOnce(SaveArg<0>(&audio_stream_status_change_cb)); + EXPECT_CALL(*video_stream_, SetStreamStatusChangeCB(_)) + .WillOnce(SaveArg<0>(&video_stream_status_change_cb)); + SetAudioRendererInitializeExpectations(PIPELINE_OK); + SetVideoRendererInitializeExpectations(PIPELINE_OK); + InitializeAndExpect(PIPELINE_OK); + Play(); + + // Verify that DemuxerStream status changes cause the corresponding + // audio/video renderer to be flushed and restarted. + base::TimeDelta time0; + EXPECT_CALL(time_source_, StopTicking()); + EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>()); + EXPECT_CALL(*audio_renderer_, StartPlaying()).Times(1); + audio_stream_status_change_cb.Run(false, time0); + + EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>()); + EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)).Times(1); + video_stream_status_change_cb.Run(false, time0); +} + } // namespace media
diff --git a/mojo/android/javatests/validation_test_util.cc b/mojo/android/javatests/validation_test_util.cc index 69ad15c5..989291d0 100644 --- a/mojo/android/javatests/validation_test_util.cc +++ b/mojo/android/javatests/validation_test_util.cc
@@ -37,7 +37,7 @@ input, &data, &num_handles, &error_message)) { ScopedJavaLocalRef<jstring> j_error_message = base::android::ConvertUTF8ToJavaString(env, error_message); - return Java_ValidationTestUtil_buildData(env, NULL, 0, + return Java_ValidationTestUtil_buildData(env, nullptr, 0, j_error_message.obj()); } void* data_ptr = &data[0]; @@ -47,7 +47,8 @@ } jobject byte_buffer = env->NewDirectByteBuffer(data_ptr, data.size()); - return Java_ValidationTestUtil_buildData(env, byte_buffer, num_handles, NULL); + return Java_ValidationTestUtil_buildData(env, byte_buffer, num_handles, + nullptr); } } // namespace android
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl index 28d6399..3d97ccb7 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl
@@ -48,7 +48,8 @@ {%- endif %} private: - {{class_name}}(); + {{class_name}}() : header_({sizeof(*this), {{struct.versions[-1].version}}}) { + } ~{{class_name}}() = delete; }; static_assert(sizeof({{class_name}}) == {{struct.versions[-1].num_bytes}},
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl index b5f4462..374b097 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl
@@ -68,7 +68,3 @@ return true; } -{{class_name}}::{{class_name}}() { - header_.num_bytes = sizeof(*this); - header_.version = {{struct.versions[-1].version}}; -}
diff --git a/net/BUILD.gn b/net/BUILD.gn index 423bbed3..ec96909 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -380,10 +380,7 @@ if (use_platform_icu_alternatives) { if (is_android) { # Use ICU alternative on Android. - sources += [ - "base/net_string_util_icu_alternatives_android.cc", - "base/net_string_util_icu_alternatives_android.h", - ] + sources += [ "base/net_string_util_icu_alternatives_android.cc" ] deps += [ ":net_jni_headers" ] } else if (is_ios) { # Use ICU alternative on iOS.
diff --git a/net/android/net_jni_registrar.cc b/net/android/net_jni_registrar.cc index 48a1314..dfa5aef 100644 --- a/net/android/net_jni_registrar.cc +++ b/net/android/net_jni_registrar.cc
@@ -14,10 +14,6 @@ #include "net/proxy/proxy_config_service_android.h" #include "url/url_features.h" -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) -#include "net/base/net_string_util_icu_alternatives_android.h" // nogncheck -#endif - namespace net { namespace android { @@ -27,9 +23,6 @@ {"NetworkChangeNotifierAndroid", NetworkChangeNotifierAndroid::Register}, {"ProxyConfigService", ProxyConfigServiceAndroid::Register}, {"X509Util", RegisterX509Util}, -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) - {"NetStringUtils", RegisterNetStringUtils} -#endif }; bool RegisterJni(JNIEnv* env) {
diff --git a/net/base/net_string_util_icu_alternatives_android.cc b/net/base/net_string_util_icu_alternatives_android.cc index 0551a03..237b698 100644 --- a/net/base/net_string_util_icu_alternatives_android.cc +++ b/net/base/net_string_util_icu_alternatives_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/base/net_string_util_icu_alternatives_android.h" - #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/strings/string16.h" @@ -113,8 +111,4 @@ return true; } -bool RegisterNetStringUtils(JNIEnv* env) { - return android::RegisterNativesImpl(env); -} - } // namespace net
diff --git a/net/base/net_string_util_icu_alternatives_android.h b/net/base/net_string_util_icu_alternatives_android.h deleted file mode 100644 index c3a6cf50..0000000 --- a/net/base/net_string_util_icu_alternatives_android.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_NET_STRING_UTIL_ICU_ALTERNATIVES_ANDROID_H_ -#define NET_BASE_NET_STRING_UTIL_ICU_ALTERNATIVES_ANDROID_H_ - -#include <jni.h> - -namespace net { - -// Explicitly register static JNI functions needed when not using ICU. -bool RegisterNetStringUtils(JNIEnv* env); - -} // namespace net - -#endif // NET_BASE_NET_STRING_UTIL_ICU_ALTERNATIVES_ANDROID_H_ -
diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc index c2bd6aa..e22ea9f0 100644 --- a/net/cert/x509_certificate_openssl.cc +++ b/net/cert/x509_certificate_openssl.cc
@@ -180,7 +180,8 @@ X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( OSCertHandle cert_handle) { DCHECK(cert_handle); - return X509_up_ref(cert_handle); + X509_up_ref(cert_handle); + return cert_handle; } // static
diff --git a/net/net.gyp b/net/net.gyp index e630835..ca18939b6 100644 --- a/net/net.gyp +++ b/net/net.gyp
@@ -117,7 +117,6 @@ ['OS == "android"', { 'sources': [ 'base/net_string_util_icu_alternatives_android.cc', - 'base/net_string_util_icu_alternatives_android.h', ], }], ['OS == "ios"', {
diff --git a/net/net.gypi b/net/net.gypi index 19b1d36..9e1397e5 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -1803,6 +1803,8 @@ 'spdy/spdy_http_stream_unittest.cc', 'spdy/spdy_http_utils_unittest.cc', 'spdy/spdy_network_transaction_unittest.cc', + 'spdy/spdy_no_op_visitor.h', + 'spdy/spdy_no_op_visitor.cc', 'spdy/spdy_pinnable_buffer_piece_test.cc', 'spdy/spdy_prefixed_buffer_reader_test.cc', 'spdy/spdy_protocol_test.cc',
diff --git a/net/nqe/effective_connection_type.h b/net/nqe/effective_connection_type.h index 0088c52..6160a4d 100644 --- a/net/nqe/effective_connection_type.h +++ b/net/nqe/effective_connection_type.h
@@ -15,12 +15,6 @@ // EffectiveConnectionType of a network is independent of if the current // connection is metered or not. For example, an unmetered slow connection may // have EFFECTIVE_CONNECTION_TYPE_SLOW_2G as its effective connection type. -// An invalid Java prefix to strip is specified to prevent the Java class -// generator from automatically stripping off the common prefix -// ("EFFECTIVE_CONNECTION_TYPE_"). -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ChromiumEffectiveConnectionType -// GENERATED_JAVA_PREFIX_TO_STRIP: PREFIX_NOT_PRESENT_ enum EffectiveConnectionType { // The connection types should be in increasing order of quality. EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0,
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index dbf4986..96c0f3c9 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -1647,14 +1647,10 @@ // last computed or a connection change event was observed since the last // computation. Strict inequalities are used to ensure that effective // connection type is recomputed on connection change events even if the clock - // has not updated. Recompute the effective connection type if the effective - // connection type was previously unavailable. This is because the RTT - // observations are voluminous, so it may now be possible to compute the - // effective connection type. + // has not updated. if (now - last_effective_connection_type_computation_ < effective_connection_type_recomputation_interval_ && - last_connection_change_ < last_effective_connection_type_computation_ && - effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { + last_connection_change_ < last_effective_connection_type_computation_) { return; } @@ -1669,7 +1665,6 @@ void NetworkQualityEstimator:: NotifyObserversOfEffectiveConnectionTypeChanged() { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); // TODO(tbansal): Add hysteresis in the notification. FOR_EACH_OBSERVER(
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index 5983029..3c0aad5 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -798,17 +798,19 @@ void QuicChromiumClientSession::OnCryptoHandshakeMessageSent( const CryptoHandshakeMessage& message) { logger_->OnCryptoHandshakeMessageSent(message); - - if (message.tag() == kREJ || message.tag() == kSREJ) { - UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.RejectLength", - message.GetSerialized().length(), 1000, 10000, - 50); - } } void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived( const CryptoHandshakeMessage& message) { logger_->OnCryptoHandshakeMessageReceived(message); + if (message.tag() == kREJ || message.tag() == kSREJ) { + UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.RejectLength", + message.GetSerialized().length(), 1000, 10000, + 50); + base::StringPiece proof; + UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.RejectHasProof", + message.GetStringPiece(kPROF, &proof)); + } } void QuicChromiumClientSession::OnGoAway(const QuicGoAwayFrame& frame) {
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index d3cafeb..a805a87a 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -54,6 +54,8 @@ #include "net/socket/socket_performance_watcher_factory.h" #include "net/ssl/token_binding.h" #include "net/udp/udp_client_socket.h" +#include "url/gurl.h" +#include "url/url_constants.h" using std::min; using NetworkHandle = net::NetworkChangeNotifier::NetworkHandle; @@ -167,6 +169,28 @@ return config; } +// An implementation of QuicCryptoClientConfig::ServerIdFilter that wraps +// an |origin_filter|. +class ServerIdOriginFilter : public QuicCryptoClientConfig::ServerIdFilter { + public: + ServerIdOriginFilter(const base::Callback<bool(const GURL&)> origin_filter) + : origin_filter_(origin_filter) {} + + bool Matches(const QuicServerId& server_id) const override { + if (origin_filter_.is_null()) + return true; + + GURL url(base::StringPrintf("%s%s%s:%d", url::kHttpsScheme, + url::kStandardSchemeSeparator, + server_id.host().c_str(), server_id.port())); + DCHECK(url.is_valid()); + return origin_filter_.Run(url); + } + + private: + const base::Callback<bool(const GURL&)> origin_filter_; +}; + } // namespace // Responsible for verifying the certificates saved in @@ -1413,8 +1437,10 @@ return std::move(list); } -void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { - crypto_config_.ClearCachedStates(); +void QuicStreamFactory::ClearCachedStatesInCryptoConfig( + const base::Callback<bool(const GURL&)>& origin_filter) { + ServerIdOriginFilter filter(origin_filter); + crypto_config_.ClearCachedStates(filter); } void QuicStreamFactory::OnIPAddressChanged() {
diff --git a/net/quic/chromium/quic_stream_factory.h b/net/quic/chromium/quic_stream_factory.h index fad86df..4a28209 100644 --- a/net/quic/chromium/quic_stream_factory.h +++ b/net/quic/chromium/quic_stream_factory.h
@@ -264,8 +264,10 @@ std::unique_ptr<base::Value> QuicStreamFactoryInfoToValue() const; - // Delete all cached state objects in |crypto_config_|. - void ClearCachedStatesInCryptoConfig(); + // Delete cached state objects in |crypto_config_|. If |origin_filter| is not + // null, only objects on matching origins will be deleted. + void ClearCachedStatesInCryptoConfig( + const base::Callback<bool(const GURL&)>& origin_filter); // Helper method that configures a DatagramClientSocket. Socket is // bound to the default network if the |network| param is
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index 0528ca2c..165bb0e 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -7,6 +7,8 @@ #include <ostream> #include <utility> +#include "base/bind.h" +#include "base/callback.h" #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -46,6 +48,7 @@ #include "net/test/test_data_directory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" using net::test::IsError; using net::test::IsOk; @@ -4876,5 +4879,52 @@ EXPECT_TRUE(AllDataConsumed()); } +// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig +// correctly transform an origin filter to a ServerIdFilter. Whether the +// deletion itself works correctly is tested in QuicCryptoClientConfigTest. +TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) { + Initialize(); + QuicCryptoClientConfig* crypto_config = + QuicStreamFactoryPeer::GetCryptoConfig(factory_.get()); + + struct TestCase { + TestCase(const std::string& host, + int port, + PrivacyMode privacy_mode, + QuicCryptoClientConfig* crypto_config) + : server_id(host, port, privacy_mode), + state(crypto_config->LookupOrCreate(server_id)) { + vector<string> certs(1); + certs[0] = "cert"; + state->SetProof(certs, "cert_sct", "chlo_hash", "signature"); + state->set_source_address_token("TOKEN"); + state->SetProofValid(); + + EXPECT_FALSE(state->certs().empty()); + } + + QuicServerId server_id; + QuicCryptoClientConfig::CachedState* state; + } test_cases[] = { + TestCase("www.google.com", 443, privacy_mode_, crypto_config), + TestCase("www.example.com", 443, privacy_mode_, crypto_config), + TestCase("www.example.com", 4433, privacy_mode_, crypto_config)}; + + // Clear cached states for the origin https://www.example.com:4433. + GURL origin("https://www.example.com:4433"); + factory_->ClearCachedStatesInCryptoConfig( + base::Bind(&GURL::operator==, base::Unretained(&origin))); + EXPECT_FALSE(test_cases[0].state->certs().empty()); + EXPECT_FALSE(test_cases[1].state->certs().empty()); + EXPECT_TRUE(test_cases[2].state->certs().empty()); + + // Clear all cached states. + factory_->ClearCachedStatesInCryptoConfig( + base::Callback<bool(const GURL&)>()); + EXPECT_TRUE(test_cases[0].state->certs().empty()); + EXPECT_TRUE(test_cases[1].state->certs().empty()); + EXPECT_TRUE(test_cases[2].state->certs().empty()); +} + } // namespace test } // namespace net
diff --git a/net/quic/core/crypto/quic_crypto_client_config.cc b/net/quic/core/crypto/quic_crypto_client_config.cc index bf67be53..47c03a7 100644 --- a/net/quic/core/crypto/quic_crypto_client_config.cc +++ b/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -400,10 +400,11 @@ return cached; } -void QuicCryptoClientConfig::ClearCachedStates() { +void QuicCryptoClientConfig::ClearCachedStates(const ServerIdFilter& filter) { for (CachedStateMap::const_iterator it = cached_states_.begin(); it != cached_states_.end(); ++it) { - it->second->Clear(); + if (filter.Matches(it->first)) + it->second->Clear(); } }
diff --git a/net/quic/core/crypto/quic_crypto_client_config.h b/net/quic/core/crypto/quic_crypto_client_config.h index 56f996f..b671793 100644 --- a/net/quic/core/crypto/quic_crypto_client_config.h +++ b/net/quic/core/crypto/quic_crypto_client_config.h
@@ -194,6 +194,13 @@ DISALLOW_COPY_AND_ASSIGN(CachedState); }; + // Used to filter server ids for partial config deletion. + class ServerIdFilter { + public: + // Returns true if |server_id| matches the filter. + virtual bool Matches(const QuicServerId& server_id) const = 0; + }; + explicit QuicCryptoClientConfig( std::unique_ptr<ProofVerifier> proof_verifier); ~QuicCryptoClientConfig(); @@ -202,8 +209,9 @@ // CachedState currently exists, it will be created and cached. CachedState* LookupOrCreate(const QuicServerId& server_id); - // Delete all CachedState objects from cached_states_. - void ClearCachedStates(); + // Delete CachedState objects whose server ids match |filter| from + // cached_states. + void ClearCachedStates(const ServerIdFilter& filter); // FillInchoateClientHello sets |out| to be a CHLO message that elicits a // source-address token or SCFG from a server. If |cached| is non-nullptr, the
diff --git a/net/quic/core/crypto/quic_crypto_client_config_test.cc b/net/quic/core/crypto/quic_crypto_client_config_test.cc index c4656972..9555dd1 100644 --- a/net/quic/core/crypto/quic_crypto_client_config_test.cc +++ b/net/quic/core/crypto/quic_crypto_client_config_test.cc
@@ -27,6 +27,23 @@ } }; +class OneServerIdFilter : public QuicCryptoClientConfig::ServerIdFilter { + public: + OneServerIdFilter(const QuicServerId* server_id) : server_id_(*server_id) {} + + bool Matches(const QuicServerId& server_id) const override { + return server_id == server_id_; + } + + private: + const QuicServerId server_id_; +}; + +class AllServerIdsFilter : public QuicCryptoClientConfig::ServerIdFilter { + public: + bool Matches(const QuicServerId& server_id) const override { return true; } +}; + } // namespace TEST(QuicCryptoClientConfigTest, CachedState_IsEmpty) { @@ -325,36 +342,88 @@ TEST(QuicCryptoClientConfigTest, ClearCachedStates) { QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); - QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); - QuicCryptoClientConfig::CachedState* state = config.LookupOrCreate(server_id); - // TODO(rch): Populate other fields of |state|. - vector<string> certs(1); - certs[0] = "Hello Cert"; - state->SetProof(certs, "cert_sct", "chlo_hash", "signature"); - state->set_source_address_token("TOKEN"); - state->SetProofValid(); - EXPECT_EQ(1u, state->generation_counter()); + + // Create two states on different origins. + struct TestCase { + TestCase(const std::string& host, QuicCryptoClientConfig* config) + : server_id(host, 443, PRIVACY_MODE_DISABLED), + state(config->LookupOrCreate(server_id)) { + // TODO(rch): Populate other fields of |state|. + CryptoHandshakeMessage scfg; + scfg.set_tag(kSCFG); + uint64_t future = 1; + scfg.SetValue(kEXPY, future); + scfg.SetStringPiece(kSCID, "12345678"); + string details; + state->SetServerConfig(scfg.GetSerialized().AsStringPiece(), + QuicWallTime::FromUNIXSeconds(0), &details); + + vector<string> certs(1); + certs[0] = "Hello Cert for " + host; + state->SetProof(certs, "cert_sct", "chlo_hash", "signature"); + state->set_source_address_token("TOKEN"); + state->SetProofValid(); + + // The generation counter starts at 2, because proof has been once + // invalidated in SetServerConfig(). + EXPECT_EQ(2u, state->generation_counter()); + } + + QuicServerId server_id; + QuicCryptoClientConfig::CachedState* state; + } test_cases[] = {TestCase("www.google.com", &config), + TestCase("www.example.com", &config)}; // Verify LookupOrCreate returns the same data. - QuicCryptoClientConfig::CachedState* other = config.LookupOrCreate(server_id); + for (const TestCase& test_case : test_cases) { + QuicCryptoClientConfig::CachedState* other = + config.LookupOrCreate(test_case.server_id); + EXPECT_EQ(test_case.state, other); + EXPECT_EQ(2u, other->generation_counter()); + } - EXPECT_EQ(state, other); - EXPECT_EQ(1u, other->generation_counter()); + // Clear the cached state for www.google.com. + OneServerIdFilter google_com_filter(&test_cases[0].server_id); + config.ClearCachedStates(google_com_filter); - // Clear the cached states. - config.ClearCachedStates(); - - // Verify LookupOrCreate doesn't have any data. + // Verify LookupOrCreate doesn't have any data for google.com. QuicCryptoClientConfig::CachedState* cleared_cache = - config.LookupOrCreate(server_id); + config.LookupOrCreate(test_cases[0].server_id); - EXPECT_EQ(state, cleared_cache); + EXPECT_EQ(test_cases[0].state, cleared_cache); EXPECT_FALSE(cleared_cache->proof_valid()); EXPECT_TRUE(cleared_cache->server_config().empty()); EXPECT_TRUE(cleared_cache->certs().empty()); EXPECT_TRUE(cleared_cache->cert_sct().empty()); EXPECT_TRUE(cleared_cache->signature().empty()); - EXPECT_EQ(2u, cleared_cache->generation_counter()); + EXPECT_EQ(3u, cleared_cache->generation_counter()); + + // But it still does for www.example.com. + QuicCryptoClientConfig::CachedState* existing_cache = + config.LookupOrCreate(test_cases[1].server_id); + + EXPECT_EQ(test_cases[1].state, existing_cache); + EXPECT_TRUE(existing_cache->proof_valid()); + EXPECT_FALSE(existing_cache->server_config().empty()); + EXPECT_FALSE(existing_cache->certs().empty()); + EXPECT_FALSE(existing_cache->cert_sct().empty()); + EXPECT_FALSE(existing_cache->signature().empty()); + EXPECT_EQ(2u, existing_cache->generation_counter()); + + // Clear all cached states. + AllServerIdsFilter all_server_ids; + config.ClearCachedStates(all_server_ids); + + // The data for www.example.com should now be cleared as well. + cleared_cache = config.LookupOrCreate(test_cases[1].server_id); + + EXPECT_EQ(test_cases[1].state, cleared_cache); + EXPECT_FALSE(cleared_cache->proof_valid()); + EXPECT_TRUE(cleared_cache->server_config().empty()); + EXPECT_TRUE(cleared_cache->certs().empty()); + EXPECT_TRUE(cleared_cache->cert_sct().empty()); + EXPECT_TRUE(cleared_cache->signature().empty()); + EXPECT_EQ(3u, cleared_cache->generation_counter()); } TEST(QuicCryptoClientConfigTest, ProcessReject) {
diff --git a/net/spdy/spdy_headers_handler_interface.h b/net/spdy/spdy_headers_handler_interface.h index 99944c67..2c48abfe 100644 --- a/net/spdy/spdy_headers_handler_interface.h +++ b/net/spdy/spdy_headers_handler_interface.h
@@ -28,7 +28,7 @@ virtual void OnHeader(base::StringPiece key, base::StringPiece value) = 0; // A callback method which notifies when the parser finishes handling a - // header block (i.e. the containing frame has the END_STREAM flag set). + // header block (i.e. the containing frame has the END_HEADERS flag set). // Also indicates the total number of bytes in this block. virtual void OnHeaderBlockEnd(size_t uncompressed_header_bytes) = 0; };
diff --git a/net/spdy/spdy_no_op_visitor.cc b/net/spdy/spdy_no_op_visitor.cc new file mode 100644 index 0000000..b9ac395 --- /dev/null +++ b/net/spdy/spdy_no_op_visitor.cc
@@ -0,0 +1,34 @@ +// Copyright (c) 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. + +#include "net/spdy/spdy_no_op_visitor.h" + +#include <type_traits> + +namespace net { +namespace test { + +SpdyNoOpVisitor::SpdyNoOpVisitor() { + static_assert(std::is_abstract<SpdyNoOpVisitor>::value == false, + "Need to update SpdyNoOpVisitor."); +} +SpdyNoOpVisitor::~SpdyNoOpVisitor() {} + +net::SpdyHeadersHandlerInterface* SpdyNoOpVisitor::OnHeaderFrameStart( + SpdyStreamId stream_id) { + return this; +} + +bool SpdyNoOpVisitor::OnControlFrameHeaderData(SpdyStreamId stream_id, + const char* header_data, + size_t header_data_len) { + return true; +} + +bool SpdyNoOpVisitor::OnUnknownFrame(SpdyStreamId stream_id, int frame_type) { + return true; +} + +} // namespace test +} // namespace net
diff --git a/net/spdy/spdy_no_op_visitor.h b/net/spdy/spdy_no_op_visitor.h new file mode 100644 index 0000000..e2cba101 --- /dev/null +++ b/net/spdy/spdy_no_op_visitor.h
@@ -0,0 +1,95 @@ +// Copyright (c) 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. +// +// SpdyNoOpVisitor implements several of the visitor and handler interfaces +// to make it easier to write tests that need to provide instances. Other +// interfaces can be added as needed. + +#ifndef NET_SPDY_SPDY_NO_OP_VISITOR_H_ +#define NET_SPDY_SPDY_NO_OP_VISITOR_H_ + +#include "net/spdy/spdy_framer.h" +#include "net/spdy/spdy_protocol.h" + +namespace net { +namespace test { + +class SpdyNoOpVisitor : public SpdyFramerVisitorInterface, + public SpdyFramerDebugVisitorInterface, + public SpdyHeadersHandlerInterface { + public: + SpdyNoOpVisitor(); + ~SpdyNoOpVisitor() override; + + // SpdyFramerVisitorInterface methods: + void OnError(SpdyFramer* framer) override {} + void OnSynStream(SpdyStreamId stream_id, + SpdyStreamId associated_stream_id, + SpdyPriority priority, + bool fin, + bool unidirectional) override {} + void OnSynReply(SpdyStreamId stream_id, bool fin) override {} + net::SpdyHeadersHandlerInterface* OnHeaderFrameStart( + SpdyStreamId stream_id) override; + void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override {} + bool OnControlFrameHeaderData(SpdyStreamId stream_id, + const char* header_data, + size_t header_data_len) override; + void OnDataFrameHeader(SpdyStreamId stream_id, + size_t length, + bool fin) override {} + void OnStreamFrameData(SpdyStreamId stream_id, + const char* data, + size_t len) override {} + void OnStreamEnd(SpdyStreamId stream_id) override {} + void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {} + void OnRstStream(SpdyStreamId stream_id, + SpdyRstStreamStatus status) override {} + void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {} + void OnPing(SpdyPingId unique_id, bool is_ack) override {} + void OnSettingsEnd() override {} + void OnSettingsAck() override {} + void OnGoAway(SpdyStreamId last_accepted_stream_id, + SpdyGoAwayStatus status) override {} + void OnHeaders(SpdyStreamId stream_id, + bool has_priority, + int weight, + SpdyStreamId parent_stream_id, + bool exclusive, + bool fin, + bool end) override {} + void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {} + void OnPushPromise(SpdyStreamId stream_id, + SpdyStreamId promised_stream_id, + bool end) override {} + void OnContinuation(SpdyStreamId stream_id, bool end) override {} + void OnAltSvc(SpdyStreamId stream_id, + base::StringPiece origin, + const SpdyAltSvcWireFormat::AlternativeServiceVector& + altsvc_vector) override {} + void OnPriority(SpdyStreamId stream_id, + SpdyStreamId parent_stream_id, + int weight, + bool exclusive) override {} + bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override; + + // SpdyFramerDebugVisitorInterface methods: + void OnSendCompressedFrame(SpdyStreamId stream_id, + SpdyFrameType type, + size_t payload_len, + size_t frame_len) override {} + void OnReceiveCompressedFrame(SpdyStreamId stream_id, + SpdyFrameType type, + size_t frame_len) override {} + + // SpdyHeadersHandlerInterface methods: + void OnHeaderBlockStart() override {} + void OnHeader(base::StringPiece key, base::StringPiece value) override {} + void OnHeaderBlockEnd(size_t uncompressed_header_bytes) override {} +}; + +} // namespace test +} // namespace net + +#endif // NET_SPDY_SPDY_NO_OP_VISITOR_H_
diff --git a/net/ssl/ssl_client_session_cache.cc b/net/ssl/ssl_client_session_cache.cc index 650d989..28a33da1 100644 --- a/net/ssl/ssl_client_session_cache.cc +++ b/net/ssl/ssl_client_session_cache.cc
@@ -45,7 +45,10 @@ cache_.Erase(iter); return nullptr; } - return ScopedSSL_SESSION(SSL_SESSION_up_ref(iter->second->session.get())); + + SSL_SESSION* session = iter->second->session.get(); + SSL_SESSION_up_ref(session); + return ScopedSSL_SESSION(session); } void SSLClientSessionCache::Insert(const std::string& cache_key, @@ -54,7 +57,8 @@ // Make a new entry. std::unique_ptr<CacheEntry> entry(new CacheEntry); - entry->session.reset(SSL_SESSION_up_ref(session)); + SSL_SESSION_up_ref(session); + entry->session.reset(session); entry->creation_time = clock_->Now(); // Takes ownership.
diff --git a/net/test/run_all_unittests.cc b/net/test/run_all_unittests.cc index 0a4df22..15116aa 100644 --- a/net/test/run_all_unittests.cc +++ b/net/test/run_all_unittests.cc
@@ -17,10 +17,6 @@ #include "base/android/jni_registrar.h" #include "net/android/dummy_spnego_authenticator.h" #include "net/android/net_jni_registrar.h" -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) -#include "url/android/url_jni_registrar.h" // nogncheck -#endif - #endif #if !defined(OS_ANDROID) && !defined(OS_IOS) @@ -39,9 +35,6 @@ {"DummySpnegoAuthenticator", net::android::DummySpnegoAuthenticator::RegisterJni}, {"NetAndroid", net::android::RegisterJni}, -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) - {"UrlAndroid", url::android::RegisterJni}, -#endif }; // Register JNI bindings for android. Doing it early as the test suite setup
diff --git a/services/shell/service_manager.cc b/services/shell/service_manager.cc index 90893f5..f23222f 100644 --- a/services/shell/service_manager.cc +++ b/services/shell/service_manager.cc
@@ -281,7 +281,8 @@ params->set_local_interfaces(std::move(local_interfaces)); params->set_client_process_connection(std::move(client_process_connection)); params->set_connect_callback(callback); - service_manager_->Connect(std::move(params)); + service_manager_->Connect( + std::move(params), nullptr, weak_factory_.GetWeakPtr()); } void Clone(mojom::ConnectorRequest request) override { @@ -517,7 +518,7 @@ } void ServiceManager::Connect(std::unique_ptr<ConnectParams> params) { - Connect(std::move(params), nullptr); + Connect(std::move(params), nullptr, nullptr); } mojom::ServiceRequest ServiceManager::StartEmbedderService( @@ -530,7 +531,7 @@ mojom::ServicePtr service; mojom::ServiceRequest request = mojo::GetProxy(&service); - Connect(std::move(params), std::move(service)); + Connect(std::move(params), std::move(service), nullptr); return request; } @@ -605,7 +606,8 @@ } void ServiceManager::Connect(std::unique_ptr<ConnectParams> params, - mojom::ServicePtr service) { + mojom::ServicePtr service, + base::WeakPtr<Instance> source_instance) { TRACE_EVENT_INSTANT1("mojo_shell", "ServiceManager::Connect", TRACE_EVENT_SCOPE_THREAD, "original_name", params->target().name()); @@ -629,7 +631,8 @@ resolver->ResolveMojoName( name, base::Bind(&shell::ServiceManager::OnGotResolvedName, weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms), - base::Passed(&service))); + base::Passed(&service), !!source_instance, + source_instance)); } ServiceManager::Instance* ServiceManager::GetExistingInstance( @@ -727,7 +730,14 @@ void ServiceManager::OnGotResolvedName(std::unique_ptr<ConnectParams> params, mojom::ServicePtr service, + bool has_source_instance, + base::WeakPtr<Instance> source_instance, mojom::ResolveResultPtr result) { + // If this request was originated by a specific Instance and that Instance is + // no longer around, we ignore this response. + if (has_source_instance && !source_instance) + return; + std::string instance_name = params->target().instance(); if (instance_name == GetNamePath(params->target().name()) && result->qualifier != GetNamePath(result->resolved_name)) { @@ -790,8 +800,7 @@ instance->StartWithService(std::move(service)); Identity factory(result->resolved_name, target.user_id(), instance_name); - CreateServiceWithFactory(factory, target.name(), - std::move(request)); + CreateServiceWithFactory(factory, target.name(), std::move(request)); } else { instance->StartWithFilePath(result->package_path); }
diff --git a/services/shell/service_manager.h b/services/shell/service_manager.h index b6226f1..d6e6b5d73 100644 --- a/services/shell/service_manager.h +++ b/services/shell/service_manager.h
@@ -102,8 +102,13 @@ // If |service| is not null, there must not be an instance of the target // application already running. The Service Manager will create a new instance // and use |service| to control it. + // + // If |instance| is not null, the lifetime of the connection request is + // bounded by that of |instance|. The connection will be cancelled dropped if + // |instance| is destroyed. void Connect(std::unique_ptr<ConnectParams> params, - mojom::ServicePtr service); + mojom::ServicePtr service, + base::WeakPtr<Instance> source_instance); // Returns a running instance matching |identity|. This might be an instance // running as a different user if one is available that services all users. @@ -139,6 +144,8 @@ // |result| contains the result of the resolve operation. void OnGotResolvedName(std::unique_ptr<ConnectParams> params, mojom::ServicePtr service, + bool has_source_instance, + base::WeakPtr<Instance> source_instance, mojom::ResolveResultPtr result); base::WeakPtr<ServiceManager> GetWeakPtr();
diff --git a/services/ui/common/gpu_service.cc b/services/ui/common/gpu_service.cc index f8bf9e79..9a2f4c56 100644 --- a/services/ui/common/gpu_service.cc +++ b/services/ui/common/gpu_service.cc
@@ -47,21 +47,18 @@ GpuService::~GpuService() { DCHECK(IsMainThread()); + DCHECK_EQ(this, g_gpu_service); if (gpu_channel_) gpu_channel_->DestroyChannel(); + g_gpu_service = nullptr; } // static -void GpuService::Initialize(shell::Connector* connector) { +std::unique_ptr<GpuService> GpuService::Initialize( + shell::Connector* connector) { DCHECK(!g_gpu_service); g_gpu_service = new GpuService(connector); -} - -// static -void GpuService::Terminate() { - DCHECK(g_gpu_service); - delete g_gpu_service; - g_gpu_service = nullptr; + return base::WrapUnique(g_gpu_service); } // static
diff --git a/services/ui/common/gpu_service.h b/services/ui/common/gpu_service.h index 7308754..d00a60c 100644 --- a/services/ui/common/gpu_service.h +++ b/services/ui/common/gpu_service.h
@@ -27,6 +27,8 @@ class MUS_COMMON_EXPORT GpuService : public gpu::GpuChannelHostFactory { public: + ~GpuService() override; + void EstablishGpuChannel(const base::Closure& callback); scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(); scoped_refptr<gpu::GpuChannelHost> GetGpuChannel(); @@ -36,16 +38,13 @@ // The GpuService has to be initialized in the main thread before establishing // the gpu channel. - static void Initialize(shell::Connector* connector); - // The GpuService has to be terminated in the main thread. - static void Terminate(); + static std::unique_ptr<GpuService> Initialize(shell::Connector* connector); static GpuService* GetInstance(); private: friend struct base::DefaultSingletonTraits<GpuService>; explicit GpuService(shell::Connector* connector); - ~GpuService() override; scoped_refptr<gpu::GpuChannelHost> GetGpuChannelLocked(); void EstablishGpuChannelOnMainThread();
diff --git a/services/ui/demo/mus_demo.cc b/services/ui/demo/mus_demo.cc index 89b601e..3710de8d 100644 --- a/services/ui/demo/mus_demo.cc +++ b/services/ui/demo/mus_demo.cc
@@ -65,7 +65,7 @@ } void MusDemo::OnStart(const shell::Identity& identity) { - GpuService::Initialize(connector()); + gpu_service_ = GpuService::Initialize(connector()); window_tree_client_ = new WindowTreeClient(this, this, nullptr); window_tree_client_->ConnectAsWindowManager(connector()); }
diff --git a/services/ui/demo/mus_demo.h b/services/ui/demo/mus_demo.h index 8957cc4..78dbde7 100644 --- a/services/ui/demo/mus_demo.h +++ b/services/ui/demo/mus_demo.h
@@ -21,6 +21,8 @@ namespace ui { class BitmapUploader; +class GpuService; + namespace demo { // A simple MUS Demo mojo app. This app connects to the mojo:ui, creates a new @@ -69,6 +71,7 @@ Window* window_ = nullptr; WindowTreeClient* window_tree_client_ = nullptr; + std::unique_ptr<GpuService> gpu_service_; // Used to send frames to mus. std::unique_ptr<ui::BitmapUploader> uploader_;
diff --git a/services/ui/surfaces/display_compositor.cc b/services/ui/surfaces/display_compositor.cc index 1f38c4f8..5cb51a1 100644 --- a/services/ui/surfaces/display_compositor.cc +++ b/services/ui/surfaces/display_compositor.cc
@@ -121,4 +121,16 @@ void DisplayCompositor::DisplaySetMemoryPolicy( const cc::ManagedMemoryPolicy& policy) {} +void DisplayCompositor::DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const cc::RenderPassList& render_passes) { + // This notification is not relevant to our client outside of tests. +} + +void DisplayCompositor::DisplayDidDrawAndSwap() { + // This notification is not relevant to our client outside of tests. We + // unblock the client from the DrawCallback when the surface is going to + // be drawn. +} + } // namespace ui
diff --git a/services/ui/surfaces/display_compositor.h b/services/ui/surfaces/display_compositor.h index 13019cb1..dfeed0d 100644 --- a/services/ui/surfaces/display_compositor.h +++ b/services/ui/surfaces/display_compositor.h
@@ -60,6 +60,9 @@ // DisplayClient implementation. void DisplayOutputSurfaceLost() override; void DisplaySetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override; + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const cc::RenderPassList& render_passes) override; + void DisplayDidDrawAndSwap() override; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<SurfacesState> surfaces_state_;
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index d70e33cb..1e9e202 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -470,19 +470,6 @@ "test": "sql_unittests" }, { - "override_isolate_target": "sync_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_type": "bullhead" - } - ] - }, - "test": "sync_unit_tests" - }, - { "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, @@ -1021,19 +1008,6 @@ "test": "sql_unittests" }, { - "override_isolate_target": "sync_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "device_os": "KTU84P", - "device_type": "hammerhead" - } - ] - }, - "test": "sync_unit_tests" - }, - { "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, @@ -1183,9 +1157,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1290,9 +1261,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1400,9 +1368,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1518,9 +1483,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1631,9 +1593,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1741,9 +1700,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1857,9 +1813,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1967,9 +1920,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index d41b2de..79baad8 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -335,12 +335,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_arc_unittests" }, { @@ -701,12 +695,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_arc_unittests" }, { @@ -1029,12 +1017,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_arc_unittests" }, {
diff --git a/testing/buildbot/chromium.full.json b/testing/buildbot/chromium.full.json index 29f26fd..cd4c928 100644 --- a/testing/buildbot/chromium.full.json +++ b/testing/buildbot/chromium.full.json
@@ -363,12 +363,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -662,12 +656,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -919,12 +907,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 82291b04..76288d5 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -113,12 +113,6 @@ "args": [ "--tool=asan" ], - "test": "sync_unit_tests" - }, - { - "args": [ - "--tool=asan" - ], "test": "ui_android_unittests" }, { @@ -608,19 +602,6 @@ "test": "sql_unittests" }, { - "override_isolate_target": "sync_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "4", - "device_type": "gce_x86" - } - ] - }, - "test": "sync_unit_tests" - }, - { "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, @@ -789,9 +770,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -1168,12 +1146,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -1530,12 +1502,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -1708,9 +1674,6 @@ "test": "sync_integration_tests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_base_unittests" }, { @@ -1859,9 +1822,6 @@ "test": "sync_integration_tests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_base_unittests" }, { @@ -2041,9 +2001,6 @@ "test": "sync_integration_tests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_base_unittests" }, { @@ -2341,12 +2298,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -2617,12 +2568,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -2905,12 +2850,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -3378,12 +3317,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -3699,12 +3632,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -3968,12 +3895,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -4231,12 +4152,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -4494,12 +4409,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -4757,12 +4666,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -5020,12 +4923,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -5283,12 +5180,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -5534,12 +5425,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -5773,12 +5658,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -5999,12 +5878,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -6244,12 +6117,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -6507,12 +6374,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -6770,12 +6631,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -7033,12 +6888,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -7296,12 +7145,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -7559,12 +7402,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -7822,12 +7659,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -8085,12 +7916,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -8342,12 +8167,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -8605,12 +8424,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -8969,12 +8782,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -9310,12 +9117,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -9534,9 +9335,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_base_unittests" }, { @@ -9860,12 +9658,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -10078,9 +9870,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_base_unittests" }, { @@ -10904,12 +10693,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -11161,12 +10944,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index bba53a4..0b362e0 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -514,20 +514,6 @@ "test": "sql_unittests" }, { - "override_isolate_target": "sync_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "4", - "device_os": "KTU84P", - "device_type": "hammerhead" - } - ] - }, - "test": "sync_unit_tests" - }, - { "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, @@ -744,9 +730,6 @@ "test": "sql_unittests" }, { - "test": "sync_unit_tests" - }, - { "test": "ui_android_unittests" }, { @@ -976,12 +959,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -1425,12 +1402,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "test_ime_unittests" }, { @@ -1879,12 +1850,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "test_ime_unittests" }, { @@ -2252,12 +2217,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index e24c3187..05e39bf 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -13,7 +13,6 @@ "printing_unittests", "skia_unittests", "sql_unittests", - "sync_unit_tests", "ui_base_unittests", "unit_tests", "url_unittests" @@ -295,12 +294,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -634,12 +627,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -974,12 +961,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -1302,12 +1283,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.memory.full.json b/testing/buildbot/chromium.memory.full.json index 29f26fd..cd4c928 100644 --- a/testing/buildbot/chromium.memory.full.json +++ b/testing/buildbot/chromium.memory.full.json
@@ -363,12 +363,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -662,12 +656,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -919,12 +907,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json index 29f26fd..cd4c928 100644 --- a/testing/buildbot/chromium.memory.fyi.json +++ b/testing/buildbot/chromium.memory.fyi.json
@@ -363,12 +363,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -662,12 +656,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -919,12 +907,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 6917cf03..75ec9bc 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -218,12 +218,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -513,12 +507,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_arc_unittests" }, { @@ -731,12 +719,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 40dc302..9cd38f8 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -418,12 +418,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -875,12 +869,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -1363,12 +1351,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, { @@ -1765,12 +1747,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "sync_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "ui_base_unittests" }, {
diff --git a/testing/buildbot/chromium_memory_trybot.json b/testing/buildbot/chromium_memory_trybot.json index c7453442..ccc8226 100644 --- a/testing/buildbot/chromium_memory_trybot.json +++ b/testing/buildbot/chromium_memory_trybot.json
@@ -125,7 +125,6 @@ }, "skia_unittests", "sql_unittests", - "sync_unit_tests", "ui_base_unittests", { "swarming": {
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json index 7d6121c..bf13927f 100644 --- a/testing/buildbot/client.v8.fyi.json +++ b/testing/buildbot/client.v8.fyi.json
@@ -50,7 +50,6 @@ "skia_unittests", "sql_unittests", "sync_integration_tests", - "sync_unit_tests", "ui_base_unittests", "ui_touch_selection_unittests", "unit_tests",
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 23a140d..c143fd6 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -539,10 +539,6 @@ "label": "//chrome/test:sync_integration_tests", "type": "windowed_test_launcher", }, - "sync_unit_tests": { - "label": "//components/sync:sync_unit_tests", - "type": "console_test_launcher", - }, "tab_capture_end2end_tests": { "label": "//chrome/test:browser_tests", "type": "gpu_browser_test",
diff --git a/testing/buildbot/tryserver.v8.json b/testing/buildbot/tryserver.v8.json index 09adc1a4..bdb04a0 100644 --- a/testing/buildbot/tryserver.v8.json +++ b/testing/buildbot/tryserver.v8.json
@@ -50,7 +50,6 @@ "skia_unittests", "sql_unittests", "sync_integration_tests", - "sync_unit_tests", "ui_base_unittests", "ui_touch_selection_unittests", "unit_tests",
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 19fdc070..ccf99cbd 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -633,6 +633,7 @@ # These tests fail / timeout until https://www.chromestatus.com/features/5643236399906816 ships crbug.com/621515 inspector/sources/debugger-async/async-await/async-callstack-async-await1.html [ Skip ] crbug.com/621515 inspector/sources/debugger-async/async-await/async-callstack-async-await2.html [ Skip ] +crbug.com/621515 inspector/sources/debugger-async/async-await/async-callstack-async-await3.html [ Skip ] # These tests pass but images do not match because of position: absolute in vertical flow bug crbug.com/492664 imported/csswg-test/css-writing-modes-3/block-flow-direction-vrl-009.xht [ Failure ] @@ -928,6 +929,97 @@ crbug.com/619060 imported/wpt/pointerevents/pointerevent_pointerleave_after_pointerup_nohover-manual.html [ Skip ] crbug.com/619060 imported/wpt/pointerevents/pointerevent_pointerleave_touch-manual.html [ Skip ] +crbug.com/451090 compositing/squashing/remove-squashed-layer-plus-move.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/abspos-shift-image-incorrect-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/align-content-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/align-content-distribution-change-grid.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/align-content-position-change-grid.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/align-self-change-grid.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/align-self-overflow-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/background-generated.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/background-resize-height.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/background-shorthand-with-gradient-and-height-changes.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/background-size-auto-with-gradient-and-height-changes.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/block-shift-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/border-radius-repaint-2.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/box-inline-resize.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/box-shadow-dynamic.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/clipped-overflow-visible-subtree.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/clipped-relative.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/content-into-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/crbug-371640-2.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/crbug-371640-3.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/crbug-371640-4.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/crbug-371640.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/dynamic-table-vertical-alignment-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/erase-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/fixed-and-absolute-position-scrolled.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/float-move-during-layout.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/float-overflow-right.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/float-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/intermediate-layout-position.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/justify-content-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/justify-content-distribution-change-grid.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/justify-content-position-change-grid.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/justify-content-position-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/justify-self-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/justify-self-overflow-change.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/layout-state-only-positioned.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/offset-change-wrong-invalidation-with-float.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/outline-child-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/overflow-into-content.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/paint-invalidation-with-reparent-across-frame-boundaries.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/percent-size-image-resize-container.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/positioned-document-element.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/positioned-great-grandparent-change-location.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/positioned-list-offset-change-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/reflection-repaint-test.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/relative-margin-change-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/repaint-descandant-on-ancestor-layer-move.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/repaint-resized-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/repaint-table-row-in-composited-document.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/replaced-clipped-positioned-not-wrong-incremental-repainting.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/resize-child-within-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/scrollbar-damage-and-full-viewport-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/selection-after-remove.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/selection-change-in-iframe-with-relative-parent.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/selection-clear.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/shift-relative-positioned-container-with-image-addition.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/shift-relative-positioned-container-with-image-removal.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/table-cell-move.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/table-section-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/table-section-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/table-shrink-row-repaint.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/text-selection-rect-in-overflow.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/text-selection-rect-in-overflow-2.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/transform-disable-layoutstate.html [ NeedsRebaseline ] +crbug.com/451090 fast/repaint/window-resize-vertical-writing-mode.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/border-collapsing/cached-change-cell-border-width.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/border-collapsing/cached-change-col-border-width.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/border-collapsing/cached-change-row-border-width.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/border-collapsing/cached-change-tbody-border-width.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/resize-table-repaint-percent-size-cell.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/resize-table-repaint-vertical-align-cell.html [ NeedsRebaseline ] +crbug.com/451090 fast/table/resize-table-row-repaint.html [ NeedsRebaseline ] +crbug.com/451090 paint/selection/invalidation-rect-includes-newline-for-rtl.html [ NeedsRebaseline ] +crbug.com/451090 paint/selection/invalidation-rect-with-br-includes-newline.html [ NeedsRebaseline ] +crbug.com/451090 svg/as-object/deep-nested-embedded-svg-size-changes-no-layout-triggers-1.html [ NeedsRebaseline ] +crbug.com/451090 svg/as-object/deep-nested-embedded-svg-size-changes-no-layout-triggers-2.html [ NeedsRebaseline ] +crbug.com/451090 svg/as-object/nested-embedded-svg-size-changes-no-layout-triggers-1.html [ NeedsRebaseline ] +crbug.com/451090 svg/as-object/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ NeedsRebaseline ] +crbug.com/451090 svg/custom/object-sizing-no-width-height-change-content-box-size.xhtml [ NeedsRebaseline ] +crbug.com/451090 svg/custom/resource-client-removal.svg [ NeedsRebaseline ] +crbug.com/451090 svg/filters/filter-refresh.svg [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/filter-child-repaint.svg [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/image-with-clip-path.svg [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/inner-svg-change-viewPort-relative.svg [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/paintorder-filtered.svg [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/text-pattern-update-2.html [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/text-pattern-update.html [ NeedsRebaseline ] +crbug.com/451090 svg/repaint/tspan-pattern-update.html [ NeedsRebaseline ] +crbug.com/451090 svg/text/text-rescale.html [ NeedsRebaseline ] +crbug.com/451090 svg/text/text-viewbox-rescale.html [ NeedsManualRebaseline ] + crbug.com/627341 imported/wpt/pointerevents/pointerevent_suppress_compat_events_on_click.html [ Skip ] crbug.com/627341 imported/wpt/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html [ Skip ] crbug.com/627341 imported/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html [ Skip ] @@ -1110,7 +1202,8 @@ crbug.com/619103 paint/invalidation/animated-gif.html [ Pass Failure ] crbug.com/619103 paint/invalidation/animated-gif-background.html [ Pass Failure ] crbug.com/619103 paint/invalidation/animated-gif-background-offscreen.html [ Pass Failure ] -crbug.com/619103 [ Win ] svg/text/text-viewbox-rescale.html [ Pass Failure ] +# TODO(wangxianzhu): Restore the following line after manual rebaseline. +# crbug.com/619103 [ Win ] svg/text/text-viewbox-rescale.html [ Pass Failure ] crbug.com/619103 paint/overflow/interest-rect-change-scroll-down.html [ Failure ] crbug.com/619103 paint/selection/text-selection-newline-mixed-ltr-rtl.html [ Failure ] crbug.com/619103 paint/selection/text-selection-newline-rtl-double-linebreak.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change-expected.html b/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change-expected.html index a951ac9..b137506 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change-expected.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change-expected.html
@@ -6,11 +6,12 @@ .child { height: 20px; width: 20px; + background-color: green; } </style> </head> <body> - <div style="display: flex; flex-direction: column; height: 100%"> + <div style="display: flex; flex-direction: column; height: 100%; background-color: blue"> <div style="flex: 1"></div> <div class='nested-row-flexbox'> <div class="child"></div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change.html b/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change.html index fa22c893..b42165f4 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/repaint-on-margin-change.html
@@ -14,11 +14,12 @@ .child { height: 20px; width: 20px; + background-color: green; } </style> </head> <body onload="runRepaintAndPixelTest()"> - <div style="display: flex; flex-direction: column; height: 100%"> + <div style="display: flex; flex-direction: column; height: 100%; background-color: blue"> <div style="flex: 1"></div> <div class='nested-row-flexbox'> <div class="child"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling-expected.png new file mode 100644 index 0000000..037eec8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling.html b/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling.html new file mode 100644 index 0000000..8e6f86c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> + +<style> + +div { + display: inline-block; + border-radius: 1px; + background-image: url('data:image/svg+xml,\ + <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 10 10" stroke="green" stroke-width="2">\ + <line x1="0" y1="0" x2="10" y2="10"/>\ + <line x1="10" y1="0" x2="0" y2="10"/>\ + </svg>'); +} +</style> + +<body> + <div style="width: 50px; height: 50px; background-size: 100px;"></div> + <div style="width: 50px; height: 50px; background-size: 50px;"></div> + <div style="width: 50px; height: 50px; background-size: 25px;"></div> + <br> + + <div style="width: 100px; height: 100px; background-size: 200px;"></div> + <div style="width: 100px; height: 100px; background-size: 100px;"></div> + <div style="width: 100px; height: 100px; background-size: 50px;"></div> + <br> + + <div style="width: 200px; height: 200px; background-size: 400px;"></div> + <div style="width: 200px; height: 200px; background-size: 200px;"></div> + <div style="width: 200px; height: 200px; background-size: 100px;"></div> + <br> + +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event-expected.txt index 0c00425..a2b696d 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event-expected.txt
@@ -1,15 +1,8 @@ -Tests that document.createEvent() works with DeviceLightEvent. +Tests the DeviceLightEvent constructor. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS typeof event == 'object' is true -PASS event.__proto__ is DeviceLightEvent.prototype -PASS event instanceof window.DeviceLightEvent is true -PASS 'type' in event is true -PASS 'bubbles' in event is true -PASS 'cancelable' in event is true -PASS 'value' in event is true PASS typeof newEvent.type == 'string' is true PASS newEvent.type is "devicelight" PASS typeof newEvent.bubbles == 'boolean' is true @@ -20,6 +13,7 @@ PASS newEvent.value is 10 PASS defaultEvent.bubbles is true PASS defaultEvent.cancelable is false +PASS defaultEvent.value is Infinity PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event.html b/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event.html index c8f934f..55c6cc8 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event.html +++ b/third_party/WebKit/LayoutTests/fast/dom/DeviceLight/create-event.html
@@ -3,9 +3,8 @@ <body> <script src="../../../resources/js-test.js"></script> <script> -description("Tests that document.createEvent() works with DeviceLightEvent."); +description("Tests the DeviceLightEvent constructor."); -var event = document.createEvent('DeviceLightEvent'); var newEvent = new DeviceLightEvent("devicelight", { bubbles: true, cancelable: false, value: 10 @@ -13,15 +12,6 @@ var defaultEvent = new DeviceLightEvent("devicelight"); -shouldBeTrue("typeof event == 'object'"); -shouldBe("event.__proto__", "DeviceLightEvent.prototype"); - -shouldBeTrue("event instanceof window.DeviceLightEvent"); -shouldBeTrue("'type' in event"); -shouldBeTrue("'bubbles' in event"); -shouldBeTrue("'cancelable' in event"); -shouldBeTrue("'value' in event"); - shouldBeTrue("typeof newEvent.type == 'string'"); shouldBeEqualToString("newEvent.type", "devicelight"); shouldBeTrue("typeof newEvent.bubbles == 'boolean'"); @@ -34,6 +24,7 @@ // FIXME: Consider making bubbles property configurable. shouldBeTrue("defaultEvent.bubbles"); shouldBeFalse("defaultEvent.cancelable"); +shouldBe("defaultEvent.value", "Infinity"); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/relatedevent-expected.txt b/third_party/WebKit/LayoutTests/fast/events/relatedevent-expected.txt index 3ea873c..2ee7a06 100644 --- a/third_party/WebKit/LayoutTests/fast/events/relatedevent-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/relatedevent-expected.txt
@@ -3,6 +3,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". +PASS relatedEvent.type is "foo" PASS relatedEvent.bubbles is false PASS relatedEvent.cancelable is false PASS relatedEvent.relatedTarget is null
diff --git a/third_party/WebKit/LayoutTests/fast/events/relatedevent.html b/third_party/WebKit/LayoutTests/fast/events/relatedevent.html index 32229d71..b746f74 100644 --- a/third_party/WebKit/LayoutTests/fast/events/relatedevent.html +++ b/third_party/WebKit/LayoutTests/fast/events/relatedevent.html
@@ -7,13 +7,15 @@ description("Tests to confirm behavior of updating IDL attributes of RelatedEvent."); -var relatedEvent = document.createEvent("RelatedEvent"); +var relatedEvent = new RelatedEvent("foo"); -// We should not be able to update readonly attributes. +// We should not be able to update readonly attributes. +relatedEvent.type = "bar"; relatedEvent.bubbles = true; relatedEvent.cancelable = true; relatedEvent.relatedTarget = document; +shouldBeEqualToString("relatedEvent.type", "foo"); shouldBeFalse("relatedEvent.bubbles"); shouldBeFalse("relatedEvent.cancelable"); shouldBeNull("relatedEvent.relatedTarget");
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt deleted file mode 100644 index 6097ca4b..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -This test checks validity.valueMissing with blank values, blank options selected, or nothing selected. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS valueMissingFor("input") is true -PASS valueMissingFor("textarea") is true -PASS valueMissingFor("select-no-option") is true -PASS valueMissingFor("select-placeholder-selected") is true -PASS valueMissingFor("select-without-placeholder") is false -PASS valueMissingFor("select-placeholder-selected-size2") is false -PASS valueMissingFor("select-without-placeholder-size2") is false -PASS valueMissingFor("select-none-selected-multiple") is true -PASS valueMissingFor("select-fake-placeholder-selected-multiple") is false -PASS valueMissingFor("select-without-fake-placeholder-multiple") is false -PASS valueMissingFor("select-none-selected-size2-multiple") is true -PASS valueMissingFor("select-fake-placeholder-selected-size2-multiple") is false -PASS valueMissingFor("select-without-fake-placeholder-size2-multiple") is false -PASS valueMissingFor("select-optgroup") is false -PASS valueMissingFor("select-disabled-option") is true -PASS valueMissingFor("select-disabled-option-2") is false -PASS document.getElementById("select-disabled-option-2").selectedIndex is 1 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-001.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-001.html deleted file mode 100644 index a372347e..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-001.html +++ /dev/null
@@ -1,96 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<title>required and basic valueMissing</title> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<p id="description"></p> -<div id="console"></div> -<input id="input" name="victim" required/> -<textarea id="textarea" name="victim" required></textarea> -<select id="select-no-option" name="victim" required> -</select> -<select id="select-placeholder-selected" name="victim" required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-placeholder" name="victim" required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-placeholder-selected-size2" name="victim" size="2" required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-placeholder-size2" name="victim" size="2" required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-none-selected-multiple" name="victim" multiple required> - <option value="" /> - <option value="X">X</option> -</select> -<select id="select-fake-placeholder-selected-multiple" name="victim" multiple required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-fake-placeholder-multiple" name="victim" multiple required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-none-selected-size2-multiple" name="victim" multiple size="2" required> - <option value="" /> - <option value="X">X</option> -</select> -<select id="select-fake-placeholder-selected-size2-multiple" name="victim" multiple size="2" required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-fake-placeholder-size2-multiple" name="victim" multiple size="2" required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-optgroup" name="victim" required> - <optgroup label="1"> - <option value="" selected /> - </optgroup> - <option value="X">X</option> -</select> -<select id="select-disabled-option" name="victim" required> - <option value="" disabled selected /> - <option value="X">X</option> -</select> -<select id="select-disabled-option-2" name="victim" required> - <option value="" disabled /> - <option value="X">X</option> -</select> -<script language="JavaScript" type="text/javascript"> - function valueMissingFor(id) { - return document.getElementById(id).validity.valueMissing; - } - - description("This test checks validity.valueMissing with blank values, blank options selected, or nothing selected."); - - v = document.getElementsByName("victim"); - - shouldBeTrue('valueMissingFor("input")'); - shouldBeTrue('valueMissingFor("textarea")'); - shouldBeTrue('valueMissingFor("select-no-option")'); - shouldBeTrue('valueMissingFor("select-placeholder-selected")'); - shouldBeFalse('valueMissingFor("select-without-placeholder")'); - shouldBeFalse('valueMissingFor("select-placeholder-selected-size2")'); - shouldBeFalse('valueMissingFor("select-without-placeholder-size2")'); - shouldBeTrue('valueMissingFor("select-none-selected-multiple")'); - shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-multiple")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-multiple")'); - shouldBeTrue('valueMissingFor("select-none-selected-size2-multiple")'); - shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-size2-multiple")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2-multiple")'); - shouldBeFalse('valueMissingFor("select-optgroup")'); - shouldBeTrue('valueMissingFor("select-disabled-option")'); - shouldBeFalse('valueMissingFor("select-disabled-option-2")'); - shouldBe('document.getElementById("select-disabled-option-2").selectedIndex', '1'); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt deleted file mode 100644 index 495faf2..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -This test checks validity.valueMissing with some values or options with some values selected. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS valueMissingFor("input") is false -PASS valueMissingFor("textarea") is false -PASS valueMissingFor("select-with-placeholder") is false -PASS valueMissingFor("select-without-placeholder") is false -PASS valueMissingFor("select-with-fake-placeholder-size2") is false -PASS valueMissingFor("select-without-fake-placeholder-size2") is false -PASS valueMissingFor("select-with-fake-placeholder-multiple") is false -PASS valueMissingFor("select-without-fake-placeholder-multiple") is false -PASS valueMissingFor("select-with-fake-placeholder-size2-multiple") is false -PASS valueMissingFor("select-without-fake-placeholder-size2-multiple") is false -Updating valueMissing state by a key input: -PASS valueMissingFor("select-selecting-by-key") is true -PASS select.value is "a" -PASS valueMissingFor("select-selecting-by-key") is false -PASS valueMissingFor("select-selecting-by-key-2") is true -PASS select.value is "a" -PASS valueMissingFor("select-selecting-by-key-2") is false -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-002.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-002.html deleted file mode 100644 index a793c39..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-002.html +++ /dev/null
@@ -1,98 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<title>required and basic valueMissing 2</title> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<p id="description"></p> -<div id="console"></div> -<div id=parent> -<input id="input" name="victim" value="something" required/> -<textarea id="textarea" name="victim" required>something</textarea> -<select id="select-with-placeholder" name="victim" required> - <option value="" /> - <option value="X" selected>X</option> -</select> -<select id="select-without-placeholder" name="victim" required> - <option value="X" selected>X</option> - <option value="" /> -</select> -<select id="select-with-fake-placeholder-size2" name="victim" size="2" required> - <option value="" /> - <option value="X" selected>X</option> -</select> -<select id="select-without-fake-placeholder-size2" name="victim" size="2" required> - <option value="X" selected>X</option> - <option value="" /> -</select> -<select id="select-with-fake-placeholder-multiple" name="victim" multiple required> - <option value="" /> - <option value="X" selected>X</option> -</select> -<select id="select-without-fake-placeholder-multiple" name="victim" multiple required> - <option value="X" selected>X</option> - <option value="" /> -</select> -<select id="select-with-fake-placeholder-size2-multiple" name="victim" multiple size="2" required> - <option value="" /> - <option value="X" selected>X</option> -</select> -<select id="select-without-fake-placeholder-size2-multiple" name="victim" multiple size="2" required> - <option value="X" selected>X</option> - <option value="" /> -</select> -<select id=select-selecting-by-key required> - <option value="" selected/> - <option>a</option> -</select> -<select id=select-selecting-by-key-2 required> - <option value="" selected/> - <option accesskey="1">a</option> -</select> -</div> -<script language="JavaScript" type="text/javascript"> - function valueMissingFor(id) { - return document.getElementById(id).validity.valueMissing; - } - - description("This test checks validity.valueMissing with some values or options with some values selected."); - - shouldBeFalse('valueMissingFor("input")'); - shouldBeFalse('valueMissingFor("textarea")'); - shouldBeFalse('valueMissingFor("select-with-placeholder")'); - shouldBeFalse('valueMissingFor("select-without-placeholder")'); - shouldBeFalse('valueMissingFor("select-with-fake-placeholder-size2")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2")'); - shouldBeFalse('valueMissingFor("select-with-fake-placeholder-multiple")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-multiple")'); - shouldBeFalse('valueMissingFor("select-with-fake-placeholder-size2-multiple")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2-multiple")'); - - // Need to use eventSender instead of initKeyboardEvent() because we can't - // make an event which returns a correct value for keyCode by initKeyboardEvent(). - if (window.eventSender) { - debug("Updating valueMissing state by a key input:") - // Select by type-ahead. - var select = document.getElementById("select-selecting-by-key"); - shouldBeTrue('valueMissingFor("select-selecting-by-key")'); - select.focus(); - eventSender.keyDown("a"); - shouldBe('select.value', '"a"'); - shouldBeFalse('valueMissingFor("select-selecting-by-key")'); - - // Select by accesskey. - select = document.getElementById("select-selecting-by-key-2"); - shouldBeTrue('valueMissingFor("select-selecting-by-key-2")'); - select.focus(); - eventSender.keyDown("1", "accessKey"); - shouldBe('select.value', '"a"'); - shouldBeFalse('valueMissingFor("select-selecting-by-key-2")'); - } else { - debug('There are tests using eventSender.'); - } - - document.body.removeChild(document.getElementById('parent')); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt deleted file mode 100644 index 63bdcc1..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt +++ /dev/null
@@ -1,22 +0,0 @@ -This test checks validity.valueMissing of disabled form controls with blank values, blank options selected, or nothing selected. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS valueMissingFor("input") is false -PASS valueMissingFor("textarea") is false -PASS valueMissingFor("select-no-option") is false -PASS valueMissingFor("select-placeholder-selected") is false -PASS valueMissingFor("select-without-placeholder") is false -PASS valueMissingFor("select-placeholder-selected-size2") is false -PASS valueMissingFor("select-without-placeholder-size2") is false -PASS valueMissingFor("select-none-selected-multiple") is false -PASS valueMissingFor("select-fake-placeholder-selected-multiple") is false -PASS valueMissingFor("select-without-fake-placeholder-multiple") is false -PASS valueMissingFor("select-none-selected-size2-multiple") is false -PASS valueMissingFor("select-fake-placeholder-selected-size2-multiple") is false -PASS valueMissingFor("select-without-fake-placeholder-size2-multiple") is false -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-003.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-003.html deleted file mode 100644 index 8db2df1..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-003.html +++ /dev/null
@@ -1,78 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<title>required and valueMissing on disabled elements</title> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<p id="description"></p> -<div id="console"></div> -<input id="input" name="victim" disabled required /> -<textarea id="textarea" name="victim" disabled required></textarea> -<select id="select-no-option" name="victim" disabled required> -</select> -<select id="select-placeholder-selected" name="victim" disabled required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-placeholder" name="victim" disabled required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-placeholder-selected-size2" name="victim" size="2" disabled required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-placeholder-size2" name="victim" size="2" disabled required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-none-selected-multiple" name="victim" multiple disabled required> - <option value="" /> - <option value="X">X</option> -</select> -<select id="select-fake-placeholder-selected-multiple" name="victim" multiple disabled required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-fake-placeholder-multiple" name="victim" multiple disabled required> - <option value="X">X</option> - <option value="" selected /> -</select> -<select id="select-none-selected-size2-multiple" name="victim" multiple size="2" disabled required> - <option value="" /> - <option value="X">X</option> -</select> -<select id="select-fake-placeholder-selected-size2-multiple" name="victim" multiple size="2" disabled required> - <option value="" selected /> - <option value="X">X</option> -</select> -<select id="select-without-fake-placeholder-size2-multiple" name="victim" multiple size="2" disabled required> - <option value="X">X</option> - <option value="" selected /> -</select> -<script language="JavaScript" type="text/javascript"> - function valueMissingFor(id) { - return document.getElementById(id).validity.valueMissing; - } - - description("This test checks validity.valueMissing of disabled form controls with blank values, blank options selected, or nothing selected."); - - v = document.getElementsByName("victim"); - - shouldBeFalse('valueMissingFor("input")'); - shouldBeFalse('valueMissingFor("textarea")'); - shouldBeFalse('valueMissingFor("select-no-option")'); - shouldBeFalse('valueMissingFor("select-placeholder-selected")'); - shouldBeFalse('valueMissingFor("select-without-placeholder")'); - shouldBeFalse('valueMissingFor("select-placeholder-selected-size2")'); - shouldBeFalse('valueMissingFor("select-without-placeholder-size2")'); - shouldBeFalse('valueMissingFor("select-none-selected-multiple")'); - shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-multiple")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-multiple")'); - shouldBeFalse('valueMissingFor("select-none-selected-size2-multiple")'); - shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-size2-multiple")'); - shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2-multiple")'); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-004-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-004-expected.txt deleted file mode 100644 index 3127cde..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-004-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -There are two readonly form control elements below, both required and with some value: validity.valueMissing should be false in both cases. - - -SUCCESS
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-004.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-004.html deleted file mode 100644 index 4dad439..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-004.html +++ /dev/null
@@ -1,27 +0,0 @@ -<html> -<head> -<title>required and valueMissing on readonly elements</title> -<script language="JavaScript" type="text/javascript"> - function log(message) { - document.getElementById("console").innerHTML += "<li>"+message+"</li>"; - } - - function test() { - if (window.testRunner) - testRunner.dumpAsText(); - - v = document.getElementsByName("victim"); - - log((!v[0].validity.valueMissing && !v[1].validity.valueMissing) ? "SUCCESS" : "FAILURE"); - } -</script> -</head> -<body onload="test()"> -<p>There are two readonly form control elements below, both required and with some value: -validity.valueMissing should be false in both cases.</p> -<input name="victim" readonly required /> -<textarea name="victim" readonly required></textarea> -<hr> -<ol id="console"></ol> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-005-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-005-expected.txt deleted file mode 100644 index 888385d..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-005-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -There's a list of form control elements below, required attribute does not apply to them: validity.valueMissing should be false. - - -SUCCESS -SUCCESS -SUCCESS -SUCCESS -SUCCESS -SUCCESS
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-005.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-005.html deleted file mode 100644 index 5dd5ce7e..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-005.html +++ /dev/null
@@ -1,32 +0,0 @@ -<html> -<head> -<title>required and valueMissing on unaccepted input types</title> -<script language="JavaScript" type="text/javascript"> - function log(message) { - document.getElementById("console").innerHTML += "<li>"+message+"</li>"; - } - - function test() { - if (window.testRunner) - testRunner.dumpAsText(); - - v = document.getElementsByName("victim"); - - for (i = 0; i < v.length; i++) - log(!v[i].validity.valueMissing ? "SUCCESS" : "FAILURE"); - } -</script> -</head> -<body onload="test()"> -<p>There's a list of form control elements below, required attribute does not apply to them: -validity.valueMissing should be false.</p> -<input name="victim" type="hidden" required /> -<input name="victim" type="range" required /> -<input name="victim" type="image" required /> -<input name="victim" type="reset" required /> -<input name="victim" type="button" required /> -<input name="victim" type="submit" required /> -<hr> -<ol id="console"></ol> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-006-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-006-expected.txt deleted file mode 100644 index 8d5d248..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-006-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -There are two checkboxes below, both are required, only one is checked. - - -SUCCESS
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-006.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-006.html deleted file mode 100644 index 0df4473..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-006.html +++ /dev/null
@@ -1,26 +0,0 @@ -<html> -<head> -<title>required and valueMissing on checkboxes</title> -<script language="JavaScript" type="text/javascript"> - function log(message) { - document.getElementById("console").innerHTML += "<li>"+message+"</li>"; - } - - function test() { - if (window.testRunner) - testRunner.dumpAsText(); - - v = document.getElementsByName("victim"); - - log(!v[0].validity.valueMissing && v[1].validity.valueMissing ? "SUCCESS" : "FAILURE"); - } -</script> -</head> -<body onload="test()"> -<p>There are two checkboxes below, both are required, only one is checked.</p> -<input name="victim" type="checkbox" required checked/> -<input name="victim" type="checkbox" required /> -<hr> -<ol id="console"></ol> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-008-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-008-expected.txt deleted file mode 100644 index d8c490a..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-008-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -There's a upload control below, with no file selected: missing value. - - -SUCCESS
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-008.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-008.html deleted file mode 100644 index 238dacb..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-008.html +++ /dev/null
@@ -1,25 +0,0 @@ -<html> -<head> -<title>required and valueMissing on file control</title> -<script language="JavaScript" type="text/javascript"> - function log(message) { - document.getElementById("console").innerHTML += "<li>"+message+"</li>"; - } - - function test() { - if (window.testRunner) - testRunner.dumpAsText(); - - v = document.getElementsByName("victim"); - - log(v[0].validity.valueMissing ? "SUCCESS" : "FAILURE"); - } -</script> -</head> -<body onload="test()"> -<p>There's a upload control below, with no file selected: missing value.</p> -<input name="victim" type="file" required/> -<hr> -<ol id="console"></ol> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-009-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-009-expected.txt deleted file mode 100644 index 1acacda..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-009-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -There's a list of form control elements below, required attribute applies to them but they're empty: validity.valueMissing should be true. - - -SUCCESS -SUCCESS -SUCCESS -SUCCESS -SUCCESS -SUCCESS -SUCCESS
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-009.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-009.html deleted file mode 100644 index e749efe0..0000000 --- a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing-009.html +++ /dev/null
@@ -1,33 +0,0 @@ -<html> -<head> -<title>required and valueMissing on new input types</title> -<script language="JavaScript" type="text/javascript"> - function log(message) { - document.getElementById("console").innerHTML += "<li>"+message+"</li>"; - } - - function test() { - if (window.testRunner) - testRunner.dumpAsText(); - - v = document.getElementsByName("victim"); - - for (i = 0; i < v.length; i++) - log(v[i].validity.valueMissing ? "SUCCESS" : "FAILURE"); - } -</script> -</head> -<body onload="test()"> -<p>There's a list of form control elements below, required attribute applies to them but they're empty: -validity.valueMissing should be true.</p> -<input name="victim" type="text" required /> -<input name="victim" type="search" required /> -<input name="victim" type="url" required /> -<input name="victim" type="telephone" required /> -<input name="victim" type="email" required /> -<input name="victim" type="password" required /> -<input name="victim" type="number" required /> -<hr> -<ol id="console"></ol> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing.html b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing.html new file mode 100644 index 0000000..434e0a8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/ValidityState-valueMissing.html
@@ -0,0 +1,319 @@ +<!DOCTYPE html> +<body> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<div id="sample"></div> +<script> +function valueMissingFor(html) { + var sample = document.getElementById('sample'); + sample.innerHTML = html; + return sample.firstChild.validity.valueMissing; +} + +test(() => { + assert_true(valueMissingFor('<input required>')); +}, 'Empty-value INPUT[required] should be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<input value="something" required>')); +}, 'INPUT[required] with a non-empty value should not be valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<textarea required></textarea>')); +}, 'Empty value TEXTAREA[required] should be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<textarea required>something</textarea>')); +}, 'TEXTAREA[required] with a non-empty value should not be valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<select required></select>')); +}, 'SELECT[required] with no OPTIONS should be valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<select required>' + + '<option value="" selected />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required] with a selected placeholder OPTION should be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select required>' + + '<option value="X">X</option>' + + '<option value="" selected />' + + '</select>')); +}, 'SELECT[required] with a selected non-placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select size="2" required>' + + '<option value="" selected />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required][size=2] with a selected placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select size="2" required>' + + '<option value="X">X</option>' + + '<option value="" selected />' + + '</select>')); +}, 'SELECT[rquired][size=2] with a selected non-placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<select multiple required>' + + '<option value="" />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required][multiple] without selected OPTIONs should be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple required>' + + '<option value="" selected />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required][multiple] with a selected placeholder-like OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple required>' + + '<option value="X">X</option>' + + '<option value="" selected />' + + '</select>')); +}, 'SELECT[required][multiple] with a selected OPTION should not be valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<select multiple size="2" required>' + + '<option value="" />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required][multiple][size=2] without selected OPTIONs should be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple size="2" required>' + + '<option value="" selected />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required][multiple][size=2] with a selected placeholder-liek OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple size="2" required>' + + '<option value="X">X</option>' + + '<option value="" selected />' + + '</select>')); +}, 'SELECT[required][multiple][size=2] with a selected OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select required>' + + '<optgroup label="1">' + + ' <option value="" selected />' + + '</optgroup>' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required] with a selected placeholder-like OPTION inside an OPTGROUP should not be valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<select required>' + + '<option value="" disabled selected />' + + '<option value="X">X</option>' + + '</select>')); +}, 'SELECT[required] with a selected disabled placeholder OPTION should be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select id="select-disabled-option-2" required>' + + '<option value="" disabled />' + + '<option value="X">X</option>' + + '</select>')); + assert_equals(document.getElementById('select-disabled-option-2').selectedIndex, 1); +}, 'SELECT[required] with a non-selected disabled placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select required>' + + '<option value="" />' + + '<option value="X" selected>X</option>' + + '</select>')); +}, 'SELECT[required] with a unselected placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select size="2" required>' + + '<option value="" />' + + '<option value="X" selected>X</option>' + + '</select>')); +}, 'SELECT[required][size=2] with a unselected placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select size="2" required>' + + '<option value="X" selected>X</option>' + + '<option value="" />' + + '</select>')); +}, 'SELECT[required][size=2] with a unselected placeholder-like OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple required>' + + '<option value="" />' + + '<option value="X" selected>X</option>' + + '</select>')); +}, 'SELECT[required][multiple] with a unselected placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple required>' + + '<option value="X" selected>X</option>' + + '<option value="" />' + + '</select>')); +}, 'SELECT[required][multiple] with a unselected placeholder-like OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple size="2" required>' + + '<option value="" />' + + '<option value="X" selected>X</option>' + + '</select>')); +}, 'SELECT[required][size=2][multiple] with a unselected placeholder OPTION should not be valueMissing.'); + +test(() => { + assert_false(valueMissingFor('<select multiple size="2" required>' + + '<option value="X" selected>X</option>' + + '<option value="" />' + + '</select>')); +}, 'SELECT[required][size=2][multiple] with a unselected placeholder-like OPTION should not be valueMissing.'); + +test(() => { + assert_true(!!window.eventSender, 'Needs eventSender.'); + // Select by type-ahead. + assert_true(valueMissingFor('<select id="select-selecting-by-key" required>' + + '<option value="" selected/>' + + '<option>a</option>' + + '</select>')); + var select = document.getElementById('select-selecting-by-key'); + select.focus(); + eventSender.keyDown('a'); + assert_equals(select.value, 'a'); + assert_false(select.validity.valueMissing); + + // Select by accesskey. + assert_true(valueMissingFor('<select id="select-selecting-by-key-2" required>' + + '<option value="" selected/>' + + '<option accesskey="1">a</option>' + + '</select>')); + select = document.getElementById('select-selecting-by-key-2'); + select.focus(); + eventSender.keyDown('1', 'accessKey'); + assert_equals(select.value, 'a'); + assert_false(select.validity.valueMissing); +}, 'Updating valueMissing state by user input.'); + +test(() => { + document.querySelector('#sample').innerHTML = '<input name="victim" disabled required />' + + '<textarea name="victim" disabled required></textarea>' + + '<select name="victim" disabled required>' + + '</select>' + + '<select name="victim" disabled required>' + + ' <option value="" selected />' + + ' <option value="X">X</option>' + + '</select>' + + '<select name="victim" disabled required>' + + ' <option value="X">X</option>' + + ' <option value="" selected />' + + '</select>' + + '<select name="victim" size="2" disabled required>' + + ' <option value="" selected />' + + ' <option value="X">X</option>' + + '</select>' + + '<select name="victim" size="2" disabled required>' + + ' <option value="X">X</option>' + + ' <option value="" selected />' + + '</select>' + + '<select name="victim" multiple disabled required>' + + ' <option value="" />' + + ' <option value="X">X</option>' + + '</select>' + + '<select name="victim" multiple disabled required>' + + ' <option value="" selected />' + + ' <option value="X">X</option>' + + '</select>' + + '<select name="victim" multiple disabled required>' + + ' <option value="X">X</option>' + + ' <option value="" selected />' + + '</select>' + + '<select name="victim" multiple size="2" disabled required>' + + ' <option value="" />' + + ' <option value="X">X</option>' + + '</select>' + + '<select name="victim" multiple size="2" disabled required>' + + ' <option value="" selected />' + + ' <option value="X">X</option>' + + '</select>' + + '<select name="victim" multiple size="2" disabled required>' + + ' <option value="X">X</option>' + + ' <option value="" selected />' + + '</select>'; + var controls = document.querySelectorAll(':disabled'); + for (var c of controls) { + assert_false(c.validity.valueMissing); + } +}, 'Disabled controls never be valueMissing.'); + +test(() => { + document.querySelector('#sample').innerHTML = + '<input readonly required />' + + '<textarea readonly required></textarea>'; + var controls = document.querySelectorAll('[readonly]'); + for (var c of controls) { + assert_false(c.validity.valueMissing); + } +}, 'Read-only controls never be valueMissing.'); + +test(() => { + document.querySelector('#sample').innerHTML = + '<fieldset id="non-supported-container">' + + '<input name="victim" type="hidden" required />' + + '<input name="victim" type="range" required />' + + '<input name="victim" type="image" required />' + + '<input name="victim" type="reset" required />' + + '<input name="victim" type="button" required />' + + '<input name="victim" type="submit" required />' + + '</fieldset>'; + var fieldset = document.querySelector('#non-supported-container'); + for (var c of fieldset.elements) { + assert_false(c.validity.valueMissing); + } +}, 'INPUT elements of some types never be valueMissing.'); + +test(() => { + document.querySelector('#sample').innerHTML = + '<input name="victim" type="checkbox" required checked />' + + '<input name="victim" type="checkbox" required />'; + var controls = document.querySelectorAll('input[type=checkbox]'); + assert_false(controls[0].validity.valueMissing); + assert_true(controls[1].validity.valueMissing); +}, 'INPUT[type=checkbox] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="file" required />')); +}, 'INPUT[type=file] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="text" required />')); +}, 'INPUT[type=text] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="search" required />')); +}, 'INPUT[type=search] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="url" required />')); +}, 'INPUT[type=url] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="tel" required />')); +}, 'INPUT[type=tel] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="email" required />')); +}, 'INPUT[type=email] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="password" required />')); +}, 'INPUT[type=password] supports valueMissing.'); + +test(() => { + assert_true(valueMissingFor('<input type="number" required />')); +}, 'INPUT[type=number] supports valueMissing.'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Document-createEvent-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Document-createEvent-expected.txt index 157dd2d1..5a2c53a 100644 --- a/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Document-createEvent-expected.txt +++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Document-createEvent-expected.txt
@@ -230,9 +230,7 @@ FAIL createEvent('WHEELEVENT') should be initialized correctly. Cannot read property 'type' of undefined PASS Should throw NOT_SUPPORTED_ERR for pluralized legacy event interface "WheelEvents" PASS Should throw NOT_SUPPORTED_ERR for unrecognized arguments -FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "AnimationPlayerEvent" assert_throws: function "function () { - var evt = document.createEvent(eventInterface); - }" did not throw +PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "AnimationPlayerEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "AnimationPlayerEvents" FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "ApplicationCacheErrorEvent" assert_throws: function "function () { var evt = document.createEvent(eventInterface); @@ -260,9 +258,7 @@ PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "CommandEvents" PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "DataContainerEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "DataContainerEvents" -FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "DeviceLightEvent" assert_throws: function "function () { - var evt = document.createEvent(eventInterface); - }" did not throw +PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "DeviceLightEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "DeviceLightEvents" FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "ExtendableEvent" assert_throws: function "function () { var evt = document.createEvent(eventInterface); @@ -286,9 +282,7 @@ PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "GamepadEvents" PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "GeofencingEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "GeofencingEvents" -FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "InstallEvent" assert_throws: function "function () { - var evt = document.createEvent(eventInterface); - }" did not throw +PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "InstallEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "InstallEvents" PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "KeyEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "KeyEvents" @@ -344,9 +338,7 @@ PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "OrientationEvents" PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "PageTransition" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "PageTransitions" -FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "PointerEvent" assert_throws: function "function () { - var evt = document.createEvent(eventInterface); - }" did not throw +PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "PointerEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "PointerEvents" PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "PopUpEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "PopUpEvents" @@ -378,9 +370,7 @@ var evt = document.createEvent(eventInterface); }" did not throw PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "RTCIceCandidateEvents" -FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "RelatedEvent" assert_throws: function "function () { - var evt = document.createEvent(eventInterface); - }" did not throw +PASS Should throw NOT_SUPPORTED_ERR for non-legacy event interface "RelatedEvent" PASS Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "RelatedEvents" FAIL Should throw NOT_SUPPORTED_ERR for non-legacy event interface "ResourceProgressEvent" assert_throws: function "function () { var evt = document.createEvent(eventInterface);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt index a38a84f..d8120a18 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt
@@ -3,72 +3,6 @@ Set timer for test function. Captured call stacks in no particular order: Call stack: - 0) doTestChainedPromises (async-callstack-async-await1.html:100) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:99) - 3) testFunctionTimeout (async-callstack-async-await1.html:50) - [setTimeout] - 0) testFunction (async-callstack-async-await1.html:43) - [setTimeout] - 0) scheduleTestFunction (debugger-test.js:3) - <... skipped remaining frames ...> - -Call stack: - 0) doTestChainedPromises (async-callstack-async-await1.html:102) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:101) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:99) - 3) testFunctionTimeout (async-callstack-async-await1.html:50) - [setTimeout] - 0) testFunction (async-callstack-async-await1.html:43) - -Call stack: - 0) doTestChainedPromises (async-callstack-async-await1.html:104) - [Promise.resolve] - 0) doTestChainedPromises (async-callstack-async-await1.html:103) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:101) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:99) - 3) testFunctionTimeout (async-callstack-async-await1.html:50) - -Call stack: - 0) doTestChainedPromises (async-callstack-async-await1.html:106) - [Promise.resolve] - 0) doTestChainedPromises (async-callstack-async-await1.html:105) - [Promise.resolve] - 0) doTestChainedPromises (async-callstack-async-await1.html:103) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:101) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - -Call stack: 0) errorCallback (async-callstack-async-await1.html:60) 1) doTestSettledPromisesRejected (async-callstack-async-await1.html:92) [Promise.reject] @@ -92,39 +26,6 @@ Call stack: 0) thenCallback (async-callstack-async-await1.html:55) - 1) doTestChainedPromises (async-callstack-async-await1.html:107) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromises (async-callstack-async-await1.html:107) - [Promise.resolve] - 0) doTestChainedPromises (async-callstack-async-await1.html:105) - [Promise.resolve] - 0) doTestChainedPromises (async-callstack-async-await1.html:103) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - -Call stack: - 0) thenCallback (async-callstack-async-await1.html:55) - 1) doTestChainedPromisesJSON (async-callstack-async-await1.html:119) - [Promise.resolve] - 0) doTestChainedPromisesJSON (async-callstack-async-await1.html:118) - [Promise.resolve] - 0) doTestChainedPromisesJSON (async-callstack-async-await1.html:117) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await1.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await1.html:21) - 1) timeoutPromise (async-callstack-async-await1.html:9) - 2) doTestChainedPromisesJSON (async-callstack-async-await1.html:116) - 3) testFunctionTimeout (async-callstack-async-await1.html:50) - [setTimeout] - 0) testFunction (async-callstack-async-await1.html:43) - -Call stack: - 0) thenCallback (async-callstack-async-await1.html:55) 1) doTestPromiseConstructor (async-callstack-async-await1.html:70) [Promise.resolve] 0) doTestPromiseConstructor (async-callstack-async-await1.html:66)
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1.html index c1c4d4a4..e6b33037 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await1.html
@@ -45,7 +45,7 @@ function testFunctionTimeout() { - var functions = [doTestPromiseConstructor, doTestSettledPromisesResolved, doTestSettledPromisesRejected, doTestChainedPromises, doTestChainedPromisesJSON]; + var functions = [doTestPromiseConstructor, doTestSettledPromisesResolved, doTestSettledPromisesRejected]; for (var i = 0; i < functions.length; ++i) functions[i](); } @@ -93,38 +93,9 @@ } } -async function doTestChainedPromises() -{ - try { - await timeoutPromise(1); - debugger; - await timeoutPromise(2); - debugger; - await 3; - debugger; - await settledPromise(4); - debugger; - thenCallback(await timeoutPromise(5)); - } catch (e) { - errorCallback(e); - } -} - -async function doTestChainedPromisesJSON() -{ - try { - let one = await timeoutPromise(1); - let stringify = await JSON.stringify(one); - let parse = await JSON.parse(stringify); - thenCallback(parse); - } catch (e) { - errorCallback(e); - } -} - var test = function() { - var totalDebuggerStatements = 10; + var totalDebuggerStatements = 4; var maxAsyncCallStackDepth = 5; InspectorTest.runAsyncCallStacksTest(totalDebuggerStatements, maxAsyncCallStackDepth); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt index 3e93c8e..abfe1c0b 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt
@@ -3,64 +3,13 @@ Set timer for test function. Captured call stacks in no particular order: Call stack: - 0) errorCallback (async-callstack-async-await2.html:60) - 1) doTestPromiseReject (async-callstack-async-await2.html:129) - [Promise.reject] - 0) doTestPromiseReject (async-callstack-async-await2.html:126) - 1) testFunctionTimeout (async-callstack-async-await2.html:50) - [setTimeout] - 0) testFunction (async-callstack-async-await2.html:43) - [setTimeout] - 0) scheduleTestFunction (debugger-test.js:3) - <... skipped remaining frames ...> - -Call stack: - 0) errorCallback (async-callstack-async-await2.html:60) - 1) doTestRejectFromChain (async-callstack-async-await2.html:109) - [Promise.reject] - 0) rejectPromise (async-callstack-async-await2.html:16) - [setTimeout] - 0) promiseCallback (async-callstack-async-await2.html:19) - 1) timeoutPromise (async-callstack-async-await2.html:9) - 2) rejectFromChain (async-callstack-async-await2.html:98) + 0) doTestChainedPromises (async-callstack-async-await2.html:67) [Promise.resolve] 0) resolvePromise (async-callstack-async-await2.html:12) [setTimeout] 0) promiseCallback (async-callstack-async-await2.html:21) 1) timeoutPromise (async-callstack-async-await2.html:9) - 2) rejectFromChain (async-callstack-async-await2.html:97) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await2.html:12) - -Call stack: - 0) errorCallback (async-callstack-async-await2.html:60) - 1) doTestThrowFromChain (async-callstack-async-await2.html:89) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await2.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await2.html:21) - 1) timeoutPromise (async-callstack-async-await2.html:9) - 2) throwFromChain (async-callstack-async-await2.html:76) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await2.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await2.html:21) - 1) timeoutPromise (async-callstack-async-await2.html:9) - 2) throwFromChain (async-callstack-async-await2.html:75) - 3) doTestThrowFromChain (async-callstack-async-await2.html:86) - 4) testFunctionTimeout (async-callstack-async-await2.html:50) - [setTimeout] - 0) testFunction (async-callstack-async-await2.html:43) - -Call stack: - 0) thenCallback (async-callstack-async-await2.html:55) - 1) doTestPromiseAll (async-callstack-async-await2.html:67) - [Promise.resolve] - 0) resolvePromise (async-callstack-async-await2.html:12) - [setTimeout] - 0) promiseCallback (async-callstack-async-await2.html:21) - 1) timeoutPromise (async-callstack-async-await2.html:9) - 2) doTestPromiseAll (async-callstack-async-await2.html:66) + 2) doTestChainedPromises (async-callstack-async-await2.html:66) 3) testFunctionTimeout (async-callstack-async-await2.html:50) [setTimeout] 0) testFunction (async-callstack-async-await2.html:43) @@ -69,15 +18,87 @@ <... skipped remaining frames ...> Call stack: - 0) thenCallback (async-callstack-async-await2.html:55) - 1) doTestPromiseResolve (async-callstack-async-await2.html:117) + 0) doTestChainedPromises (async-callstack-async-await2.html:69) [Promise.resolve] - 0) doTestPromiseResolve (async-callstack-async-await2.html:116) - 1) testFunctionTimeout (async-callstack-async-await2.html:50) + 0) resolvePromise (async-callstack-async-await2.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromises (async-callstack-async-await2.html:68) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromises (async-callstack-async-await2.html:66) + 3) testFunctionTimeout (async-callstack-async-await2.html:50) [setTimeout] 0) testFunction (async-callstack-async-await2.html:43) + +Call stack: + 0) doTestChainedPromises (async-callstack-async-await2.html:71) + [Promise.resolve] + 0) doTestChainedPromises (async-callstack-async-await2.html:70) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) [setTimeout] - 0) scheduleTestFunction (debugger-test.js:3) - <... skipped remaining frames ...> + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromises (async-callstack-async-await2.html:68) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromises (async-callstack-async-await2.html:66) + 3) testFunctionTimeout (async-callstack-async-await2.html:50) + +Call stack: + 0) doTestChainedPromises (async-callstack-async-await2.html:73) + [Promise.resolve] + 0) doTestChainedPromises (async-callstack-async-await2.html:72) + [Promise.resolve] + 0) doTestChainedPromises (async-callstack-async-await2.html:70) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromises (async-callstack-async-await2.html:68) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + +Call stack: + 0) thenCallback (async-callstack-async-await2.html:55) + 1) doTestChainedPromises (async-callstack-async-await2.html:74) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromises (async-callstack-async-await2.html:74) + [Promise.resolve] + 0) doTestChainedPromises (async-callstack-async-await2.html:72) + [Promise.resolve] + 0) doTestChainedPromises (async-callstack-async-await2.html:70) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + +Call stack: + 0) thenCallback (async-callstack-async-await2.html:55) + 1) doTestChainedPromisesJSON (async-callstack-async-await2.html:86) + [Promise.resolve] + 0) doTestChainedPromisesJSON (async-callstack-async-await2.html:85) + [Promise.resolve] + 0) doTestChainedPromisesJSON (async-callstack-async-await2.html:84) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await2.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await2.html:21) + 1) timeoutPromise (async-callstack-async-await2.html:9) + 2) doTestChainedPromisesJSON (async-callstack-async-await2.html:83) + 3) testFunctionTimeout (async-callstack-async-await2.html:50) + [setTimeout] + 0) testFunction (async-callstack-async-await2.html:43)
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2.html index 77b73e4..d87dd494 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await2.html
@@ -45,7 +45,7 @@ function testFunctionTimeout() { - var functions = [doTestPromiseAll, doTestThrowFromChain, doTestRejectFromChain, doTestPromiseResolve, doTestPromiseReject]; + var functions = [doTestChainedPromises, doTestChainedPromisesJSON]; for (var i = 0; i < functions.length; ++i) functions[i](); } @@ -60,71 +60,30 @@ debugger; } -async function doTestPromiseAll() +async function doTestChainedPromises() { try { - let all = await Promise.all([11, 22, 33, 44, 55].map(timeoutPromise)); - thenCallback(all); + await timeoutPromise(1); + debugger; + await timeoutPromise(2); + debugger; + await 3; + debugger; + await settledPromise(4); + debugger; + thenCallback(await timeoutPromise(5)); } catch (e) { errorCallback(e); } } -async function throwFromChain() -{ - await timeoutPromise(1); - await timeoutPromise(2); - await settledPromise(3); - throw Error("thrown from 4"); - await timeoutPromise(5); - debugger; -} - -async function doTestThrowFromChain() +async function doTestChainedPromisesJSON() { try { - let result = await throwFromChain(); - thencallback(result); - } catch (e) { - errorCallback(e); - } -} - -async function rejectFromChain() -{ - await timeoutPromise(1); - await timeoutPromise(2); - await timeoutPromise(3); - await timeoutPromise(new Error(4)); - throw new Error("thrown from rejectFromChain"); - debugger; -} - -async function doTestRejectFromChain() -{ - try { - let result = await rejectFromChain(); - thenCallback(result); - } catch (e) { - errorCallback(e); - } -} - -async function doTestPromiseResolve() -{ - try { - let result = await Promise.resolve(1); - thenCallback(result); - } catch (e) { - errorCallback(e); - } -} - -async function doTestPromiseReject() -{ - try { - let result = await Promise.reject(new Error("2")) - thenCallback(result); + let one = await timeoutPromise(1); + let stringify = await JSON.stringify(one); + let parse = await JSON.parse(stringify); + thenCallback(parse); } catch (e) { errorCallback(e); } @@ -132,7 +91,7 @@ var test = function() { - var totalDebuggerStatements = 5; + var totalDebuggerStatements = 6; var maxAsyncCallStackDepth = 5; InspectorTest.runAsyncCallStacksTest(totalDebuggerStatements, maxAsyncCallStackDepth); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt new file mode 100644 index 0000000..a283de8e3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt
@@ -0,0 +1,83 @@ +Tests asynchronous call stacks for async functions. + +Set timer for test function. +Captured call stacks in no particular order: +Call stack: + 0) errorCallback (async-callstack-async-await3.html:60) + 1) doTestPromiseReject (async-callstack-async-await3.html:129) + [Promise.reject] + 0) doTestPromiseReject (async-callstack-async-await3.html:126) + 1) testFunctionTimeout (async-callstack-async-await3.html:50) + [setTimeout] + 0) testFunction (async-callstack-async-await3.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) errorCallback (async-callstack-async-await3.html:60) + 1) doTestRejectFromChain (async-callstack-async-await3.html:109) + [Promise.reject] + 0) rejectPromise (async-callstack-async-await3.html:16) + [setTimeout] + 0) promiseCallback (async-callstack-async-await3.html:19) + 1) timeoutPromise (async-callstack-async-await3.html:9) + 2) rejectFromChain (async-callstack-async-await3.html:98) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await3.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await3.html:21) + 1) timeoutPromise (async-callstack-async-await3.html:9) + 2) rejectFromChain (async-callstack-async-await3.html:97) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await3.html:12) + +Call stack: + 0) errorCallback (async-callstack-async-await3.html:60) + 1) doTestThrowFromChain (async-callstack-async-await3.html:89) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await3.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await3.html:21) + 1) timeoutPromise (async-callstack-async-await3.html:9) + 2) throwFromChain (async-callstack-async-await3.html:76) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await3.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await3.html:21) + 1) timeoutPromise (async-callstack-async-await3.html:9) + 2) throwFromChain (async-callstack-async-await3.html:75) + 3) doTestThrowFromChain (async-callstack-async-await3.html:86) + 4) testFunctionTimeout (async-callstack-async-await3.html:50) + [setTimeout] + 0) testFunction (async-callstack-async-await3.html:43) + +Call stack: + 0) thenCallback (async-callstack-async-await3.html:55) + 1) doTestPromiseAll (async-callstack-async-await3.html:67) + [Promise.resolve] + 0) resolvePromise (async-callstack-async-await3.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-async-await3.html:21) + 1) timeoutPromise (async-callstack-async-await3.html:9) + 2) doTestPromiseAll (async-callstack-async-await3.html:66) + 3) testFunctionTimeout (async-callstack-async-await3.html:50) + [setTimeout] + 0) testFunction (async-callstack-async-await3.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) thenCallback (async-callstack-async-await3.html:55) + 1) doTestPromiseResolve (async-callstack-async-await3.html:117) + [Promise.resolve] + 0) doTestPromiseResolve (async-callstack-async-await3.html:116) + 1) testFunctionTimeout (async-callstack-async-await3.html:50) + [setTimeout] + 0) testFunction (async-callstack-async-await3.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await3.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await3.html new file mode 100644 index 0000000..77b73e4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-await/async-callstack-async-await3.html
@@ -0,0 +1,149 @@ +<html> +<head> +<script src="../../../../http/tests/inspector/inspector-test.js"></script> +<script src="../../../../http/tests/inspector/debugger-test.js"></script> +<script> + +function timeoutPromise(value, ms) +{ + return new Promise(function promiseCallback(resolve, reject) { + function resolvePromise() + { + resolve(value); + } + function rejectPromise() + { + reject(value); + } + if (value instanceof Error) + setTimeout(rejectPromise, ms || 0); + else + setTimeout(resolvePromise, ms || 0); + }); +} + +function settledPromise(value) +{ + function resolveCallback(resolve, reject) + { + resolve(value); + } + function rejectCallback(resolve, reject) + { + reject(value); + } + if (value instanceof Error) + return new Promise(rejectCallback); + else + return new Promise(resolveCallback); +} + +function testFunction() +{ + setTimeout(testFunctionTimeout, 0); +} + +function testFunctionTimeout() +{ + var functions = [doTestPromiseAll, doTestThrowFromChain, doTestRejectFromChain, doTestPromiseResolve, doTestPromiseReject]; + for (var i = 0; i < functions.length; ++i) + functions[i](); +} + +function thenCallback(value) +{ + debugger; +} + +function errorCallback(error) +{ + debugger; +} + +async function doTestPromiseAll() +{ + try { + let all = await Promise.all([11, 22, 33, 44, 55].map(timeoutPromise)); + thenCallback(all); + } catch (e) { + errorCallback(e); + } +} + +async function throwFromChain() +{ + await timeoutPromise(1); + await timeoutPromise(2); + await settledPromise(3); + throw Error("thrown from 4"); + await timeoutPromise(5); + debugger; +} + +async function doTestThrowFromChain() +{ + try { + let result = await throwFromChain(); + thencallback(result); + } catch (e) { + errorCallback(e); + } +} + +async function rejectFromChain() +{ + await timeoutPromise(1); + await timeoutPromise(2); + await timeoutPromise(3); + await timeoutPromise(new Error(4)); + throw new Error("thrown from rejectFromChain"); + debugger; +} + +async function doTestRejectFromChain() +{ + try { + let result = await rejectFromChain(); + thenCallback(result); + } catch (e) { + errorCallback(e); + } +} + +async function doTestPromiseResolve() +{ + try { + let result = await Promise.resolve(1); + thenCallback(result); + } catch (e) { + errorCallback(e); + } +} + +async function doTestPromiseReject() +{ + try { + let result = await Promise.reject(new Error("2")) + thenCallback(result); + } catch (e) { + errorCallback(e); + } +} + +var test = function() +{ + var totalDebuggerStatements = 5; + var maxAsyncCallStackDepth = 5; + InspectorTest.runAsyncCallStacksTest(totalDebuggerStatements, maxAsyncCallStackDepth); +} + +</script> +</head> + +<body onload="runTest()"> +<p> +Tests asynchronous call stacks for async functions. +</p> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.png new file mode 100644 index 0000000..5309f61 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.txt new file mode 100644 index 0000000..def0eb24 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.txt
@@ -0,0 +1,35 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x381 + LayoutBlockFlow {HTML} at (0,0) size 800x381 + LayoutBlockFlow {BODY} at (8,8) size 784x365 + LayoutBlockFlow {DIV} at (0,0) size 50x50 + LayoutText {#text} at (50,35) size 4x19 + text run at (50,35) width 4: " " + LayoutBlockFlow {DIV} at (54,0) size 50x50 + LayoutText {#text} at (104,35) size 4x19 + text run at (104,35) width 4: " " + LayoutBlockFlow {DIV} at (108,0) size 50x50 + LayoutText {#text} at (158,35) size 4x19 + text run at (158,35) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,55) size 100x100 + LayoutText {#text} at (100,140) size 4x19 + text run at (100,140) width 4: " " + LayoutBlockFlow {DIV} at (104,55) size 100x100 + LayoutText {#text} at (204,140) size 4x19 + text run at (204,140) width 4: " " + LayoutBlockFlow {DIV} at (208,55) size 100x100 + LayoutText {#text} at (308,140) size 4x19 + text run at (308,140) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,160) size 200x200 + LayoutText {#text} at (200,345) size 4x19 + text run at (200,345) width 4: " " + LayoutBlockFlow {DIV} at (204,160) size 200x200 + LayoutText {#text} at (404,345) size 4x19 + text run at (404,345) width 4: " " + LayoutBlockFlow {DIV} at (408,160) size 200x200 + LayoutText {#text} at (608,345) size 4x19 + text run at (608,345) width 4: " " + LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-expected.txt new file mode 100644 index 0000000..bf26658c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-expected.txt
@@ -0,0 +1,35 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x378 + LayoutBlockFlow {HTML} at (0,0) size 800x378 + LayoutBlockFlow {BODY} at (8,8) size 784x362 + LayoutBlockFlow {DIV} at (0,0) size 50x50 + LayoutText {#text} at (50,36) size 4x18 + text run at (50,36) width 4: " " + LayoutBlockFlow {DIV} at (54,0) size 50x50 + LayoutText {#text} at (104,36) size 4x18 + text run at (104,36) width 4: " " + LayoutBlockFlow {DIV} at (108,0) size 50x50 + LayoutText {#text} at (158,36) size 4x18 + text run at (158,36) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,54) size 100x100 + LayoutText {#text} at (100,140) size 4x18 + text run at (100,140) width 4: " " + LayoutBlockFlow {DIV} at (104,54) size 100x100 + LayoutText {#text} at (204,140) size 4x18 + text run at (204,140) width 4: " " + LayoutBlockFlow {DIV} at (208,54) size 100x100 + LayoutText {#text} at (308,140) size 4x18 + text run at (308,140) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,158) size 200x200 + LayoutText {#text} at (200,344) size 4x18 + text run at (200,344) width 4: " " + LayoutBlockFlow {DIV} at (204,158) size 200x200 + LayoutText {#text} at (404,344) size 4x18 + text run at (404,344) width 4: " " + LayoutBlockFlow {DIV} at (408,158) size 200x200 + LayoutText {#text} at (608,344) size 4x18 + text run at (608,344) width 4: " " + LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.txt new file mode 100644 index 0000000..e2bfe9a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.txt
@@ -0,0 +1,35 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x378 + LayoutBlockFlow {HTML} at (0,0) size 800x378 + LayoutBlockFlow {BODY} at (8,8) size 784x362 + LayoutBlockFlow {DIV} at (0,0) size 50x50 + LayoutText {#text} at (50,36) size 4x17 + text run at (50,36) width 4: " " + LayoutBlockFlow {DIV} at (54,0) size 50x50 + LayoutText {#text} at (104,36) size 4x17 + text run at (104,36) width 4: " " + LayoutBlockFlow {DIV} at (108,0) size 50x50 + LayoutText {#text} at (158,36) size 4x17 + text run at (158,36) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,54) size 100x100 + LayoutText {#text} at (100,140) size 4x17 + text run at (100,140) width 4: " " + LayoutBlockFlow {DIV} at (104,54) size 100x100 + LayoutText {#text} at (204,140) size 4x17 + text run at (204,140) width 4: " " + LayoutBlockFlow {DIV} at (208,54) size 100x100 + LayoutText {#text} at (308,140) size 4x17 + text run at (308,140) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,158) size 200x200 + LayoutText {#text} at (200,344) size 4x17 + text run at (200,344) width 4: " " + LayoutBlockFlow {DIV} at (204,158) size 200x200 + LayoutText {#text} at (404,344) size 4x17 + text run at (404,344) width 4: " " + LayoutBlockFlow {DIV} at (408,158) size 200x200 + LayoutText {#text} at (608,344) size 4x17 + text run at (608,344) width 4: " " + LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.html b/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.html index 03e0925..6a84c91 100644 --- a/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.html +++ b/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.html
@@ -1,32 +1,37 @@ <!DOCTYPE html> <title>Sizing SVG image when drawn to canvas</title> <script> -function createCircle(x, y, r, sx, sy) +function createCanvas(drawFunc) { var canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 100; document.documentElement.appendChild(canvas); - var ctx = canvas.getContext('2d'); + drawFunc(canvas.getContext('2d')); +} + +function drawCircle(ctx, x, y, r, sx, sy) +{ ctx.fillStyle = "blue"; - ctx.translate(50, 50); ctx.scale(sx || 1, sy || 1); ctx.beginPath(); ctx.arc(x, y, r, 0, 2*Math.PI); ctx.fill(); } -createCircle(0, 0, 50); -createCircle(0, -25, 25); -createCircle(-25, 0, 25); -createCircle(0, 0, 25, 1, 2); -createCircle(0, 0, 25, 2, 1); -createCircle(-25, 0, 25); -createCircle(0, -25, 25); -createCircle(0, -25, 25); -createCircle(0, 0, 50); -createCircle(0, 0, 50); -createCircle(0, -25, 25); -createCircle(0, 0, 50); + +createCanvas(function (ctx) { drawCircle(ctx, 50, 50, 50); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 25, 25); }); +createCanvas(function (ctx) { drawCircle(ctx, 25, 50, 25); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 25, 25, 1, 2); }); +createCanvas(function (ctx) { drawCircle(ctx, 25, 50, 25, 2, 1); }); +createCanvas(function (ctx) { drawCircle(ctx, 25, 50, 25); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 25, 25); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 25, 25); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 50, 50); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 50, 50); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 25, 25); drawCircle(ctx, 50, 75, 25); }); +createCanvas(function (ctx) { drawCircle(ctx, 50, 50, 50); }); + </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffer-getChannelData.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffer-getChannelData.html index bb5064a3..667dbfd9 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffer-getChannelData.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffer-getChannelData.html
@@ -1,10 +1,10 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> - <script src="../resources/js-test.js"></script> <title>Test AudioBuffer.getChannelData() Returns the Same Object</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffer-resample.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffer-resample.html index 0a56884..85eeeb0 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffer-resample.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffer-resample.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-grain.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-grain.html index 0011e27..040c284 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-grain.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-grain.html
@@ -2,9 +2,9 @@ <html> <head> <title>Test Start Grain with Delayed Buffer Setting </title> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-loop-comprehensive.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-loop-comprehensive.html index b012b24e..bece52e 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-loop-comprehensive.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-loop-comprehensive.html
@@ -2,10 +2,10 @@ <html> <head> -<script src="resources/audio-testing.js"></script> -<script src="resources/compatibility.js"></script> -<script src="resources/audiobuffersource-testing.js"></script> <script src="../resources/js-test.js"></script> +<script src="resources/compatibility.js"></script> +<script src="resources/audio-testing.js"></script> +<script src="resources/audiobuffersource-testing.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-one-sample-loop.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-one-sample-loop.html index f15d77e..906c100 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-one-sample-loop.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-one-sample-loop.html
@@ -2,9 +2,9 @@ <html> <head> <title>Test AudioBufferSourceNode With Looping a Single-Sample Buffer</title> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-start.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-start.html index 012c0c4..2f803873 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-start.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-start.html
@@ -2,10 +2,10 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audiobuffersource-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiocontext-close-basic.html b/third_party/WebKit/LayoutTests/webaudio/audiocontext-close-basic.html index c661916f..2785fed 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiocontext-close-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiocontext-close-basic.html
@@ -2,9 +2,9 @@ <html> <head> <title>Test AudioContext.close() closes many contexts</title> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-connect-audioratesignal.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-connect-audioratesignal.html index f261959..93f13cda 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-connect-audioratesignal.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-connect-audioratesignal.html
@@ -11,9 +11,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-exponentialRampToValueAtTime.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-exponentialRampToValueAtTime.html index 5af3ffb2..b0cfe3a 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-exponentialRampToValueAtTime.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-exponentialRampToValueAtTime.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> - <script src="../resources/js-test.js"></script> <title>Test AudioParam.exponentialRampToValueAtTime</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html index 6f5ade8..5862738 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> -<script src="../resources/js-test.js"></script> <title>Test AudioParam.linearRampToValueAtTime</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-sampling.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-sampling.html index c4561788..af68c36 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-sampling.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-sampling.html
@@ -1,10 +1,10 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> - <script src="../resources/js-test.js"></script> <title>Test Sampling of LinearRampToValueAtTime</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime-sampling.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime-sampling.html index adbce48..e9a6651 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime-sampling.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime-sampling.html
@@ -1,10 +1,10 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> - <script src="../resources/js-test.js"></script> <title>Test Sampling for SetTargetAtTime</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime.html index 200f02d..b10f6942 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-setTargetAtTime.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> -<script src="../resources/js-test.js"></script> <title>Test AudioParam.setTargetAtTime</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueAtTime.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueAtTime.html index 908c4b9..9319240 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueAtTime.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueAtTime.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurve-duration.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurve-duration.html index 50be73c..982af386 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurve-duration.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurve-duration.html
@@ -1,10 +1,10 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> - <script src="../resources/js-test.js"></script> <title>Test setValueCurveAtTime with Huge Duration</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurveAtTime.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurveAtTime.html index 09f60e9..4cc47c1d 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurveAtTime.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurveAtTime.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> -<script src="../resources/js-test.js"></script> <title>Test AudioParam.setValueCurveAtTime</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-summingjunction.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-summingjunction.html index 60bf7fa..7bd5eef 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-summingjunction.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-summingjunction.html
@@ -7,10 +7,10 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/mix-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-update-value-attribute.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-update-value-attribute.html index 8cb4eab2..4824971 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-update-value-attribute.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-update-value-attribute.html
@@ -1,10 +1,10 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audio-param.js"></script> - <script src="../resources/js-test.js"></script> <title>Updating of Value Attribute from Timeline</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiosource-time-limits.html b/third_party/WebKit/LayoutTests/webaudio/audiosource-time-limits.html index 59cdb7b..7a9f6c7 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiosource-time-limits.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiosource-time-limits.html
@@ -1,10 +1,10 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/audioparam-testing.js"></script> - <script src="../resources/js-test.js"></script> <title>Test Scheduled Sources with Huge Time Limits</title> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-allpass.html b/third_party/WebKit/LayoutTests/webaudio/biquad-allpass.html index 8493418..41a07b1 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-allpass.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-allpass.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-bandpass.html b/third_party/WebKit/LayoutTests/webaudio/biquad-bandpass.html index 14885e7..69c3996 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-bandpass.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-bandpass.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-getFrequencyResponse.html b/third_party/WebKit/LayoutTests/webaudio/biquad-getFrequencyResponse.html index b517a6e..0c95af10 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-getFrequencyResponse.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-getFrequencyResponse.html
@@ -1,11 +1,11 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-highpass.html b/third_party/WebKit/LayoutTests/webaudio/biquad-highpass.html index d12b482..ddf1819 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-highpass.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-highpass.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-highshelf.html b/third_party/WebKit/LayoutTests/webaudio/biquad-highshelf.html index 346867da..d47f654 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-highshelf.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-highshelf.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-lowpass.html b/third_party/WebKit/LayoutTests/webaudio/biquad-lowpass.html index cb8c306..daaf838 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-lowpass.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-lowpass.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-lowshelf.html b/third_party/WebKit/LayoutTests/webaudio/biquad-lowshelf.html index 27a6f3b5..92d1410 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-lowshelf.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-lowshelf.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-notch.html b/third_party/WebKit/LayoutTests/webaudio/biquad-notch.html index 177f4d0..cc99940 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-notch.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-notch.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/biquad-peaking.html b/third_party/WebKit/LayoutTests/webaudio/biquad-peaking.html index 0f09286..bd44394 100644 --- a/third_party/WebKit/LayoutTests/webaudio/biquad-peaking.html +++ b/third_party/WebKit/LayoutTests/webaudio/biquad-peaking.html
@@ -2,9 +2,9 @@ <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-filters.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/convolution-mono-mono.html b/third_party/WebKit/LayoutTests/webaudio/convolution-mono-mono.html index 8f4cc79..57d6cb2c 100644 --- a/third_party/WebKit/LayoutTests/webaudio/convolution-mono-mono.html +++ b/third_party/WebKit/LayoutTests/webaudio/convolution-mono-mono.html
@@ -2,9 +2,9 @@ <html> <head> -<script src="resources/compatibility.js"></script> -<script type="text/javascript" src="resources/audio-testing.js"></script> <script src="../resources/js-test.js"></script> +<script src="resources/compatibility.js"></script> +<script src="resources/audio-testing.js"></script> <script src="resources/convolution-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html b/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html index 72a46e9..403f513 100644 --- a/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html +++ b/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/distance-exponential.html b/third_party/WebKit/LayoutTests/webaudio/distance-exponential.html index 2d87447..a7c321f 100644 --- a/third_party/WebKit/LayoutTests/webaudio/distance-exponential.html +++ b/third_party/WebKit/LayoutTests/webaudio/distance-exponential.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/distance-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/distance-inverse.html b/third_party/WebKit/LayoutTests/webaudio/distance-inverse.html index 8fe4258..37196055 100644 --- a/third_party/WebKit/LayoutTests/webaudio/distance-inverse.html +++ b/third_party/WebKit/LayoutTests/webaudio/distance-inverse.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/distance-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/distance-linear.html b/third_party/WebKit/LayoutTests/webaudio/distance-linear.html index 57e9fda..75b1741b 100644 --- a/third_party/WebKit/LayoutTests/webaudio/distance-linear.html +++ b/third_party/WebKit/LayoutTests/webaudio/distance-linear.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/distance-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html index afea8f6..a8e5a97 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> <script src="resources/biquad-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/dynamicscompressor-clear-internal-state.html b/third_party/WebKit/LayoutTests/webaudio/dynamicscompressor-clear-internal-state.html index 8867190..8c6ea19 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dynamicscompressor-clear-internal-state.html +++ b/third_party/WebKit/LayoutTests/webaudio/dynamicscompressor-clear-internal-state.html
@@ -2,9 +2,9 @@ <html> <head> <title>Validate Reduction Value of DynamicsComporessor after Disabling</title> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/note-grain-on-play.html b/third_party/WebKit/LayoutTests/webaudio/note-grain-on-play.html index 6f6c3d9c..119cf52 100644 --- a/third_party/WebKit/LayoutTests/webaudio/note-grain-on-play.html +++ b/third_party/WebKit/LayoutTests/webaudio/note-grain-on-play.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/note-grain-on-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/note-grain-on-timing.html b/third_party/WebKit/LayoutTests/webaudio/note-grain-on-timing.html index 543f8b9..44625343 100644 --- a/third_party/WebKit/LayoutTests/webaudio/note-grain-on-timing.html +++ b/third_party/WebKit/LayoutTests/webaudio/note-grain-on-timing.html
@@ -1,10 +1,10 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> <script src="resources/note-grain-on-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-detached-no-crash.html b/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-detached-no-crash.html index 378de48..b1ff8bd 100644 --- a/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-detached-no-crash.html +++ b/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-detached-no-crash.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body> <script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/oscillator-basic.html b/third_party/WebKit/LayoutTests/webaudio/oscillator-basic.html index a55042b..f08b5db5 100644 --- a/third_party/WebKit/LayoutTests/webaudio/oscillator-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/oscillator-basic.html
@@ -5,9 +5,9 @@ --> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> -<script type="text/javascript" src="resources/audio-testing.js"></script> -<script type="text/javascript" src="../resources/js-test.js"></script> +<script src="resources/audio-testing.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/panner-automation-equalpower-stereo.html b/third_party/WebKit/LayoutTests/webaudio/panner-automation-equalpower-stereo.html index 42e6e285..3e0683ca 100644 --- a/third_party/WebKit/LayoutTests/webaudio/panner-automation-equalpower-stereo.html +++ b/third_party/WebKit/LayoutTests/webaudio/panner-automation-equalpower-stereo.html
@@ -1,9 +1,9 @@ <!doctype html> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/panner-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/panner-equalpower-stereo.html b/third_party/WebKit/LayoutTests/webaudio/panner-equalpower-stereo.html index ed76004..7fb68f7 100644 --- a/third_party/WebKit/LayoutTests/webaudio/panner-equalpower-stereo.html +++ b/third_party/WebKit/LayoutTests/webaudio/panner-equalpower-stereo.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/panner-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/panner-equalpower.html b/third_party/WebKit/LayoutTests/webaudio/panner-equalpower.html index 2ce02a9e..097aa787 100644 --- a/third_party/WebKit/LayoutTests/webaudio/panner-equalpower.html +++ b/third_party/WebKit/LayoutTests/webaudio/panner-equalpower.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/panner-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/panner-loop.html b/third_party/WebKit/LayoutTests/webaudio/panner-loop.html index e069dfd..5b20173 100644 --- a/third_party/WebKit/LayoutTests/webaudio/panner-loop.html +++ b/third_party/WebKit/LayoutTests/webaudio/panner-loop.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/panner-model-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js index c248762..09f2bf7 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js
@@ -1,3 +1,51 @@ +/* global self */ + +// testharness.js has the higher priority. +var TESTHARNESS = true; +var JSTEST = false; + +(function () { + // Selected properies from testharness.js + var testharnessProperties = [ + 'test', 'async_test', 'promise_test', 'promise_rejects', + 'generate_tests', 'setup', 'done', 'assert_true', 'assert_false' + ]; + + // Selected properties from js-test.js + var jsTestProperties = [ + 'isJsTest', 'testPassed', 'testFailed', 'gc', 'finishJSTest' + ]; + + // Check if testharness.js is properly loaded and set up a flag for it. + for (var name in testharnessProperties) { + if (!self.hasOwnProperty(testharnessProperties[name])) { + TESTHARNESS = false; + break; + } + } + + // Immediately return here because testharness.js is ready. + if (TESTHARNESS) + return; + + // Because testharness.js is not loaded, let us assume that js-test.js might + // be in use. Check if js-test.js is properly loaded and set up a flag for + // it. + JSTEST = true; + for (var name in jsTestProperties) { + if (!self.hasOwnProperty(jsTestProperties[name])) { + JSTEST = false; + break; + } + } + + // If both are not loaded at all, throw here. + if (!JSTEST) + throw new Error('Cannot proceed. No test infrastructure is loaded.'); +})(); + + + function writeString(s, a, offset) { for (var i = 0; i < s.length; ++i) { a[offset + i] = s.charCodeAt(i); @@ -301,6 +349,24 @@ this.currentTask = 0; } + // This is to prime the task runner for the testharness.js async operation. + Tasks.prototype._initialize = function () { + if (TESTHARNESS) { + setup(new Function(), { + explicit_done: true + }); + } + }; + + // Finalize the task runner by notifying testharness and testRunner that + // all the task is completed. + Tasks.prototype._finalize = function () { + if (TESTHARNESS) { + // From testharness.js + done(); + } + }; + Tasks.prototype.defineTask = function (taskName, taskFunc) { // Check if there is a task defined with the same name. If found, do // not add the task to the roster. @@ -320,6 +386,8 @@ // is no argument, run all the defined tasks. Tasks.prototype.runTasks = function () { + this._initialize(); + if (arguments.length > 0) { // Reset task queue and refill it with the with the given arguments, @@ -341,21 +409,23 @@ return; } - // done() callback from each task. Increase the task index and call the - // next task. Note that explicit signaling by done() in each task - // is needed because some of tests run asynchronously. - var done = function () { + // taskDone() callback from each task. Increase the task index and call + // the next task. Note that explicit signaling by taskDone() in each + // task is needed because some of tests run asynchronously. + var taskDone = function () { if (this.currentTask !== this.queue.length - 1) { ++this.currentTask; // debug('>> Audit.runTasks: ' + this.queue[this.currentTask]); - this.tasks[this.queue[this.currentTask]](done); + this.tasks[this.queue[this.currentTask]](taskDone); + } else { + this._finalize(); } return; }.bind(this); // Start the first task. // debug('>> Audit.runTasks: ' + this.queue[this.currentTask]); - this.tasks[this.queue[this.currentTask]](done); + this.tasks[this.queue[this.currentTask]](taskDone); }; return { @@ -399,12 +469,6 @@ // Check if the target contains any NaN value. this._checkNaN(this.target, 'ACTUAL'); - // if (resultNaNCheck.length > 0) { - // var failureMessage = 'NaN found while testing the target (' + label + ')'; - // testFailed(failureMessage + ': "' + this.desc + '" \n' + - // resultNaNCheck); - // throw failureMessage; - // } // |_testPassed| and |_testFailed| set this appropriately. this._success = false; @@ -428,13 +492,28 @@ // Internal methods starting with a underscore. ShouldModel.prototype._testPassed = function (msg) { - testPassed(this.desc + ' ' + msg + '.'); this._success = true; + if (TESTHARNESS) { + // Using testharness.js + test(function () { + assert_true(true); + }, this.desc + ' ' + msg + '.'); + } else { + // Using js-test.js + testPassed(this.desc + ' ' + msg + '.'); + } }; ShouldModel.prototype._testFailed = function (msg) { - testFailed(this.desc + ' ' + msg + '.'); this._success = false; + var that = this; + if (TESTHARNESS) { + test(function () { + assert_true(false, that.desc + ' ' + msg + '.'); + }, this.desc); + } else { + testFailed(this.desc + ' ' + msg + '.'); + } }; ShouldModel.prototype._isArray = function (arg) { @@ -451,7 +530,15 @@ var failureMessage = 'Assertion failed: ' + reason + ' ' + this.desc +'.'; if (arguments.length >= 3) failureMessage += ": " + value; - testFailed(failureMessage); + + if (TESTHARNESS) { + test(function () { + assert_true(false, reason + ' (' + value + ')'); + }, this.desc) + } else { + testFailed(failureMessage); + } + throw failureMessage; }; @@ -464,7 +551,14 @@ // Checking a single variable first. if (Number.isNaN(value)) { - testFailed(failureMessage); + if (TESTHARNESS) { + test(function () { + assert_true(false, failureMessage); + }, this.desc) + } else { + testFailed(failureMessage); + } + throw failureMessage; } @@ -492,7 +586,14 @@ } } - testFailed(failureMessage + failureDetail); + if (TESTHARNESS) { + test(function () { + assert_true(false, failureMessage + failureDetail); + }, this.desc) + } else { + testFailed(failureMessage + failureDetail); + } + throw failureMessage; };
diff --git a/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-detached-no-crash.html b/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-detached-no-crash.html index 84a4da8..e2533a0 100644 --- a/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-detached-no-crash.html +++ b/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-detached-no-crash.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body> <script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-zero-input-channels.html b/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-zero-input-channels.html index e54a603..8491bb6 100644 --- a/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-zero-input-channels.html +++ b/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-zero-input-channels.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> +<script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> -<script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-basic.html b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-basic.html index 96f7c662..cd2a73f 100644 --- a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-basic.html
@@ -2,9 +2,9 @@ <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-panning.html b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-panning.html index 8fffd0b..70c62bd3 100644 --- a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-panning.html +++ b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-panning.html
@@ -2,9 +2,9 @@ <html> <head> + <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="../resources/js-test.js"></script> <script src="resources/stereopanner-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/jstest-test-expected.txt b/third_party/WebKit/LayoutTests/webaudio/unit-tests/jstest-test-expected.txt new file mode 100644 index 0000000..af4df7a3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/jstest-test-expected.txt
@@ -0,0 +1,20 @@ +A simple unit testing for audio-testing.js and js-test.js + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS Zero is equal to 0. +PASS One is not equal to 0. +PASS Expected SNR (110) is greater than or equal to 100. +PASS Maximum error value (0.000001) is less than or equal to 0.00001. +FAIL max error (0.000001) is not less than or equal to -1. +PASS One point double zero one is 1 within a relative error of 0.1. +FAIL Two is not 1 within a relative error of 0.1: 2 with relative error 1. +PASS [2, 2, 2] contains only the constant 2. +PASS [1, 2, 3] is identical to the array [1,2,3]. +PASS My array equals [0.1,0.2] with an element-wise tolerance of 0.02. +PASS My random array contains all the expected values in the correct order: [1,3,2]. +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/jstest-test.html b/third_party/WebKit/LayoutTests/webaudio/unit-tests/jstest-test.html new file mode 100644 index 0000000..5c3b694 --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/jstest-test.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> + <title>A simple unit testing for audio-testing.js and js-test.js</title> + <script src="../../resources/js-test.js"></script> + <script src="../resources/audio-testing.js"></script> +</head> +<body> + <script> + description('A simple unit testing for audio-testing.js and js-test.js'); + window.jsTestIsAsync = true; + + var audit = Audit.createTaskRunner(); + + audit.defineTask('foo', function (taskDone) { + Should('Zero', 0).beEqualTo(0); + Should('One', 1).notBeEqualTo(0); + Should('Expected SNR', 110).beGreaterThanOrEqualTo(100); + taskDone(); + }); + + audit.defineTask('bar', function (taskDone) { + var maxError = 1e-6; + Should("Maximum error value", maxError).beLessThanOrEqualTo(1e-5); + Should("max error", maxError).beLessThanOrEqualTo(-1); + Should('One point double zero one', 1.001).beCloseTo(1, .1); + Should('Two', 2).beCloseTo(1, .1); + taskDone(); + }); + + audit.defineTask('boo', function (taskDone) { + Should('[2, 2, 2]', [2, 2, 2]).beConstantValueOf(2); + Should('[1, 2, 3]', [1, 2, 3]).beEqualToArray([1, 2, 3]); + Should('My array', [0.11, 0.19]).beCloseToArray([0.1, 0.2], 0.02); + Should('My random array', [1, 1, 3, 3, 2]).containValues([1, 3, 2]); + taskDone(); + }); + + audit.defineTask("finish", function (done) { + finishJSTest(); + done(); + }); + + audit.runTasks(); + </script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/testharness-test.html b/third_party/WebKit/LayoutTests/webaudio/unit-tests/testharness-test.html new file mode 100644 index 0000000..c2c80da --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/testharness-test.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> + <title>A simple unit testing for audio-testing.js and testharness.js</title> + + <!-- This is the required dependency for testharness + audio-testing. Note + that the including order matters because audio-testing.js depends on + testharness.js --> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> + <script src="../resources/audio-testing.js"></script> + +</head> +<body> + <script> + var audit = Audit.createTaskRunner(); + + audit.defineTask('foo', function (taskDone) { + Should('Zero', 0).beEqualTo(0); + Should('One', 1).notBeEqualTo(0); + Should('Expected SNR', 110).beGreaterThanOrEqualTo(100); + taskDone(); + }); + + audit.defineTask('bar', function (taskDone) { + var maxError = 1e-6; + Should("Maximum error value", maxError).beLessThanOrEqualTo(1e-5); + Should('One point double zero one', 1.001).beCloseTo(1, .1); + taskDone(); + }); + + audit.defineTask('boo', function (taskDone) { + Should('[2, 2, 2]', [2, 2, 2]).beConstantValueOf(2); + Should('[1, 2, 3]', [1, 2, 3]).beEqualToArray([1, 2, 3]); + Should('My array', [0.11, 0.19]).beCloseToArray([0.1, 0.2], 0.02); + Should('My random array', [1, 1, 3, 3, 2]).containValues([1, 3, 2]); + taskDone(); + }); + + audit.runTasks(); + </script> +</body> +</html>
diff --git a/third_party/WebKit/Source/build/scripts/make_event_factory.py b/third_party/WebKit/Source/build/scripts/make_event_factory.py index 48b9586..a6ae1858 100755 --- a/third_party/WebKit/Source/build/scripts/make_event_factory.py +++ b/third_party/WebKit/Source/build/scripts/make_event_factory.py
@@ -71,7 +71,6 @@ # or be deprecated/removed. https://crbug.com/569690 def create_event_legacy_whitelist(name): return (name == 'AnimationEvent' - or name == 'AnimationPlayerEvent' or name == 'ApplicationCacheErrorEvent' or name == 'AudioProcessingEvent' or name == 'BeforeInstallPromptEvent' @@ -80,7 +79,6 @@ or name == 'ClipboardEvent' or name == 'CloseEvent' or name == 'CompositionEvent' - or name == 'DeviceLightEvent' or name == 'DeviceMotionEvent' or name == 'DeviceOrientationEvent' or name == 'DragEvent' @@ -90,12 +88,9 @@ or name == 'FetchEvent' or name == 'FocusEvent' or name == 'FontFaceSetLoadEvent' - or name == 'ForeignFetchEvent' or name == 'GamepadEvent' or name == 'HashChangeEvent' or name == 'IDBVersionChangeEvent' - or name == 'InputEvent' - or name == 'InstallEvent' or name == 'KeyboardEvents' or name == 'MediaEncryptedEvent' or name == 'MediaKeyMessageEvent' @@ -110,22 +105,17 @@ or name == 'OfflineAudioCompletionEvent' or name == 'OrientationEvent' or name == 'PageTransitionEvent' - or name == 'PaymentRequestUpdateEvent' - or name == 'PointerEvent' or name == 'PopStateEvent' or name == 'PresentationConnectionAvailableEvent' or name == 'PresentationConnectionCloseEvent' or name == 'ProgressEvent' or name == 'PromiseRejectionEvent' or name == 'PushEvent' - or name == 'RelatedEvent' or name == 'ResourceProgressEvent' or name == 'RTCDataChannelEvent' or name == 'RTCDTMFToneChangeEvent' or name == 'RTCIceCandidateEvent' or name == 'SecurityPolicyViolationEvent' - or name == 'SensorErrorEvent' - or name == 'SensorReadingEvent' or name == 'ServiceWorkerMessageEvent' or name == 'SpeechRecognitionError' or name == 'SpeechRecognitionEvent'
diff --git a/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp b/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp index 55891e8..1ff3250 100644 --- a/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp +++ b/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp
@@ -6,12 +6,6 @@ namespace blink { -AnimationPlayerEvent::AnimationPlayerEvent() - : m_currentTime(0.0) - , m_timelineTime(0.0) -{ -} - AnimationPlayerEvent::AnimationPlayerEvent(const AtomicString& type, double currentTime, double timelineTime) : Event(type, false, false) , m_currentTime(currentTime)
diff --git a/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h b/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h index f5d2287..01fa2b29 100644 --- a/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h +++ b/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h
@@ -13,10 +13,6 @@ class AnimationPlayerEvent final : public Event { DEFINE_WRAPPERTYPEINFO(); public: - static AnimationPlayerEvent* create() - { - return new AnimationPlayerEvent; - } static AnimationPlayerEvent* create(const AtomicString& type, double currentTime, double timelineTime) { return new AnimationPlayerEvent(type, currentTime, timelineTime); @@ -37,7 +33,6 @@ DECLARE_VIRTUAL_TRACE(); private: - AnimationPlayerEvent(); AnimationPlayerEvent(const AtomicString& type, double currentTime, double timelineTime); AnimationPlayerEvent(const AtomicString&, const AnimationPlayerEventInit&);
diff --git a/third_party/WebKit/Source/core/events/InputEvent.cpp b/third_party/WebKit/Source/core/events/InputEvent.cpp index 2c99eda..395b5d9b 100644 --- a/third_party/WebKit/Source/core/events/InputEvent.cpp +++ b/third_party/WebKit/Source/core/events/InputEvent.cpp
@@ -85,10 +85,6 @@ } // anonymous namespace -InputEvent::InputEvent() -{ -} - InputEvent::InputEvent(const AtomicString& type, const InputEventInit& initializer) : UIEvent(type, initializer) {
diff --git a/third_party/WebKit/Source/core/events/InputEvent.h b/third_party/WebKit/Source/core/events/InputEvent.h index a8d6c07..2a002647 100644 --- a/third_party/WebKit/Source/core/events/InputEvent.h +++ b/third_party/WebKit/Source/core/events/InputEvent.h
@@ -15,11 +15,6 @@ DEFINE_WRAPPERTYPEINFO(); public: - static InputEvent* create() - { - return new InputEvent; - } - static InputEvent* create(const AtomicString& type, const InputEventInit& initializer) { return new InputEvent(type, initializer); @@ -110,7 +105,6 @@ private: friend class InputEventDispatchMediator; - InputEvent(); InputEvent(const AtomicString&, const InputEventInit&); InputType m_inputType;
diff --git a/third_party/WebKit/Source/core/events/PointerEvent.cpp b/third_party/WebKit/Source/core/events/PointerEvent.cpp index cf32bc42..9d0adc5 100644 --- a/third_party/WebKit/Source/core/events/PointerEvent.cpp +++ b/third_party/WebKit/Source/core/events/PointerEvent.cpp
@@ -9,17 +9,6 @@ namespace blink { -PointerEvent::PointerEvent() - : m_pointerId(0) - , m_width(0) - , m_height(0) - , m_pressure(0) - , m_tiltX(0) - , m_tiltY(0) - , m_isPrimary(false) -{ -} - PointerEvent::PointerEvent(const AtomicString& type, const PointerEventInit& initializer) : MouseEvent(type, initializer) , m_pointerId(0)
diff --git a/third_party/WebKit/Source/core/events/PointerEvent.h b/third_party/WebKit/Source/core/events/PointerEvent.h index 2ca02ba6..4f943c8a 100644 --- a/third_party/WebKit/Source/core/events/PointerEvent.h +++ b/third_party/WebKit/Source/core/events/PointerEvent.h
@@ -15,11 +15,6 @@ DEFINE_WRAPPERTYPEINFO(); public: - static PointerEvent* create() - { - return new PointerEvent; - } - static PointerEvent* create(const AtomicString& type, const PointerEventInit& initializer) { return new PointerEvent(type, initializer); @@ -43,7 +38,6 @@ DECLARE_VIRTUAL_TRACE(); private: - PointerEvent(); PointerEvent(const AtomicString&, const PointerEventInit&); int m_pointerId;
diff --git a/third_party/WebKit/Source/core/events/RelatedEvent.cpp b/third_party/WebKit/Source/core/events/RelatedEvent.cpp index a214507..549de548 100644 --- a/third_party/WebKit/Source/core/events/RelatedEvent.cpp +++ b/third_party/WebKit/Source/core/events/RelatedEvent.cpp
@@ -10,11 +10,6 @@ { } -RelatedEvent* RelatedEvent::create() -{ - return new RelatedEvent; -} - RelatedEvent* RelatedEvent::create(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget) { return new RelatedEvent(type, canBubble, cancelable, relatedTarget); @@ -25,10 +20,6 @@ return new RelatedEvent(type, initializer); } -RelatedEvent::RelatedEvent() -{ -} - RelatedEvent::RelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget) : Event(type, canBubble, cancelable) , m_relatedTarget(relatedTarget)
diff --git a/third_party/WebKit/Source/core/events/RelatedEvent.h b/third_party/WebKit/Source/core/events/RelatedEvent.h index f590a52..3dd3c1a 100644 --- a/third_party/WebKit/Source/core/events/RelatedEvent.h +++ b/third_party/WebKit/Source/core/events/RelatedEvent.h
@@ -13,7 +13,6 @@ class RelatedEvent final : public Event { DEFINE_WRAPPERTYPEINFO(); public: - static RelatedEvent* create(); static RelatedEvent* create(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget); static RelatedEvent* create(const AtomicString& eventType, const RelatedEventInit&); @@ -27,7 +26,6 @@ DECLARE_VIRTUAL_TRACE(); private: - RelatedEvent(); RelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget*); RelatedEvent(const AtomicString& type, const RelatedEventInit&);
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index c1a17a1..944166c 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -954,7 +954,6 @@ DocumentCreateEventFontFaceSetLoadEvent = 1160, DocumentCreateEventMediaQueryListEvent = 1161, DocumentCreateEventAnimationEvent = 1162, - DocumentCreateEventAnimationPlayerEvent = 1163, DocumentCreateEventApplicationCacheErrorEvent = 1164, DocumentCreateEventBeforeUnloadEvent = 1166, DocumentCreateEventClipboardEvent = 1167, @@ -965,11 +964,9 @@ DocumentCreateEventHashChangeEvent = 1172, DocumentCreateEventMutationEvent = 1173, DocumentCreateEventPageTransitionEvent = 1174, - DocumentCreateEventPointerEvent = 1175, DocumentCreateEventPopStateEvent = 1176, DocumentCreateEventProgressEvent = 1177, DocumentCreateEventPromiseRejectionEvent = 1178, - DocumentCreateEventRelatedEvent = 1179, DocumentCreateEventResourceProgressEvent = 1180, DocumentCreateEventSecurityPolicyViolationEvent = 1181, DocumentCreateEventTextEvent = 1182, @@ -983,7 +980,6 @@ DocumentCreateEventWebKitTransitionEvent = 1191, DocumentCreateEventBeforeInstallPromptEvent = 1192, DocumentCreateEventSyncEvent = 1193, - DocumentCreateEventDeviceLightEvent = 1194, DocumentCreateEventDeviceMotionEvent = 1195, DocumentCreateEventDeviceOrientationEvent = 1196, DocumentCreateEventMediaEncryptedEvent = 1197, @@ -1003,7 +999,6 @@ DocumentCreateEventExtendableEvent = 1213, DocumentCreateEventExtendableMessageEvent = 1214, DocumentCreateEventFetchEvent = 1215, - DocumentCreateEventInstallEvent = 1216, DocumentCreateEventServiceWorkerMessageEvent = 1217, DocumentCreateEventSpeechRecognitionError = 1218, DocumentCreateEventSpeechRecognitionEvent = 1219, @@ -1027,7 +1022,6 @@ V8ForInInitializer = 1238, V8Animation_Id_AttributeGetter = 1239, V8Animation_Id_AttributeSetter = 1240, - DocumentCreateEventInputEvent = 1242, WebAnimationHyphenatedProperty = 1243, FormControlsCollectionReturnsRadioNodeListForFieldSet = 1244, ApplicationCacheManifestSelectInsecureOrigin = 1245, @@ -1066,7 +1060,6 @@ InvalidReportUriDirectiveInMetaCSP = 1281, InvalidSandboxDirectiveInMetaCSP = 1282, InvalidFrameAncestorsDirectiveInMetaCSP = 1283, - DocumentCreateEventForeignFetchEvent = 1286, SVGCalcModeDiscrete = 1287, SVGCalcModeLinear = 1288, SVGCalcModePaced = 1289, @@ -1121,7 +1114,6 @@ During_Microtask_Print = 1336, During_Microtask_Prompt = 1337, During_Microtask_SyncXHR = 1338, - DocumentCreateEventPaymentRequestUpdateEvent = 1341, CredentialManagerGetReturnedCredential = 1342, GeolocationInsecureOriginDeprecatedNotRemoved = 1343, GeolocationInsecureOriginIframeDeprecatedNotRemoved = 1344, @@ -1167,8 +1159,6 @@ RTCPeerConnectionAddIceCandidatePromise = 1384, RTCPeerConnectionAddIceCandidateLegacy = 1385, RTCIceCandidateDefaultSdpMLineIndex = 1386, - DocumentCreateEventSensorErrorEvent = 1387, - DocumentCreateEventSensorReadingEvent = 1388, MediaStreamConstraintsOldAndNew = 1389, V8ArrayProtectorDirtied = 1390, V8ArraySpeciesModified = 1391,
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h index 578b4b78..a2547141 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -341,6 +341,7 @@ void addOutlineRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, IncludeBlockVisualOverflowOrNot) const override; + bool paintedOutputOfObjectHasNoEffect() const override; PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState&) override; Node* nodeForHitTest() const final;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp index c0e08b00..6d210be 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -2062,6 +2062,15 @@ firstRootBox->setShouldDoFullPaintInvalidationRecursively(); } +bool LayoutBlockFlow::paintedOutputOfObjectHasNoEffect() const +{ + // LayoutBlockFlow is in charge of paint invalidation of the first line. + if (firstLineBox()) + return false; + + return LayoutBlock::paintedOutputOfObjectHasNoEffect(); +} + PaintInvalidationReason LayoutBlockFlow::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) { if (containsFloats())
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 89b23b0..7a739571 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -2034,6 +2034,28 @@ return isForcedFragmentainerBreakValue(classABreakPointValue(previousBreakAfterValue)); } +bool LayoutBox::paintedOutputOfObjectHasNoEffect() const +{ + // In case scrollbars got repositioned (which will typically happen if the box got + // resized), we cannot skip invalidation. + if (hasNonCompositedScrollbars()) + return false; + + // Cannot skip paint invalidation if the box has real things to paint. + if (getSelectionState() != SelectionNone || hasBoxDecorationBackground() || styleRef().hasVisualOverflowingEffect()) + return false; + + // If the box has clip, we need issue a paint invalidation to cover the changed part of + // children because of change of clip when the box got resized. In theory the children + // should invalidate themselves when ancestor clip changes, but for now this is missing + // and ensuring it may hurt performance. + // TODO(wangxianzhu): Paint invalidation for clip change will be different in spv2. + if (hasClipRelatedProperty() || hasControlClip()) + return false; + + return true; +} + LayoutRect LayoutBox::localOverflowRectForPaintInvalidation() const { if (style()->visibility() != VISIBLE)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h index e204676..d7aab38 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.h +++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -695,6 +695,7 @@ // break, we also need to know the break-after value of the previous in-flow sibling. bool needsForcedBreakBefore(EBreak previousBreakAfterValue) const; + bool paintedOutputOfObjectHasNoEffect() const override; LayoutRect localOverflowRectForPaintInvalidation() const override; bool mapToVisualRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect&, VisualRectFlags = DefaultVisualRectFlags) const override; virtual void invalidatePaintForOverhangingFloats(bool paintAllDescendants);
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp index 78d02a87..fbabc29 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -684,28 +684,6 @@ return LayoutFlowThread::locateFlowThreadContainingBlockOf(*this); } -bool LayoutObject::skipInvalidationWhenLaidOutChildren() const -{ - if (!m_bitfields.neededLayoutBecauseOfChildren()) - return false; - - // SVG layoutObjects need to be invalidated when their children are laid out. - // LayoutBlocks with line boxes are responsible to invalidate them so we can't ignore them. - if (isSVG() || (isLayoutBlockFlow() && toLayoutBlockFlow(this)->firstLineBox())) - return false; - - // In case scrollbars got repositioned (which will typically happen if the layout object got - // resized), we cannot skip invalidation. - if (hasNonCompositedScrollbars()) - return false; - - // We can't detect whether a plugin has box effects, so disable this optimization for that case. - if (isEmbeddedObject()) - return false; - - return !hasBoxEffect(); -} - static inline bool objectIsRelayoutBoundary(const LayoutObject* object) { // FIXME: In future it may be possible to broaden these conditions in order to improve performance. @@ -1330,7 +1308,6 @@ selectionPaintInvalidationMap->set(this, selectionRect); } -// TODO(wangxianzhu): Remove this for slimming paint v2 because we won't care about paint invalidation rects. inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason invalidationReason) { // Update selection rect when we are doing full invalidation (in case that the object is moved, composite status changed, etc.) @@ -1354,11 +1331,10 @@ setPreviousSelectionRectForPaintInvalidation(newSelectionRect); - // TODO(wangxianzhu): Combine the following two conditions when removing LayoutView::doingFullPaintInvalidation(). - if (!fullInvalidation) + if (!fullInvalidation) { fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelection, oldSelectionRect, newSelectionRect); - if (shouldInvalidateSelection()) invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, PaintInvalidationSelection); + } } PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) @@ -1423,7 +1399,7 @@ // invalidation is issued. See crbug.com/508383 and crbug.com/515977. // This is a workaround to force display items to update paint offset. if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paintInvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, invalidationReason); + invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, PaintInvalidationLocationChange); return invalidationReason; } @@ -1447,6 +1423,9 @@ if (shouldDoFullPaintInvalidation()) return m_bitfields.fullPaintInvalidationReason(); + if (paintedOutputOfObjectHasNoEffect()) + return PaintInvalidationNone; + // The outline may change shape because of position change of descendants. For simplicity, // just force full paint invalidation if this object is marked for checking paint invalidation // for any reason. @@ -1465,13 +1444,6 @@ if (newBounds.location() != oldBounds.location()) return PaintInvalidationBoundsChange; - // This covers the case where we mark containing blocks for layout - // and they change size but don't have anything to paint. This is - // a pretty common case for <body> as we add / remove children - // (and the default background is done by FrameView). - if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && skipInvalidationWhenLaidOutChildren()) - return PaintInvalidationNone; - // If the size is zero on one of our bounds then we know we're going to have // to do a full invalidation of either old bounds or new bounds. If we fall // into the incremental invalidation we'll issue two invalidations instead @@ -3458,7 +3430,6 @@ ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() || paintInvalidationStateIsDirty()); clearShouldDoFullPaintInvalidation(); m_bitfields.setChildShouldCheckForPaintInvalidation(false); - m_bitfields.setNeededLayoutBecauseOfChildren(false); m_bitfields.setMayNeedPaintInvalidation(false); m_bitfields.setMayNeedPaintInvalidationSubtree(false); m_bitfields.setShouldInvalidateSelection(false);
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h index 7a88a69..96447e7 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -354,12 +354,6 @@ #endif - // Correct version of !layoutObjectHasNoBoxEffectObsolete(). - bool hasBoxEffect() const - { - return hasBoxDecorationBackground() || style()->hasVisualOverflowingEffect(); - } - // LayoutObject tree manipulation ////////////////////////////////////////// virtual bool canHaveChildren() const { return virtualChildren(); } @@ -444,8 +438,6 @@ // or from Parent element. PassRefPtr<ComputedStyle> getUncachedPseudoStyleFromParentOrShadowHost() const; - bool skipInvalidationWhenLaidOutChildren() const; - public: #ifndef NDEBUG void showTreeForThis() const; @@ -694,8 +686,6 @@ bool boxDecorationBackgroundIsKnownToBeObscured() const; bool hasBackground() const { return style()->hasBackground(); } - bool needsLayoutBecauseOfChildren() const { return needsLayout() && !selfNeedsLayout() && !needsPositionedMovementLayout() && !needsSimplifiedNormalFlowLayout(); } - bool needsLayout() const { return m_bitfields.selfNeedsLayout() || m_bitfields.normalChildNeedsLayout() || m_bitfields.posChildNeedsLayout() @@ -1131,6 +1121,12 @@ void invalidatePaintIncludingNonSelfPaintingLayerDescendants(const LayoutBoxModelObject& paintInvalidationContainer); void setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); + // Returns true if the object will not generate any effective painted output. + // It's used to skip unforced paint invalidation (which is when shouldDoFullPaintInvalidation + // is false, but mayNeedPaintInvalidation or childShouldCheckForPaintInvalidation is true) to + // avoid unnecessary paint invalidations of empty areas covered by such objects. + virtual bool paintedOutputOfObjectHasNoEffect() const { return false; } + // Returns the rect that should have paint invalidated whenever this object changes. The rect is in the view's // coordinate space. This method deals with outlines and overflow. virtual LayoutRect absoluteClippedOverflowRect() const; @@ -1555,7 +1551,7 @@ #if ENABLE(ASSERT) virtual bool paintInvalidationStateIsDirty() const { - return m_bitfields.neededLayoutBecauseOfChildren() || shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState(); + return shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState(); } #endif @@ -1748,7 +1744,6 @@ , m_mayNeedPaintInvalidation(false) , m_mayNeedPaintInvalidationSubtree(false) , m_shouldInvalidateSelection(false) - , m_neededLayoutBecauseOfChildren(false) , m_floating(false) , m_isAnonymous(!node) , m_isText(false) @@ -1782,7 +1777,7 @@ { } - // 32 bits have been used in the first word, and 17 in the second. + // 32 bits have been used in the first word, and 16 in the second. // Self needs layout means that this layout object is marked for a full layout. // This is the default layout but it is expensive as it recomputes everything. @@ -1833,8 +1828,7 @@ ADD_BOOLEAN_BITFIELD(childShouldCheckForPaintInvalidation, ChildShouldCheckForPaintInvalidation); ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidation, MayNeedPaintInvalidation); ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidationSubtree, MayNeedPaintInvalidationSubtree); - ADD_BOOLEAN_BITFIELD(shouldInvalidateSelection, ShouldInvalidateSelection); // TODO(wangxianzhu): Remove for slimming paint v2. - ADD_BOOLEAN_BITFIELD(neededLayoutBecauseOfChildren, NeededLayoutBecauseOfChildren); // TODO(wangxianzhu): Remove for slimming paint v2. + ADD_BOOLEAN_BITFIELD(shouldInvalidateSelection, ShouldInvalidateSelection); // This boolean is the cached value of 'float' // (see ComputedStyle::isFloating). @@ -2051,7 +2045,6 @@ // Set flags for later stages/cycles. setEverHadLayout(); setMayNeedPaintInvalidation(); - m_bitfields.setNeededLayoutBecauseOfChildren(needsLayoutBecauseOfChildren()); // Clear needsLayout flags. setSelfNeedsLayout(false);
diff --git a/third_party/WebKit/Source/core/layout/LayoutReplaced.h b/third_party/WebKit/Source/core/layout/LayoutReplaced.h index 492bf53c..190d429 100644 --- a/third_party/WebKit/Source/core/layout/LayoutReplaced.h +++ b/third_party/WebKit/Source/core/layout/LayoutReplaced.h
@@ -72,6 +72,9 @@ void paint(const PaintInfo&, const LayoutPoint&) const override; + // Replaced objects often have contents to paint. + bool paintedOutputOfObjectHasNoEffect() const final { return false; } + struct IntrinsicSizingInfo { STACK_ALLOCATED(); IntrinsicSizingInfo() : hasWidth(true), hasHeight(true) {}
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp index a1f5a97..ae252ca 100644 --- a/third_party/WebKit/Source/core/layout/LayoutView.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -571,13 +571,6 @@ continue; o->setShouldInvalidateSelection(); - - // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well. - for (LayoutBlock* block = o->containingBlock(); block && !block->isLayoutView(); block = block->containingBlock()) { - if (!processedBlocks.add(block).isNewEntry) - break; - block->setShouldInvalidateSelection(); - } } }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.cpp index d7bf42b..03facf1c 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.cpp
@@ -44,16 +44,6 @@ clearNeedsLayout(); } -void LayoutSVGHiddenContainer::paint(const PaintInfo&, const LayoutPoint&) const -{ - // This subtree does not paint. -} - -void LayoutSVGHiddenContainer::absoluteQuads(Vector<FloatQuad>&) const -{ - // This subtree does not take up space or paint -} - bool LayoutSVGHiddenContainer::nodeAtFloatPoint(HitTestResult&, const FloatPoint&, HitTestAction) { return false;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h index 629f7b4..542087e 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h
@@ -40,10 +40,12 @@ bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectSVGHiddenContainer || LayoutSVGContainer::isOfType(type); } private: - void paint(const PaintInfo&, const LayoutPoint&) const final; + // LayoutSVGHiddenContainer paints nothing. + void paint(const PaintInfo&, const LayoutPoint&) const final { } + bool paintedOutputOfObjectHasNoEffect() const final { return true; } LayoutRect absoluteClippedOverflowRect() const final { return LayoutRect(); } FloatRect paintInvalidationRectInLocalSVGCoordinates() const final { return FloatRect(); } - void absoluteQuads(Vector<FloatQuad>&) const final; + void absoluteQuads(Vector<FloatQuad>&) const final { } bool nodeAtFloatPoint(HitTestResult&, const FloatPoint& pointInParent, HitTestAction) final; };
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp index 33ebc16..70543b2 100644 --- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -341,7 +341,7 @@ DocumentThreadableLoader::~DocumentThreadableLoader() { CHECK(!m_client); - DCHECK(!m_resource); + DCHECK(!resource()); } void DocumentThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) @@ -971,9 +971,9 @@ DEFINE_TRACE(DocumentThreadableLoader) { - visitor->trace(m_resource); visitor->trace(m_document); ThreadableLoader::trace(visitor); + ResourceOwner<RawResource>::trace(visitor); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h index 227541b..79e8336d 100644 --- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h +++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
@@ -54,7 +54,8 @@ class SecurityOrigin; class ThreadableLoaderClient; -class CORE_EXPORT DocumentThreadableLoader final : public ThreadableLoader, private RawResourceClient { +class CORE_EXPORT DocumentThreadableLoader final : public ThreadableLoader, private ResourceOwner<RawResource> { + USING_GARBAGE_COLLECTED_MIXIN(DocumentThreadableLoader); public: static void loadResourceSynchronously(Document&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); static DocumentThreadableLoader* create(Document&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); @@ -150,29 +151,6 @@ // returns allowCredentials value of m_resourceLoaderOptions. StoredCredentials effectiveAllowCredentials() const; - // TODO(oilpan): DocumentThreadableLoader used to be a ResourceOwner, - // but ResourceOwner was moved onto the oilpan heap before - // DocumentThreadableLoader was ready. When DocumentThreadableLoader - // moves onto the oilpan heap, make it a ResourceOwner again and remove - // this re-implementation of ResourceOwner. - RawResource* resource() const { return m_resource.get(); } - void clearResource() { setResource(nullptr); } - void setResource(RawResource* newResource) - { - if (newResource == m_resource) - return; - - if (RawResource* oldResource = m_resource.release()) - oldResource->removeClient(this); - - if (newResource) { - m_resource = newResource; - m_resource->addClient(this); - } - } - Member<RawResource> m_resource; - // End of ResourceOwner re-implementation, see above. - SecurityOrigin* getSecurityOrigin() const; Document& document() const;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 79e12d4d..93bda38 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -64,6 +64,7 @@ #include "platform/Logging.h" #include "platform/TracedValue.h" #include "platform/mhtml/MHTMLArchive.h" +#include "platform/network/NetworkUtils.h" #include "platform/network/ResourceLoadPriority.h" #include "platform/network/ResourceTimingInfo.h" #include "platform/weborigin/SchemeRegistry.h" @@ -110,7 +111,20 @@ // Avoid blocking same origin scripts, as they may be used to render main // page content, whereas cross-origin scripts inserted via document.write // are likely to be third party content. - if (request.url().host() == document.getSecurityOrigin()->domain()) + String requestHost = request.url().host(); + String documentHost = document.getSecurityOrigin()->domain(); + if (requestHost == documentHost) + return false; + + // If the hosts didn't match, then see if the domains match. For example, if + // a script is served from static.example.com for a document served from + // www.example.com, we consider that a first party script and allow it. + String requestDomain = NetworkUtils::getDomainAndRegistry(requestHost, NetworkUtils::IncludePrivateRegistries); + String documentDomain = NetworkUtils::getDomainAndRegistry(documentHost, NetworkUtils::IncludePrivateRegistries); + // getDomainAndRegistry will return the empty string for domains that are + // already top-level, such as localhost. Thus we only compare domains if we + // get non-empty results back from getDomainAndRegistry. + if (!requestDomain.isEmpty() && !documentDomain.isEmpty() && requestDomain == documentDomain) return false; emitWarningForDocWriteScripts(request.url().getString(), document);
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp index ab02e4ff..a64cf35 100644 --- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -224,7 +224,7 @@ WorkerThreadableLoader::~WorkerThreadableLoader() { - DCHECK(!m_peer); + DCHECK(!m_mainThreadLoaderHolder); DCHECK(!m_client); } @@ -240,7 +240,7 @@ eventWithTasks = WaitableEventWithTasks::create(); m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask( - &Peer::createAndStart, + &MainThreadLoaderHolder::createAndStart, wrapCrossThreadPersistent(this), m_workerLoaderProxy, wrapCrossThreadPersistent(m_workerGlobalScope->thread()->getWorkerThreadLifecycleContext()), @@ -278,17 +278,17 @@ void WorkerThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) { DCHECK(!isMainThread()); - if (!m_peer) + if (!m_mainThreadLoaderHolder) return; - m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::overrideTimeout, m_peer, timeoutMilliseconds)); + m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadLoaderHolder::overrideTimeout, m_mainThreadLoaderHolder, timeoutMilliseconds)); } void WorkerThreadableLoader::cancel() { DCHECK(!isMainThread()); - if (m_peer) { - m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::cancel, m_peer)); - m_peer = nullptr; + if (m_mainThreadLoaderHolder) { + m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadLoaderHolder::cancel, m_mainThreadLoaderHolder)); + m_mainThreadLoaderHolder = nullptr; } if (!m_client) @@ -304,17 +304,17 @@ DCHECK(!m_client); } -void WorkerThreadableLoader::didStart(Peer* peer) +void WorkerThreadableLoader::didStart(MainThreadLoaderHolder* mainThreadLoaderHolder) { DCHECK(!isMainThread()); - DCHECK(!m_peer); - DCHECK(peer); + DCHECK(!m_mainThreadLoaderHolder); + DCHECK(mainThreadLoaderHolder); if (!m_client) { // The loading is already cancelled. return; } - m_peer = peer; + m_mainThreadLoaderHolder = mainThreadLoaderHolder; } void WorkerThreadableLoader::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) @@ -358,7 +358,7 @@ return; auto* client = m_client; m_client = nullptr; - m_peer = nullptr; + m_mainThreadLoaderHolder = nullptr; client->didFinishLoading(identifier, finishTime); } @@ -369,7 +369,7 @@ return; auto* client = m_client; m_client = nullptr; - m_peer = nullptr; + m_mainThreadLoaderHolder = nullptr; client->didFail(error); } @@ -380,7 +380,7 @@ return; auto* client = m_client; m_client = nullptr; - m_peer = nullptr; + m_mainThreadLoaderHolder = nullptr; client->didFailAccessControlCheck(error); } @@ -391,7 +391,7 @@ return; auto* client = m_client; m_client = nullptr; - m_peer = nullptr; + m_mainThreadLoaderHolder = nullptr; client->didFailRedirectCheck(); } @@ -419,7 +419,7 @@ ThreadableLoader::trace(visitor); } -void WorkerThreadableLoader::Peer::createAndStart( +void WorkerThreadableLoader::MainThreadLoaderHolder::createAndStart( WorkerThreadableLoader* workerLoader, PassRefPtr<WorkerLoaderProxy> passLoaderProxy, WorkerThreadLifecycleContext* workerThreadLifecycleContext, @@ -437,25 +437,25 @@ else forwarder = new AsyncTaskForwarder(loaderProxy); - Peer* peer = new Peer(forwarder, workerThreadLifecycleContext); - if (peer->wasContextDestroyedBeforeObserverCreation()) { + MainThreadLoaderHolder* mainThreadLoaderHolder = new MainThreadLoaderHolder(forwarder, workerThreadLifecycleContext); + if (mainThreadLoaderHolder->wasContextDestroyedBeforeObserverCreation()) { // The thread is already terminating. forwarder->abort(); - peer->m_forwarder = nullptr; + mainThreadLoaderHolder->m_forwarder = nullptr; return; } - peer->m_workerLoader = workerLoader; - peer->start(*toDocument(executionContext), std::move(request), options, resourceLoaderOptions); - forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didStart, wrapCrossThreadPersistent(workerLoader), wrapCrossThreadPersistent(peer))); + mainThreadLoaderHolder->m_workerLoader = workerLoader; + mainThreadLoaderHolder->start(*toDocument(executionContext), std::move(request), options, resourceLoaderOptions); + forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didStart, wrapCrossThreadPersistent(workerLoader), wrapCrossThreadPersistent(mainThreadLoaderHolder))); } -WorkerThreadableLoader::Peer::~Peer() +WorkerThreadableLoader::MainThreadLoaderHolder::~MainThreadLoaderHolder() { DCHECK(isMainThread()); DCHECK(!m_workerLoader); } -void WorkerThreadableLoader::Peer::overrideTimeout(unsigned long timeoutMilliseconds) +void WorkerThreadableLoader::MainThreadLoaderHolder::overrideTimeout(unsigned long timeoutMilliseconds) { DCHECK(isMainThread()); if (!m_mainThreadLoader) @@ -463,7 +463,7 @@ m_mainThreadLoader->overrideTimeout(timeoutMilliseconds); } -void WorkerThreadableLoader::Peer::cancel() +void WorkerThreadableLoader::MainThreadLoaderHolder::cancel() { DCHECK(isMainThread()); if (!m_mainThreadLoader) @@ -472,7 +472,7 @@ m_mainThreadLoader = nullptr; } -void WorkerThreadableLoader::Peer::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) +void WorkerThreadableLoader::MainThreadLoaderHolder::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -481,7 +481,7 @@ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didSendData, workerLoader, bytesSent, totalBytesToBeSent)); } -void WorkerThreadableLoader::Peer::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -490,7 +490,7 @@ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveResponse, workerLoader, identifier, response, passed(std::move(handle)))); } -void WorkerThreadableLoader::Peer::didReceiveData(const char* data, unsigned dataLength) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveData(const char* data, unsigned dataLength) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -499,7 +499,7 @@ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveData, workerLoader, passed(createVectorFromMemoryRegion(data, dataLength)))); } -void WorkerThreadableLoader::Peer::didDownloadData(int dataLength) +void WorkerThreadableLoader::MainThreadLoaderHolder::didDownloadData(int dataLength) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -508,7 +508,7 @@ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didDownloadData, workerLoader, dataLength)); } -void WorkerThreadableLoader::Peer::didReceiveCachedMetadata(const char* data, int dataLength) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveCachedMetadata(const char* data, int dataLength) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -517,7 +517,7 @@ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveCachedMetadata, workerLoader, passed(createVectorFromMemoryRegion(data, dataLength)))); } -void WorkerThreadableLoader::Peer::didFinishLoading(unsigned long identifier, double finishTime) +void WorkerThreadableLoader::MainThreadLoaderHolder::didFinishLoading(unsigned long identifier, double finishTime) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -527,7 +527,7 @@ m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didFail(const ResourceError& error) +void WorkerThreadableLoader::MainThreadLoaderHolder::didFail(const ResourceError& error) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -537,7 +537,7 @@ m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didFailAccessControlCheck(const ResourceError& error) +void WorkerThreadableLoader::MainThreadLoaderHolder::didFailAccessControlCheck(const ResourceError& error) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -547,7 +547,7 @@ m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didFailRedirectCheck() +void WorkerThreadableLoader::MainThreadLoaderHolder::didFailRedirectCheck() { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -557,7 +557,7 @@ m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didReceiveResourceTiming(const ResourceTimingInfo& info) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveResourceTiming(const ResourceTimingInfo& info) { DCHECK(isMainThread()); CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); @@ -566,7 +566,7 @@ m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveResourceTiming, workerLoader, info)); } -void WorkerThreadableLoader::Peer::contextDestroyed() +void WorkerThreadableLoader::MainThreadLoaderHolder::contextDestroyed() { DCHECK(isMainThread()); if (m_forwarder) { @@ -577,21 +577,21 @@ cancel(); } -DEFINE_TRACE(WorkerThreadableLoader::Peer) +DEFINE_TRACE(WorkerThreadableLoader::MainThreadLoaderHolder) { visitor->trace(m_forwarder); visitor->trace(m_mainThreadLoader); WorkerThreadLifecycleObserver::trace(visitor); } -WorkerThreadableLoader::Peer::Peer(TaskForwarder* forwarder, WorkerThreadLifecycleContext* context) +WorkerThreadableLoader::MainThreadLoaderHolder::MainThreadLoaderHolder(TaskForwarder* forwarder, WorkerThreadLifecycleContext* context) : WorkerThreadLifecycleObserver(context) , m_forwarder(forwarder) { DCHECK(isMainThread()); } -void WorkerThreadableLoader::Peer::start( +void WorkerThreadableLoader::MainThreadLoaderHolder::start( Document& document, std::unique_ptr<CrossThreadResourceRequestData> request, const ThreadableLoaderOptions& options,
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h index 02c0d8a..bcd683ee 100644 --- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h +++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
@@ -56,9 +56,31 @@ struct CrossThreadResourceRequestData; struct CrossThreadResourceTimingInfoData; -// TODO(yhirano): Draw a diagram to illustrate the class relationship. -// TODO(yhirano): Rename inner classes so that readers can see in which thread -// they are living easily. +// A WorkerThreadableLoader is a ThreadableLoader implementation intended to +// be used in a WebWorker thread. Because Blink's ResourceFetcher and +// ResourceLoader work only in the main thread, a WorkerThreadableLoader holds +// a ThreadableLoader in the main thread and delegates tasks asynchronously +// to the loader. +// +// CTP: CrossThreadPersistent +// CTWP: CrossThreadWeakPersistent +// +// ---------------------------------------------------------------- +// +------------------------+ +// raw ptr | ThreadableLoaderClient | +// +--------> | worker thread | +// | +------------------------+ +// | +// +----+------------------+ CTP +------------------------+ +// + WorkerThreadableLoader|<--------+ MainThreadLoaderHolder | +// | worker thread +-------->| main thread | +// +-----------------------+ CTWP +----------------------+-+ +// | +// +------------------+ | Member +// | ThreadableLoader | <---+ +// | main thread | +// +------------------+ +// class WorkerThreadableLoader final : public ThreadableLoader { public: static void loadResourceSynchronously(WorkerGlobalScope&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); @@ -101,8 +123,8 @@ // ThreadableLoaderClient for a DocumentThreadableLoader and forward // notifications to the associated WorkerThreadableLoader living in the // worker thread. - class Peer final : public GarbageCollectedFinalized<Peer>, public ThreadableLoaderClient, public WorkerThreadLifecycleObserver { - USING_GARBAGE_COLLECTED_MIXIN(Peer); + class MainThreadLoaderHolder final : public GarbageCollectedFinalized<MainThreadLoaderHolder>, public ThreadableLoaderClient, public WorkerThreadLifecycleObserver { + USING_GARBAGE_COLLECTED_MIXIN(MainThreadLoaderHolder); public: static void createAndStart( WorkerThreadableLoader*, @@ -113,7 +135,7 @@ const ResourceLoaderOptions&, PassRefPtr<WaitableEventWithTasks>, ExecutionContext*); - ~Peer() override; + ~MainThreadLoaderHolder() override; void overrideTimeout(unsigned long timeoutMillisecond); void cancel(); @@ -134,7 +156,7 @@ DECLARE_TRACE(); private: - Peer(TaskForwarder*, WorkerThreadLifecycleContext*); + MainThreadLoaderHolder(TaskForwarder*, WorkerThreadLifecycleContext*); void start(Document&, std::unique_ptr<CrossThreadResourceRequestData>, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); Member<TaskForwarder> m_forwarder; @@ -145,7 +167,7 @@ }; WorkerThreadableLoader(WorkerGlobalScope&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&, BlockingBehavior); - void didStart(Peer*); + void didStart(MainThreadLoaderHolder*); void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent); void didReceiveResponse(unsigned long identifier, std::unique_ptr<CrossThreadResourceResponseData>, std::unique_ptr<WebDataConsumerHandle>); @@ -166,8 +188,8 @@ ResourceLoaderOptions m_resourceLoaderOptions; BlockingBehavior m_blockingBehavior; - // |*m_peer| lives in the main thread. - CrossThreadPersistent<Peer> m_peer; + // |*m_mainThreadLoaderHolder| lives in the main thread. + CrossThreadPersistent<MainThreadLoaderHolder> m_mainThreadLoaderHolder; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp index 9621186..031d7517 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -540,9 +540,12 @@ if (layer->parent()) { layer = layer->parent(); - } else if (LayoutObject* parentDocLayoutObject = layer->layoutObject()->frame()->ownerLayoutObject()) { - layer = parentDocLayoutObject->enclosingLayer(); - touchHandlerInChildFrame = true; + } else { + LayoutItem parentDocLayoutItem = layer->layoutObject()->frame()->ownerLayoutItem(); + if (!parentDocLayoutItem.isNull()) { + layer = parentDocLayoutItem.enclosingLayer(); + touchHandlerInChildFrame = true; + } } } while (layer); }
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp index fba8378..68e572e1 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -99,6 +99,7 @@ EXPECT_EQ(scrollerProperties->overflowClip(), target2Properties->overflowClip()->parent()); CHECK_VISUAL_RECT(target1->layoutObject(), frameView->layoutView()); + CHECK_VISUAL_RECT(target2->layoutObject(), frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, PositionAndScroll)
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index 821e926..6e9bfe2 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -304,12 +304,18 @@ if (!m_page) return nullptr; - SkPictureRecorder recorder; - SkCanvas* canvas = recorder.beginRecording(width(), height()); - drawForContainer(canvas, SkPaint(), containerSize, 1, rect(), rect(), url); + const FloatRect containerRect(FloatPoint(), containerSize); + SkPictureRecorder recorder; + SkCanvas* canvas = recorder.beginRecording(containerRect); + drawForContainer(canvas, SkPaint(), containerSize, 1, containerRect, containerRect, url); + + const IntSize imageSize = roundedIntSize(containerSize); + const SkMatrix residualScale = SkMatrix::MakeScale( + static_cast<float>(imageSize.width()) / containerSize.width(), + static_cast<float>(imageSize.height()) / containerSize.height()); return fromSkSp(SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), - SkISize::Make(width(), height()), nullptr, nullptr)); + SkISize::Make(imageSize.width(), imageSize.height()), &residualScale, nullptr)); } static bool drawNeedsLayer(const SkPaint& paint)
diff --git a/third_party/WebKit/Source/devtools/front_end/components/breakpointsList.css b/third_party/WebKit/Source/devtools/front_end/components/breakpointsList.css index b7b3d1a..6d06233 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/breakpointsList.css +++ b/third_party/WebKit/Source/devtools/front_end/components/breakpointsList.css
@@ -98,7 +98,7 @@ } .event-listener-breakpoints { - margin-top: 0; + margin: 0; padding: 2px 6px; list-style: none; min-height: 18px;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js index f04872af..60942ecf3 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
@@ -83,7 +83,8 @@ this._treeElementsBeingUpdated = new Set(); this._domModel.addEventListener(WebInspector.DOMModel.Events.MarkersChanged, this._markersChanged, this); - WebInspector.moduleSetting("showHTMLComments").addChangeListener(this._onShowHTMLCommentsChange.bind(this)); + this._showHTMLCommentsSetting = WebInspector.moduleSetting("showHTMLComments"); + this._showHTMLCommentsSetting.addChangeListener(this._onShowHTMLCommentsChange.bind(this)); } WebInspector.ElementsTreeOutline._treeOutlineSymbol = Symbol("treeOutline"); @@ -137,7 +138,7 @@ _onShowHTMLCommentsChange: function() { var selectedNode = this.selectedDOMNode(); - if (selectedNode && selectedNode.nodeType() === Node.COMMENT_NODE && !WebInspector.moduleSetting("showHTMLComments").get()) + if (selectedNode && selectedNode.nodeType() === Node.COMMENT_NODE && !this._showHTMLCommentsSetting.get()) this.selectDOMNode(selectedNode.parentNode); this.update(); }, @@ -1351,7 +1352,7 @@ if (node.childNodeCount()) { var children = node.children(); - if (!WebInspector.moduleSetting("showHTMLComments").get()) + if (!this._showHTMLCommentsSetting.get()) children = children.filter(n => n.nodeType() !== Node.COMMENT_NODE); visibleChildren = visibleChildren.concat(children); }
diff --git a/third_party/WebKit/Source/devtools/front_end/inspector.js b/third_party/WebKit/Source/devtools/front_end/inspector.js index 0b71b5b..322527d 100644 --- a/third_party/WebKit/Source/devtools/front_end/inspector.js +++ b/third_party/WebKit/Source/devtools/front_end/inspector.js
@@ -2,13 +2,4 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Preload protocol resources for hosted mode. -if (!/** @type {?Object} */(window.InspectorFrontendHost)) { - Promise.all([ - Runtime.loadResourceIntoCache("./sdk/protocol/browser_protocol.json", false /* appendSourceURL */), - Runtime.loadResourceIntoCache("./sdk/protocol/js_protocol.json", false /* appendSourceURL */) - ]).then(() => Runtime.startApplication("inspector")); -} else { - Runtime.startApplication("inspector"); -} - +Runtime.startApplication("inspector");
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js index 829ecad..a385128 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js
@@ -118,19 +118,6 @@ } WebInspector.RequestContentView.prototype = { - /** - * @return {!WebInspector.Widget} - */ - get innerView() - { - return this._innerView; - }, - - set innerView(innerView) - { - this._innerView = innerView; - }, - wasShown: function() { this._ensureInnerViewShown();
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js index a316ec37..45ce5c3 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js
@@ -38,6 +38,8 @@ { WebInspector.RequestContentView.call(this, request); this._responseView = responseView; + /** @type {?WebInspector.Widget} */ + this._previewView = null; } WebInspector.RequestPreviewView.prototype = { @@ -47,21 +49,20 @@ if (!this._emptyWidget) { this._emptyWidget = this._createEmptyWidget(); this._emptyWidget.show(this.element); - this.innerView = this._emptyWidget; + this._previewView = this._emptyWidget; } - } else { - if (this._emptyWidget) { - this._emptyWidget.detach(); - delete this._emptyWidget; - } - - if (!this._previewView) { - this._createPreviewView(handlePreviewView.bind(this)); - } else { - this.innerView = this._previewView; - handlePreviewView.call(this, this.innerView); - } + return; } + if (this._emptyWidget) { + this._emptyWidget.detach(); + delete this._emptyWidget; + this._previewView = null; + } + + if (!this._previewView) + this._createPreviewView(handlePreviewView.bind(this)); + else + this._previewView.show(this.element); /** * @param {!WebInspector.Widget} view @@ -70,14 +71,13 @@ function handlePreviewView(view) { this._previewView = view; - this._previewView.show(this.element); - if (this._previewView instanceof WebInspector.View) { + view.show(this.element); + if (view instanceof WebInspector.View) { var toolbar = new WebInspector.Toolbar("network-item-preview-toolbar", this.element); - for (var item of /** @type {!WebInspector.View} */ (this._previewView).toolbarItems()) + for (var item of /** @type {!WebInspector.View} */ (view).toolbarItems()) toolbar.appendToolbarItem(item); } - this.innerView = this._previewView; - this._previewViewHandledForTest(this._previewView); + this._previewViewHandledForTest(view); } },
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js index 34c35d6..44710cd1 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js
@@ -65,7 +65,6 @@ if (!this._emptyWidget) { this._emptyWidget = this._createMessageView(WebInspector.UIString("This request has no response data available.")); this._emptyWidget.show(this.element); - this.innerView = this._emptyWidget; } } else { if (this._emptyWidget) { @@ -75,12 +74,10 @@ if (this.request.content && this.sourceView) { this.sourceView.show(this.element); - this.innerView = this.sourceView; } else { if (!this._errorView) this._errorView = this._createMessageView(WebInspector.UIString("Failed to load response data")); this._errorView.show(this.element); - this.innerView = this._errorView; } } },
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css b/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css index 70f415e..8ee0bd29 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css
@@ -112,6 +112,9 @@ padding: 6px; color: #888; pointer-events: none; + display: flex; + align-items: center; + justify-content: center; } .callstack-info.status { @@ -133,6 +136,7 @@ background-repeat: no-repeat; border: 0 none transparent; position: absolute; + top: 4px; right: 3px; display: none; } @@ -143,6 +147,7 @@ .watch-expressions { overflow-x: hidden; + min-height: 26px; } .watch-expressions .dimmed { @@ -153,7 +158,7 @@ white-space: nowrap; text-overflow: ellipsis; overflow: hidden; - line-height: 12px; + line-height: 16px; margin-left: 11px; }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/uiList.css b/third_party/WebKit/Source/devtools/front_end/sources/uiList.css index 88a60cf8..b7d757d 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/uiList.css +++ b/third_party/WebKit/Source/devtools/front_end/sources/uiList.css
@@ -7,8 +7,10 @@ .list-item { padding: 2px 8px 3px 8px; position: relative; - min-height: 18px; + min-height: 26px; white-space: nowrap; + align-items: center; + display: flex; } .list-item:nth-of-type(2n) {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js index 3f9e839..41d618c 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
@@ -477,8 +477,9 @@ this._removeAllLayoutProperties(); // this._totalSizeDIP is available below since we successfully applied constraints. - var sidebarSizeValue = WebInspector.zoomManager.dipToCSS(sizeDIP) + "px"; - var mainSizeValue = (this._totalSizeCSS - WebInspector.zoomManager.dipToCSS(sizeDIP)) + "px"; + var roundSizeCSS = Math.round(WebInspector.zoomManager.dipToCSS(sizeDIP)); + var sidebarSizeValue = roundSizeCSS + "px"; + var mainSizeValue = (this._totalSizeCSS - roundSizeCSS) + "px"; this._sidebarElement.style.flexBasis = sidebarSizeValue; // Make both sides relayout boundaries.
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ViewContainers.js b/third_party/WebKit/Source/devtools/front_end/ui/ViewContainers.js index 5f79c4c..df45b20 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/ViewContainers.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/ViewContainers.js
@@ -44,12 +44,13 @@ this._titleElement.addEventListener("click", this._toggleExpanded.bind(this), false); this._titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(this), false); this.contentElement.insertBefore(this._titleElement, this.contentElement.firstChild); + var toolbarElement = this.contentElement.createChild("div"); var toolbarItems = view.toolbarItems(); if (toolbarItems.length) { - var toolbar = new WebInspector.Toolbar("", this._titleElement); + this._toolbar = new WebInspector.Toolbar(""); for (var item of toolbarItems) - toolbar.appendToolbarItem(item); + this._toolbar.appendToolbarItem(item); } this.contentElement.createChild("content"); @@ -72,6 +73,8 @@ { if (this._titleElement.classList.contains("expanded")) return true; + if (this._toolbar) + this._titleElement.appendChild(this._toolbar.element); this._titleElement.classList.add("expanded"); this._view.showWidget(this.element); return true; @@ -81,6 +84,8 @@ { if (!this._titleElement.classList.contains("expanded")) return; + if (this._toolbar) + this._toolbar.element.remove(); this._titleElement.classList.remove("expanded"); this._view.hideWidget(); },
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/viewContainers.css b/third_party/WebKit/Source/devtools/front_end/ui/viewContainers.css index 2ce52a00..dc2fe7e 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/viewContainers.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/viewContainers.css
@@ -35,12 +35,13 @@ display: flex; align-items: center; background-color: #eee; - height: 20px; + height: 26px; padding: 0 5px; border-top: 1px solid #dadada; white-space: nowrap; overflow: hidden; position: relative; + border-bottom: 1px solid transparent; } .expandable-view-title.expanded, @@ -78,7 +79,7 @@ .expandable-view-title > .toolbar { position: absolute; right: 0; - top: -3px; + top: 0; } .sidebar-pane-container .toolbar {
diff --git a/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js b/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js index 8d6dfd1e5..811bf70a 100644 --- a/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js +++ b/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js
@@ -1,23 +1,26 @@ // Copyright (c) 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. - var fs = require("fs"); var http = require("http"); var https = require("https"); var path = require("path"); var parseURL = require("url").parse; +var Stream = require("stream").Transform; -var port = parseInt(process.env.PORT, 10) || 8090; +var remoteDebuggingPort = parseInt(process.env.REMOTE_DEBUGGING_PORT, 10) || 9222; +var serverPort = parseInt(process.env.PORT, 10) || 8090; +var devtoolsFolder = path.resolve(path.join(__dirname, "../..")); -http.createServer(requestHandler).listen(port); -console.log("Started hosted mode server at http://localhost:" + port); +http.createServer(requestHandler).listen(serverPort); +console.log("Started hosted mode server at http://localhost:" + serverPort); function requestHandler(request, response) { var filePath = parseURL(request.url).pathname; - if (filePath === "/front_end/InspectorBackendCommands.js") { - sendResponse(200, " "); + if (filePath === "/") { + var landingURL = `http://localhost:${remoteDebuggingPort}#http://localhost:${serverPort}/front_end/inspector.html?experiments=true`; + sendResponse(200, `<html>Please go to <a href="${landingURL}">${landingURL}</a></html>`); return; } @@ -32,10 +35,17 @@ function handleProxyError(err) { console.log(`Error fetching over the internet file ${filePath}:`, err); + console.log(`Make sure you opened Chrome with the flag "--remote-debugging-port=${remoteDebuggingPort}"`); sendResponse(500, "500 - Internal Server Error"); } var absoluteFilePath = path.join(process.cwd(), filePath); + if (!path.resolve(absoluteFilePath).startsWith(devtoolsFolder)) { + console.log(`File requested is outside of devtools folder: ${devtoolsFolder}`); + sendResponse(403, "`403 - Access denied. File requested is outside of devtools folder: ${devtoolsFolder}`"); + return; + } + fs.exists(absoluteFilePath, fsExistsCallback); function fsExistsCallback(fileExists) @@ -67,25 +77,14 @@ } var proxyFilePathToURL = { - "/front_end/sdk/protocol/js_protocol.json": getWebKitURL.bind(null, "platform/v8_inspector/js_protocol.json"), - "/front_end/sdk/protocol/browser_protocol.json": getWebKitURL.bind(null, "core/inspector/browser_protocol.json"), - "/front_end/SupportedCSSProperties.js": getFrontendURL.bind(null, "SupportedCSSProperties.js") + "/front_end/SupportedCSSProperties.js": cloudURL.bind(null, "SupportedCSSProperties.js"), + "/front_end/InspectorBackendCommands.js": cloudURL.bind(null, "InspectorBackendCommands.js"), + "/favicon.ico": () => "https://chrome-devtools-frontend.appspot.com/favicon.ico" }; -function getWebKitURL(path, commitHash) +function cloudURL(path, commitHash) { - return { - url: `https://chromium.googlesource.com/chromium/src/+/${commitHash}/third_party/WebKit/Source/${path}?format=TEXT`, - isBase64: true - } -} - -function getFrontendURL(path, commitHash) -{ - return { - url: `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitHash}/${path}`, - isBase64: false - } + return `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitHash}/${path}`; } var proxyFileCache = new Map(); @@ -94,7 +93,7 @@ { if (!(filePath in proxyFilePathToURL)) return null; - return fetch("http://localhost:9222/json/version") + return fetch(`http://localhost:${remoteDebuggingPort}/json/version`) .then(onBrowserMetadata); function onBrowserMetadata(metadata) @@ -102,12 +101,10 @@ var metadataObject = JSON.parse(metadata); var match = metadataObject["WebKit-Version"].match(/\s\(@(\b[0-9a-f]{5,40}\b)/); var commitHash = match[1]; - var proxyFile = proxyFilePathToURL[filePath](commitHash); - var proxyFileURL = proxyFile.url; + var proxyFileURL = proxyFilePathToURL[filePath](commitHash); if (proxyFileCache.has(proxyFileURL)) return proxyFileCache.get(proxyFileURL); return fetch(proxyFileURL) - .then(text => proxyFile.isBase64 ? new Buffer(text, "base64").toString("binary") : text) .then(cacheProxyFile.bind(null, proxyFileURL)); } @@ -122,7 +119,8 @@ { return new Promise(fetchPromise); - function fetchPromise(resolve, reject) { + function fetchPromise(resolve, reject) + { var request; var protocol = parseURL(url).protocol; var handleResponse = getCallback.bind(null, resolve, reject); @@ -143,9 +141,9 @@ reject(new Error(`Request error: + ${response.statusCode}`)); return; } - var body = ""; - response.on("data", chunk => body += chunk); - response.on("end", () => resolve(body)); + var body = new Stream(); + response.on("data", chunk => body.push(chunk)); + response.on("end", () => resolve(body.read())); } }
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp index f85fa19..8f80b020 100644 --- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -949,7 +949,12 @@ void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, CanvasImageSource* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const SkPaint* paint) { - trackDrawCall(DrawImage, nullptr, dstRect.width(), dstRect.height()); + if (imageSource->isSVGSource()) { + trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height()); + } else { + trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height()); + } + int initialSaveCount = c->getSaveCount(); SkPaint imagePaint = *paint; @@ -1523,12 +1528,17 @@ void BaseRenderingContext2D::trackDrawCall(DrawCallType callType, Path2D* path2d, int width, int height) { + if (!RuntimeEnabledFeatures::enableCanvas2dDynamicRenderingModeSwitchingEnabled()) { + // Rendering mode switching is disabled so no need to track the usage + return; + } + m_usageCounters.numDrawCalls[callType]++; - double boundingRectWidth = static_cast<double>(width); - double boundingRectHeight = static_cast<double>(height); - double boundingRectArea = boundingRectWidth * boundingRectHeight; - double boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRectHeight); + float boundingRectWidth = static_cast<float>(width); + float boundingRectHeight = static_cast<float>(height); + float boundingRectArea = boundingRectWidth * boundingRectHeight; + float boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRectHeight); if (callType == FillText || callType == FillPath @@ -1544,19 +1554,21 @@ skPath = m_path.getSkPath(); } - if (callType == FillPath && !(skPath.getConvexity() == SkPath::kConvex_Convexity)) { - m_usageCounters.numNonConvexFillPathCalls++; - } - if (!(callType == FillRect || callType == StrokeRect || callType == DrawImage)) { + if (!(callType == FillRect || callType == StrokeRect || callType == DrawVectorImage || callType == DrawBitmapImage)) { // The correct width and height were not passed as parameters const SkRect& boundingRect = skPath.getBounds(); - boundingRectWidth = static_cast<double>(std::abs(boundingRect.width())); - boundingRectHeight = static_cast<double>(std::abs(boundingRect.height())); + boundingRectWidth = static_cast<float>(std::abs(boundingRect.width())); + boundingRectHeight = static_cast<float>(std::abs(boundingRect.height())); boundingRectArea = boundingRectWidth * boundingRectHeight; boundingRectPerimeter = 2.0 * boundingRectWidth + 2.0 * boundingRectHeight; } + if (callType == FillPath && skPath.getConvexity() != SkPath::kConvex_Convexity) { + m_usageCounters.numNonConvexFillPathCalls++; + m_usageCounters.nonConvexFillPathArea += boundingRectArea; + } + m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectPerimeter; m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea; @@ -1569,10 +1581,12 @@ CanvasGradient* gradient = canvasStyle->getCanvasGradient(); if (gradient) { - m_usageCounters.numGradients++; + if (gradient->getGradient()->isRadial()) { + m_usageCounters.numRadialGradients++; m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::RadialGradientFillType] += boundingRectArea; } else { + m_usageCounters.numLinearGradients++; m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::LinearGradientFillType] += boundingRectArea; } } else if (canvasStyle->getCanvasPattern()) { @@ -1583,9 +1597,9 @@ } } - if (callType == DrawImage) { - m_usageCounters.boundingBoxPerimeterDrawCalls[DrawImage] += boundingRectPerimeter; - m_usageCounters.boundingBoxAreaDrawCalls[DrawImage] += boundingRectArea; + if (callType == DrawVectorImage || callType == DrawBitmapImage) { + m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectPerimeter; + m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea; } if (callType == FillText @@ -1594,7 +1608,8 @@ || callType == StrokePath || callType == FillRect || callType == StrokeRect - || callType == DrawImage) { + || callType == DrawVectorImage + || callType == DrawBitmapImage) { if (state().shadowBlur() > 0.0 && SkColorGetA(state().shadowColor()) > 0) { m_usageCounters.numBlurredShadows++; m_usageCounters.boundingBoxAreaTimesShadowBlurSquared += boundingRectArea * state().shadowBlur() * state().shadowBlur(); @@ -1622,17 +1637,19 @@ } BaseRenderingContext2D::UsageCounters::UsageCounters() : - numDrawCalls {0, 0, 0, 0, 0, 0}, - boundingBoxPerimeterDrawCalls {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - boundingBoxAreaDrawCalls {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - boundingBoxAreaFillType {0.0, 0.0, 0.0, 0.0}, + numDrawCalls {0, 0, 0, 0, 0, 0, 0}, + boundingBoxPerimeterDrawCalls {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, + boundingBoxAreaDrawCalls {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, + boundingBoxAreaFillType {0.0f, 0.0f, 0.0f, 0.0f}, numNonConvexFillPathCalls(0), - numGradients(0), + nonConvexFillPathArea(0.0f), + numRadialGradients(0), + numLinearGradients(0), numPatterns(0), numDrawWithComplexClips(0), numBlurredShadows(0), - boundingBoxAreaTimesShadowBlurSquared(0.0), - boundingBoxPerimeterTimesShadowBlurSquared(0.0), + boundingBoxAreaTimesShadowBlurSquared(0.0f), + boundingBoxPerimeterTimesShadowBlurSquared(0.0f), numFilters(0), numGetImageDataCalls(0), areaGetImageDataCalls(0.0), @@ -1642,4 +1659,51 @@ numDrawFocusCalls(0), numFramesSinceReset(0) {} + +float BaseRenderingContext2D::estimateRenderingCost(ExpensiveCanvasHeuristicParameters::RenderingModeCostIndex index) const +{ + float basicCostOfDrawCalls = + ExpensiveCanvasHeuristicParameters::FillRectFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::FillRect] + + ExpensiveCanvasHeuristicParameters::FillConvexPathFixedCost[index] * (m_usageCounters.numDrawCalls[BaseRenderingContext2D::FillPath] - m_usageCounters.numNonConvexFillPathCalls) + + ExpensiveCanvasHeuristicParameters::FillNonConvexPathFixedCost[index] * m_usageCounters.numNonConvexFillPathCalls + + ExpensiveCanvasHeuristicParameters::FillTextFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::FillText] + + + ExpensiveCanvasHeuristicParameters::StrokeRectFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::StrokeRect] + + ExpensiveCanvasHeuristicParameters::StrokePathFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::StrokePath] + + ExpensiveCanvasHeuristicParameters::StrokeTextFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::StrokeText] + + + ExpensiveCanvasHeuristicParameters::FillRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillRect] + + ExpensiveCanvasHeuristicParameters::FillConvexPathVariableCostPerArea[index] * (m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillPath] - m_usageCounters.nonConvexFillPathArea) + + ExpensiveCanvasHeuristicParameters::FillNonConvexPathVariableCostPerArea[index] * m_usageCounters.nonConvexFillPathArea + + ExpensiveCanvasHeuristicParameters::FillTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillText] + + + ExpensiveCanvasHeuristicParameters::StrokeRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeRect] + + ExpensiveCanvasHeuristicParameters::StrokePathVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokePath] + + ExpensiveCanvasHeuristicParameters::StrokeTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeText] + + + ExpensiveCanvasHeuristicParameters::PutImageDataFixedCost[index] * m_usageCounters.numPutImageDataCalls + + ExpensiveCanvasHeuristicParameters::PutImageDataVariableCostPerArea[index] * m_usageCounters.areaPutImageDataCalls + + + ExpensiveCanvasHeuristicParameters::DrawSVGImageFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::DrawVectorImage] + + ExpensiveCanvasHeuristicParameters::DrawPNGImageFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::DrawBitmapImage] + + + ExpensiveCanvasHeuristicParameters::DrawSVGImageVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawVectorImage] + + ExpensiveCanvasHeuristicParameters::DrawPNGImageVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawBitmapImage]; + + float fillTypeAdjustment = + ExpensiveCanvasHeuristicParameters::PatternFillTypeFixedCost[index] * m_usageCounters.numPatterns + + ExpensiveCanvasHeuristicParameters::LinearGradientFillTypeFixedCost[index] * m_usageCounters.numLinearGradients + + ExpensiveCanvasHeuristicParameters::RadialGradientFillTypeFixedCost[index] * m_usageCounters.numRadialGradients + + + ExpensiveCanvasHeuristicParameters::PatternFillTypeVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::PatternFillType] + + ExpensiveCanvasHeuristicParameters::LinearGradientFillVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::LinearGradientFillType] + + ExpensiveCanvasHeuristicParameters::RadialGradientFillVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::RadialGradientFillType]; + + float shadowAdjustment = + ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * m_usageCounters.numBlurredShadows + + ExpensiveCanvasHeuristicParameters::ShadowVariableCostPerAreaTimesShadowBlurSquared[index] * m_usageCounters.boundingBoxAreaTimesShadowBlurSquared; + + return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h index 9638d7e..10ce134 100644 --- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h
@@ -13,6 +13,7 @@ #include "modules/canvas2d/CanvasPathMethods.h" #include "modules/canvas2d/CanvasRenderingContext2DState.h" #include "modules/canvas2d/CanvasStyle.h" +#include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" #include "third_party/skia/include/core/SkCanvas.h" namespace blink { @@ -165,7 +166,8 @@ enum DrawCallType { StrokePath = 0, FillPath, - DrawImage, + DrawVectorImage, + DrawBitmapImage, FillText, StrokeText, FillRect, @@ -183,21 +185,23 @@ struct UsageCounters { int numDrawCalls[DrawCallTypeCount]; // use DrawCallType enum as index - double boundingBoxPerimeterDrawCalls[DrawCallTypeCount]; - double boundingBoxAreaDrawCalls[DrawCallTypeCount]; - double boundingBoxAreaFillType[PathFillTypeCount]; + float boundingBoxPerimeterDrawCalls[DrawCallTypeCount]; + float boundingBoxAreaDrawCalls[DrawCallTypeCount]; + float boundingBoxAreaFillType[PathFillTypeCount]; int numNonConvexFillPathCalls; - int numGradients; + float nonConvexFillPathArea; + int numRadialGradients; + int numLinearGradients; int numPatterns; int numDrawWithComplexClips; int numBlurredShadows; - double boundingBoxAreaTimesShadowBlurSquared; - double boundingBoxPerimeterTimesShadowBlurSquared; + float boundingBoxAreaTimesShadowBlurSquared; + float boundingBoxPerimeterTimesShadowBlurSquared; int numFilters; int numGetImageDataCalls; - double areaGetImageDataCalls; + float areaGetImageDataCalls; int numPutImageDataCalls; - double areaPutImageDataCalls; + float areaPutImageDataCalls; int numClearRectCalls; int numDrawFocusCalls; int numFramesSinceReset; @@ -235,6 +239,8 @@ mutable UsageCounters m_usageCounters; + + float estimateRenderingCost(ExpensiveCanvasHeuristicParameters::RenderingModeCostIndex) const; private: void realizeSaves();
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 65195a0..fac95df 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -1070,28 +1070,20 @@ bool CanvasRenderingContext2D::isAccelerationOptimalForCanvasContent() const { - // Simple heuristic to determine if the GPU accelerated pipeline should be - // used to maximize performance of 2D canvas based on past usage. + // Heuristic to determine if the GPU accelerated rendering pipeline is optimal + // for performance based on past usage. It has a bias towards suggesting that the + // accelerated pipeline is optimal. - int numDrawPathCalls = - m_usageCounters.numDrawCalls[StrokePath] + - m_usageCounters.numDrawCalls[FillPath] + - m_usageCounters.numDrawCalls[FillText] + - m_usageCounters.numDrawCalls[StrokeText] + - m_usageCounters.numDrawCalls[FillRect] + - m_usageCounters.numDrawCalls[StrokeRect]; + float acceleratedCost = estimateRenderingCost(ExpensiveCanvasHeuristicParameters::AcceleratedModeIndex); - double acceleratedCost = - numDrawPathCalls * ExpensiveCanvasHeuristicParameters::AcceleratedDrawPathApproximateCost + - m_usageCounters.numGetImageDataCalls * ExpensiveCanvasHeuristicParameters::AcceleratedGetImageDataApproximateCost+ - m_usageCounters.numDrawCalls[DrawImage] * ExpensiveCanvasHeuristicParameters::AcceleratedDrawImageApproximateCost; + float recordingCost = estimateRenderingCost(ExpensiveCanvasHeuristicParameters::RecordingModeIndex); - double recordingCost = - numDrawPathCalls * ExpensiveCanvasHeuristicParameters::RecordingDrawPathApproximateCost + - m_usageCounters.numGetImageDataCalls * ExpensiveCanvasHeuristicParameters::UnacceleratedGetImageDataApproximateCost + - m_usageCounters.numDrawCalls[DrawImage] * ExpensiveCanvasHeuristicParameters::RecordingDrawImageApproximateCost; + float costDifference = acceleratedCost - recordingCost; + float percentCostReduction = costDifference / acceleratedCost * 100.0; + float costDifferencePerFrame = costDifference / m_usageCounters.numFramesSinceReset; - if (recordingCost * ExpensiveCanvasHeuristicParameters::AcceleratedHeuristicBias < acceleratedCost) { + if (percentCostReduction >= ExpensiveCanvasHeuristicParameters::MinPercentageImprovementToSuggestDisableAcceleration + && costDifferencePerFrame >= ExpensiveCanvasHeuristicParameters::MinCostPerFrameImprovementToSuggestDisableAcceleration) { return false; } return true;
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp index 3f4c464..d7c01fbc 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -814,14 +814,21 @@ EXPECT_TRUE(context->isAccelerationOptimalForCanvasContent()); context->fillRect(10, 10, 100, 100); - EXPECT_FALSE(context->isAccelerationOptimalForCanvasContent()); - - context->drawImage(canvasElement().getExecutionContext(), &m_opaqueBitmap, 0, 0, 1, 1, 0, 0, 10, 10, exceptionState); EXPECT_TRUE(context->isAccelerationOptimalForCanvasContent()); int numReps = 100; for (int i = 0; i < numReps; i++) { - context->fillRect(10, 10, 100, 100); + context->fillText("Text", 10, 10, 1); // faster with no acceleration + } + EXPECT_FALSE(context->isAccelerationOptimalForCanvasContent()); + + for (int i = 0; i < numReps; i++) { + context->fillRect(10, 10, 200, 200); // faster with acceleration + } + EXPECT_TRUE(context->isAccelerationOptimalForCanvasContent()); + + for (int i = 0; i < numReps * 100; i++) { + context->strokeText("Text", 10, 10, 1); // faster with no acceleration } EXPECT_FALSE(context->isAccelerationOptimalForCanvasContent()); }
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp index 8087727b..08934b2b 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp
@@ -18,6 +18,7 @@ #include "modules/canvas2d/CanvasPattern.h" #include "modules/canvas2d/HitRegionOptions.h" #include "modules/webgl/WebGLRenderingContext.h" +#include "platform/RuntimeEnabledFeatures.h" #include "platform/graphics/StaticBitmapImage.h" #include "platform/graphics/UnacceleratedImageBufferSurface.h" #include "testing/gmock/include/gmock/gmock.h" @@ -134,6 +135,8 @@ m_fullImageData = ImageData::create(IntSize(10, 10)); m_globalMemoryCache = replaceMemoryCacheForTesting(MemoryCache::create()); + + RuntimeEnabledFeatures::setEnableCanvas2dDynamicRenderingModeSwitchingEnabled(true); } TEST_F(CanvasRenderingContextUsageTrackingTest, FillTracking) @@ -190,14 +193,15 @@ gradient = context2d()->createLinearGradient(0, 0, 100, 100); context2d()->setFillStyle(StringOrCanvasGradientOrCanvasPattern::fromCanvasGradient(gradient)); context2d()->fillRect(10, 10, 100, 20); - EXPECT_EQ(1, context2d()->getUsage().numGradients); + EXPECT_EQ(1, context2d()->getUsage().numLinearGradients); EXPECT_NEAR(100 * 20, context2d()->getUsage().boundingBoxAreaFillType[BaseRenderingContext2D::LinearGradientFillType], 1.0); NonThrowableExceptionState exceptionState; gradient = context2d()->createRadialGradient(0, 0, 100, 100, 200, 200, exceptionState); context2d()->setFillStyle(StringOrCanvasGradientOrCanvasPattern::fromCanvasGradient(gradient)); context2d()->fillRect(10, 10, 100, 20); - EXPECT_EQ(2, context2d()->getUsage().numGradients); + EXPECT_EQ(1, context2d()->getUsage().numLinearGradients); + EXPECT_EQ(1, context2d()->getUsage().numRadialGradients); EXPECT_NEAR(100 * 20, context2d()->getUsage().boundingBoxAreaFillType[BaseRenderingContext2D::RadialGradientFillType], 1.0); // create pattern @@ -217,7 +221,8 @@ EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::StrokePath]); EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::StrokeText]); EXPECT_EQ(0, context2d()->getUsage().numPutImageDataCalls); - EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawImage]); + EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawVectorImage]); + EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawBitmapImage]); EXPECT_EQ(0, context2d()->getUsage().numGetImageDataCalls); } @@ -257,7 +262,7 @@ gradient = context2d()->createLinearGradient(0, 0, 100, 100); context2d()->setStrokeStyle(StringOrCanvasGradientOrCanvasPattern::fromCanvasGradient(gradient)); context2d()->strokeRect(10, 10, 100, 100); - EXPECT_EQ(1, context2d()->getUsage().numGradients); + EXPECT_EQ(1, context2d()->getUsage().numLinearGradients); EXPECT_NEAR(100 * 100, context2d()->getUsage().boundingBoxAreaFillType[BaseRenderingContext2D::LinearGradientFillType], 1.0); // create pattern @@ -277,7 +282,8 @@ EXPECT_EQ(0, context2d()->getUsage().numNonConvexFillPathCalls); EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::FillText]); EXPECT_EQ(0, context2d()->getUsage().numPutImageDataCalls); - EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawImage]); + EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawVectorImage]); + EXPECT_EQ(0, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawBitmapImage]); EXPECT_EQ(0, context2d()->getUsage().numGetImageDataCalls); } @@ -296,8 +302,11 @@ context2d()->getImageData(0, 0, 10, 100, exceptionState); } - EXPECT_NEAR(numReps * imgWidth * imgHeight, context2d()->getUsage().boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawImage], 0.1); - EXPECT_NEAR(numReps * (2*imgWidth + 2*imgHeight), context2d()->getUsage().boundingBoxPerimeterDrawCalls[BaseRenderingContext2D::DrawImage], 0.1); + EXPECT_NEAR(numReps * imgWidth * imgHeight, context2d()->getUsage().boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawBitmapImage], 0.1); + EXPECT_NEAR(numReps * (2*imgWidth + 2*imgHeight), context2d()->getUsage().boundingBoxPerimeterDrawCalls[BaseRenderingContext2D::DrawBitmapImage], 0.1); + + EXPECT_NEAR(0.0, context2d()->getUsage().boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawVectorImage], 0.1); + EXPECT_NEAR(0.0, context2d()->getUsage().boundingBoxPerimeterDrawCalls[BaseRenderingContext2D::DrawVectorImage], 0.1); context2d()->setFilter("blur(5px)"); context2d()->drawImage(canvasElement().getExecutionContext(), &m_opaqueBitmap, 0, 0, 1, 1, 0, 0, 10, 10, exceptionState); @@ -306,7 +315,7 @@ EXPECT_NE(0, context2d()->getUsage().areaPutImageDataCalls); EXPECT_NEAR(numReps * m_fullImageData.get()->width() * m_fullImageData.get()->height(), context2d()->getUsage().areaPutImageDataCalls, 0.1); - EXPECT_EQ(numReps + 1, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawImage]); + EXPECT_EQ(numReps + 1, context2d()->getUsage().numDrawCalls[BaseRenderingContext2D::DrawBitmapImage]); EXPECT_EQ(numReps, context2d()->getUsage().numGetImageDataCalls); EXPECT_EQ(1, context2d()->getUsage().numFilters);
diff --git a/third_party/WebKit/Source/modules/canvas2d/tools/GeneratePerformanceData.html b/third_party/WebKit/Source/modules/canvas2d/tools/GeneratePerformanceData.html new file mode 100644 index 0000000..0d075b7 --- /dev/null +++ b/third_party/WebKit/Source/modules/canvas2d/tools/GeneratePerformanceData.html
@@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> +<head></head> +<body> +<table> +<tr> + <td> + <canvas id="canvas" width="1000" height="800"> + </td> +</tr> +<tr> + <td> + <div id="fps_div"> </div> + </td> +</tr> +<tr> + <td> ------------------------------------------------------------------------------- <br> + CSV String: <br> + <textarea id="csv_string" rows="1" cols="50"></textarea> + </td> +</tr> +</table> + +<img src="../../../../../../tools/perf/page_sets/tough_canvas_cases/rendering_throughput/images/Chromium_11_Logo.svg" style="display: none;" id="svg_image_element"/> +<img src="../../../../../../tools/perf/page_sets/tough_canvas_cases/many_images/images/image1_t.png" style="display: none;" id="png_image_element"/> + +<script type="text/javascript" src="bench.js"></script> +<script type="text/javascript" src="GeneratePerformanceData.js"></script> +<script type="text/javascript"> +window.onload = init; + +var canvas; +var context; + +function init() { + canvas = document.getElementById('canvas'); + context = canvas.getContext('2d'); + + list_of_frame_parameters = []; + list_of_frame_parameters = list_of_frame_parameters.concat(generatePathFrameParameters()); + list_of_frame_parameters = list_of_frame_parameters.concat(generateImageFrameParameters()); + list_of_frame_parameters = list_of_frame_parameters.concat(generatePutDataFrameParameters(context)); + + // The frames where get data is called should be measured last because rendering mode may switch automatically + list_of_frame_parameters = list_of_frame_parameters.concat(generateGetDataFrameParameters(context)); + + console.log("list_of_frame_parameters.length = " + list_of_frame_parameters.length); + + bench.run(draw); +} + +function draw() { + context.clearRect(0, 0, 1000, 800); + + drawAndRecord(context); +}; + +</script> +</body>
diff --git a/third_party/WebKit/Source/modules/canvas2d/tools/GeneratePerformanceData.js b/third_party/WebKit/Source/modules/canvas2d/tools/GeneratePerformanceData.js new file mode 100644 index 0000000..7cf2a25 --- /dev/null +++ b/third_party/WebKit/Source/modules/canvas2d/tools/GeneratePerformanceData.js
@@ -0,0 +1,647 @@ +// 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. + +// ==========// +// Constants // +// ==========// + +var CALL_TYPE = { + PATH : "PATH", + IMAGE : "IMAGE", + GET_DATA : "GET_DATA", + PUT_DATA : "PUT_DATA" +} + +var SHAPE_TYPE = { + STROKE_PATH : "STROKE_PATH", + FILL_CONVEX_PATH : "FILL_CONVEX_PATH", + FILL_NON_CONVEX_PATH : "FILL_NON_CONVEX_PATH", + STROKE_RECT : "STROKE_RECT", + FILL_RECT : "FILL_RECT", + STROKE_TEXT : "STROKE_TEXT", + FILL_TEXT : "FILL_TEXT" +} + +var SHAPE_STYLE = { + COLOR : "COLOR", + LINEAR_GRADIENT : "LINEAR_GRADIENT", + RADIAL_GRADIENT: "RADIAL_GRADIENT", + PATTERN : "PATTERN" +} + +var IMAGE_TYPE = { + DRAW_SVG_IMAGE : "DRAW_SVG_IMAGE", + DRAW_PNG_IMAGE : "DRAW_PNG_IMAGE" +} + +var NUMBER_OF_FRAME_PER_ESTIMATE = 3; +var NUMBER_OF_BLANK_FRAMES_BETWEEN_MEASUREMENTS = 5; + +// The max frames per second (fps) should be less than 60 because the rendering +// speed should be the limiting factor, not screen refresh rate. +var MAX_FRAMES_PER_SECOND_FOR_MEASUREMENTS = 30; +var MIN_FRAMES_PER_SECOND_FOR_MEASUREMENTS = 10; +var TARGET_FPS = 20; +var TARGET_TPF = 1000 / TARGET_FPS; + +// ================// +// State Variables // +// ================// + +var recording_helper = new RecordingHelper(); +recording_helper.restartRecordingTime(); + +// list of list of DrawParameter's to describe the each frame to draw +var list_of_frame_parameters = []; + + // list of PerformanceMeasurement +var performance_measurements = []; + +var frame_index = 0; +var blank_counter = 0; + +// =============================// +// Main rendering loop function // +// =============================// + +function drawAndRecord(context) { + if (frame_index >= list_of_frame_parameters.length) return; + + if (blank_counter > 0) { + recording_helper.restartRecordingTime(); + blank_counter--; + return; + } + + var newMeasurement = false; + if (blank_counter < 0) { + if (frame_index == 0 + && recording_helper.getNumberOfFramesRecorded() == 0) { + newMeasurement = true; + } else { + var tpf = recording_helper.getAverageTimePerFrame(); + var fps = recording_helper.getAverageFramesPerSecond(); + + if (fps > MAX_FRAMES_PER_SECOND_FOR_MEASUREMENTS) { + // too fast, increase quantity and try again + var new_quantity = quantityForTarget( + list_of_frame_parameters[frame_index][0].quantity, + tpf, TARGET_TPF); + + list_of_frame_parameters[frame_index][0].quantity = new_quantity; + + // reset total bounding box area values + for (var i = 0; i<list_of_frame_parameters[frame_index].length; i++) { + list_of_frame_parameters[frame_index][i].resetBoundingBoxArea(); + } + + newMeasurement = true; + + } else if (fps < MIN_FRAMES_PER_SECOND_FOR_MEASUREMENTS) { + // too slow, move on to the next measurement + console.log("Too slow - moving on to next measurement."); + frame_index++; + newMeasurement = true; + } + + if (recording_helper.getNumberOfFramesRecorded() >= + NUMBER_OF_FRAME_PER_ESTIMATE && newMeasurement == false) { + if (fps < MAX_FRAMES_PER_SECOND_FOR_MEASUREMENTS) { + // Redering speed, not refresh rate is the limiting factor + console.log("Recording: frame_index = " + + frame_index + ",\n\ttfp = "+ tpf + + "\n\tfps = " + fps); + + performance_measurements.push( + new PerformanceMeasurement( + tpf, fps, + list_of_frame_parameters[frame_index])); + + } + + frame_index++; + newMeasurement = true; + } + } + + if (newMeasurement) { + recording_helper.restartRecordingTime(); + blank_counter = NUMBER_OF_BLANK_FRAMES_BETWEEN_MEASUREMENTS; + if (frame_index >= list_of_frame_parameters.length) { + console.log(performance_measurements); + drawCSVString(getCSVString(performance_measurements)); + return; + } + } + } + + if (blank_counter == 0) { + recording_helper.restartRecordingTime(); + blank_counter--; + } + + DrawParameters(context, list_of_frame_parameters[frame_index]); + recording_helper.recordFrame(); +} + +// =====================// +// Data storage classes // +// =====================// + +function DrawSize(width, height) { + this.width = Math.round(width); + this.height = Math.round(height); +} + +function DrawParameter( + call_type, draw_sub_type, size, shadow_blur, quantity, fill_style) { + this.call_type = call_type; // path, image, put or get image data + this.draw_sub_type = draw_sub_type; // image type or path type + this.fill_style = fill_style; // for paths only + this.shadow_blur = shadow_blur; + + // Target size of side of square bounding box. Actuall size can differ. + // total_bounding_box_area is returned by draw call and represents actuall + // area of the call. + this.size = size; + + this.total_bounding_box_area = 0; // computed elsewhere + this.total_shadow_bounding_box_area = 0; // computed elsewhere + this.total_bounding_box_perimeter = 0; // computed elsewhere + + this.resetBoundingBoxArea = function() { + this.total_bounding_box_area = 0; + this.total_shadow_bounding_box_area = 0; + this.total_bounding_box_perimeter = 0; + } + + this.quantity = quantity; +} + +function PerformanceMeasurement(tpf, fps, parameters) { + this.tpf = tpf; // time per frame + this.fps = fps; // frames per second + this.parameters = parameters; // DrawParameter object +} + +// ===========================================================// +// Utility functions for generating lists of frame parameters // +// ===========================================================// + +function generatePathFrameParameters() { + var path_sizes = [20, 50, 200, 300, 400]; + var quantities = [10, 20, 50, 100, 500, 1000, 2000]; + var shadow_blurs = [0, 1, 10, 20]; + + // Only draw combinations that contain shadows with this probability + // to reduce the number of permutations. + var shadowedPermutationProbability = 0.1; + + var list_of_frame_parameters = []; + + for (shape_type in SHAPE_TYPE) { + for (var size_i = 0; size_i < path_sizes.length; size_i++) { + for (var qty_i = 0; qty_i < quantities.length; qty_i++) { + for (var sh_i = 0; sh_i < shadow_blurs.length; sh_i++) { + for (fill_style in SHAPE_STYLE) { + if (shadow_blurs[sh_i] == 0 + || getTrueWithProbability(shadowedPermutationProbability)) { + + list_of_frame_parameters.push([ + new DrawParameter(CALL_TYPE.PATH, shape_type, + path_sizes[size_i], shadow_blurs[sh_i], + quantities[qty_i], fill_style)]); + } + } + } + } + } + } + return list_of_frame_parameters; +} + +function generateImageFrameParameters() { + var png_image_sizes = [5, 10, 20, 50, 90]; + var svg_image_sizes = [5, 20, 50, 90, 200, 300]; + + var png_quantities = [10, 50, 100, 500, 1000]; + var svg_quantities = [10, 50, 100, 200, 500]; + var shadow_blurs = [0, 1, 5, 10]; + + // Only draw combinations that contain shadows with this probability + // to reduce the number of permutations. + var shadowedPermutationProbability = 0.1; + + var list_of_frame_parameters = []; + + for (var size_i = 0; size_i < png_image_sizes.length; size_i++) { + for (var qty_i = 0; qty_i < png_quantities.length; qty_i++) { + for (var sh_i = 0; sh_i < shadow_blurs.length; sh_i++) { + if (shadow_blurs[sh_i] == 0 + || getTrueWithProbability(shadowedPermutationProbability)) { + + list_of_frame_parameters.push([ + new DrawParameter(CALL_TYPE.IMAGE, + IMAGE_TYPE.DRAW_PNG_IMAGE, + png_image_sizes[size_i], + shadow_blurs[sh_i], + png_quantities[qty_i], "")]); + } + } + } + } + + for (var size_i = 0; size_i < svg_image_sizes.length; size_i++) { + for (var qty_i = 0; qty_i < svg_quantities.length; qty_i++) { + for (var sh_i = 0; sh_i < shadow_blurs.length; sh_i++) { + if (shadow_blurs[sh_i] == 0 + || getTrueWithProbability(shadowedPermutationProbability)) { + + list_of_frame_parameters.push([ + new DrawParameter(CALL_TYPE.IMAGE, + IMAGE_TYPE.DRAW_SVG_IMAGE, + svg_image_sizes[size_i], + shadow_blurs[sh_i], + svg_quantities[qty_i], "")]); + } + } + } + } + return list_of_frame_parameters; +} + +function generatePutDataFrameParameters(context) { + var sizes = [20, 50, 100, 200, 300]; + var quantities = [10, 50, 100, 500, 1000, 2000]; + + var list_of_frame_parameters = []; + + for (var size_i = 0; size_i < sizes.length; size_i++) { + for (var qty_i = 0; qty_i < quantities.length; qty_i++) { + // Call putImageData so it aquires and caches image data of + // the correct dimensions + putImageData(context, sizes[size_i]); + + list_of_frame_parameters.push([ + new DrawParameter(CALL_TYPE.PUT_DATA, + "", + sizes[size_i], + 0, + quantities[qty_i], "")]); + } + } + + return list_of_frame_parameters; +} + +function generateGetDataFrameParameters(context) { + var sizes = [20, 50, 100, 200, 300]; + var quantities = [10, 50, 100, 500, 1000, 2000]; + + var list_of_frame_parameters = []; + + for (var size_i = 0; size_i < sizes.length; size_i++) { + for (var qty_i = 0; qty_i < quantities.length; qty_i++) { + list_of_frame_parameters.push([ + new DrawParameter(CALL_TYPE.GET_DATA, + "", + sizes[size_i], + 0, + quantities[qty_i], "")]); + } + } + + return list_of_frame_parameters; +} + +// Draw each DrawParameter in the parameter_list on the canvas context, +// updates their total_bounding_box_area, total_bounding_box_perimeter +// and total_shadow_bounding_box_area fields. +function DrawParameters(context, parameter_list) { + for (var i = 0; i < parameter_list.length; i++) { + var p = parameter_list[i]; + p.resetBoundingBoxArea(); + for (var count = 0; count < p.quantity; count++) { + var draw_size; + switch (p.call_type) { + case CALL_TYPE.PATH: + setShapeStyle(context, p.fill_style); + setShadeStyle(context, p.shadow_blur); + draw_size = drawShape(context, p.draw_sub_type, p.size); + break; + case CALL_TYPE.IMAGE: + setShadeStyle(context, p.shadow_blur); + draw_size = drawImageType(context, p.draw_sub_type, p.size); + break; + case CALL_TYPE.GET_DATA: + draw_size = getImageData(context, p.size); + break; + case CALL_TYPE.PUT_DATA: + draw_size = putImageData(context, p.size); + break; + default: + draw_size = new DrawSize(0, 0); + } + + p.total_bounding_box_area += + draw_size.width * draw_size.height; + + p.total_bounding_box_perimeter += + (2*draw_size.width) + (2*draw_size.height); + + if (p.call_type == CALL_TYPE.PATH || p.call_type == CALL_TYPE.IMAGE) { + p.total_shadow_bounding_box_area += + (draw_size.width+2*p.shadow_blur) * + (draw_size.height+2*p.shadow_blur); + } + } + } +} + +// =======================================================================// +// Utility functions to make a CSV string that encodes the generated data // +// =======================================================================// + +function getDataFrame(performance_measurements) { + var data = {}; + + // shadow_blur * total bounding box area + data["SHADOW_BLUR_TIMES_AREA"] = []; + + // shadow_blur^2 * total bounding box area + data["SHADOW_BLUR_SQUARED_TIMES_AREA"] = []; + + // shadow_blur^2 * total shadow bounding box area + data["SHADOW_BLUR_SQUARED_TIMES_SHADOW_AREA"] = []; + + // the number of draw calls that have a shadow + data["NUM_SHADOWS"] = []; + + data["CALL_TYPE"] = []; + + for (var i = 0; i < performance_measurements.length; i++) { + var performance_measurement = performance_measurements[i]; + for (var j = 0; j < performance_measurement.parameters.length; j++) { + var p = performance_measurement.parameters[j]; + var call_type = p.call_type + "_" + p.draw_sub_type; + var call_type_area = p.call_type + "_" + p.draw_sub_type + "_AREA"; + + data[call_type] = []; + data[call_type_area] = []; + + if (p.call_type == CALL_TYPE.PATH) { + data[p.fill_style] = []; + data[p.fill_style + "_AREA"] = []; + } + } + } + + for (var i = 0; i < performance_measurements.length; i++) { + var performance_measurement = performance_measurements[i]; + for (var j = 0; j < performance_measurement.parameters.length; j++) { + var p = performance_measurement.parameters[j]; + for (var key in data) { + data[key].push(0); + } + + var call_type = p.call_type + "_" + p.draw_sub_type; + var call_type_area = p.call_type + "_" + p.draw_sub_type + "_AREA"; + + data[call_type][i] += p.quantity; + + data[call_type_area][i] += p.total_bounding_box_area; + + if (p.call_type == CALL_TYPE.PATH) { + data[p.fill_style][i] += p.quantity; + data[p.fill_style + "_AREA"][i] += p.total_bounding_box_area; + } + + if (p.call_type == CALL_TYPE.PATH || p.call_type == CALL_TYPE.IMAGE) { + data["NUM_SHADOWS"][i] += (p.shadow_blur > 0.0) ? p.quantity : 0; + + data["SHADOW_BLUR_TIMES_AREA"][i] += + p.total_bounding_box_area * p.shadow_blur; + + data["SHADOW_BLUR_SQUARED_TIMES_AREA"][i] += + p.total_bounding_box_area * p.shadow_blur * p.shadow_blur; + + data["SHADOW_BLUR_SQUARED_TIMES_SHADOW_AREA"][i] += + p.total_shadow_bounding_box_area * p.shadow_blur * p.shadow_blur; + } + + data["CALL_TYPE"][i] = p.call_type; + } + } + + return data; +} + +function getCSVString(performance_measurements) { + var csv_string = ""; + + var data_frame = getDataFrame(performance_measurements); + + csv_string += "TIME_PER_FRAME, FRAMES_PER_SECOND" + for (var key in data_frame) { + csv_string += ", " + key; + } + csv_string += "\n"; + + for (var i = 0; i < performance_measurements.length; i++) { + var performance_measurement = performance_measurements[i]; + csv_string += performance_measurement.tpf; + csv_string += ", " + performance_measurement.fps; + + for (var key in data_frame) { + csv_string += ", " + data_frame[key][i]; + } + csv_string += "\n"; + } + + return csv_string; +} + +function drawCSVString(csv_string) { + var div = document.getElementById("csv_string"); + div.innerHTML = csv_string; +} + +// =========================================================================// +// Utility functions to set canvas parameters and perform canvas draw calls // +// =========================================================================// + +function drawShape(context, shape_type, size) { + context.lineWidth = 3; + switch (shape_type) { + case SHAPE_TYPE.STROKE_PATH: + var radius = size/2; + context.beginPath(); + context.ellipse(400, 400, radius, radius, 0, 0, 2*Math.PI, false); + context.stroke(); + return new DrawSize(size, size); + + case SHAPE_TYPE.FILL_CONVEX_PATH: + var radius = size/2; + context.beginPath(); + context.ellipse(400, 400, radius, radius, 0, 0, 2*Math.PI, false); + context.fill(); + return new DrawSize(size, size); + + case SHAPE_TYPE.FILL_NON_CONVEX_PATH: + var radius = size/2; + context.beginPath(); + context.lineTo(400, 400); + context.arc(400, 400, radius, 0, Math.PI*3/2, false); + context.lineTo(this.x, this.y); + context.fill(); + return new DrawSize(size, size); + + case SHAPE_TYPE.STROKE_RECT: + context.beginPath(); + context.rect(100, 100, size, size); + context.stroke(); + return new DrawSize(size, size); + + case SHAPE_TYPE.FILL_RECT: + context.beginPath(); + context.rect(100, 100, size, size); + context.fill(); + return new DrawSize(size, size); + + case SHAPE_TYPE.STROKE_TEXT: + context.font = size + "px Georgia"; + context.strokeText("M", 40, 500); + return new DrawSize(context.measureText("M").width, size); + + case SHAPE_TYPE.FILL_TEXT: + context.font = size + "px Georgia"; + context.fillText("M", 40, 500); + return new DrawSize(context.measureText("M").width, size); + + default: + console.log("Invalid SHAPE_TYPE: " + shape_type); + return new DrawSize(0, 0); + } +} + +var svg_image = document.getElementById("svg_image_element"); +var png_image = document.getElementById("png_image_element"); +function drawImageType(context, image_type, size) { + switch (image_type) { + case IMAGE_TYPE.DRAW_SVG_IMAGE: + context.drawImage(svg_image, 50, 50, size, size); + return new DrawSize(size, size); + + case IMAGE_TYPE.DRAW_PNG_IMAGE: + if (size > png_image.width) { + throw "In drawImageType (png) - size too big "; + } + if (size > png_image.height) { + throw "In drawImageType (png) - size too big "; + } + context.drawImage(png_image, 0, 0, size, size, 50, 50, size, size); + return new DrawSize(size, size); + } +} + +function setShapeStyle(context, shape_style, area) { + var gradient = ""; + switch (shape_style) { + case SHAPE_STYLE.LINEAR_GRADIENT: + var gradient = context.createLinearGradient(0, 0, 800, 600); + gradient.addColorStop(0, "blue"); + gradient.addColorStop(1, "white"); + context.fillStyle = gradient; + context.strokeStyle = gradient; + break; + case SHAPE_STYLE.COLOR: + context.fillStyle = "blue"; + context.strokeStyle = "blue"; + break; + case SHAPE_STYLE.RADIAL_GRADIENT: + var gradient = + context.createRadialGradient(400, 300, 100, 400, 300, 800); + gradient.addColorStop(0, "blue"); + gradient.addColorStop(1, "white"); + context.fillStyle = gradient; + context.strokeStyle = gradient; + break; + case SHAPE_STYLE.PATTERN: + var pattern = context.createPattern(png_image,"repeat"); + context.fillStyle = pattern; + context.strokeStyle = pattern; + break; + default: + console.log("Invalid SHAPE_STYLE: " + shape_style); + break; + } +} + +function setShadeStyle(context, shadow_blur) { + context.shadowBlur = shadow_blur; + context.shadowColor= "black"; +} + +function getImageData(context, size) { + var image = context.getImageData(10,10, size, size); + return new DrawSize(size, size); +} + + +var image_data_cache = {}; +function putImageData(context, size) { + if (!(size in image_data_cache)) { + // Cache a data source so that subsequent calls with the same size don't + // need to generate a new data source of the appropriate size + image_data_cache[size] = context.createImageData(size, size); + } + + context.putImageData(image_data_cache[size], 10, 10); + return new DrawSize(size, size); +} + +// ================// +// Other utilities // +// ================// + +function RecordingHelper() { + this.num_frames_since_restart = 0; + this.recording_start_time = Date.now(); + + this.restartRecordingTime = function() { + this.num_frames_since_restart = 0; + this.recording_start_time = Date.now(); + } + + this.recordFrame = function() { + this.num_frames_since_restart += 1; + } + + this.getAverageTimePerFrame = function() { + var time_interval = Date.now() - this.recording_start_time; + return time_interval / this.num_frames_since_restart; + } + + this.getAverageFramesPerSecond = function() { + return 1000 / this.getAverageTimePerFrame(); + } + + this.getNumberOfFramesRecorded = function() { + return this.num_frames_since_restart; + } +} + +function getTrueWithProbability(probability) { + return Math.random() < probability; +} + +// Given the current quantity of a call, the current time per frame and target +// time per frame, return a suggested quantity that should yield a rendering +// speed closer to the target time per frame assuming that the time per frame +// is linearly proportional to the quantity. +function quantityForTarget(current_quantity, current_tpf, target_tpf) { + if (current_quantity <= 0) return 1; + return Math.round(current_quantity * target_tpf / current_tpf); +} +
diff --git a/third_party/WebKit/Source/modules/canvas2d/tools/README.md b/third_party/WebKit/Source/modules/canvas2d/tools/README.md new file mode 100644 index 0000000..077eb4d --- /dev/null +++ b/third_party/WebKit/Source/modules/canvas2d/tools/README.md
@@ -0,0 +1,17 @@ +Performance Analysis +=== + +This directory contains tools that support a data driven approach to improve the 2D canvas graphics rendering performance. They have 2 main purposes: +1. Improve our understandind of the 2D canvas graphics rendering performance. This better understanding can yield new performance optimization ideas. +2. Help design and calibrate heuristics to determine the optimal rendering strategies at run time. + +Performance Data Generation +--- + +GeneratePerformanceData.html measures the graphics rendering performance for a series of frames involving various 2D canvas operations in varying quantities, scales and shadow blur levels, including: + - Drawing various types of shapes with multiple different fill types. + - Drawing SVG and PNG images. + - Calling getImagedata and putImageData. + +After recording performance for all the frames, it generates a CSV string that includes the performance (in frames per second and time per frame) and description of every frame measured. +
diff --git a/third_party/WebKit/Source/modules/canvas2d/tools/bench.js b/third_party/WebKit/Source/modules/canvas2d/tools/bench.js new file mode 100644 index 0000000..82750f7 --- /dev/null +++ b/third_party/WebKit/Source/modules/canvas2d/tools/bench.js
@@ -0,0 +1,29 @@ +// 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. + +var bench = (function() { + var rafFunc; + var drawFunc; + + function tick() { + drawFunc(); + rafFunc(tick); + }; + + function startAnimation() { + rafFunc = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame; + rafFunc(tick); + }; + + var bench = {}; + bench.run = function(df) { + drawFunc = df; + startAnimation(); + }; + return bench; +})();
diff --git a/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.cpp b/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.cpp index 2d5ee691..3ec2249 100644 --- a/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.cpp +++ b/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.cpp
@@ -10,11 +10,6 @@ { } -DeviceLightEvent::DeviceLightEvent() - : m_value(std::numeric_limits<double>::infinity()) -{ -} - DeviceLightEvent::DeviceLightEvent(const AtomicString& eventType, double value) : Event(eventType, true, false) // The DeviceLightEvent bubbles but is not cancelable. , m_value(value) @@ -34,7 +29,3 @@ } } // namespace blink - - - -
diff --git a/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.h b/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.h index 3713f99b..d8d1a38c 100644 --- a/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.h +++ b/third_party/WebKit/Source/modules/device_light/DeviceLightEvent.h
@@ -16,10 +16,6 @@ public: ~DeviceLightEvent() override; - static DeviceLightEvent* create() - { - return new DeviceLightEvent; - } static DeviceLightEvent* create(const AtomicString& eventType, double value) { return new DeviceLightEvent(eventType, value); @@ -34,7 +30,6 @@ const AtomicString& interfaceName() const override; private: - DeviceLightEvent(); DeviceLightEvent(const AtomicString& eventType, double value); DeviceLightEvent(const AtomicString& eventType, const DeviceLightEventInit& initializer);
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp index 6aba81f..d03e5d78 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.cpp
@@ -85,11 +85,6 @@ { } -PaymentRequestUpdateEvent* PaymentRequestUpdateEvent::create() -{ - return new PaymentRequestUpdateEvent(); -} - PaymentRequestUpdateEvent* PaymentRequestUpdateEvent::create(const AtomicString& type, const PaymentRequestUpdateEventInit& init) { return new PaymentRequestUpdateEvent(type, init); @@ -139,12 +134,6 @@ Event::trace(visitor); } -PaymentRequestUpdateEvent::PaymentRequestUpdateEvent() - : m_waitForUpdate(false) - , m_abortTimer(this, &PaymentRequestUpdateEvent::onTimerFired) -{ -} - PaymentRequestUpdateEvent::PaymentRequestUpdateEvent(const AtomicString& type, const PaymentRequestUpdateEventInit& init) : Event(type, init) , m_waitForUpdate(false)
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h index 7fa6894..69162dc 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEvent.h
@@ -25,7 +25,6 @@ public: ~PaymentRequestUpdateEvent() override; - static PaymentRequestUpdateEvent* create(); static PaymentRequestUpdateEvent* create(const AtomicString& type, const PaymentRequestUpdateEventInit& = PaymentRequestUpdateEventInit()); void setPaymentDetailsUpdater(PaymentUpdater*); @@ -37,7 +36,6 @@ DECLARE_VIRTUAL_TRACE(); private: - PaymentRequestUpdateEvent(); PaymentRequestUpdateEvent(const AtomicString& type, const PaymentRequestUpdateEventInit&); Member<PaymentUpdater> m_updater;
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEventTest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEventTest.cpp index 5f883aa..fdaa7f8 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEventTest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestUpdateEventTest.cpp
@@ -36,7 +36,7 @@ TEST(PaymentRequestUpdateEventTest, OnUpdatePaymentDetailsCalled) { V8TestingScope scope; - PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(); + PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(EventTypeNames::shippingaddresschange); MockPaymentUpdater* updater = new MockPaymentUpdater; event->setPaymentDetailsUpdater(updater); event->setEventPhase(Event::kCapturingPhase); @@ -109,7 +109,7 @@ PaymentRequestMockFunctionScope funcs(scope.getScriptState()); makePaymentRequestOriginSecure(scope.document()); PaymentRequest* request = PaymentRequest::create(scope.getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), scope.getExceptionState()); - PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(); + PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(EventTypeNames::shippingaddresschange); event->setPaymentDetailsUpdater(request); EXPECT_FALSE(scope.getExceptionState().hadException());
diff --git a/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp b/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp index 0348945..d756af6f 100644 --- a/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp +++ b/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp
@@ -13,11 +13,6 @@ { } -SensorErrorEvent::SensorErrorEvent() - : Event(EventTypeNames::error, false, true) -{ -} - SensorErrorEvent::SensorErrorEvent(const AtomicString& eventType) : Event(eventType, true, false) // let default be bubbles but is not cancelable. {
diff --git a/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.h b/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.h index a10a333..0eedcaa 100644 --- a/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.h +++ b/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.h
@@ -16,11 +16,6 @@ DEFINE_WRAPPERTYPEINFO(); public: - static SensorErrorEvent* create() - { - return new SensorErrorEvent; - } - static SensorErrorEvent* create(const AtomicString& eventType) { return new SensorErrorEvent(eventType); @@ -37,7 +32,6 @@ const AtomicString& interfaceName() const override; - SensorErrorEvent(); explicit SensorErrorEvent(const AtomicString& eventType); SensorErrorEvent(const AtomicString& eventType, const SensorErrorEventInit& initializer);
diff --git a/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.cpp b/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.cpp index 1b90ea6f..911ea906 100644 --- a/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.cpp +++ b/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.cpp
@@ -10,10 +10,6 @@ { } -SensorReadingEvent::SensorReadingEvent() -{ -} - SensorReadingEvent::SensorReadingEvent(const AtomicString& eventType) : Event(eventType, true, false) // let default be bubbles but is not cancelable. , m_reading(SensorReading::create())
diff --git a/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.h b/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.h index 4616f65..d2c1b44 100644 --- a/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.h +++ b/third_party/WebKit/Source/modules/sensor/SensorReadingEvent.h
@@ -16,11 +16,6 @@ DEFINE_WRAPPERTYPEINFO(); public: - static SensorReadingEvent* create() - { - return new SensorReadingEvent; - } - static SensorReadingEvent* create(const AtomicString& eventType) { return new SensorReadingEvent(eventType); @@ -48,7 +43,6 @@ Member<SensorReading> m_reading; private: - SensorReadingEvent(); explicit SensorReadingEvent(const AtomicString& eventType); SensorReadingEvent(const AtomicString& eventType, SensorReading&); SensorReadingEvent(const AtomicString& eventType, const SensorReadingEventInit& initializer);
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp index 483be1f..a9b09ef 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp
@@ -11,10 +11,6 @@ #include "wtf/RefPtr.h" namespace blink { -ForeignFetchEvent* ForeignFetchEvent::create() -{ - return new ForeignFetchEvent(); -} ForeignFetchEvent* ForeignFetchEvent::create(ScriptState* scriptState, const AtomicString& type, const ForeignFetchEventInit& initializer) { @@ -48,10 +44,6 @@ return EventNames::ForeignFetchEvent; } -ForeignFetchEvent::ForeignFetchEvent() -{ -} - ForeignFetchEvent::ForeignFetchEvent(ScriptState* scriptState, const AtomicString& type, const ForeignFetchEventInit& initializer, ForeignFetchRespondWithObserver* respondWithObserver, WaitUntilObserver* waitUntilObserver) : ExtendableEvent(type, initializer, waitUntilObserver) , m_observer(respondWithObserver)
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.h b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.h index 2e9a2a9..4f7579e 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.h +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.h
@@ -26,7 +26,6 @@ class MODULES_EXPORT ForeignFetchEvent final : public ExtendableEvent { DEFINE_WRAPPERTYPEINFO(); public: - static ForeignFetchEvent* create(); static ForeignFetchEvent* create(ScriptState*, const AtomicString& type, const ForeignFetchEventInit&); static ForeignFetchEvent* create(ScriptState*, const AtomicString& type, const ForeignFetchEventInit&, ForeignFetchRespondWithObserver*, WaitUntilObserver*); @@ -40,7 +39,6 @@ DECLARE_VIRTUAL_TRACE(); protected: - ForeignFetchEvent(); ForeignFetchEvent(ScriptState*, const AtomicString& type, const ForeignFetchEventInit&, ForeignFetchRespondWithObserver*, WaitUntilObserver*); private:
diff --git a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.cpp index 7c98811..30f6d7a 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.cpp
@@ -10,11 +10,6 @@ namespace blink { -InstallEvent* InstallEvent::create() -{ - return new InstallEvent(); -} - InstallEvent* InstallEvent::create(const AtomicString& type, const ExtendableEventInit& eventInit) { return new InstallEvent(type, eventInit); @@ -95,10 +90,6 @@ return EventNames::InstallEvent; } -InstallEvent::InstallEvent() -{ -} - InstallEvent::InstallEvent(const AtomicString& type, const ExtendableEventInit& initializer) : ExtendableEvent(type, initializer) {
diff --git a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.h b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.h index eb075a7..46982c9 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.h +++ b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.h
@@ -18,7 +18,6 @@ DEFINE_WRAPPERTYPEINFO(); public: - static InstallEvent* create(); static InstallEvent* create(const AtomicString& type, const ExtendableEventInit&); static InstallEvent* create(const AtomicString& type, const ExtendableEventInit&, WaitUntilObserver*); @@ -29,7 +28,6 @@ const AtomicString& interfaceName() const override; protected: - InstallEvent(); InstallEvent(const AtomicString& type, const ExtendableEventInit&); InstallEvent(const AtomicString& type, const ExtendableEventInit&, WaitUntilObserver*); };
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp index 6197aec4..81180b47 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
@@ -218,8 +218,6 @@ EXPECT_FALSE(m_image->hasColorProfile()); } -#if USE(QCMSLIB) - TEST_F(BitmapImageTest, jpegHasColorProfile) { loadImage("/LayoutTests/fast/images/resources/icc-v2-gbr.jpg"); @@ -244,8 +242,6 @@ EXPECT_TRUE(m_image->hasColorProfile()); } -#endif // USE(QCMSLIB) - TEST_F(BitmapImageTest, icoHasWrongFrameDimensions) { loadImage("/LayoutTests/fast/images/resources/wrong-frame-dimensions.ico");
diff --git a/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h b/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h index 50a022e..f32dda3d 100644 --- a/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h +++ b/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h
@@ -75,34 +75,65 @@ // Approximate relative costs of different types of operations for the // accelerated rendering pipeline and the recording rendering pipeline. -// These costs were estimated experimentally based on the performance -// of each pipeline in the animometer benchmark. Multiple factors influence -// the true cost of each type of operation, including: -// - The hardware configuration -// - Version of the project -// - Additional details about the operation: -// - Subtype of operation (png vs svg image, arc vs line...) -// - Scale -// - Associated effects (patterns, gradients...) -// The coefficients are equal to 1/n, where n is equal to the number of calls -// of a type that can be performed in each frame while maintaining -// 50 frames per second. They were estimated using the animometer benchmark. +// These costs were estimated experimentally using the tools located in the +// third_party/WebKit/Source/modules/canvas2d/performance_analysis directory. -const double AcceleratedDrawPathApproximateCost = 0.004; -const double AcceleratedGetImageDataApproximateCost = 0.1; -const double AcceleratedDrawImageApproximateCost = 0.002; +// The RenderingModeCostIndex enum is used to access the heuristic coefficients that correspond +// to a given rendering mode. For exmaple, FillRectFixedCost[RecordingModeIndex] is the estimated +// fixed cost for FillRect in recording mode. +enum RenderingModeCostIndex { + RecordingModeIndex = 0, + AcceleratedModeIndex = 1, + NumRederingModesCostIdexes = 2 +}; -const double RecordingDrawPathApproximateCost = 0.0014; -const double UnacceleratedGetImageDataApproximateCost = 0.001; // This cost is for non-display-list mode after fallback. -const double RecordingDrawImageApproximateCost = 0.004; +const float FillRectFixedCost[NumRederingModesCostIdexes] = {6.190e-03f, 7.715e-03f}; +const float FillConvexPathFixedCost[NumRederingModesCostIdexes] = {1.251e-02f, 1.231e-02f}; +const float FillNonConvexPathFixedCost[NumRederingModesCostIdexes] = {1.714e-02f, 4.497e-02f}; +const float FillTextFixedCost[NumRederingModesCostIdexes] = {1.119e-02f, 2.203e-02f}; -// Coefficient used in the isAccelerationOptimalForCanvasContent -// heuristic to create a bias in the output. -// If set to a value greater than 1, it creates a bias towards suggesting acceleration. -// If set to a value smaller than 1, it creates a bias towards not suggesting acceleration -// For example, if its value is 1.5, then disabling gpu acceleration will only be suggested if -// recordingCost * 1.5 < acceleratedCost. -const double AcceleratedHeuristicBias = 1.5; +const float StrokeRectFixedCost[NumRederingModesCostIdexes] = {1.485e-02f, 7.287e-03f}; +const float StrokePathFixedCost[NumRederingModesCostIdexes] = {2.390e-02f, 5.125e-02f}; +const float StrokeTextFixedCost[NumRederingModesCostIdexes] = {1.149e-02f, 1.742e-02f}; + +const float FillRectVariableCostPerArea[NumRederingModesCostIdexes] = {2.933e-07f, 2.188e-09f}; +const float FillConvexPathVariableCostPerArea[NumRederingModesCostIdexes] = {7.871e-07f, 1.608e-07f}; +const float FillNonConvexPathVariableCostPerArea[NumRederingModesCostIdexes] = {8.336e-07f, 1.384e-06f}; +const float FillTextVariableCostPerArea[NumRederingModesCostIdexes] = {1.411e-06f, 0.0f}; + +const float StrokeRectVariableCostPerArea[NumRederingModesCostIdexes] = {9.882e-07f, 0.0f}; +const float StrokePathVariableCostPerArea[NumRederingModesCostIdexes] = {1.583e-06f, 2.401e-06f}; +const float StrokeTextVariableCostPerArea[NumRederingModesCostIdexes] = {1.530e-06f, 6.699e-07f}; + +const float PatternFillTypeFixedCost[NumRederingModesCostIdexes] = {1.377e-02f, 1.035e-02f}; +const float LinearGradientFillTypeFixedCost[NumRederingModesCostIdexes] = {7.694e-03f, 6.900e-03f}; +const float RadialGradientFillTypeFixedCost[NumRederingModesCostIdexes] = {2.260e-02f, 7.193e-03f}; + +const float PatternFillTypeVariableCostPerArea[NumRederingModesCostIdexes] = {6.080e-07f, 0.0f}; +const float LinearGradientFillVariableCostPerArea[NumRederingModesCostIdexes] = {9.635e-07f, 0.0f}; +const float RadialGradientFillVariableCostPerArea[NumRederingModesCostIdexes] = {6.662e-06f, 0.0f}; + +const float ShadowFixedCost[NumRederingModesCostIdexes] = {2.502e-02f, 2.274e-02f}; +const float ShadowVariableCostPerAreaTimesShadowBlurSquared[NumRederingModesCostIdexes] = {6.856e-09f, 0.0f}; + +const float PutImageDataFixedCost[NumRederingModesCostIdexes] = {1.209e-03f, 1.885e-02f}; +const float PutImageDataVariableCostPerArea[NumRederingModesCostIdexes] = {6.231e-06f, 4.116e-06f}; + +const float DrawSVGImageFixedCost[NumRederingModesCostIdexes] = {1.431e-01f, 2.958e-01f}; +const float DrawPNGImageFixedCost[NumRederingModesCostIdexes] = {1.278e-02f, 1.306e-02f}; + +const float DrawSVGImageVariableCostPerArea[NumRederingModesCostIdexes] = {1.030e-05f, 4.463e-06f}; +const float DrawPNGImageVariableCostPerArea[NumRederingModesCostIdexes] = {1.727e-06f, 0.0f}; + +// Two conditions must be met before the isAccelerationOptimalForCanvasContent heuristics recommends +// switching out of the accelerated mode. +// 1. The difference in estimated cost per frame is larger than MinCostPerFrameImprovementToSuggestDisableAcceleration. +// This ensures that the overhead involved in a switch of rendering mode and the risk of making a wrong decision +// are justified by a large expected increased performance. +// 2. The percent reduction in rendering cost is larger than MinPercentageImprovementToSuggestDisableAcceleration. +// This ensures that there is a high level of confidence that the performance would be improved in recording mode. +const float MinCostPerFrameImprovementToSuggestDisableAcceleration = 15.0f; +const float MinPercentageImprovementToSuggestDisableAcceleration = 30.0f; // Minimum number of frames that need to be rendered // before the rendering pipeline may be switched. Having this set
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp index d6f1897..63afa759 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
@@ -178,7 +178,7 @@ if ((*it) != ancestorState.transform) { TransformationMatrix localTransformMatrix = (*it)->matrix(); localTransformMatrix.applyTransformOrigin((*it)->origin()); - transformMatrix = localTransformMatrix * transformMatrix; + transformMatrix = transformMatrix * localTransformMatrix; } precomputedData.toAncestorTransforms.set(*it, transformMatrix);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp index 6003d402..e78cf293 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -162,6 +162,31 @@ EXPECT_EQ(rotateTransform, getPrecomputedDataForAncestor(rootPropertyTreeState()).toAncestorTransforms.get(transform1.get())); } +TEST_F(GeometryMapperTest, NestedTransformsScaleAndTranslation) +{ + TransformationMatrix scaleTransform; + scaleTransform.scale(2); + RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, scaleTransform, FloatPoint3D()); + + TransformationMatrix translateTransform; + translateTransform.translate(100, 0); + RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(transform1, translateTransform, FloatPoint3D()); + + PropertyTreeState localState = rootPropertyTreeState(); + localState.transform = transform2.get(); + + FloatRect input(0, 0, 100, 100); + // Note: unlike NestedTransforms, the order of these transforms matters. This tests correct order of matrix multiplication. + TransformationMatrix final = scaleTransform * translateTransform; + FloatRect output = final.mapRect(input); + + CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect(), localState, rootPropertyTreeState()); + + // Check the cached matrix for the intermediate transform. + EXPECT_EQ(scaleTransform, getPrecomputedDataForAncestor(rootPropertyTreeState()).toAncestorTransforms.get(transform1.get())); +} + + TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) { TransformationMatrix rotateTransform;
diff --git a/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h b/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h index f40291e9..99e7518 100644 --- a/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h +++ b/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h
@@ -129,7 +129,7 @@ void initializeNewFrame(size_t index) override { - m_frameBufferCache[index].setSize(size().width(), size().height()); + m_frameBufferCache[index].setSizeAndColorProfile(size().width(), size().height(), colorProfile()); m_frameBufferCache[index].setHasAlpha(false); }
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp index 93d5cc8..691e9e4 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -294,9 +294,10 @@ return m_rowBytes[i]; } -#if USE(QCMSLIB) namespace { +#if USE(QCMSLIB) + const unsigned kIccColorProfileHeaderLength = 128; bool rgbColorProfile(const char* profileData, unsigned profileLength) @@ -317,11 +318,14 @@ SpinLock gTargetColorProfileLock; qcms_profile* gTargetColorProfile = nullptr; +#endif // USE(QCMSLIB) + } // namespace // static void ImageDecoder::setTargetColorProfile(const WebVector<char>& profile) { +#if USE(QCMSLIB) if (profile.isEmpty()) return; @@ -349,15 +353,18 @@ } qcms_profile_precache_output_transform(gTargetColorProfile); +#endif // USE(QCMSLIB) } -bool ImageDecoder::hasColorProfile() const +void ImageDecoder::setColorProfileAndComputeTransform(const char* iccData, unsigned iccLength, bool hasAlpha, bool useSRGB) { - return m_sourceToOutputDeviceColorTransform.get(); -} + // Sub-classes should not call this if they were instructed to ignore embedded color profiles. + DCHECK(!m_ignoreGammaAndColorProfile); -void ImageDecoder::setColorProfileAndTransform(const char* iccData, unsigned iccLength, bool hasAlpha, bool useSRGB) -{ + m_colorProfile.assign(iccData, iccLength); + m_hasColorProfile = true; + +#if USE(QCMSLIB) m_sourceToOutputDeviceColorTransform.reset(); // Create the input profile @@ -396,19 +403,7 @@ // FIXME: Don't force perceptual intent if the image profile contains an intent. m_sourceToOutputDeviceColorTransform.reset(qcms_transform_create(inputProfile.get(), dataFormat, gTargetColorProfile, QCMS_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL)); -} - -#else // USE(QCMSLIB) - -void ImageDecoder::setTargetColorProfile(const WebVector<char>&) -{ -} - -bool ImageDecoder::hasColorProfile() const -{ - return false; -} - #endif // USE(QCMSLIB) +} } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h index 0a73a82..a44d261 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
@@ -112,10 +112,7 @@ ImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes) : m_premultiplyAlpha(alphaOption == AlphaPremultiplied) , m_ignoreGammaAndColorProfile(colorOptions == GammaAndColorProfileIgnored) - , m_maxDecodedBytes(maxDecodedBytes) - , m_sizeAvailable(false) - , m_isAllDataReceived(false) - , m_failed(false) { } + , m_maxDecodedBytes(maxDecodedBytes) { } virtual ~ImageDecoder() { } @@ -231,14 +228,19 @@ ImageOrientation orientation() const { return m_orientation; } - void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; } bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; } - static void setTargetColorProfile(const WebVector<char>&); - bool hasColorProfile() const; + + + // Note that hasColorProfile refers to the existence of a not-ignored + // embedded color profile, and is independent of whether or not that + // profile's transform has been baked into the pixel values. + bool hasColorProfile() const { return m_hasColorProfile; } + void setColorProfileAndComputeTransform(const char* iccData, unsigned iccLength, bool hasAlpha, bool useSRGB); #if USE(QCMSLIB) - void setColorProfileAndTransform(const char* iccData, unsigned iccLength, bool hasAlpha, bool useSRGB); + // In contrast with hasColorProfile, this refers to the transform that has + // been baked into the pixels. qcms_transform* colorTransform() { return m_sourceToOutputDeviceColorTransform.get(); } #endif @@ -315,10 +317,13 @@ // Decodes the requested frame. virtual void decode(size_t) = 0; + // Returns the embedded image color profile. + const ImageFrame::ICCProfile& colorProfile() const { return m_colorProfile; } + RefPtr<SegmentReader> m_data; // The encoded data. Vector<ImageFrame, 1> m_frameBufferCache; - bool m_premultiplyAlpha; - bool m_ignoreGammaAndColorProfile; + const bool m_premultiplyAlpha; + const bool m_ignoreGammaAndColorProfile; ImageOrientation m_orientation; // The maximum amount of memory a decoded image should require. Ideally, @@ -326,7 +331,7 @@ // (and then return the downsampled size from decodedSize()). Ignoring // this limit can cause excessive memory use or even crashes on low- // memory devices. - size_t m_maxDecodedBytes; + const size_t m_maxDecodedBytes; private: // Some code paths compute the size of the image as "width * height * 4" @@ -339,9 +344,12 @@ } IntSize m_size; - bool m_sizeAvailable; - bool m_isAllDataReceived; - bool m_failed; + bool m_sizeAvailable = false; + bool m_isAllDataReceived = false; + bool m_failed = false; + + bool m_hasColorProfile = false; + ImageFrame::ICCProfile m_colorProfile; #if USE(QCMSLIB) QCMSTransformUniquePtr m_sourceToOutputDeviceColorTransform;
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp index 13904396..1803280 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp
@@ -93,11 +93,14 @@ return other.m_bitmap.copyTo(&m_bitmap, other.m_bitmap.colorType()); } -bool ImageFrame::setSize(int newWidth, int newHeight) +bool ImageFrame::setSizeAndColorProfile(int newWidth, int newHeight, const ICCProfile& newIccProfile) { - // setSize() should only be called once, it leaks memory otherwise. + // setSizeAndColorProfile() should only be called once, it leaks memory otherwise. ASSERT(!width() && !height()); + // TODO(ccameron): Populate the color space parameter of the SkImageInfo + // with newIccProfile, under a runtime flag. + m_bitmap.setInfo(SkImageInfo::MakeN32(newWidth, newHeight, m_premultiplyAlpha ? kPremul_SkAlphaType : kUnpremul_SkAlphaType)); if (!m_bitmap.tryAllocPixels(m_allocator, 0))
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h index 7a51c75..f6e4e8b 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h +++ b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h
@@ -29,6 +29,7 @@ #include "platform/PlatformExport.h" #include "platform/geometry/IntRect.h" +#include "public/platform/WebVector.h" #include "third_party/skia/include/core/SkBitmap.h" #include "wtf/Allocator.h" #include "wtf/Assertions.h" @@ -70,6 +71,8 @@ }; typedef uint32_t PixelData; + typedef WebVector<char> ICCProfile; + ImageFrame(); // The assignment operator reads m_hasAlpha (inside setStatus()) before it @@ -111,7 +114,7 @@ // Allocates space for the pixel data. Must be called before any pixels // are written. Must only be called once. Returns whether allocation // succeeded. - bool setSize(int newWidth, int newHeight); + bool setSizeAndColorProfile(int newWidth, int newHeight, const ICCProfile& newIccProfile); bool hasAlpha() const; const IntRect& originalFrameRect() const { return m_originalFrameRect; }
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp index 3f48117..0ee27a6c 100644 --- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp
@@ -119,7 +119,7 @@ // Initialize the framebuffer if needed. ASSERT(m_buffer); // Parent should set this before asking us to decode! if (m_buffer->getStatus() == ImageFrame::FrameEmpty) { - if (!m_buffer->setSize(m_parent->size().width(), m_parent->size().height())) + if (!m_buffer->setSizeAndColorProfile(m_parent->size().width(), m_parent->size().height(), ImageFrame::ICCProfile())) return m_parent->setFailed(); // Unable to allocate. m_buffer->setStatus(ImageFrame::FramePartial); // setSize() calls eraseARGB(), which resets the alpha flag, so we force
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp index 72f2c834..a769b6d0 100644 --- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -353,7 +353,7 @@ size_t requiredPreviousFrameIndex = buffer->requiredPreviousFrameIndex(); if (requiredPreviousFrameIndex == kNotFound) { // This frame doesn't rely on any previous data. - if (!buffer->setSize(size().width(), size().height())) + if (!buffer->setSizeAndColorProfile(size().width(), size().height(), ImageFrame::ICCProfile())) return setFailed(); } else { const ImageFrame* prevBuffer = &m_frameBufferCache[requiredPreviousFrameIndex];
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp index da081e5..6c5c1c5 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -49,6 +49,7 @@ , m_fastReader(nullptr) , m_decodedOffset(0) , m_dirEntriesCount(0) + , m_gammaAndColorProfileOption(colorOptions) { } @@ -210,8 +211,7 @@ if (!m_pngDecoders[index]) { AlphaOption alphaOption = m_premultiplyAlpha ? AlphaPremultiplied : AlphaNotPremultiplied; - GammaAndColorProfileOption colorOptions = m_ignoreGammaAndColorProfile ? GammaAndColorProfileIgnored : GammaAndColorProfileApplied; - m_pngDecoders[index] = wrapUnique(new PNGImageDecoder(alphaOption, colorOptions, m_maxDecodedBytes, dirEntry.m_imageOffset)); + m_pngDecoders[index] = wrapUnique(new PNGImageDecoder(alphaOption, m_gammaAndColorProfileOption, m_maxDecodedBytes, dirEntry.m_imageOffset)); setDataForPNGDecoderAtIndex(index); } // Fail if the size the PNGImageDecoder calculated does not match the size
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h index c4e91b0d..b2a1fe2 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
@@ -174,6 +174,9 @@ // Valid only while a BMPImageReader is decoding, this holds the size // for the particular entry being decoded. IntSize m_frameSize; + + // Used to pass on to an internally created PNG decoder. + const GammaAndColorProfileOption m_gammaAndColorProfileOption; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 63827d4..23d6d5a 100644 --- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -451,17 +451,17 @@ m_decoder->setOrientation(readImageOrientation(info())); -#if USE(QCMSLIB) // Allow color management of the decoded RGBA pixels if possible. if (!m_decoder->ignoresGammaAndColorProfile()) { #if USE(ICCJPEG) JOCTET* profile = nullptr; unsigned profileLength = 0; if (read_icc_profile(info(), &profile, &profileLength)) { - decoder()->setColorProfileAndTransform(reinterpret_cast<char*>(profile), profileLength, colorSpaceHasAlpha(info()->out_color_space), false /* useSRGB */); + decoder()->setColorProfileAndComputeTransform(reinterpret_cast<char*>(profile), profileLength, colorSpaceHasAlpha(info()->out_color_space), false /* useSRGB */); free(profile); } #endif // USE(ICCJPEG) +#if USE(QCMSLIB) if (decoder()->colorTransform()) { overrideColorSpace = JCS_UNKNOWN; #if defined(TURBO_JPEG_RGB_SWIZZLE) @@ -470,8 +470,8 @@ m_info.out_color_space = JCS_EXT_RGBA; #endif // defined(TURBO_JPEG_RGB_SWIZZLE) } - } #endif // USE(QCMSLIB) + } if (overrideColorSpace == JCS_YCbCr) { m_info.out_color_space = JCS_YCbCr; m_info.raw_data_out = TRUE; @@ -927,7 +927,7 @@ ASSERT(info->output_width == static_cast<JDIMENSION>(m_decodedSize.width())); ASSERT(info->output_height == static_cast<JDIMENSION>(m_decodedSize.height())); - if (!buffer.setSize(info->output_width, info->output_height)) + if (!buffer.setSizeAndColorProfile(info->output_width, info->output_height, colorProfile())) return setFailed(); // The buffer is transparent outside the decoded area while the image is
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp index c0b8473a..dff41e3 100644 --- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -216,7 +216,6 @@ if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png); -#if USE(QCMSLIB) if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { // We only support color profiles for color PALETTE and RGB[A] PNG. Supporting // color profiles for gray-scale images is slightly tricky, at least using the @@ -227,7 +226,7 @@ bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount; #ifdef PNG_iCCP_SUPPORTED if (png_get_valid(png, info, PNG_INFO_sRGB)) { - setColorProfileAndTransform(nullptr, 0, imageHasAlpha, true /* useSRGB */); + setColorProfileAndComputeTransform(nullptr, 0, imageHasAlpha, true /* useSRGB */); } else { char* profileName = nullptr; int compressionType = 0; @@ -238,12 +237,11 @@ #endif png_uint_32 profileLength = 0; if (png_get_iCCP(png, info, &profileName, &compressionType, &profile, &profileLength)) { - setColorProfileAndTransform(reinterpret_cast<char*>(profile), profileLength, imageHasAlpha, false /* useSRGB */); + setColorProfileAndComputeTransform(reinterpret_cast<char*>(profile), profileLength, imageHasAlpha, false /* useSRGB */); } } #endif // PNG_iCCP_SUPPORTED } -#endif // USE(QCMSLIB) if (!hasColorProfile()) { // Deal with gamma and keep it under our control. @@ -294,7 +292,7 @@ ImageFrame& buffer = m_frameBufferCache[0]; if (buffer.getStatus() == ImageFrame::FrameEmpty) { png_structp png = m_reader->pngPtr(); - if (!buffer.setSize(size().width(), size().height())) { + if (!buffer.setSizeAndColorProfile(size().width(), size().height(), colorProfile())) { longjmp(JMPBUF(png), 1); return; }
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp index fae908a7..d5e4397 100644 --- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp
@@ -231,10 +231,8 @@ m_formatFlags &= ~ICCP_FLAG; } -#if USE(QCMSLIB) if ((m_formatFlags & ICCP_FLAG) && !ignoresGammaAndColorProfile()) readColorProfile(); -#endif } ASSERT(isDecodedSizeAvailable()); @@ -250,7 +248,7 @@ const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(); if (requiredPreviousFrameIndex == kNotFound) { // This frame doesn't rely on any previous data. - if (!buffer.setSize(size().width(), size().height())) + if (!buffer.setSizeAndColorProfile(size().width(), size().height(), colorProfile())) return setFailed(); m_frameBackgroundHasAlpha = !buffer.originalFrameRect().contains(IntRect(IntPoint(), size())); } else { @@ -300,8 +298,6 @@ ImageDecoder::clearFrameBuffer(frameIndex); } -#if USE(QCMSLIB) - void WEBPImageDecoder::readColorProfile() { WebPChunkIterator chunkIterator; @@ -313,13 +309,11 @@ const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.bytes); size_t profileSize = chunkIterator.chunk.size; - setColorProfileAndTransform(profileData, profileSize, true /* hasAlpha */, false /* useSRGB */); + setColorProfileAndComputeTransform(profileData, profileSize, true /* hasAlpha */, false /* useSRGB */); WebPDemuxReleaseChunkIterator(&chunkIterator); } -#endif // USE(QCMSLIB) - void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) { ImageFrame& buffer = m_frameBufferCache[frameIndex]; @@ -462,7 +456,7 @@ ASSERT(buffer.getStatus() != ImageFrame::FrameComplete); if (buffer.getStatus() == ImageFrame::FrameEmpty) { - if (!buffer.setSize(size().width(), size().height())) + if (!buffer.setSizeAndColorProfile(size().width(), size().height(), colorProfile())) return setFailed(); buffer.setStatus(ImageFrame::FramePartial); // The buffer is transparent outside the decoded area while the image is loading.
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h index 718ae30..969d25f2 100644 --- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h
@@ -65,10 +65,7 @@ int m_formatFlags; bool m_frameBackgroundHasAlpha; -#if USE(QCMSLIB) void readColorProfile(); -#endif - bool updateDemuxer(); bool initFrameBuffer(size_t frameIndex); void applyPostProcessing(size_t frameIndex);
diff --git a/third_party/WebKit/Source/platform/network/NetworkUtils.cpp b/third_party/WebKit/Source/platform/network/NetworkUtils.cpp index 57c0b4c..49d0ba03 100644 --- a/third_party/WebKit/Source/platform/network/NetworkUtils.cpp +++ b/third_party/WebKit/Source/platform/network/NetworkUtils.cpp
@@ -5,10 +5,30 @@ #include "platform/network/NetworkUtils.h" #include "net/base/ip_address.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" #include "wtf/text/StringUTF8Adaptor.h" #include "wtf/text/WTFString.h" +namespace { + +net::registry_controlled_domains::PrivateRegistryFilter getNetPrivateRegistryFilter(blink::NetworkUtils::PrivateRegistryFilter filter) +{ + switch (filter) { + case blink::NetworkUtils::IncludePrivateRegistries: + return net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES; + case blink::NetworkUtils::ExcludePrivateRegistries: + return net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES; + } + // There are only two NetworkUtils::PrivateRegistryFilter enum entries, so + // we should never reach this point. However, we must have a default return + // value to avoid a compiler error. + NOTREACHED(); + return net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES; +} + +} // namespace + namespace blink { namespace NetworkUtils { @@ -28,6 +48,13 @@ return net::IsLocalHostname(utf8.asStringPiece(), isLocal6); } +String getDomainAndRegistry(const String& host, PrivateRegistryFilter filter) +{ + StringUTF8Adaptor hostUtf8(host); + std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(hostUtf8.asStringPiece(), getNetPrivateRegistryFilter(filter)); + return String(domain.data(), domain.length()); +} + } // NetworkUtils } // namespace blink
diff --git a/third_party/WebKit/Source/platform/network/NetworkUtils.h b/third_party/WebKit/Source/platform/network/NetworkUtils.h index 98e733a..471ebb1 100644 --- a/third_party/WebKit/Source/platform/network/NetworkUtils.h +++ b/third_party/WebKit/Source/platform/network/NetworkUtils.h
@@ -12,10 +12,17 @@ namespace NetworkUtils { +enum PrivateRegistryFilter { + IncludePrivateRegistries, + ExcludePrivateRegistries, +}; + PLATFORM_EXPORT bool isReservedIPAddress(const String& host); PLATFORM_EXPORT bool isLocalHostname(const String& host, bool* isLocal6); +PLATFORM_EXPORT String getDomainAndRegistry(const String& host, PrivateRegistryFilter); + } // NetworkUtils } // namespace blink
diff --git a/third_party/WebKit/Source/platform/network/NetworkUtilsTest.cpp b/third_party/WebKit/Source/platform/network/NetworkUtilsTest.cpp index d5d84f93..5eac73c 100644 --- a/third_party/WebKit/Source/platform/network/NetworkUtilsTest.cpp +++ b/third_party/WebKit/Source/platform/network/NetworkUtilsTest.cpp
@@ -61,4 +61,30 @@ } } +TEST(NetworkUtilsTest, GetDomainAndRegistry) +{ + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry("", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry(".", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry("..", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry("com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry(".com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry("www.example.com:8000", NetworkUtils::IncludePrivateRegistries)); + + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry("localhost", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("", NetworkUtils::getDomainAndRegistry("127.0.0.1", NetworkUtils::IncludePrivateRegistries)); + + EXPECT_EQ("example.com", NetworkUtils::getDomainAndRegistry("example.com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("example.com", NetworkUtils::getDomainAndRegistry("www.example.com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("example.com", NetworkUtils::getDomainAndRegistry("static.example.com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("example.com", NetworkUtils::getDomainAndRegistry("multilevel.www.example.com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("example.co.uk", NetworkUtils::getDomainAndRegistry("www.example.co.uk", NetworkUtils::IncludePrivateRegistries)); + + // Verify proper handling of 'private registries'. + EXPECT_EQ("foo.appspot.com", NetworkUtils::getDomainAndRegistry("www.foo.appspot.com", NetworkUtils::IncludePrivateRegistries)); + EXPECT_EQ("appspot.com", NetworkUtils::getDomainAndRegistry("www.foo.appspot.com", NetworkUtils::ExcludePrivateRegistries)); + + // Verify that unknown registries are included. + EXPECT_EQ("example.notarealregistry", NetworkUtils::getDomainAndRegistry("www.example.notarealregistry", NetworkUtils::IncludePrivateRegistries)); +} + } // namespace blink
diff --git a/third_party/WebKit/Tools/Scripts/generate_w3c_directory_owner_json b/third_party/WebKit/Tools/Scripts/generate-w3c-directory-owner-json similarity index 100% rename from third_party/WebKit/Tools/Scripts/generate_w3c_directory_owner_json rename to third_party/WebKit/Tools/Scripts/generate-w3c-directory-owner-json
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot.py index f899ca2..374a8ad 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot.py
@@ -87,6 +87,10 @@ def latest_layout_test_results(self, builder_name): return self.fetch_layout_test_results(self.accumulated_results_url_base(builder_name)) + @memoized + def fetch_results(self, build): + return self.fetch_layout_test_results(self.results_url(build.builder_name, build.build_number)) + def fetch_layout_test_results(self, results_url): """Returns a LayoutTestResults object for results fetched from a given URL.""" # FIXME: This should cache that the result was a 404 and stop hitting the network.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot_mock.py index 568a70d..bd4bdd8b 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot_mock.py
@@ -33,5 +33,18 @@ class MockBuildBot(BuildBot): + def __init__(self): + super(MockBuildBot, self).__init__() + # Dict of Build to canned LayoutTestResults. + self._canned_results = {} + def fetch_layout_test_results(self, _): return LayoutTestResults.results_from_string(LayoutTestResultsTest.example_full_results_json) + + def set_results(self, build, results): + self._canned_results[build] = results + + def fetch_results(self, build): + return self._canned_results.get( + build, + LayoutTestResults.results_from_string(LayoutTestResultsTest.example_full_results_json))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline.py index 3314a95..c4e35d4 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline.py
@@ -64,7 +64,8 @@ def bot_revision_data(self, scm): revisions = [] - for result in self.build_data().values(): + for builder_name in self._release_builders(): + result = self._tool.buildbot.fetch_results(Build(builder_name)) if result.run_was_interrupted(): _log.error("Can't rebaseline because the latest run on %s exited early.", result.builder_name()) return []
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline_unittest.py index ee2ce82..d768ab9d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/auto_rebaseline_unittest.py
@@ -36,7 +36,6 @@ "MOCK Win7": {"port_name": "test-win-win7", "specifiers": ["Win7", "Release"]}, "MOCK Win7 (dbg)": {"port_name": "test-win-win7", "specifiers": ["Win7", "Debug"]}, }) - self.command.latest_revision_processed_on_all_bots = lambda: 9000 self.command.bot_revision_data = lambda scm: [{"builder": "MOCK Win7", "revision": "9000"}] @@ -144,33 +143,50 @@ test_port = self.tool.port_factory.get('test') - def build_data(): - # Have prototype-chocolate only fail on "MOCK Mac10.11". - self._build_data[Build('MOCK Mac10.11')] = LayoutTestResults({ - "tests": { - "fast": { - "dom": { - "prototype-taco.html": { - "expected": "PASS", - "actual": "PASS TEXT", - "is_unexpected": True - }, - "prototype-chocolate.html": { - "expected": "FAIL", - "actual": "PASS" - }, - "prototype-strawberry.html": { - "expected": "PASS", - "actual": "IMAGE PASS", - "is_unexpected": True - } + # Have prototype-chocolate only fail on "MOCK Mac10.11", + # and pass on "Mock Mac10.10". + self.tool.buildbot.set_results(Build('MOCK Mac10.11'), LayoutTestResults({ + "tests": { + "fast": { + "dom": { + "prototype-taco.html": { + "expected": "PASS", + "actual": "PASS TEXT", + "is_unexpected": True + }, + "prototype-chocolate.html": { + "expected": "FAIL", + "actual": "PASS" + }, + "prototype-strawberry.html": { + "expected": "PASS", + "actual": "IMAGE PASS", + "is_unexpected": True } } } - }) - return self._build_data - - self.command.build_data = build_data + } + })) + self.tool.buildbot.set_results(Build('MOCK Mac10.10'), LayoutTestResults({ + "tests": { + "fast": { + "dom": { + "prototype-taco.html": { + "expected": "PASS", + "actual": "PASS", + }, + "prototype-chocolate.html": { + "expected": "FAIL", + "actual": "FAIL" + }, + "prototype-strawberry.html": { + "expected": "PASS", + "actual": "PASS", + } + } + } + } + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ crbug.com/24182 [ Debug ] path/to/norebaseline.html [ Rebaseline ] @@ -243,27 +259,20 @@ test_port = self.tool.port_factory.get('test') - original_build_data = self.command.build_data - - def build_data(): - original_build_data() - # Have prototype-chocolate only fail on "MOCK Mac10.11". - self._build_data[Build('MOCK Mac10.11')] = LayoutTestResults({ - "tests": { - "fast": { - "dom": { - "prototype-taco.html": { - "expected": "PASS", - "actual": "PASS TEXT", - "is_unexpected": True - } + # Have prototype-chocolate only fail on "MOCK Mac10.11". + self.tool.buildbot.set_results(Build('MOCK Mac10.11'), LayoutTestResults({ + "tests": { + "fast": { + "dom": { + "prototype-taco.html": { + "expected": "PASS", + "actual": "PASS TEXT", + "is_unexpected": True } } } - }) - return self._build_data - - self.command.build_data = build_data + } + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ Bug(foo) fast/dom/prototype-taco.html [ NeedsRebaseline ] @@ -282,14 +291,10 @@ self._execute_with_mock_options() self.assertEqual(self.tool.executive.calls, [ - [ - ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt', - '--builder', 'MOCK Mac10.11', '--test', 'fast/dom/prototype-taco.html'], - ], - [ - ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt', - '--builder', 'MOCK Mac10.11', '--test', 'fast/dom/prototype-taco.html'], - ], + [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt', + '--builder', 'MOCK Mac10.11', '--test', 'fast/dom/prototype-taco.html']], + [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt', + '--builder', 'MOCK Mac10.11', '--test', 'fast/dom/prototype-taco.html']], [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', 'txt', 'fast/dom/prototype-taco.html']], ['git', 'cl', 'upload', '-f'], ]) @@ -303,8 +308,8 @@ test_port = self.tool.port_factory.get('test') - def build_data(): - self._build_data[Build('MOCK Mac10.10')] = self._build_data[Build('MOCK Mac10.11')] = LayoutTestResults({ + for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']: + self.tool.buildbot.set_results(Build(builder), LayoutTestResults({ "tests": { "fast": { "dom": { @@ -316,10 +321,7 @@ } } } - }) - return self._build_data - - self.command.build_data = build_data + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ Bug(foo) fast/dom/prototype-taco.html [ NeedsRebaseline ] @@ -357,23 +359,19 @@ test_port = self.tool.port_factory.get('test') - def build_data(): - self._build_data[Build('MOCK Win')] = LayoutTestResults({ - "tests": { - "fast": { - "dom": { - "prototype-taco.html": { - "expected": "FAIL", - "actual": "PASS", - "is_unexpected": True - } + self.tool.buildbot.set_results(Build('MOCK Win7'), LayoutTestResults({ + "tests": { + "fast": { + "dom": { + "prototype-taco.html": { + "expected": "FAIL", + "actual": "PASS", + "is_unexpected": True } } } - }) - return self._build_data - - self.command.build_data = build_data + } + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ Bug(foo) fast/dom/prototype-taco.html [ NeedsRebaseline ] @@ -413,23 +411,19 @@ test_port = self.tool.port_factory.get('test') - def build_data(): - self._build_data[Build('MOCK Win')] = LayoutTestResults({ - "tests": { - "fast": { - "dom": { - "prototype-taco.html": { - "expected": "FAIL", - "actual": "PASS", - "is_unexpected": True - } + self.tool.buildbot.set_results(Build('MOCK Win7'), LayoutTestResults({ + "tests": { + "fast": { + "dom": { + "prototype-taco.html": { + "expected": "FAIL", + "actual": "PASS", + "is_unexpected": True } } } - }) - return self._build_data - - self.command.build_data = build_data + } + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ Bug(foo) fast/dom/prototype-taco.html [ NeedsRebaseline ] @@ -442,7 +436,6 @@ self.tool.builders = BuilderList({ "MOCK Win7": {"port_name": "test-win-win7", "specifiers": ["Win7", "Release"]}, }) - old_branch_name = self.tool.scm().current_branch_or_ref try: self.command.tree_status = lambda: 'open' @@ -470,8 +463,8 @@ test_port = self.tool.port_factory.get('test') - def build_data(): - self._build_data[Build('MOCK Mac10.10')] = self._build_data[Build('MOCK Mac10.11')] = LayoutTestResults({ + for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']: + self.tool.buildbot.set_results(Build(builder), LayoutTestResults({ "tests": { "fast": { "dom": { @@ -483,10 +476,7 @@ } } } - }) - return self._build_data - - self.command.build_data = build_data + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ Bug(foo) fast/dom/prototype-taco.html [ NeedsRebaseline ]
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py index 4cbaec1d..6dc139f0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -233,27 +233,17 @@ def __init__(self, options=None): super(AbstractParallelRebaselineCommand, self).__init__(options=options) - @memoized - def build_data(self): - """Returns a map of Build objects to LayoutTestResult objects. - - The Build objects are the latest builds for the release builders, - and LayoutTestResult objects for results fetched from archived layout - test results. - """ - build_to_results = {} - for builder_name in self._release_builders(): - builder_results = self._tool.buildbot.latest_layout_test_results(builder_name) - if builder_results: - build_to_results[Build(builder_name)] = builder_results - else: - raise Exception("No result for builder %s." % builder_name) - return build_to_results - - # The release builders cycle much faster than the debug ones and cover all the platforms. def _release_builders(self): + """Returns a list of builder names for continuous release builders. + + The release builders cycle much faster than the debug ones and cover all the platforms. + """ release_builders = [] for builder_name in self._tool.builders.all_continuous_builder_names(): + # TODO(qyearsley): Remove this check. Explicitly excluding ASAN builders + # should be unnecessary, since there are no ASAN builders listed in + # webkitpy/common/config/builders.py. If we do want to keep this check, + # then we should probably also explicitly exclude MSAN builders. if 'ASAN' in builder_name: continue port = self._tool.port_factory.get_from_builder_name(builder_name) @@ -304,7 +294,7 @@ # of some class, then this could be replaced with a method on that class. return [b.builder_name for b in builds] - def _rebaseline_commands(self, test_prefix_list, options, skip_checking_actual_results=False): + def _rebaseline_commands(self, test_prefix_list, options): path_to_webkit_patch = self._tool.path() cwd = self._tool.scm().checkout_root copy_baseline_commands = [] @@ -316,14 +306,9 @@ for test in port.tests([test_prefix]): builders_to_fetch_from = self._builders_to_fetch_from(self._builder_names(test_prefix_list[test_prefix])) for build in sorted(test_prefix_list[test_prefix]): - # TODO(qyearsley): Remove the parameter skip_checking_actual_results - # and instead refactor the existing code so that this is not necessary. builder, build_number = build.builder_name, build.build_number - if builder not in builders_to_fetch_from: break - if skip_checking_actual_results: - actual_failures_suffixes = test_prefix_list[test_prefix][build] else: actual_failures_suffixes = self._suffixes_for_actual_failures( test, build, test_prefix_list[test_prefix][build]) @@ -466,7 +451,7 @@ self._tool.scm().add_list(files_to_add) return lines_to_remove - def _rebaseline(self, options, test_prefix_list, skip_checking_actual_results=False): + def _rebaseline(self, options, test_prefix_list): """Downloads new baselines in parallel, then updates expectations files and optimizes baselines. @@ -484,10 +469,6 @@ "some/other.html" but only from builder-1. TODO(qyearsley): Replace test_prefix_list everywhere with some sort of class that contains the same data. - skip_checking_actual_results: If True, then the lists of suffixes - to rebaseline from |test_prefix_list| will be used directly; - if False, then the list of suffixes will filtered to include - suffixes with mismatches in actual results. """ for test, builds_to_check in sorted(test_prefix_list.items()): _log.info("Rebaselining %s", test) @@ -495,7 +476,7 @@ _log.debug(" %s: %s", build, ",".join(suffixes)) copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = self._rebaseline_commands( - test_prefix_list, options, skip_checking_actual_results) + test_prefix_list, options) lines_to_remove = {} self._run_in_parallel_and_update_scm(copy_baseline_commands) @@ -527,10 +508,13 @@ Returns: A set of file suffix strings. """ - if build not in self.build_data(): + results = self._tool.buildbot.fetch_results(build) + if not results: + _log.debug('No results found for build %s', build) return set() - test_result = self.build_data()[build].result_for_test(test) + test_result = results.result_for_test(test) if not test_result: + _log.debug('No test result for test %s in build %s', test, build) return set() return set(existing_suffixes) & TestExpectations.suffixes_for_test_result(test_result)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs.py index 9719f98e..77fe0e4 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs.py
@@ -56,7 +56,7 @@ if options.dry_run: return - self._rebaseline(options, test_prefix_list, skip_checking_actual_results=True) + self._rebaseline(options, test_prefix_list) def _get_issue_number(self, options): """Gets the Rietveld CL number from either |options| or from the current local branch."""
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs_unittest.py index 98f4cf1..19f17e2 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_from_try_jobs_unittest.py
@@ -121,14 +121,14 @@ self.command._rebaseline( self.command_options(issue=11112222), - {"fast/dom/prototype-taco.html": {Build("MOCK Try Win", 5000): ["txt", "png"]}}, - skip_checking_actual_results=True) + {"fast/dom/prototype-taco.html": {Build("MOCK Try Win", 5000): ["txt", "png"]}}) self.assertEqual( self.tool.executive.calls, [ - [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png', + [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt', '--builder', 'MOCK Try Win', '--test', 'fast/dom/prototype-taco.html', '--build-number', '5000']], - [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', - '--builder', 'MOCK Try Win', '--test', 'fast/dom/prototype-taco.html', '--build-number', '5000']] + [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt', + '--builder', 'MOCK Try Win', '--test', 'fast/dom/prototype-taco.html', '--build-number', '5000']], + [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', 'txt', 'fast/dom/prototype-taco.html']] ])
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py index a0f635e..f988172 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
@@ -60,7 +60,6 @@ # we can make the default port also a "test" port. self.original_port_factory_get = self.tool.port_factory.get test_port = self.tool.port_factory.get('test') - self._build_data = {} def get_test_port(port_name=None, options=None, **kwargs): if not port_name: @@ -91,28 +90,21 @@ self.tool.filesystem.written_files = {} def _setup_mock_build_data(self): - data = LayoutTestResults({ - "tests": { - "userscripts": { - "first-test.html": { - "expected": "PASS", - "actual": "IMAGE+TEXT" - }, - "second-test.html": { - "expected": "FAIL", - "actual": "IMAGE+TEXT" + for builder in ['MOCK Win7', 'MOCK Win7 (dbg)', 'MOCK Mac10.11']: + self.tool.buildbot.set_results(Build(builder), LayoutTestResults({ + "tests": { + "userscripts": { + "first-test.html": { + "expected": "PASS", + "actual": "IMAGE+TEXT" + }, + "second-test.html": { + "expected": "FAIL", + "actual": "IMAGE+TEXT" + } } } - } - }) - - def build_data(): - self._build_data = {} - for builder in ['MOCK Win7', 'MOCK Win7 (dbg)', 'MOCK Mac10.11']: - self._build_data[Build(builder)] = data - return self._build_data - - self.command.build_data = build_data + })) class TestCopyExistingBaselinesInternal(BaseTestCase): command_constructor = CopyExistingBaselinesInternal @@ -373,20 +365,16 @@ def test_rebaseline_test_passes_on_all_builders(self): self._setup_mock_build_data() - def build_data(): - self._build_data[Build('MOCK Win7')] = LayoutTestResults({ - "tests": { - "userscripts": { - "first-test.html": { - "expected": "NEEDSREBASELINE", - "actual": "PASS" - } + self.tool.buildbot.set_results(Build('MOCK Win7'), LayoutTestResults({ + "tests": { + "userscripts": { + "first-test.html": { + "expected": "NEEDSREBASELINE", + "actual": "PASS" } } - }) - return self._build_data - - self.command.build_data = build_data + } + })) options = MockOptions(optimize=True, verbose=True, results_directory=None) @@ -405,15 +393,16 @@ self.command._rebaseline(options, {"userscripts/first-test.html": {Build("MOCK Win7"): ["txt", "png"]}}) # Note that we have one run_in_parallel() call followed by a run_command() - self.assertEqual(self.tool.executive.calls, - [ - [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png', - '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']], - [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', - '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']], - [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', 'txt,png', - 'userscripts/first-test.html', '--verbose']] - ]) + self.assertEqual( + self.tool.executive.calls, + [ + [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png', + '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']], + [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', + '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']], + [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', 'txt,png', + 'userscripts/first-test.html', '--verbose']] + ]) def test_rebaseline_debug(self): self._setup_mock_build_data() @@ -436,19 +425,20 @@ def test_no_optimize(self): self._setup_mock_build_data() + print self.tool.buildbot._canned_results options = MockOptions(optimize=False, verbose=True, results_directory=None) self._write("userscripts/first-test.html", "Dummy test contents") - self.command._rebaseline(options, {"userscripts/first-test.html": {Build("MOCK Win7 (dbg)"): ["txt", "png"]}}) + self.command._rebaseline(options, {"userscripts/first-test.html": {Build("MOCK Win7"): ["txt", "png"]}}) # Note that we have only one run_in_parallel() call self.assertEqual( self.tool.executive.calls, [ [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png', - '--builder', 'MOCK Win7 (dbg)', '--test', 'userscripts/first-test.html', '--verbose']], + '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']], [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', - '--builder', 'MOCK Win7 (dbg)', '--test', 'userscripts/first-test.html', '--verbose']] + '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']] ]) def test_results_directory(self): @@ -641,8 +631,8 @@ self.tool.executive = MockExecutive2() - def build_data(): - self._build_data[Build('MOCK Mac10.11')] = self._build_data[Build('MOCK Mac10.10')] = LayoutTestResults({ + for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']: + self.tool.buildbot.set_results(Build(builder), LayoutTestResults({ "tests": { "userscripts": { "another-test.html": { @@ -655,10 +645,7 @@ } } } - }) - return self._build_data - - self.command.build_data = build_data + })) self._write("userscripts/another-test.html", "Dummy test contents") self._write("userscripts/images.svg", "Dummy test contents") @@ -698,8 +685,8 @@ self.tool.executive = MockExecutive2() - def build_data(): - self._build_data[Build('MOCK Mac10.10')] = self._build_data[Build('MOCK Mac10.11')] = LayoutTestResults({ + for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']: + self.tool.buildbot.set_results(Build(builder), LayoutTestResults({ "tests": { "userscripts": { "reftest-text.html": { @@ -716,10 +703,7 @@ } } } - }) - return self._build_data - - self.command.build_data = build_data + })) self._write("userscripts/reftest-text.html", "Dummy test contents") self._write("userscripts/reftest-text-expected.html", "Dummy test contents") @@ -785,8 +769,8 @@ def test_rebaseline_test_passes_everywhere(self): test_port = self.tool.port_factory.get('test') - def build_data(): - self._build_data[Build('MOCK Mac10.10')] = self._build_data[Build('MOCK Mac10.11')] = LayoutTestResults({ + for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']: + self.tool.buildbot.set_results(Build(builder), LayoutTestResults({ "tests": { "fast": { "dom": { @@ -798,10 +782,7 @@ } } } - }) - return self._build_data - - self.command.build_data = build_data + })) self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """ Bug(foo) fast/dom/prototype-taco.html [ Rebaseline ] @@ -825,37 +806,33 @@ """) def test_rebaseline_missing(self): - def build_data(): - self._build_data[Build('MOCK Mac10.10')] = LayoutTestResults({ - "tests": { - "fast": { - "dom": { - "missing-text.html": { - "expected": "PASS", - "actual": "MISSING", - "is_unexpected": True, - "is_missing_text": True - }, - "missing-text-and-image.html": { - "expected": "PASS", - "actual": "MISSING", - "is_unexpected": True, - "is_missing_text": True, - "is_missing_image": True - }, - "missing-image.html": { - "expected": "PASS", - "actual": "MISSING", - "is_unexpected": True, - "is_missing_image": True - } + self.tool.buildbot.set_results(Build('MOCK Mac10.10'), LayoutTestResults({ + "tests": { + "fast": { + "dom": { + "missing-text.html": { + "expected": "PASS", + "actual": "MISSING", + "is_unexpected": True, + "is_missing_text": True + }, + "missing-text-and-image.html": { + "expected": "PASS", + "actual": "MISSING", + "is_unexpected": True, + "is_missing_text": True, + "is_missing_image": True + }, + "missing-image.html": { + "expected": "PASS", + "actual": "MISSING", + "is_unexpected": True, + "is_missing_image": True } } } - }) - return self._build_data - - self.command.build_data = build_data + } + })) self._write('fast/dom/missing-text.html', "Dummy test contents") self._write('fast/dom/missing-text-and-image.html', "Dummy test contents")
diff --git a/third_party/libvpx/generate_gypi.sh b/third_party/libvpx/generate_gypi.sh index 350c05ea..9dc5440 100755 --- a/third_party/libvpx/generate_gypi.sh +++ b/third_party/libvpx/generate_gypi.sh
@@ -382,6 +382,7 @@ # Generate *_rtcd.h files. # $1 - Header file directory. # $2 - Architecture. +# $3 - Optional - any additional arguments to pass through. function gen_rtcd_header { echo "Generate $LIBVPX_CONFIG_DIR/$1/*_rtcd.h files." @@ -397,28 +398,28 @@ $BASE_DIR/$LIBVPX_SRC_DIR/build/make/rtcd.pl \ --arch=$2 \ - --sym=vp8_rtcd $DISABLE_AVX \ + --sym=vp8_rtcd $DISABLE_AVX $3 \ --config=$BASE_DIR/$TEMP_DIR/libvpx.config \ $BASE_DIR/$LIBVPX_SRC_DIR/vp8/common/rtcd_defs.pl \ > $BASE_DIR/$LIBVPX_CONFIG_DIR/$1/vp8_rtcd.h $BASE_DIR/$LIBVPX_SRC_DIR/build/make/rtcd.pl \ --arch=$2 \ - --sym=vp9_rtcd $DISABLE_AVX \ + --sym=vp9_rtcd $DISABLE_AVX $3 \ --config=$BASE_DIR/$TEMP_DIR/libvpx.config \ $BASE_DIR/$LIBVPX_SRC_DIR/vp9/common/vp9_rtcd_defs.pl \ > $BASE_DIR/$LIBVPX_CONFIG_DIR/$1/vp9_rtcd.h $BASE_DIR/$LIBVPX_SRC_DIR/build/make/rtcd.pl \ --arch=$2 \ - --sym=vpx_scale_rtcd $DISABLE_AVX \ + --sym=vpx_scale_rtcd $DISABLE_AVX $3 \ --config=$BASE_DIR/$TEMP_DIR/libvpx.config \ $BASE_DIR/$LIBVPX_SRC_DIR/vpx_scale/vpx_scale_rtcd.pl \ > $BASE_DIR/$LIBVPX_CONFIG_DIR/$1/vpx_scale_rtcd.h $BASE_DIR/$LIBVPX_SRC_DIR/build/make/rtcd.pl \ --arch=$2 \ - --sym=vpx_dsp_rtcd $DISABLE_AVX \ + --sym=vpx_dsp_rtcd $DISABLE_AVX $3 \ --config=$BASE_DIR/$TEMP_DIR/libvpx.config \ $BASE_DIR/$LIBVPX_SRC_DIR/vpx_dsp/vpx_dsp_rtcd_defs.pl \ > $BASE_DIR/$LIBVPX_CONFIG_DIR/$1/vpx_dsp_rtcd.h @@ -463,10 +464,10 @@ all_platforms="--enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 $DISABLE_AVX --as=yasm" gen_config_files linux/ia32 "--target=x86-linux-gcc --disable-ccache --enable-pic --enable-realtime-only ${all_platforms}" gen_config_files linux/x64 "--target=x86_64-linux-gcc --disable-ccache --enable-pic --enable-realtime-only ${all_platforms}" -gen_config_files linux/arm "--target=armv6-linux-gcc --enable-pic --enable-realtime-only --disable-install-bins --disable-install-libs --disable-edsp ${all_platforms}" -gen_config_files linux/arm-neon "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --disable-edsp ${all_platforms}" -gen_config_files linux/arm-neon-cpu-detect "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --enable-runtime-cpu-detect --disable-edsp ${all_platforms}" -gen_config_files linux/arm64 "--force-target=armv8-linux-gcc --enable-pic --enable-realtime-only --disable-edsp ${all_platforms}" +gen_config_files linux/arm "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --disable-install-bins --disable-install-libs --disable-neon ${all_platforms}" +gen_config_files linux/arm-neon "--target=armv7-linux-gcc --enable-pic --enable-realtime-only ${all_platforms}" +gen_config_files linux/arm-neon-cpu-detect "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --enable-runtime-cpu-detect ${all_platforms}" +gen_config_files linux/arm64 "--force-target=armv8-linux-gcc --enable-pic --enable-realtime-only ${all_platforms}" gen_config_files linux/mipsel "--target=mips32-linux-gcc ${all_platforms}" gen_config_files linux/mips64el "--target=mips64-linux-gcc ${all_platforms}" gen_config_files linux/generic "--target=generic-gnu --enable-pic --enable-realtime-only ${all_platforms}" @@ -504,7 +505,7 @@ gen_rtcd_header linux/ia32 x86 gen_rtcd_header linux/x64 x86_64 -gen_rtcd_header linux/arm armv6 +gen_rtcd_header linux/arm armv7 "--disable-neon --disable-neon_asm" gen_rtcd_header linux/arm-neon armv7 gen_rtcd_header linux/arm-neon-cpu-detect armv7 gen_rtcd_header linux/arm64 armv8
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.c b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.c index 135d0ef..71ea1c4 100644 --- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.c +++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.c
@@ -6,5 +6,5 @@ /* in the file PATENTS. All contributing project authors may */ /* be found in the AUTHORS file in the root of the source tree. */ #include "vpx/vpx_codec.h" -static const char* const cfg = "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --enable-runtime-cpu-detect --disable-edsp --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; +static const char* const cfg = "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --enable-runtime-cpu-detect --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; const char *vpx_codec_build_config(void) {return cfg;}
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.c b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.c index 588edd5..3f3a72bf 100644 --- a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.c +++ b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.c
@@ -6,5 +6,5 @@ /* in the file PATENTS. All contributing project authors may */ /* be found in the AUTHORS file in the root of the source tree. */ #include "vpx/vpx_codec.h" -static const char* const cfg = "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --disable-edsp --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; +static const char* const cfg = "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; const char *vpx_codec_build_config(void) {return cfg;}
diff --git a/third_party/libvpx/source/config/linux/arm/vpx_config.c b/third_party/libvpx/source/config/linux/arm/vpx_config.c index 9e8bc81..6361b2f8 100644 --- a/third_party/libvpx/source/config/linux/arm/vpx_config.c +++ b/third_party/libvpx/source/config/linux/arm/vpx_config.c
@@ -6,5 +6,5 @@ /* in the file PATENTS. All contributing project authors may */ /* be found in the AUTHORS file in the root of the source tree. */ #include "vpx/vpx_codec.h" -static const char* const cfg = "--target=armv6-linux-gcc --enable-pic --enable-realtime-only --disable-install-bins --disable-install-libs --disable-edsp --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; +static const char* const cfg = "--target=armv7-linux-gcc --enable-pic --enable-realtime-only --disable-install-bins --disable-install-libs --disable-neon --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; const char *vpx_codec_build_config(void) {return cfg;}
diff --git a/third_party/libvpx/source/config/linux/arm64/vpx_config.c b/third_party/libvpx/source/config/linux/arm64/vpx_config.c index 64b0c80..1b8dffc 100644 --- a/third_party/libvpx/source/config/linux/arm64/vpx_config.c +++ b/third_party/libvpx/source/config/linux/arm64/vpx_config.c
@@ -6,5 +6,5 @@ /* in the file PATENTS. All contributing project authors may */ /* be found in the AUTHORS file in the root of the source tree. */ #include "vpx/vpx_codec.h" -static const char* const cfg = "--force-target=armv8-linux-gcc --enable-pic --enable-realtime-only --disable-edsp --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; +static const char* const cfg = "--force-target=armv8-linux-gcc --enable-pic --enable-realtime-only --enable-external-build --enable-postproc --disable-install-srcs --enable-multi-res-encoding --enable-temporal-denoising --disable-unit-tests --disable-install-docs --disable-examples --enable-vp9-temporal-denoising --enable-vp9-postproc --size-limit=16384x16384 --as=yasm"; const char *vpx_codec_build_config(void) {return cfg;}
diff --git a/third_party/qcms/BUILD.gn b/third_party/qcms/BUILD.gn index b6f5f05..1183569b 100644 --- a/third_party/qcms/BUILD.gn +++ b/third_party/qcms/BUILD.gn
@@ -6,8 +6,7 @@ include_dirs = [ "src" ] } -# Do not build QCMS on Android or iOS. (See http://crbug.com/577155) -disable_qcms = is_android || is_ios +disable_qcms = false static_library("qcms") { if (disable_qcms) {
diff --git a/third_party/qcms/qcms.gyp b/third_party/qcms/qcms.gyp index 8a96979..9d52c0a 100644 --- a/third_party/qcms/qcms.gyp +++ b/third_party/qcms/qcms.gyp
@@ -4,14 +4,7 @@ { 'variables': { - 'conditions': [ - # Do not build QCMS on Android or iOS. (See http://crbug.com/577155) - ['OS == "android" or OS == "ios"', { - 'disable_qcms%': 1, - }, { - 'disable_qcms%': 0, - }], - ], + 'disable_qcms%': 0, }, 'targets': [ {
diff --git a/tools/android/mempressure.py b/tools/android/mempressure.py index ffa7c12..053f0a1 100755 --- a/tools/android/mempressure.py +++ b/tools/android/mempressure.py
@@ -12,7 +12,7 @@ _SRC_PATH = os.path.abspath(os.path.join( os.path.dirname(__file__), '..', '..')) -sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'catapult', 'devil') +sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'catapult', 'devil')) from devil.android import device_errors from devil.android import device_utils from devil.android import flag_changer
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 279ed57..a7196497 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -470,6 +470,7 @@ ldflags = [] base_cmake_args = ['-GNinja', + '-DCMAKE_BUILD_TYPE=Release', '-DLLVM_ENABLE_ASSERTIONS=ON', '-DLLVM_ENABLE_THREADS=OFF', '-DLLVM_ENABLE_TIMESTAMPS=OFF', @@ -477,13 +478,6 @@ '-DLLVM_USE_CRT_RELEASE=MT', ] - if use_head_revision: - # For ToT builds, which are used to catch compiler bugs early, enable debug - # info for better backtraces when crashing. - base_cmake_args += ['-DCMAKE_BUILD_TYPE=RelWithDebInfo'] - else: - base_cmake_args += ['-DCMAKE_BUILD_TYPE=Release'] - binutils_incdir = '' if sys.platform.startswith('linux'): binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include') @@ -658,13 +652,11 @@ # If any Chromium tools were built, install those now. RunCommand(['ninja', 'cr-install'], msvc_arch='x64') - if not use_head_revision: - # Strip the binaries to save size, except for ToT builds. - if sys.platform == 'darwin': - # See http://crbug.com/256342 - RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) - elif sys.platform.startswith('linux'): - RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) + if sys.platform == 'darwin': + # See http://crbug.com/256342 + RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) + elif sys.platform.startswith('linux'): + RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) # TODO(thakis): Check that `clang --version` matches VERSION.
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py index aadb2328..0148f9e 100644 --- a/tools/cygprofile/profile_android_startup.py +++ b/tools/cygprofile/profile_android_startup.py
@@ -31,7 +31,7 @@ sys.path.append(os.path.join(sys.path[0], '..', '..', 'tools', 'perf')) from chrome_telemetry_build import chromium_config sys.path.append(chromium_config.GetTelemetryDir()) -from telemetry.internal.util import webpagereplay +from telemetry.internal.util import wpr_server sys.path.append(os.path.join(sys.path[0], '..', '..', 'third_party', 'webpagereplay')) @@ -143,10 +143,9 @@ if self._is_test_ca_installed: args.extend(['--should_generate_certs', '--https_root_ca_cert_path=' + self._wpr_ca_cert_path]) - wpr_server = webpagereplay.ReplayServer(self._wpr_archive, + self._wpr_server = wpr_server.ReplayServer(self._wpr_archive, '127.0.0.1', 0, 0, None, args) - ports = wpr_server.StartServer()[:-1] - self._wpr_server = wpr_server + ports = self._wpr_server.StartServer()[:-1] self._host_http_port = ports[0] self._host_https_port = ports[1]
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md index d25782f..f06b517 100644 --- a/tools/gn/docs/reference.md +++ b/tools/gn/docs/reference.md
@@ -2022,6 +2022,7 @@ The output file directory corresponding to the path of the given file, not including a trailing slash. "//foo/bar/baz.txt" => "//out/Default/obj/foo/bar" + "gen_dir" The generated file directory corresponding to the path of the given file, not including a trailing slash. @@ -3437,20 +3438,6 @@ requires a lot of duplicate of rules) so should only be used when absolutely necessary. - concurrent_links - In integer expressing the number of links that Ninja will perform in - parallel. GN will create a pool for shared library and executable - link steps with this many processes. Since linking is memory- and - I/O-intensive, projects with many large targets may want to limit - the number of parallel steps to avoid overloading the computer. - Since creating static libraries is generally not as intensive - there is no limit to "alink" steps. - - Defaults to 0 which Ninja interprets as "no limit". - - The value used will be the one from the default toolchain of the - current build. - ``` ### **Invoking targets in toolchains**: @@ -3481,8 +3468,6 @@ ### **Example**: ``` toolchain("plugin_toolchain") { - concurrent_links = 8 - tool("cc") { command = "gcc {{source}}" ...
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc index 3501ec1..faa190e6 100644 --- a/tools/gn/function_toolchain.cc +++ b/tools/gn/function_toolchain.cc
@@ -332,20 +332,6 @@ " requires a lot of duplicate of rules) so should only be used when\n" " absolutely necessary.\n" "\n" - " concurrent_links\n" - " In integer expressing the number of links that Ninja will perform in\n" - " parallel. GN will create a pool for shared library and executable\n" - " link steps with this many processes. Since linking is memory- and\n" - " I/O-intensive, projects with many large targets may want to limit\n" - " the number of parallel steps to avoid overloading the computer.\n" - " Since creating static libraries is generally not as intensive\n" - " there is no limit to \"alink\" steps.\n" - "\n" - " Defaults to 0 which Ninja interprets as \"no limit\".\n" - "\n" - " The value used will be the one from the default toolchain of the\n" - " current build.\n" - "\n" "Invoking targets in toolchains:\n" "\n" " By default, when a target depends on another, there is an implicit\n" @@ -370,8 +356,6 @@ "\n" "Example:\n" " toolchain(\"plugin_toolchain\") {\n" - " concurrent_links = 8\n" - "\n" " tool(\"cc\") {\n" " command = \"gcc {{source}}\"\n" " ...\n" @@ -428,21 +412,6 @@ return Value(); } - // Read concurrent_links (if any). - const Value* concurrent_links_value = - block_scope.GetValue("concurrent_links", true); - if (concurrent_links_value) { - if (!concurrent_links_value->VerifyTypeIs(Value::INTEGER, err)) - return Value(); - if (concurrent_links_value->int_value() < 0 || - concurrent_links_value->int_value() > std::numeric_limits<int>::max()) { - *err = Err(*concurrent_links_value, "Value out of range."); - return Value(); - } - toolchain->set_concurrent_links( - static_cast<int>(concurrent_links_value->int_value())); - } - if (!block_scope.CheckForUnusedVars(err)) return Value();
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc index a7f56f9..fba1ccb 100644 --- a/tools/gn/ninja_build_writer.cc +++ b/tools/gn/ninja_build_writer.cc
@@ -254,10 +254,6 @@ } void NinjaBuildWriter::WriteAllPools() { - out_ << "pool link_pool\n" - << " depth = " << default_toolchain_->concurrent_links() << std::endl - << std::endl; - // Compute the pools referenced by all tools of all used toolchains. std::set<const Pool*> used_pools; for (const auto& pair : used_toolchains_) {
diff --git a/tools/gn/ninja_build_writer_unittest.cc b/tools/gn/ninja_build_writer_unittest.cc index abb54753..9fee37a 100644 --- a/tools/gn/ninja_build_writer_unittest.cc +++ b/tools/gn/ninja_build_writer_unittest.cc
@@ -66,9 +66,6 @@ "build build.ninja: gn\n" " generator = 1\n" " depfile = build.ninja.d\n"; - const char expected_link_pool[] = - "pool link_pool\n" - " depth = 0\n"; const char expected_other_pool[] = "pool other_toolchain_other_pool\n" " depth = 42\n"; @@ -91,7 +88,6 @@ "Within: " << out_str EXPECT_SNIPPET(expected_rule_gn); EXPECT_SNIPPET(expected_build_ninja); - EXPECT_SNIPPET(expected_link_pool); EXPECT_SNIPPET(expected_other_pool); EXPECT_SNIPPET(expected_toolchain); EXPECT_SNIPPET(expected_targets);
diff --git a/tools/gn/toolchain.cc b/tools/gn/toolchain.cc index 03c9c59..70c6ce06 100644 --- a/tools/gn/toolchain.cc +++ b/tools/gn/toolchain.cc
@@ -29,7 +29,6 @@ Toolchain::Toolchain(const Settings* settings, const Label& label) : Item(settings, label), - concurrent_links_(0), setup_complete_(false) { }
diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h index 4ccfdc8..7b61f34 100644 --- a/tools/gn/toolchain.h +++ b/tools/gn/toolchain.h
@@ -124,16 +124,9 @@ return substitution_bits_; } - void set_concurrent_links(int cl) { concurrent_links_ = cl; } - int concurrent_links() const { return concurrent_links_; } - private: std::unique_ptr<Tool> tools_[TYPE_NUMTYPES]; - // How many links to run in parallel. Only the default toolchain's version of - // this variable applies. - int concurrent_links_; - bool setup_complete_; // Substitutions used by the tools in this toolchain.
diff --git a/tools/ipc_fuzzer/message_lib/message_names.h b/tools/ipc_fuzzer/message_lib/message_names.h index 5a9e442..8b412d0 100644 --- a/tools/ipc_fuzzer/message_lib/message_names.h +++ b/tools/ipc_fuzzer/message_lib/message_names.h
@@ -7,8 +7,8 @@ #include <stdint.h> -#include <map> #include <string> +#include <unordered_map> #include "base/logging.h" #include "base/macros.h" @@ -46,8 +46,8 @@ } private: - typedef std::map<uint32_t, std::string> TypeToNameMap; - typedef std::map<std::string, uint32_t> NameToTypeMap; + typedef std::unordered_map<uint32_t, std::string> TypeToNameMap; + typedef std::unordered_map<std::string, uint32_t> NameToTypeMap; TypeToNameMap name_map_; NameToTypeMap type_map_;
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index bf1fc66..a905bd5f 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -1336,7 +1336,7 @@ ], 'gn_asan_edge_fuzzer_v8_heap_release_bot_x86': [ - 'gn', 'asan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', + 'gn', 'clang', 'asan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', 'x86', ], @@ -1356,12 +1356,12 @@ ], 'gn_asan_fuzzer_v8_heap_chrome_with_codecs_release_bot_x86': [ - 'gn', 'asan', 'fuzzer', 'v8_heap', 'chrome_with_codecs', 'release_bot', - 'x86', + 'gn', 'clang', 'asan', 'fuzzer', 'v8_heap', 'chrome_with_codecs', + 'release_bot', 'x86', ], 'gn_asan_fuzzer_v8_heap_release_bot_x86': [ - 'gn', 'asan', 'fuzzer', 'v8_heap', 'release_bot', 'x86', + 'gn', 'clang', 'asan', 'fuzzer', 'v8_heap', 'release_bot', 'x86', ], 'gn_asan_lsan_edge_debug_bot': [ @@ -1805,17 +1805,17 @@ ('swarming_gn_asan_clang_edge_fuzzer' '_static_v8_heap_x86_full_symbols_release'): [ 'swarming', 'gn', 'asan', 'clang_tot', 'edge', 'fuzzer', 'static', - 'v8_heap', 'full_symbols', 'release', + 'v8_heap', 'full_symbols', 'release', 'x86', ], 'swarming_gn_asan_clang_shared_v8_heap_x86_full_symbols_release': [ 'swarming', 'gn', 'asan', 'clang_tot', 'shared', 'v8_heap', - 'full_symbols', 'release', + 'full_symbols', 'release', 'x86', ], 'swarming_gn_asan_clang_fuzzer_static_v8_heap_x86_full_symbols_release': [ 'swarming', 'gn', 'asan', 'clang_tot', 'fuzzer', 'static', 'v8_heap', - 'full_symbols', 'release', + 'full_symbols', 'release', 'x86', ], 'swarming_gn_asan_disable_nacl_clang_tot_full_symbols_static_release': [
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index cba61b4..16a5904 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2755,6 +2755,15 @@ <summary>The Autofill credit card info bar was denied.</summary> </histogram> +<histogram name="Autofill.CreditCardFillingInfoBar" + enum="AutofillCreditCardInfoBar"> + <owner>mathp@chromium.org</owner> + <summary> + The relative frequency with which users accept, deny, or ignore the Autofill + credit card assisted filling infobar prompt. + </summary> +</histogram> + <histogram name="Autofill.CreditCardInfoBar" enum="AutofillCreditCardInfoBar"> <owner>isherman@chromium.org</owner> <summary> @@ -30442,6 +30451,13 @@ </summary> </histogram> +<histogram name="Net.QuicSession.RejectHasProof" enum="Boolean"> + <owner>rch@chromium.org</owner> + <summary> + True if the QUIC REJ message received from the server contains a proof. + </summary> +</histogram> + <histogram name="Net.QuicSession.RejectLength"> <owner>rch@chromium.org</owner> <summary> @@ -37778,6 +37794,15 @@ </summary> </histogram> +<histogram name="PageLoad.AbortTiming.ClientRedirect" units="ms"> + <owner>csharrison@chromium.org</owner> + <summary> + This metric is still experimental and not yet ready to be relied upon. + Measures the time from navigation start to the time the page load was + aborted by a client side redirect (Javascript navigation). + </summary> +</histogram> + <histogram name="PageLoad.AbortTiming.Close" units="ms"> <owner>csharrison@chromium.org</owner> <summary> @@ -47993,6 +48018,26 @@ </summary> </histogram> +<histogram name="SafeBrowsing.V4DecodeAdditionsResult" + enum="SafeBrowsingV4DecodeResult"> + <owner>vakh@chromium.org</owner> + <summary> + Track the result of decoding the Rice-encoded list of additions of 4-byte + hash prefixes. This is logged once per store, per update containing + Rice-encoded additions. + </summary> +</histogram> + +<histogram name="SafeBrowsing.V4DecodeRemovalsResult" + enum="SafeBrowsingV4DecodeResult"> + <owner>vakh@chromium.org</owner> + <summary> + Track the result of decoding the Rice-encoded list of indexes of hash + prefixes to remove since the last update. This is logged once per store, per + update containing Rice-encoded removals. + </summary> +</histogram> + <histogram name="SafeBrowsing.V4FullHashCacheResult" enum="SafeBrowsingV4FullHashCacheResult"> <owner>kcarattini@chromium.org</owner> @@ -48006,7 +48051,7 @@ </histogram> <histogram name="SafeBrowsing.V4StoreReadResult" - enum="SafeBrowsingStoreReadResult"> + enum="SafeBrowsingV4StoreReadResult"> <owner>vakh@chromium.org</owner> <summary> Track the parsing results of reading the SafeBrowsing V4 store file from @@ -48023,7 +48068,7 @@ </histogram> <histogram name="SafeBrowsing.V4StoreWriteResult" - enum="SafeBrowsingStoreWriteResult"> + enum="SafeBrowsingV4StoreWriteResult"> <owner>vakh@chromium.org</owner> <summary> Track the results of writing the SafeBrowsing V4 store file to disk. @@ -80733,6 +80778,7 @@ <int value="62" label="WINDOWS_DESKTOP_SEARCH_INFOBAR_DELEGATE"/> <int value="63" label="UPDATE_PASSWORD_INFOBAR_DELEGATE"/> <int value="64" label="DATA_REDUCTION_PROMO_INFOBAR_DELEGATE_ANDROID"/> + <int value="65" label="AUTOFILL_CC_ASSIST_INFOBAR_DELEGATE"/> </enum> <enum name="InfoBarResponse" type="int"> @@ -82509,6 +82555,7 @@ <int value="-1941852572" label="floating-virtual-keyboard"/> <int value="-1940806558" label="enable-syncfs-directory-operation"/> <int value="-1938263248" label="enable-extension-info-dialog"/> + <int value="-1934673791" label="gl-composited-texture-quad-border"/> <int value="-1930720286" label="nacl-debug-mask"/> <int value="-1928198763" label="enable-async-dns"/> <int value="-1925117279" label="disable-quic-https"/> @@ -89817,25 +89864,6 @@ <int value="4" label="NO_STATE_ERROR"/> </enum> -<enum name="SafeBrowsingStoreReadResult" type="int"> - <int value="0" label="READ_SUCCESS"/> - <int value="1" label="UNEXPECTED_READ_FAILURE"/> - <int value="2" label="FILE_UNREADABLE_FAILURE"/> - <int value="3" label="FILE_EMPTY_FAILURE"/> - <int value="4" label="PROTO_PARSING_FAILURE"/> - <int value="5" label="UNEXPECTED_MAGIC_NUMBER_FAILURE"/> - <int value="6" label="FILE_VERSION_TOO_LOW_FAILURE"/> - <int value="7" label="HASH_PREFIX_INFO_MISSING_FAILURE"/> -</enum> - -<enum name="SafeBrowsingStoreWriteResult" type="int"> - <int value="0" label="WRITE_SUCCESS"/> - <int value="1" label="UNEXPECTED_WRITE_FAILURE"/> - <int value="2" label="INVALID_RESPONSE_TYPE_FAILURE"/> - <int value="3" label="UNEXPECTED_BYTES_WRITTEN_FAILURE"/> - <int value="4" label="UNABLE_TO_RENAME_FAILURE"/> -</enum> - <enum name="SafeBrowsingV4ApplyUpdateResult" type="int"> <int value="0" label="APPLY_UPDATE_SUCCESS"/> <int value="1" label="UNEXPECTED_APPLY_UPDATE_FAILURE"/> @@ -89844,6 +89872,21 @@ <int value="4" label="ADDITIONS_SIZE_UNEXPECTED_FAILURE"/> <int value="5" label="ADDITIONS_HAS_EXISTING_PREFIX_FAILURE"/> <int value="6" label="UNEXPECTED_RESPONSE_TYPE_FAILURE"/> + <int value="7" label="REMOVALS_INDEX_TOO_LARGE_FAILURE"/> + <int value="8" label="RICE_DECODING_FAILURE"/> + <int value="9" label="UNEXPECTED_COMPRESSION_TYPE_ADDITIONS_FAILURE"/> + <int value="10" label="UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE"/> +</enum> + +<enum name="SafeBrowsingV4DecodeResult" type="int"> + <int value="0" label="DECODE_SUCCESS"/> + <int value="1" label="DECODE_NO_MORE_ENTRIES_FAILURE"/> + <int value="2" label="DECODE_REQUESTED_TOO_MANY_BITS_FAILURE"/> + <int value="3" label="DECODE_RAN_OUT_OF_BITS_FAILURE"/> + <int value="4" label="NUM_ENTRIES_NEGATIVE_FAILURE"/> + <int value="5" label="RICE_PARAMETER_NON_POSITIVE_FAILURE"/> + <int value="6" label="ENCODED_DATA_UNEXPECTED_EMPTY_FAILURE"/> + <int value="7" label="DECODED_INTEGER_OVERFLOW_FAILURE"/> </enum> <enum name="SafeBrowsingV4FullHashCacheResult" type="int"> @@ -89868,6 +89911,25 @@ <int value="6" label="ALREADY_PENDING_ERROR"/> </enum> +<enum name="SafeBrowsingV4StoreReadResult" type="int"> + <int value="0" label="READ_SUCCESS"/> + <int value="1" label="UNEXPECTED_READ_FAILURE"/> + <int value="2" label="FILE_UNREADABLE_FAILURE"/> + <int value="3" label="FILE_EMPTY_FAILURE"/> + <int value="4" label="PROTO_PARSING_FAILURE"/> + <int value="5" label="UNEXPECTED_MAGIC_NUMBER_FAILURE"/> + <int value="6" label="FILE_VERSION_TOO_LOW_FAILURE"/> + <int value="7" label="HASH_PREFIX_INFO_MISSING_FAILURE"/> +</enum> + +<enum name="SafeBrowsingV4StoreWriteResult" type="int"> + <int value="0" label="WRITE_SUCCESS"/> + <int value="1" label="UNEXPECTED_WRITE_FAILURE"/> + <int value="2" label="INVALID_RESPONSE_TYPE_FAILURE"/> + <int value="3" label="UNEXPECTED_BYTES_WRITTEN_FAILURE"/> + <int value="4" label="UNABLE_TO_RENAME_FAILURE"/> +</enum> + <enum name="SavePasswordPromptResponseType" type="int"> <int value="0" label="NO_RESPONSE"/> <int value="1" label="REMEMBER_PASSWORD"/> @@ -99800,6 +99862,7 @@ <suffix name="last_n" label="Offline recent pages"/> <suffix name="async_loading" label="Offline async loaded pages"/> <suffix name="custom_tabs" label="Offline custom tabs"/> + <suffix name="download" label="Offline downloaded pages"/> <affected-histogram name="OfflinePages.DeletePage.AccessCount"/> <affected-histogram name="OfflinePages.DeletePage.LastOpenToCreated"/> <affected-histogram name="OfflinePages.DeletePage.PageSize"/> @@ -99965,6 +100028,7 @@ <suffix name="AfterPaint.BeforeInteraction"/> <suffix name="AfterPaint.Before1sDelayedInteraction"/> <suffix name="DuringParse"/> + <affected-histogram name="PageLoad.AbortTiming.ClientRedirect"/> <affected-histogram name="PageLoad.AbortTiming.Close"/> <affected-histogram name="PageLoad.AbortTiming.ForwardBackNavigation"/> <affected-histogram name="PageLoad.AbortTiming.NewNavigation"/> @@ -100013,6 +100077,16 @@ name="PageLoad.AbortTiming.UnknownNavigation.BeforeCommit"/> </histogram_suffixes> +<histogram_suffixes name="PageLoadMetricsCacheInfo" separator="."> + <suffix name="NoStore" label="Main resource had cache-control: no-store"/> + <affected-histogram + name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/> + <affected-histogram + name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType.ForwardBackNavigation"/> + <affected-histogram + name="PageLoad.ParseTiming.NavigationToParseStart.LoadType.ForwardBackNavigation"/> +</histogram_suffixes> + <histogram_suffixes name="PageLoadMetricsClients" separator="." ordering="prefix"> <affected-histogram
diff --git a/tools/perf/benchmarks/page_cycler.py b/tools/perf/benchmarks/page_cycler.py index e888314..a62424f 100644 --- a/tools/perf/benchmarks/page_cycler.py +++ b/tools/perf/benchmarks/page_cycler.py
@@ -138,13 +138,14 @@ options = {'pageset_repeat': 3} @classmethod - def ShouldDisable(cls, possible_browser): # http://crbug.com/597656 - if (possible_browser.browser_type == 'reference' and - possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X'): - return True - # http://crbug.com/616781 + def ShouldDisable(cls, possible_browser): + if possible_browser.browser_type == 'reference': + if possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X': + return True # http://crbug.com/597656 + if possible_browser.platform.GetOSVersionName() == 'yosemite': + return True # http://crbug.com/634337 if possible_browser.platform.GetDeviceTypeName() == 'AOSP on BullHead': - return True + return True # http://crbug.com/616781 return False @classmethod
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index c905d8c..5975313 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -32,7 +32,7 @@ _DISABLED_TESTS = frozenset({ - # crbug.com/622409 + # crbug.com/634389 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:news:cnn', # pylint: disable=line-too-long # crbug.com/629123 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.browse:news:hackernews', # pylint: disable=line-too-long
diff --git a/tools/perf/benchmarks/tab_switching.py b/tools/perf/benchmarks/tab_switching.py index 2cd77df..689ac16 100644 --- a/tools/perf/benchmarks/tab_switching.py +++ b/tools/perf/benchmarks/tab_switching.py
@@ -49,6 +49,7 @@ @benchmark.Disabled('android') # http://crbug.com/460084 +@benchmark.Disabled('mac-reference') # http://crbug.com/634360 @benchmark.Enabled('has tabs') class TabSwitchingFiveBlankTabs(perf_benchmark.PerfBenchmark): """This test records the MPArch.RWH_TabSwitchPaintDuration histogram. @@ -68,8 +69,8 @@ @benchmark.Enabled('has tabs') -# http://crbug.com/460084, http://crbug.com/488067 -@benchmark.Disabled('android', 'linux') +# http://crbug.com/460084, http://crbug.com/488067, http://crbug.com/634347 +@benchmark.Disabled('android', 'linux', 'mac-reference') class TabSwitchingToughEnergyCases(perf_benchmark.PerfBenchmark): """This test records the MPArch.RWH_TabSwitchPaintDuration histogram.
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py index 458acfd2..c7f6d6c8 100755 --- a/tools/valgrind/chrome_tests.py +++ b/tools/valgrind/chrome_tests.py
@@ -453,9 +453,6 @@ def TestSql(self): return self.SimpleTest("chrome", "sql_unittests") - def TestSync(self): - return self.SimpleTest("chrome", "sync_unit_tests") - def TestLinuxSandbox(self): return self.SimpleTest("sandbox", "sandbox_linux_unittests") @@ -709,7 +706,6 @@ "sandbox": TestLinuxSandbox, "sandbox_linux_unittests": TestLinuxSandbox, "skia": TestSkia, "skia_unittests": TestSkia, "sql": TestSql, "sql_unittests": TestSql, - "sync": TestSync, "sync_unit_tests": TestSync, "sync_integration_tests": TestSyncIntegration, "sync_integration": TestSyncIntegration, "ui_base_unit": TestUIBaseUnit, "ui_base_unittests": TestUIBaseUnit, @@ -735,6 +731,8 @@ "as well.") parser.add_option("--baseline", action="store_true", default=False, help="generate baseline data instead of validating") + parser.add_option("-f", "--force", action="store_true", default=False, + help="run a broken test anyway") parser.add_option("--gtest_filter", help="additional arguments to --gtest_filter") parser.add_option("--gtest_repeat", help="argument for --gtest_repeat") @@ -793,7 +791,59 @@ if len(options.test) != 1 and options.gtest_filter: parser.error("--gtest_filter and multiple tests don't make sense together") + BROKEN_TESTS = { + 'drmemory_light': [ + 'addressinput', + 'aura', + 'base_unittests', + 'cc', + 'components', # x64 only? + 'content', + 'gfx', + 'mojo_public_bindings', + ], + 'drmemory_full': [ + 'addressinput', + 'aura', + 'base_unittests', + 'blink_heap', + 'blink_platform', + 'browser_tests', + 'cast', + 'cc', + 'chromedriver', + 'compositor', + 'content', + 'content_browsertests', + 'device', + 'events', + 'extensions', + 'gfx', + 'google_apis', + 'gpu', + 'ipc_tests', + 'jingle', + 'keyboard', + 'media', + 'midi', + 'mojo_common', + 'mojo_public_bindings', + 'mojo_public_sysperf', + 'mojo_public_system', + 'mojo_system', + 'net', + 'remoting', + 'unit', + 'url', + ], + } + for t in options.test: + if t in BROKEN_TESTS[options.valgrind_tool] and not options.force: + logging.info("Skipping broken %s test %s -- see crbug.com/633693" % + (options.valgrind_tool, t)) + return 0 + tests = ChromeTests(options, args, t) ret = tests.Run() if ret: return ret
diff --git a/ui/android/resources/resource_manager_impl_unittest.cc b/ui/android/resources/resource_manager_impl_unittest.cc index e3b6974..3fca7da 100644 --- a/ui/android/resources/resource_manager_impl_unittest.cc +++ b/ui/android/resources/resource_manager_impl_unittest.cc
@@ -52,7 +52,7 @@ canvas.drawColor(SK_ColorWHITE); small_bitmap.setImmutable(); - OnResourceReady(NULL, NULL, res_type, res_id, + OnResourceReady(nullptr, nullptr, res_type, res_id, gfx::ConvertToJavaBitmap(&small_bitmap), 0, 0, 0, 0, 0, 0, 0, 0); } @@ -103,7 +103,9 @@ resource_manager_.Init(host_.get()); } - ~ResourceManagerTest() override { window_android_->Destroy(NULL, NULL); } + ~ResourceManagerTest() override { + window_android_->Destroy(nullptr, nullptr); + } void PreloadResource(ui::SystemUIResourceType type) { resource_manager_.PreloadResource(ui::ANDROID_RESOURCE_TYPE_SYSTEM, type);
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 846bab0..ee97043 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -130,6 +130,8 @@ #elif defined(OS_MACOSX) settings.renderer_settings.release_overlay_resources_after_gpu_query = true; #endif + settings.renderer_settings.gl_composited_texture_quad_border = + command_line->HasSwitch(cc::switches::kGlCompositedTextureQuadBorder); // These flags should be mirrored by renderer versions in content/renderer/. settings.initial_debug_state.show_debug_borders =
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 8657405..bf496f5 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -265,6 +265,7 @@ "//skia", "//third_party/harfbuzz-ng", "//third_party/libpng", + "//third_party/qcms", "//third_party/zlib", ]
diff --git a/ui/gfx/DEPS b/ui/gfx/DEPS index 27aa7392f..73c5294 100644 --- a/ui/gfx/DEPS +++ b/ui/gfx/DEPS
@@ -3,6 +3,7 @@ "+skia/ext", "+third_party/harfbuzz-ng", "+third_party/skia", + "+third_party/qcms", "+ui/ios", "-testing/gmock",
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc index f513d4d..7e5f05a7 100644 --- a/ui/gfx/color_transform.cc +++ b/ui/gfx/color_transform.cc
@@ -8,7 +8,15 @@ #include "base/logging.h" #include "ui/gfx/color_space.h" +#include "ui/gfx/icc_profile.h" #include "ui/gfx/transform.h" +#include "third_party/qcms/src/qcms.h" + +#ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H +extern "C" { +#include "third_party/qcms/src/chain.h" +}; +#endif namespace gfx { @@ -178,7 +186,7 @@ dest_response.y() / source_response.y(), dest_response.z() / source_response.z()); - return bradford * adapter * Invert(bradford) * ret; + return Invert(bradford) * adapter * bradford * ret; } GFX_EXPORT float FromLinear(ColorSpace::TransferID id, float v) { @@ -547,14 +555,104 @@ Transform c_; }; +class QCMSColorTransform : public ColorTransform { + public: + // Takes ownership of the profiles + QCMSColorTransform(qcms_profile* from, qcms_profile* to) + : from_(from), to_(to) {} + ~QCMSColorTransform() { + qcms_profile_release(from_); + qcms_profile_release(to_); + } + void transform(TriStim* colors, size_t num) override { + CHECK(sizeof(TriStim) == sizeof(float[3])); + // QCMS doesn't like numbers outside 0..1 + for (size_t i = 0; i < num; i++) { + colors[i].set_x(fmin(1.0f, fmax(0.0f, colors[i].x()))); + colors[i].set_y(fmin(1.0f, fmax(0.0f, colors[i].y()))); + colors[i].set_z(fmin(1.0f, fmax(0.0f, colors[i].z()))); + } + qcms_chain_transform(from_, to_, reinterpret_cast<float*>(colors), + reinterpret_cast<float*>(colors), num * 3); + } + + private: + qcms_profile *from_, *to_; +}; + +class ChainColorTransform : public ColorTransform { + public: + ChainColorTransform(std::unique_ptr<ColorTransform> a, + std::unique_ptr<ColorTransform> b) + : a_(std::move(a)), b_(std::move(b)) {} + + private: + void transform(TriStim* colors, size_t num) override { + a_->transform(colors, num); + b_->transform(colors, num); + } + std::unique_ptr<ColorTransform> a_; + std::unique_ptr<ColorTransform> b_; +}; + +qcms_profile* GetQCMSProfileIfAvailable(const ColorSpace& color_space) { + ICCProfile icc_profile = ICCProfile::FromColorSpace(color_space); + if (icc_profile.GetData().empty()) + return nullptr; + return qcms_profile_from_memory(icc_profile.GetData().data(), + icc_profile.GetData().size()); +} + +qcms_profile* GetXYZD50Profile() { + // QCMS is trixy, it has a datatype called qcms_CIE_xyY, but what it expects + // is in fact not xyY color coordinates, it just wants the x/y values of the + // primaries with Y equal to 1.0. + qcms_CIE_xyYTRIPLE xyz; + qcms_CIE_xyY w; + xyz.red.x = 1.0f; + xyz.red.y = 0.0f; + xyz.red.Y = 1.0f; + xyz.green.x = 0.0f; + xyz.green.y = 1.0f; + xyz.green.Y = 1.0f; + xyz.blue.x = 0.0f; + xyz.blue.y = 0.0f; + xyz.blue.Y = 1.0f; + w.x = 0.34567f; + w.y = 0.35850f; + w.Y = 1.0f; + return qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f); +} + std::unique_ptr<ColorTransform> ColorTransform::NewColorTransform( const ColorSpace& from, const ColorSpace& to, Intent intent) { - // TODO(Hubbe): Check if from and/or to can be mapped to ICC profiles and - // provide better transforms in those cases. - return std::unique_ptr<ColorTransform>( - new ColorSpaceToColorSpaceTransform(from, to, intent)); + qcms_profile* from_profile = GetQCMSProfileIfAvailable(from); + qcms_profile* to_profile = GetQCMSProfileIfAvailable(to); + if (from_profile) { + if (to_profile) { + return std::unique_ptr<ColorTransform>( + new QCMSColorTransform(from_profile, to_profile)); + } else { + return std::unique_ptr<ColorTransform>(new ChainColorTransform( + std::unique_ptr<ColorTransform>( + new QCMSColorTransform(from_profile, GetXYZD50Profile())), + std::unique_ptr<ColorTransform>(new ColorSpaceToColorSpaceTransform( + ColorSpace::CreateXYZD50(), to, intent)))); + } + } else { + if (to_profile) { + return std::unique_ptr<ColorTransform>(new ChainColorTransform( + std::unique_ptr<ColorTransform>(new ColorSpaceToColorSpaceTransform( + from, ColorSpace::CreateXYZD50(), intent)), + std::unique_ptr<ColorTransform>( + new QCMSColorTransform(GetXYZD50Profile(), to_profile)))); + } else { + return std::unique_ptr<ColorTransform>( + new ColorSpaceToColorSpaceTransform(from, to, intent)); + } + } } } // namespace gfx
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index 0d686e0..d943c7d 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/logging.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/color_space.h" #include "ui/gfx/color_transform.h" +#include "ui/gfx/icc_profile.h" #include "ui/gfx/transform.h" namespace gfx { @@ -78,6 +80,290 @@ EXPECT_GT(tmp.z(), tmp.y()); } +unsigned char srgb_icc_data[] = { + 0x00, 0x00, 0x0b, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xd9, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x15, 0x00, 0x24, 0x00, 0x1f, + 0x61, 0x63, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x00, 0x00, 0x00, 0x00, + 0x12, 0xe2, 0xc7, 0xe9, 0xc6, 0x02, 0x6e, 0x10, 0x5e, 0xdb, 0x15, 0x15, + 0x9c, 0x6f, 0x26, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, 0x00, 0x79, + 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c, + 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c, + 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x09, 0xe0, 0x00, 0x00, 0x00, 0x88, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x0a, 0x68, 0x00, 0x00, 0x00, 0x14, + 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x0a, 0x7c, 0x00, 0x00, 0x00, 0x14, + 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x0a, 0x90, 0x00, 0x00, 0x00, 0x24, + 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x0a, 0xb4, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x0a, 0xc8, 0x00, 0x00, 0x00, 0x14, + 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x0a, 0xdc, 0x00, 0x00, 0x00, 0x0c, + 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x87, + 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x0b, 0x70, 0x00, 0x00, 0x00, 0x14, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x0b, 0x84, 0x00, 0x00, 0x00, 0x37, + 0x63, 0x68, 0x61, 0x64, 0x00, 0x00, 0x0b, 0xbc, 0x00, 0x00, 0x00, 0x2c, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, + 0x36, 0x2d, 0x32, 0x2d, 0x31, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x20, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xcf, + 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, + 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, + 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, + 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72, + 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90, + 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae, + 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb, + 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb, + 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d, + 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, + 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, + 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, + 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, + 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, + 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14, + 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b, + 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84, + 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1, + 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00, + 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43, + 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, + 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, + 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, + 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, + 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, + 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c, + 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77, + 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5, + 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37, + 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d, + 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07, + 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, + 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, + 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, + 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, + 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, + 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf, + 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54, + 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc, + 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69, + 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9, + 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e, + 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, + 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, + 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, + 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, + 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, + 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61, + 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13, + 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9, + 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84, + 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43, + 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06, + 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, + 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, + 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, + 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, + 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, + 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa, + 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd, + 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5, + 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2, + 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3, + 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99, + 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, + 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, + 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, + 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, + 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, + 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2, + 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda, + 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7, + 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18, + 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f, + 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b, + 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, + 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, + 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, + 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, + 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, + 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb, + 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a, + 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f, + 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8, + 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37, + 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c, + 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, + 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, + 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, + 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, + 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, + 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64, + 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee, + 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d, + 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12, + 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab, + 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b, + 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, + 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, + 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, + 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, + 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, + 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c, + 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42, + 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f, + 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0, + 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8, + 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95, + 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, + 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, + 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, + 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, + 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, + 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d, + 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43, + 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f, + 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60, + 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78, + 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95, + 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, + 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, + 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, + 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, + 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, + 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2, + 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a, + 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57, + 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab, + 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04, + 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64, + 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, + 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, + 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, + 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, + 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, + 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24, + 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf, + 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40, + 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8, + 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76, + 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a, + 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, + 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, + 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, + 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, + 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, + 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79, + 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a, + 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21, + 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff, + 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3, + 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce, + 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, + 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, + 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, + 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, + 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, + 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8, + 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1, + 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10, + 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36, + 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63, + 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96, + 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, + 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, + 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, + 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, + 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, + 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57, + 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba, + 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, + 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2d, 0x31, 0x20, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x43, 0x6f, + 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x53, 0x70, 0x61, 0x63, 0x65, 0x20, 0x2d, + 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, + 0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x87, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, + 0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x73, 0x69, 0x67, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, + 0x2d, 0x32, 0x2d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x78, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x43, 0x6f, + 0x6e, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x75, 0x6d, 0x2c, 0x20, 0x32, 0x30, + 0x30, 0x39, 0x00, 0x00, 0x73, 0x66, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x0c, 0x44, 0x00, 0x00, 0x05, 0xdf, 0xff, 0xff, 0xf3, 0x26, + 0x00, 0x00, 0x07, 0x94, 0x00, 0x00, 0xfd, 0x8f, 0xff, 0xff, 0xfb, 0xa1, + 0xff, 0xff, 0xfd, 0xa2, 0x00, 0x00, 0x03, 0xdb, 0x00, 0x00, 0xc0, 0x75}; + +TEST(SimpleColorSpace, BT709toSRGBICC) { + ICCProfile srgb_icc = ICCProfile::FromData( + reinterpret_cast<char*>(srgb_icc_data), arraysize(srgb_icc_data)); + + ColorSpace bt709 = ColorSpace::CreateREC709(); + ColorSpace sRGB = srgb_icc.GetColorSpace(); + std::unique_ptr<ColorTransform> t(ColorTransform::NewColorTransform( + bt709, sRGB, ColorTransform::Intent::ABSOLUTE)); + + ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); + t->transform(&tmp, 1); + EXPECT_NEAR(tmp.x(), 0.0f, 0.001f); + EXPECT_NEAR(tmp.y(), 0.0f, 0.001f); + EXPECT_NEAR(tmp.z(), 0.0f, 0.001f); + + tmp = ColorTransform::TriStim(235.0f / 255.0f, 0.5f, 0.5f); + t->transform(&tmp, 1); + EXPECT_NEAR(tmp.x(), 1.0f, 0.001f); + EXPECT_NEAR(tmp.y(), 1.0f, 0.001f); + EXPECT_NEAR(tmp.z(), 1.0f, 0.001f); + + // Test a blue color + tmp = ColorTransform::TriStim(128.0f / 255.0f, 240.0f / 255.0f, 0.5f); + t->transform(&tmp, 1); + EXPECT_GT(tmp.z(), tmp.x()); + EXPECT_GT(tmp.z(), tmp.y()); +} + TEST(SimpleColorSpace, UnknownToSRGB) { ColorSpace unknown; ColorSpace sRGB = ColorSpace::CreateSRGB();
diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp index 3df9eda..620e37a 100644 --- a/ui/gfx/gfx.gyp +++ b/ui/gfx/gfx.gyp
@@ -82,6 +82,7 @@ '<(DEPTH)/third_party/icu/icu.gyp:icui18n', '<(DEPTH)/third_party/icu/icu.gyp:icuuc', '<(DEPTH)/third_party/libpng/libpng.gyp:libpng', + '<(DEPTH)//third_party/qcms/qcms.gyp:qcms", '<(DEPTH)/third_party/zlib/zlib.gyp:zlib', 'gfx_geometry', 'gfx_range',
diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc index cd3e4e8..9fbbdd0 100644 --- a/ui/gfx/icc_profile.cc +++ b/ui/gfx/icc_profile.cc
@@ -46,11 +46,11 @@ } // static -ICCProfile ICCProfile::FromData(const std::vector<char>& icc_profile_data) { +ICCProfile ICCProfile::FromData(const char* data, size_t size) { ICCProfile icc_profile; - if (IsValidProfileLength(icc_profile_data.size())) { + if (IsValidProfileLength(size)) { icc_profile.valid_ = true; - icc_profile.data_ = icc_profile_data; + icc_profile.data_.insert(icc_profile.data_.begin(), data, data + size); } if (!icc_profile.valid_) return icc_profile;
diff --git a/ui/gfx/icc_profile.h b/ui/gfx/icc_profile.h index 3b34ca2..7a2ad768 100644 --- a/ui/gfx/icc_profile.h +++ b/ui/gfx/icc_profile.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <vector> +#include "base/gtest_prod_util.h" #include "ui/gfx/color_space.h" #if defined(OS_MACOSX) @@ -57,7 +58,7 @@ #endif private: - static ICCProfile FromData(const std::vector<char>& icc_profile); + static ICCProfile FromData(const char* icc_profile, size_t size); static bool IsValidProfileLength(size_t length); bool valid_ = false; @@ -67,6 +68,7 @@ // profile from a ColorSpace object created from it. uint64_t id_ = 0; + FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, BT709toSRGBICC); friend class ColorSpace; friend struct IPC::ParamTraits<gfx::ICCProfile>; };
diff --git a/ui/gfx/icc_profile_mac.mm b/ui/gfx/icc_profile_mac.mm index 92fe8dd..ec51749 100644 --- a/ui/gfx/icc_profile_mac.mm +++ b/ui/gfx/icc_profile_mac.mm
@@ -24,7 +24,7 @@ const unsigned char* data = CFDataGetBytePtr(cf_icc_profile); std::vector<char> vector_icc_profile; vector_icc_profile.assign(data, data + length); - return FromData(vector_icc_profile); + return FromData(vector_icc_profile.data(), vector_icc_profile.size()); } } // namespace gfx
diff --git a/ui/gfx/icc_profile_win.cc b/ui/gfx/icc_profile_win.cc index 826ecde..7e1b0ca0 100644 --- a/ui/gfx/icc_profile_win.cc +++ b/ui/gfx/icc_profile_win.cc
@@ -57,7 +57,8 @@ void ICCProfile::UpdateCachedProfilesOnBackgroundThread() { std::vector<char> icc_profile; ReadBestMonitorICCProfile(&icc_profile); - gfx::ICCProfile color_space = FromData(icc_profile); + gfx::ICCProfile color_space = FromData( + icc_profile.data(), icc_profile.size()); base::AutoLock lock(g_best_monitor_color_space_lock.Get()); g_best_monitor_color_space.Get() = color_space;
diff --git a/ui/gfx/mojo/transform.mojom b/ui/gfx/mojo/transform.mojom index 1ce0e753..5d6103d 100644 --- a/ui/gfx/mojo/transform.mojom +++ b/ui/gfx/mojo/transform.mojom
@@ -6,6 +6,6 @@ // See ui/gfx/transform.h. struct Transform { - // Row major order. + // Column major order. array<float, 16> matrix; };
diff --git a/ui/gfx/mojo/transform.typemap b/ui/gfx/mojo/transform.typemap index 848cd071..e2f6921 100644 --- a/ui/gfx/mojo/transform.typemap +++ b/ui/gfx/mojo/transform.typemap
@@ -5,5 +5,8 @@ mojom = "//ui/gfx/mojo/transform.mojom" public_headers = [ "//ui/gfx/transform.h" ] traits_headers = [ "//ui/gfx/mojo/transform_struct_traits.h" ] -public_deps = [ "//ui/gfx" ] +public_deps = [ + "//mojo/public/cpp/bindings", + "//ui/gfx", +] type_mappings = [ "gfx.mojom.Transform=gfx::Transform" ]
diff --git a/ui/gfx/mojo/transform_struct_traits.h b/ui/gfx/mojo/transform_struct_traits.h index df51a6f..a55122e 100644 --- a/ui/gfx/mojo/transform_struct_traits.h +++ b/ui/gfx/mojo/transform_struct_traits.h
@@ -5,26 +5,34 @@ #ifndef UI_GFX_MOJO_TRANSFORM_STRUCT_TRAITS_H_ #define UI_GFX_MOJO_TRANSFORM_STRUCT_TRAITS_H_ +#include "mojo/public/cpp/bindings/array_traits.h" #include "ui/gfx/mojo/transform.mojom.h" #include "ui/gfx/transform.h" namespace mojo { template <> +struct ArrayTraits<SkMatrix44> { + using Element = float; + + static size_t GetSize(const SkMatrix44& input) { return 16; } + + static float GetAt(const SkMatrix44& input, size_t index) { + return input.getFloat(static_cast<int>(index % 4), + static_cast<int>(index / 4)); + } +}; + +template <> struct StructTraits<gfx::mojom::Transform, gfx::Transform> { - static mojo::Array<float> matrix(const gfx::Transform& transform) { - std::vector<float> storage(16); - transform.matrix().asRowMajorf(&storage[0]); - mojo::Array<float> matrix; - matrix.Swap(&storage); - return matrix; + static const SkMatrix44& matrix(const gfx::Transform& transform) { + return transform.matrix(); } static bool Read(gfx::mojom::TransformDataView data, gfx::Transform* out) { - mojo::Array<float> matrix; - if (!data.ReadMatrix(&matrix)) - return false; - out->matrix().setRowMajorf(&matrix.storage()[0]); + ArrayDataView<float> matrix; + data.GetMatrixDataView(&matrix); + out->matrix().setColMajorf(matrix.data()); return true; } };
diff --git a/ui/gl/init/BUILD.gn b/ui/gl/init/BUILD.gn index c7d1e67..baec674 100644 --- a/ui/gl/init/BUILD.gn +++ b/ui/gl/init/BUILD.gn
@@ -60,8 +60,6 @@ sources += [ "gl_factory_ozone.cc", "gl_initializer_ozone.cc", - "gl_surface_ozone.cc", - "gl_surface_ozone.h", ] deps += [ "//ui/ozone" ]
diff --git a/ui/gl/init/gl_factory_ozone.cc b/ui/gl/init/gl_factory_ozone.cc index 2fdcec5..ca53347 100644 --- a/ui/gl/init/gl_factory_ozone.cc +++ b/ui/gl/init/gl_factory_ozone.cc
@@ -17,10 +17,8 @@ #include "ui/gl/gl_surface_egl.h" #include "ui/gl/gl_surface_osmesa.h" #include "ui/gl/gl_surface_stub.h" -#include "ui/gl/init/gl_surface_ozone.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/surface_factory_ozone.h" -#include "ui/ozone/public/surface_ozone_egl.h" namespace gl { namespace init { @@ -62,34 +60,6 @@ return nullptr; } -// TODO(kylechar): Remove when all implementations are switched over. -scoped_refptr<GLSurface> CreateViewGLSurfaceOld(gfx::AcceleratedWidget window) { - switch (GetGLImplementation()) { - case kGLImplementationEGLGLES2: - DCHECK_NE(window, gfx::kNullAcceleratedWidget); - return CreateViewGLSurfaceOzone(window); - default: - NOTREACHED(); - } - return nullptr; -} - -// TODO(kylechar): Remove when all implementations are switched over. -scoped_refptr<GLSurface> CreateOffscreenGLSurfaceOld(const gfx::Size& size) { - switch (GetGLImplementation()) { - case kGLImplementationEGLGLES2: - if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && - (size.width() == 0 && size.height() == 0)) { - return InitializeGLSurface(new SurfacelessEGL(size)); - } else { - return InitializeGLSurface(new PbufferGLSurfaceEGL(size)); - } - default: - NOTREACHED(); - } - return nullptr; -} - } // namespace std::vector<GLImplementation> GetAllowedGLImplementations() { @@ -121,11 +91,10 @@ case kGLImplementationEGLGLES2: return InitializeGLContext(new GLContextEGL(share_group), compatible_surface, gpu_preference); - default: NOTREACHED(); - return nullptr; } + return nullptr; } scoped_refptr<GLSurface> CreateViewGLSurface(gfx::AcceleratedWidget window) { @@ -134,10 +103,6 @@ if (HasDefaultImplementation(GetGLImplementation())) return CreateDefaultViewGLSurface(window); - // TODO(kylechar): This is deprecated, remove when possible. - if (!GetSurfaceFactory()->UseNewSurfaceAPI()) - return CreateViewGLSurfaceOld(window); - return GetSurfaceFactory()->CreateViewGLSurface(GetGLImplementation(), window); } @@ -156,10 +121,6 @@ if (HasDefaultImplementation(GetGLImplementation())) return CreateDefaultOffscreenGLSurface(size); - // TODO(kylechar): This is deprecated, remove when possible. - if (!GetSurfaceFactory()->UseNewSurfaceAPI()) - return CreateOffscreenGLSurfaceOld(size); - return GetSurfaceFactory()->CreateOffscreenGLSurface(GetGLImplementation(), size); }
diff --git a/ui/gl/init/gl_init.gyp b/ui/gl/init/gl_init.gyp index 78375eb4..2eb113e9 100644 --- a/ui/gl/init/gl_init.gyp +++ b/ui/gl/init/gl_init.gyp
@@ -38,8 +38,6 @@ 'gl_factory_win.cc', 'gl_factory_x11.cc', 'gl_init_export.h', - 'gl_surface_ozone.cc', - 'gl_surface_ozone.h', ], 'conditions': [ ['OS=="mac"', {
diff --git a/ui/gl/init/gl_surface_ozone.cc b/ui/gl/init/gl_surface_ozone.cc deleted file mode 100644 index a7315be..0000000 --- a/ui/gl/init/gl_surface_ozone.cc +++ /dev/null
@@ -1,194 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gl/init/gl_surface_ozone.h" - -#include <stddef.h> - -#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/scoped_vector.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/worker_pool.h" -#include "ui/gl/egl_util.h" -#include "ui/gl/gl_context.h" -#include "ui/gl/gl_image.h" -#include "ui/gl/gl_implementation.h" -#include "ui/gl/gl_surface_egl.h" -#include "ui/gl/gl_surface_osmesa.h" -#include "ui/gl/gl_surface_overlay.h" -#include "ui/gl/gl_surface_stub.h" -#include "ui/gl/scoped_binders.h" -#include "ui/gl/scoped_make_current.h" -#include "ui/ozone/gl/gl_image_ozone_native_pixmap.h" -#include "ui/ozone/public/native_pixmap.h" -#include "ui/ozone/public/ozone_platform.h" -#include "ui/ozone/public/surface_factory_ozone.h" -#include "ui/ozone/public/surface_ozone_egl.h" - -namespace gl { - -namespace { - -// Helper function for base::Bind to create callback to eglChooseConfig. -bool EglChooseConfig(EGLDisplay display, - const int32_t* attribs, - EGLConfig* configs, - int32_t config_size, - int32_t* num_configs) { - return eglChooseConfig(display, attribs, configs, config_size, num_configs); -} - -// Helper function for base::Bind to create callback to eglGetConfigAttrib. -bool EglGetConfigAttribute(EGLDisplay display, - EGLConfig config, - int32_t attribute, - int32_t* value) { - return eglGetConfigAttrib(display, config, attribute, value); -} - -// Populates EglConfigCallbacks with appropriate callbacks. -ui::EglConfigCallbacks GetEglConfigCallbacks(EGLDisplay display) { - ui::EglConfigCallbacks callbacks; - callbacks.choose_config = base::Bind(EglChooseConfig, display); - callbacks.get_config_attribute = base::Bind(EglGetConfigAttribute, display); - callbacks.get_last_error_string = base::Bind(&ui::GetLastEGLErrorString); - return callbacks; -} - -// A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow. -class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { - public: - GLSurfaceOzoneEGL(std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, - gfx::AcceleratedWidget widget); - - // GLSurface: - bool Initialize(GLSurface::Format format) override; - bool Resize(const gfx::Size& size, - float scale_factor, - bool has_alpha) override; - gfx::SwapResult SwapBuffers() override; - bool ScheduleOverlayPlane(int z_order, - gfx::OverlayTransform transform, - GLImage* image, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect) override; - EGLConfig GetConfig() override; - - private: - using NativeViewGLSurfaceEGL::Initialize; - - ~GLSurfaceOzoneEGL() override; - - bool ReinitializeNativeSurface(); - - // The native surface. Deleting this is allowed to free the EGLNativeWindow. - std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface_; - gfx::AcceleratedWidget widget_; - - DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL); -}; - -GLSurfaceOzoneEGL::GLSurfaceOzoneEGL( - std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, - gfx::AcceleratedWidget widget) - : NativeViewGLSurfaceEGL(ozone_surface->GetNativeWindow()), - ozone_surface_(std::move(ozone_surface)), - widget_(widget) {} - -bool GLSurfaceOzoneEGL::Initialize(GLSurface::Format format) { - format_ = format; - return Initialize(ozone_surface_->CreateVSyncProvider()); -} - -bool GLSurfaceOzoneEGL::Resize(const gfx::Size& size, - float scale_factor, - bool has_alpha) { - if (!ozone_surface_->ResizeNativeWindow(size)) { - if (!ReinitializeNativeSurface() || - !ozone_surface_->ResizeNativeWindow(size)) - return false; - } - - return NativeViewGLSurfaceEGL::Resize(size, scale_factor, has_alpha); -} - -gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() { - gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers(); - if (result != gfx::SwapResult::SWAP_ACK) - return result; - - return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK - : gfx::SwapResult::SWAP_FAILED; -} - -bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order, - gfx::OverlayTransform transform, - GLImage* image, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect) { - return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect, - crop_rect); -} - -EGLConfig GLSurfaceOzoneEGL::GetConfig() { - if (!config_) { - ui::EglConfigCallbacks callbacks = GetEglConfigCallbacks(GetDisplay()); - config_ = ozone_surface_->GetEGLSurfaceConfig(callbacks); - } - if (config_) - return config_; - return NativeViewGLSurfaceEGL::GetConfig(); -} - -GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() { - Destroy(); // The EGL surface must be destroyed before SurfaceOzone. -} - -bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() { - std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current; - GLContext* current_context = GLContext::GetCurrent(); - bool was_current = current_context && current_context->IsCurrent(this); - if (was_current) { - scoped_make_current.reset(new ui::ScopedMakeCurrent(current_context, this)); - } - - Destroy(); - ozone_surface_ = ui::OzonePlatform::GetInstance() - ->GetSurfaceFactoryOzone() - ->CreateEGLSurfaceForWidget(widget_); - if (!ozone_surface_) { - LOG(ERROR) << "Failed to create native surface."; - return false; - } - - window_ = ozone_surface_->GetNativeWindow(); - if (!Initialize(format_)) { - LOG(ERROR) << "Failed to initialize."; - return false; - } - - return true; -} - -} // namespace - -scoped_refptr<GLSurface> CreateViewGLSurfaceOzone( - gfx::AcceleratedWidget window) { - std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone = - ui::OzonePlatform::GetInstance() - ->GetSurfaceFactoryOzone() - ->CreateEGLSurfaceForWidget(window); - if (!surface_ozone) - return nullptr; - return InitializeGLSurface( - new GLSurfaceOzoneEGL(std::move(surface_ozone), window)); -} - -} // namespace gl
diff --git a/ui/gl/init/gl_surface_ozone.h b/ui/gl/init/gl_surface_ozone.h deleted file mode 100644 index 3203f30..0000000 --- a/ui/gl/init/gl_surface_ozone.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_GL_INIT_GL_SURFACE_OZONE_H_ -#define UI_GL_INIT_GL_SURFACE_OZONE_H_ - -#include "base/memory/ref_counted.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/gl/gl_surface.h" - -namespace gl { - -// TODO(kylechar): These functions, plus the corresponding GLSurface classes -// have been moved into //ui/gl/init as a temporary step to break the dependency -// from //ui/gl to //ui/ozone. Once that dependency is broken the Ozone -// GLSurface classes should be made into base classes for each Ozone platform to -// override and moved back to //ui/gl. - -scoped_refptr<GLSurface> CreateViewGLSurfaceOzone( - gfx::AcceleratedWidget window); - -} // namespace gl - -#endif // UI_GL_INIT_GL_SURFACE_OZONE_H_
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn index a35e783a..5f46ca5 100644 --- a/ui/ozone/BUILD.gn +++ b/ui/ozone/BUILD.gn
@@ -82,8 +82,7 @@ "public/surface_factory_ozone.cc", "public/surface_factory_ozone.h", "public/surface_ozone_canvas.h", - "public/surface_ozone_egl.cc", - "public/surface_ozone_egl.h", + "public/swap_completion_callback.h", "public/system_input_injector.h", ]
diff --git a/ui/ozone/common/egl_util.cc b/ui/ozone/common/egl_util.cc index b33407a..0dd4d332 100644 --- a/ui/ozone/common/egl_util.cc +++ b/ui/ozone/common/egl_util.cc
@@ -86,27 +86,4 @@ return config; } -void* /* EGLConfig */ ChooseEGLConfig(const EglConfigCallbacks& egl, - const int32_t* attributes) { - void* config; - int32_t num_configs; - if (!egl.choose_config.Run(attributes, nullptr, 0, &num_configs)) { - LOG(ERROR) << "eglChooseConfig failed with error " - << egl.get_last_error_string.Run(); - return nullptr; - } - - if (num_configs == 0) { - LOG(ERROR) << "No suitable EGL configs found."; - return nullptr; - } - - if (!egl.choose_config.Run(attributes, &config, 1, &num_configs)) { - LOG(ERROR) << "eglChooseConfig failed with error " - << egl.get_last_error_string.Run(); - return nullptr; - } - return config; -} - } // namespace ui
diff --git a/ui/ozone/common/egl_util.h b/ui/ozone/common/egl_util.h index 64d336c8..99fee71d 100644 --- a/ui/ozone/common/egl_util.h +++ b/ui/ozone/common/egl_util.h
@@ -6,7 +6,6 @@ #define UI_OZONE_COMMON_EGL_UTIL_H_ #include "ui/ozone/public/surface_factory_ozone.h" -#include "ui/ozone/public/surface_ozone_egl.h" namespace ui { @@ -25,10 +24,6 @@ void* /* EGLConfig */ ChooseEGLConfig(void* /* EGLConfig */ display, const int32_t* attributes); -// TODO(kylechar): This is deprecated, delete when all callers are gone. -void* /* EGLConfig */ ChooseEGLConfig(const EglConfigCallbacks& egl, - const int32_t* attributes); - } // namespace ui #endif // UI_OZONE_COMMON_EGL_UTIL_H_
diff --git a/ui/ozone/ozone.gyp b/ui/ozone/ozone.gyp index 485137ae..1f09044 100644 --- a/ui/ozone/ozone.gyp +++ b/ui/ozone/ozone.gyp
@@ -63,8 +63,7 @@ 'public/surface_factory_ozone.cc', 'public/surface_factory_ozone.h', 'public/surface_ozone_canvas.h', - 'public/surface_ozone_egl.cc', - 'public/surface_ozone_egl.h', + 'public/swap_completion_callback.h', 'public/system_input_injector.h', ], },
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc index e6c06c14..7074271 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -167,10 +167,6 @@ overlay_bounds_ = display_bounds; } -bool SurfaceFactoryCast::UseNewSurfaceAPI() { - return true; -} - scoped_refptr<gl::GLSurface> SurfaceFactoryCast::CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) {
diff --git a/ui/ozone/platform/cast/surface_factory_cast.h b/ui/ozone/platform/cast/surface_factory_cast.h index 67aaad22..632367f 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.h +++ b/ui/ozone/platform/cast/surface_factory_cast.h
@@ -30,7 +30,6 @@ ~SurfaceFactoryCast() override; // SurfaceFactoryOzone implementation: - bool UseNewSurfaceAPI() override; scoped_refptr<gl::GLSurface> CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) override;
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h index 9580c91..ca91988e 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.h +++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -20,7 +20,7 @@ #include "ui/gfx/vsync_provider.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" #include "ui/ozone/public/interfaces/device_cursor.mojom.h" -#include "ui/ozone/public/surface_ozone_egl.h" +#include "ui/ozone/public/swap_completion_callback.h" namespace base { struct FileDescriptor;
diff --git a/ui/ozone/platform/drm/gpu/drm_window.h b/ui/ozone/platform/drm/gpu/drm_window.h index 84ee2554..877ff0c7 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.h +++ b/ui/ozone/platform/drm/gpu/drm_window.h
@@ -16,7 +16,7 @@ #include "ui/gfx/vsync_provider.h" #include "ui/ozone/platform/drm/gpu/overlay_plane.h" #include "ui/ozone/platform/drm/gpu/page_flip_request.h" -#include "ui/ozone/public/surface_ozone_egl.h" +#include "ui/ozone/public/swap_completion_callback.h" class SkBitmap;
diff --git a/ui/ozone/platform/drm/gpu/drm_window_proxy.h b/ui/ozone/platform/drm/gpu/drm_window_proxy.h index b358364..40213f4 100644 --- a/ui/ozone/platform/drm/gpu/drm_window_proxy.h +++ b/ui/ozone/platform/drm/gpu/drm_window_proxy.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/vsync_provider.h" -#include "ui/ozone/public/surface_ozone_egl.h" +#include "ui/ozone/public/swap_completion_callback.h" namespace ui {
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc index 1633000..df62b301 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -54,10 +54,6 @@ return it->second; } -bool GbmSurfaceFactory::UseNewSurfaceAPI() { - return true; -} - scoped_refptr<gl::GLSurface> GbmSurfaceFactory::CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) {
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h index f35edf1..0e6a1f7 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
@@ -33,7 +33,6 @@ GbmSurfaceless* GetSurface(gfx::AcceleratedWidget widget) const; // SurfaceFactoryOzone: - bool UseNewSurfaceAPI() override; scoped_refptr<gl::GLSurface> CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) override;
diff --git a/ui/ozone/platform/drm/gpu/page_flip_request.h b/ui/ozone/platform/drm/gpu/page_flip_request.h index 5d3d8019..09eb305 100644 --- a/ui/ozone/platform/drm/gpu/page_flip_request.h +++ b/ui/ozone/platform/drm/gpu/page_flip_request.h
@@ -11,7 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "ui/gfx/swap_result.h" -#include "ui/ozone/public/surface_ozone_egl.h" +#include "ui/ozone/public/swap_completion_callback.h" namespace ui {
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.cc b/ui/ozone/platform/wayland/wayland_surface_factory.cc index 5c809ba..80acd19 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/wayland_surface_factory.cc
@@ -17,7 +17,6 @@ #include "ui/ozone/platform/wayland/wayland_object.h" #include "ui/ozone/platform/wayland/wayland_window.h" #include "ui/ozone/public/surface_ozone_canvas.h" -#include "ui/ozone/public/surface_ozone_egl.h" #if defined(USE_WAYLAND_EGL) #include "ui/ozone/platform/wayland/gl_surface_wayland.h"
diff --git a/ui/ozone/platform/x11/x11_surface_factory.cc b/ui/ozone/platform/x11/x11_surface_factory.cc index 986dda1..f061a7f 100644 --- a/ui/ozone/platform/x11/x11_surface_factory.cc +++ b/ui/ozone/platform/x11/x11_surface_factory.cc
@@ -125,10 +125,6 @@ X11SurfaceFactory::~X11SurfaceFactory() {} -bool X11SurfaceFactory::UseNewSurfaceAPI() { - return true; -} - scoped_refptr<gl::GLSurface> X11SurfaceFactory::CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) {
diff --git a/ui/ozone/platform/x11/x11_surface_factory.h b/ui/ozone/platform/x11/x11_surface_factory.h index 93620ad4..0a2ffa5 100644 --- a/ui/ozone/platform/x11/x11_surface_factory.h +++ b/ui/ozone/platform/x11/x11_surface_factory.h
@@ -20,7 +20,6 @@ ~X11SurfaceFactory() override; // SurfaceFactoryOzone: - bool UseNewSurfaceAPI() override; scoped_refptr<gl::GLSurface> CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) override;
diff --git a/ui/ozone/public/surface_factory_ozone.cc b/ui/ozone/public/surface_factory_ozone.cc index 76050437..55e3be9 100644 --- a/ui/ozone/public/surface_factory_ozone.cc +++ b/ui/ozone/public/surface_factory_ozone.cc
@@ -9,24 +9,17 @@ #include "base/command_line.h" #include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/surface_ozone_canvas.h" -#include "ui/ozone/public/surface_ozone_egl.h" namespace ui { -SurfaceFactoryOzone::SurfaceFactoryOzone() { -} +SurfaceFactoryOzone::SurfaceFactoryOzone() {} -SurfaceFactoryOzone::~SurfaceFactoryOzone() { -} +SurfaceFactoryOzone::~SurfaceFactoryOzone() {} intptr_t SurfaceFactoryOzone::GetNativeDisplay() { return 0; } -bool SurfaceFactoryOzone::UseNewSurfaceAPI() { - return true; -} - scoped_refptr<gl::GLSurface> SurfaceFactoryOzone::CreateViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget) { @@ -46,17 +39,6 @@ return nullptr; } -std::unique_ptr<SurfaceOzoneEGL> SurfaceFactoryOzone::CreateEGLSurfaceForWidget( - gfx::AcceleratedWidget widget) { - return nullptr; -} - -std::unique_ptr<SurfaceOzoneEGL> -SurfaceFactoryOzone::CreateSurfacelessEGLSurfaceForWidget( - gfx::AcceleratedWidget widget) { - return nullptr; -} - std::unique_ptr<SurfaceOzoneCanvas> SurfaceFactoryOzone::CreateCanvasForWidget( gfx::AcceleratedWidget widget) { return nullptr;
diff --git a/ui/ozone/public/surface_factory_ozone.h b/ui/ozone/public/surface_factory_ozone.h index 0522b45..de8d5bd 100644 --- a/ui/ozone/public/surface_factory_ozone.h +++ b/ui/ozone/public/surface_factory_ozone.h
@@ -27,7 +27,6 @@ class NativePixmap; class SurfaceOzoneCanvas; -class SurfaceOzoneEGL; // The Ozone interface allows external implementations to hook into Chromium to // provide a system specific implementation. The Ozone interface supports two @@ -71,10 +70,6 @@ // display connection for the native display. virtual intptr_t GetNativeDisplay(); - // Checks if platform uses the new surface creation API. - // TODO(kylechar): Delete when using all implementations use new surface API. - virtual bool UseNewSurfaceAPI(); - // Creates a GL surface that renders directly to a view for the specified GL // implementation. virtual scoped_refptr<gl::GLSurface> CreateViewGLSurface( @@ -82,7 +77,9 @@ gfx::AcceleratedWidget widget); // Creates a GL surface that renders directly into a window with surfaceless - // semantics for the specified GL implementation. + // semantics for the specified GL implementation. The surface is not backed + // by any buffers and is used for overlay-only displays. This will return + // nullptr if surfaceless mode unsupported. virtual scoped_refptr<gl::GLSurface> CreateSurfacelessViewGLSurface( gl::GLImplementation implementation, gfx::AcceleratedWidget widget); @@ -93,20 +90,6 @@ gl::GLImplementation implementation, const gfx::Size& size); - // Create SurfaceOzoneEGL for the specified gfx::AcceleratedWidget. - // - // Note: When used from content, this is called in the GPU process. The - // platform must support creation of SurfaceOzoneEGL from the GPU process - // using only the handle contained in gfx::AcceleratedWidget. - virtual std::unique_ptr<SurfaceOzoneEGL> CreateEGLSurfaceForWidget( - gfx::AcceleratedWidget widget); - - // Create an EGL surface that isn't backed by any buffers, and is used - // for overlay-only displays. This will return NULL if this mode is - // not supported. - virtual std::unique_ptr<SurfaceOzoneEGL> CreateSurfacelessEGLSurfaceForWidget( - gfx::AcceleratedWidget widget); - // Create SurfaceOzoneCanvas for the specified gfx::AcceleratedWidget. // // Note: The platform must support creation of SurfaceOzoneCanvas from the
diff --git a/ui/ozone/public/surface_ozone_egl.cc b/ui/ozone/public/surface_ozone_egl.cc deleted file mode 100644 index ba61f4f..0000000 --- a/ui/ozone/public/surface_ozone_egl.cc +++ /dev/null
@@ -1,20 +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 "ui/ozone/public/surface_ozone_egl.h" - -namespace ui { - -EglConfigCallbacks::EglConfigCallbacks() {} - -EglConfigCallbacks::EglConfigCallbacks(const EglConfigCallbacks& other) = - default; - -EglConfigCallbacks::~EglConfigCallbacks() {} - -bool SurfaceOzoneEGL::IsUniversalDisplayLinkDevice() { - return false; -} - -} // namespace ui
diff --git a/ui/ozone/public/surface_ozone_egl.h b/ui/ozone/public/surface_ozone_egl.h deleted file mode 100644 index a8a6553..0000000 --- a/ui/ozone/public/surface_ozone_egl.h +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_OZONE_PUBLIC_SURFACE_OZONE_EGL_H_ -#define UI_OZONE_PUBLIC_SURFACE_OZONE_EGL_H_ - -#include <memory> - -#include "base/callback.h" -#include "ui/gfx/overlay_transform.h" -#include "ui/gfx/swap_result.h" -#include "ui/ozone/ozone_base_export.h" - -namespace gfx { -class Size; -class VSyncProvider; -} - -namespace ui { -class NativePixmap; - -typedef base::Callback<void(gfx::SwapResult)> SwapCompletionCallback; - -// Holds callbacks to functions for configuring EGL on platform. -struct OZONE_BASE_EXPORT EglConfigCallbacks { - EglConfigCallbacks(); - EglConfigCallbacks(const EglConfigCallbacks& other); - ~EglConfigCallbacks(); - base::Callback<bool(const int32_t* attribs, - void** /* EGLConfig* */ configs, - int32_t config_size, - int32_t* num_configs)> - choose_config; - base::Callback< - bool(void* /* EGLConfig */ config, int32_t attribute, int32_t* value)> - get_config_attribute; - base::Callback<const char*()> get_last_error_string; -}; - -// The platform-specific part of an EGL surface. -// -// This class owns any bits that the ozone implementation needs freed when -// the EGL surface is destroyed. -class OZONE_BASE_EXPORT SurfaceOzoneEGL { - public: - virtual ~SurfaceOzoneEGL() {} - - // Returns the EGL native window for rendering onto this surface. - // This can be used to to create a GLSurface. - virtual intptr_t /* EGLNativeWindowType */ GetNativeWindow() = 0; - - // Attempts to resize the EGL native window to match the viewport - // size. - virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) = 0; - - // Called after we swap buffers. This is usually a no-op but can - // be used to present the new front buffer if the platform requires this. - virtual bool OnSwapBuffers() = 0; - - // Called after we swap buffers. This is usually a no-op but can - // be used to present the new front buffer if the platform requires this. - // The callback should be run on the calling thread - // (i.e. same thread SwapBuffersAsync is called). - virtual void OnSwapBuffersAsync(const SwapCompletionCallback& callback) = 0; - - // Returns a gfx::VsyncProvider for this surface. Note that this may be - // called after we have entered the sandbox so if there are operations (e.g. - // opening a file descriptor providing vsync events) that must be done - // outside of the sandbox, they must have been completed in - // InitializeHardware. Returns an empty scoped_ptr on error. - virtual std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() = 0; - - // Returns true if the surface is created on a UDL device. - virtual bool IsUniversalDisplayLinkDevice(); - - // Returns the EGL configuration to use for this surface. The default EGL - // configuration will be used if this returns nullptr. - virtual void* /* EGLConfig */ GetEGLSurfaceConfig( - const EglConfigCallbacks& egl) = 0; -}; - -} // namespace ui - -#endif // UI_OZONE_PUBLIC_SURFACE_OZONE_EGL_H_
diff --git a/ui/ozone/public/swap_completion_callback.h b/ui/ozone/public/swap_completion_callback.h new file mode 100644 index 0000000..8dfc583 --- /dev/null +++ b/ui/ozone/public/swap_completion_callback.h
@@ -0,0 +1,17 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PUBLIC_SWAP_COMPLETION_CALLBACK_H_ +#define UI_OZONE_PUBLIC_SWAP_COMPLETION_CALLBACK_H_ + +#include "base/callback.h" +#include "ui/gfx/swap_result.h" + +namespace ui { + +using SwapCompletionCallback = base::Callback<void(gfx::SwapResult)>; + +} // namespace ui + +#endif // UI_OZONE_PUBLIC_SWAP_COMPLETION_CALLBACK_H_
diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc index 2389915d..a16ed870 100644 --- a/ui/views/mus/window_manager_connection.cc +++ b/ui/views/mus/window_manager_connection.cc
@@ -41,7 +41,7 @@ // we are still valid. client_.reset(); ui::Clipboard::DestroyClipboardForCurrentThread(); - ui::GpuService::Terminate(); + gpu_service_.reset(); lazy_tls_ptr.Pointer()->Set(nullptr); if (ViewsDelegate::GetInstance()) { @@ -150,8 +150,7 @@ : connector_(connector), identity_(identity) { lazy_tls_ptr.Pointer()->Set(this); - ui::GpuService::Initialize(connector); - + gpu_service_ = ui::GpuService::Initialize(connector); client_.reset(new ui::WindowTreeClient(this, nullptr, nullptr)); client_->ConnectViaWindowTreeFactory(connector_);
diff --git a/ui/views/mus/window_manager_connection.h b/ui/views/mus/window_manager_connection.h index 867e97b..69291f7 100644 --- a/ui/views/mus/window_manager_connection.h +++ b/ui/views/mus/window_manager_connection.h
@@ -24,6 +24,10 @@ class Connector; } +namespace ui { +class GpuService; +} + namespace views { class ClipboardMus; class NativeWidget; @@ -96,6 +100,7 @@ shell::Identity identity_; std::unique_ptr<ScreenMus> screen_; std::unique_ptr<ui::WindowTreeClient> client_; + std::unique_ptr<ui::GpuService> gpu_service_; // Must be empty on destruction. base::ObserverList<PointerWatcher, true> pointer_watchers_; base::ObserverList<TouchEventWatcher, true> touch_event_watchers_;
diff --git a/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp b/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp index 7e71e2bd..b722f17e 100644 --- a/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp +++ b/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp
@@ -14,6 +14,7 @@ { 'target_name': 'cr_policy_pref_behavior', 'dependencies': [ + '<(EXTERNS_GYP):settings_private', 'cr_policy_indicator_behavior', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/ui/webui/resources/css/roboto.css b/ui/webui/resources/css/roboto.css index 0ff4df5..00cbd32a 100644 --- a/ui/webui/resources/css/roboto.css +++ b/ui/webui/resources/css/roboto.css
@@ -2,6 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +<if expr="not chromeos"> @font-face { font-family: 'Roboto'; font-style: normal; @@ -25,3 +26,4 @@ src: local('Roboto Bold'), local('Roboto-Bold'), url(chrome://resources/roboto/roboto-bold.woff2) format('woff2'); } +</if>
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index 352b60d..34e3ba8 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -17,8 +17,9 @@ <include name="IDR_WEBUI_JSTEMPLATE_JS" file="js/jstemplate_compiled.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_WEBUI_ANALYTICS_JS" file="js/analytics.js" flattenhtml="true" type="BINDATA" /> <!-- Roboto Font. Roboto-Regular and Roboto-Light is already available on - Android, and Roboto-Medium is not used on Android. --> - <if expr="not android"> + Android, and Roboto-Medium is not used on Android. All 6 weights of + Roboto are available on Chrome OS.--> + <if expr="not android and not chromeos"> <include name="IDR_WEBUI_ROBOTO_ROBOTO_REGULAR_WOFF2" file="roboto/roboto-regular.woff2" type="BINDATA" /> <include name="IDR_WEBUI_ROBOTO_ROBOTO_MEDIUM_WOFF2" file="roboto/roboto-medium.woff2" type="BINDATA" /> <include name="IDR_WEBUI_ROBOTO_ROBOTO_BOLD_WOFF2" file="roboto/roboto-bold.woff2" type="BINDATA" /> @@ -240,7 +241,7 @@ <structure name="IDR_WEBUI_CSS_OVERLAY" file="css/overlay.css" type="chrome_html" flattenhtml="true" /> - <structure name="IDR_WEBUI_CSS_ROBOTO" + <structure name="IDR_WEBUI_CSS_ROBOTO" preprocess="true" file="css/roboto.css" type="chrome_html" /> <structure name="IDR_WEBUI_CSS_SPINNER" file="css/spinner.css" type="chrome_html"
diff --git a/url/BUILD.gn b/url/BUILD.gn index 764e3a9..c6020fb 100644 --- a/url/BUILD.gn +++ b/url/BUILD.gn
@@ -73,12 +73,7 @@ # ICU support. if (use_platform_icu_alternatives) { if (is_android) { - sources += [ - "android/url_jni_registrar.cc", - "android/url_jni_registrar.h", - "url_canon_icu_alternatives_android.cc", - "url_canon_icu_alternatives_android.h", - ] + sources += [ "url_canon_icu_alternatives_android.cc" ] deps += [ ":url_features", ":url_java",
diff --git a/url/android/url_jni_registrar.cc b/url/android/url_jni_registrar.cc deleted file mode 100644 index f594d24..0000000 --- a/url/android/url_jni_registrar.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "url/android/url_jni_registrar.h" -#include "url/url_features.h" - -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) -#include "url/url_canon_icu_alternatives_android.h" -#endif - -namespace url { -namespace android { - -bool RegisterJni(JNIEnv* env) { -#if BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES) - return RegisterIcuAlternativesJni(env); -#endif - - // Do nothing if USE_PLATFORM_ICU_ALTERNATIVES is false. - return true; -} - -} // namespace android -} // namespace url
diff --git a/url/android/url_jni_registrar.h b/url/android/url_jni_registrar.h deleted file mode 100644 index 8fe7ded..0000000 --- a/url/android/url_jni_registrar.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef URL_ANDROID_URL_JNI_REGISTRAR_H_ -#define URL_ANDROID_URL_JNI_REGISTRAR_H_ - -#include <jni.h> - -#include "url/url_export.h" - -namespace url { -namespace android { - -// Register all JNI bindings necessary for url. -URL_EXPORT bool RegisterJni(JNIEnv* env); - -} // namespace android -} // namespace url - -#endif // URL_ANDROID_URL_JNI_REGISTRAR_H_
diff --git a/url/url.gyp b/url/url.gyp index a7e5b02..12f23f5 100644 --- a/url/url.gyp +++ b/url/url.gyp
@@ -50,7 +50,6 @@ ], 'sources': [ 'url_canon_icu_alternatives_android.cc', - 'url_canon_icu_alternatives_android.h', ], }], ['OS == "ios"', {
diff --git a/url/url_canon_icu_alternatives_android.cc b/url/url_canon_icu_alternatives_android.cc index f43efce5..9536bc7 100644 --- a/url/url_canon_icu_alternatives_android.cc +++ b/url/url_canon_icu_alternatives_android.cc
@@ -34,8 +34,4 @@ return true; } -bool RegisterIcuAlternativesJni(JNIEnv* env) { - return android::RegisterNativesImpl(env); -} - } // namespace url
diff --git a/url/url_canon_icu_alternatives_android.h b/url/url_canon_icu_alternatives_android.h deleted file mode 100644 index 67306db..0000000 --- a/url/url_canon_icu_alternatives_android.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef URL_URL_CANON_ICU_ALTERNATIVES_ANDROID_H_ -#define URL_URL_CANON_ICU_ALTERNATIVES_ANDROID_H_ - -#include <jni.h> - -namespace url { - -// Explicitly register static JNI functions needed when not using ICU. -bool RegisterIcuAlternativesJni(JNIEnv* env); - -} // namespace url - -#endif // URL_URL_CANON_ICU_ALTERNATIVES_ANDROID_H_ -
diff --git a/url/url_srcs.gypi b/url/url_srcs.gypi index dfa1e3f..ec1615f 100644 --- a/url/url_srcs.gypi +++ b/url/url_srcs.gypi
@@ -5,8 +5,6 @@ { 'variables': { 'gurl_sources': [ - 'android/url_jni_registrar.cc', - 'android/url_jni_registrar.h', 'gurl.cc', 'gurl.h', 'origin.cc',